From 333d31b32c95d686781876d569e87fdf6a5c01ca Mon Sep 17 00:00:00 2001 From: Vivek Panyam Date: Fri, 20 Oct 2023 17:45:30 -0400 Subject: [PATCH] Build and upload the C and C++ bindings in nightly builds --- .buildkite/nightly.yml | 6 +- .github/workflows/nightly.yml | 25 +++- Cargo.lock | 5 + ci/build.py | 17 ++- ci/trigger_cirrus_build.py | 14 ++- source/build-utils/Cargo.toml | 7 ++ .../src/bin/build_c_cpp_bindings.rs | 118 ++++++++++++++++++ .../src/bin/upload_c_cpp_bindings.rs | 71 +++++++++++ source/build-utils/src/lib.rs | 117 +++++++++++------ source/carton-bindings-c/Cargo.toml | 2 +- .../tests/test_c_examples.rs | 13 +- .../tests/test_cpp_examples.rs | 3 +- 12 files changed, 337 insertions(+), 61 deletions(-) create mode 100644 source/build-utils/src/bin/build_c_cpp_bindings.rs create mode 100644 source/build-utils/src/bin/upload_c_cpp_bindings.rs diff --git a/.buildkite/nightly.yml b/.buildkite/nightly.yml index b424975..e38b616 100644 --- a/.buildkite/nightly.yml +++ b/.buildkite/nightly.yml @@ -3,11 +3,12 @@ steps: - name: "Native Build x86_64-unknown-linux-gnu" agents: queue: default - command: "python3 ci/build.py --release --target x86_64-unknown-linux-gnu --nightly --runner_release_dir target/runner_releases" + command: "python3 ci/build.py --release --target x86_64-unknown-linux-gnu --nightly --runner_release_dir target/runner_releases --c_cpp_bindings_release_dir target/bindings_releases" artifact_paths: - "target/cargo-timings/*" - "target/wheels/*" - "target/runner_releases/*" + - "target/bindings_releases/*" plugins: - docker-compose#v3.7.0: run: x86_64 @@ -16,11 +17,12 @@ steps: - name: "Native Build aarch64-unknown-linux-gnu" agents: queue: arm64 - command: "python3 ci/build.py --release --target aarch64-unknown-linux-gnu --nightly --runner_release_dir target/runner_releases" + command: "python3 ci/build.py --release --target aarch64-unknown-linux-gnu --nightly --runner_release_dir target/runner_releases --c_cpp_bindings_release_dir target/bindings_releases" artifact_paths: - "target/cargo-timings/*" - "target/wheels/*" - "target/runner_releases/*" + - "target/bindings_releases/*" plugins: - docker-compose#v3.7.0: run: arm64 diff --git a/.github/workflows/nightly.yml b/.github/workflows/nightly.yml index 71b3fa2..a3c86a8 100644 --- a/.github/workflows/nightly.yml +++ b/.github/workflows/nightly.yml @@ -18,7 +18,7 @@ jobs: - run: rustup default stable - uses: Swatinem/rust-cache@v2 - run: pip3 install toml maturin==0.14.13 - - run: python3 ci/build.py --target x86_64-apple-darwin --release --nightly --runner_release_dir /tmp/runner_releases + - run: python3 ci/build.py --target x86_64-apple-darwin --release --nightly --runner_release_dir /tmp/runner_releases --c_cpp_bindings_release_dir /tmp/bindings_releases - name: Upload runners uses: actions/upload-artifact@v3 with: @@ -29,6 +29,11 @@ jobs: with: name: py-wheels-macos-x86 path: target/wheels/ + - name: Upload C/C++ bindings + uses: actions/upload-artifact@v3 + with: + name: c-cpp-bindings-x86_64-apple-darwin + path: /tmp/bindings_releases nightly_release_mac_aarch64: name: "Native Build macOS aarch64" runs-on: ubuntu-latest @@ -50,6 +55,11 @@ jobs: with: name: py-wheels-macos-aarch64 path: /tmp/target/wheels/ + - name: Upload C/C++ bindings + uses: actions/upload-artifact@v3 + with: + name: c-cpp-bindings-macos-aarch64 + path: /tmp/bindings_releases nightly_release_buildkite: name: "Native Builds Linux (x86_64 and aarch64)" runs-on: ubuntu-latest @@ -71,6 +81,11 @@ jobs: with: name: py-wheels-linux path: /tmp/target/wheels/ + - name: Upload C/C++ bindings + uses: actions/upload-artifact@v3 + with: + name: c-cpp-bindings-linux + path: /tmp/target/bindings_releases upload_nightly_builds: name: "Upload nightly builds" @@ -101,6 +116,14 @@ jobs: TWINE_USERNAME: __token__ TWINE_PASSWORD: ${{ secrets.PYPI_NIGHTLY_TOKEN }} TWINE_NON_INTERACTIVE: true + - name: Upload C and C++ bindings + run: cargo run --package build-utils --bin upload_c_cpp_bindings + env: + CARTON_NIGHTLY_S3_BUCKET: ${{ vars.CARTON_NIGHTLY_S3_BUCKET }} + CARTON_NIGHTLY_S3_REGION: ${{ vars.CARTON_NIGHTLY_S3_REGION }} + CARTON_NIGHTLY_S3_ENDPOINT: ${{ secrets.CARTON_NIGHTLY_S3_ENDPOINT }} + CARTON_NIGHTLY_ACCESS_KEY_ID: ${{ secrets.CARTON_NIGHTLY_ACCESS_KEY_ID }} + CARTON_NIGHTLY_SECRET_ACCESS_KEY: ${{ secrets.CARTON_NIGHTLY_SECRET_ACCESS_KEY }} build_wasm: name: WASM Build wasm32-unknown-unknown runs-on: ubuntu-latest diff --git a/Cargo.lock b/Cargo.lock index 3b84bdc..228419c 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -434,8 +434,13 @@ name = "build-utils" version = "0.0.1" dependencies = [ "cc", + "clap 4.4.6", + "env_logger 0.9.3", "escargot", "log", + "rust-s3", + "tempfile", + "tokio", ] [[package]] diff --git a/ci/build.py b/ci/build.py index 53a39a3..ed2e72d 100644 --- a/ci/build.py +++ b/ci/build.py @@ -63,18 +63,23 @@ def update_version_numbers(): parser.add_argument("--nightly", action="store_true", help="Update version numbers with a dev build suffix") parser.add_argument("--hide_output", action="store_true", help="Redirect all subprocess output to /dev/null") parser.add_argument("--runner_release_dir", help="The runner release dir (if any)") + parser.add_argument("--c_cpp_bindings_release_dir", help="The C/C++ bindings release dir (if any)") args = parser.parse_args() TARGET = args.target RELEASE_FLAG = "--release" if args.release else None HIDE_OUTPUT = args.hide_output + # We don't use `--locked` on nightly builds because we need to change version numbers + LOCKED_FLAG = "--locked" if not args.nightly else None + print(f""" Building with configuration: Target: `{TARGET}` Release mode: {args.release} Nightly mode: {args.nightly} Runner release dir: {args.runner_release_dir} + Bindings release dir: {args.c_cpp_bindings_release_dir} """) # Check up front so we don't build and then fail @@ -82,6 +87,10 @@ def update_version_numbers(): if os.path.exists(args.runner_release_dir): raise ValueError("Supplied runner release dir already exists! Please remove it and try again.") + if args.c_cpp_bindings_release_dir is not None: + if os.path.exists(args.c_cpp_bindings_release_dir): + raise ValueError("Supplied runner bindings dir already exists! Please remove it and try again.") + # Update version numbers if this is a nightly build if args.nightly: update_version_numbers() @@ -94,10 +103,10 @@ def update_version_numbers(): os.environ["LIBTORCH_CXX11_ABI"] = "0" # Fetch deps (always in release mode) - run_command(["cargo", "run", "--locked", "--timings", "--release", "-p", "fetch-deps", "--target", TARGET]) + run_command(["cargo", "run", LOCKED_FLAG, "--timings", "--release", "-p", "fetch-deps", "--target", TARGET]) # Build everything - run_command(["cargo", "build", "--locked", RELEASE_FLAG, "--verbose", "--timings", "--target", TARGET]) + run_command(["cargo", "build", LOCKED_FLAG, RELEASE_FLAG, "--verbose", "--timings", "--target", TARGET]) # Build wheels for the python bindings # TODO: store timing info @@ -118,6 +127,10 @@ def update_version_numbers(): run_command(["cargo", "run", RELEASE_FLAG, "--timings", "--target", TARGET, "-p", "carton-runner-torch", "--bin", "build_torch_releases", "--", "--output-path", args.runner_release_dir]) run_command(["cargo", "run", RELEASE_FLAG, "--timings", "--target", TARGET, "-p", "carton-runner-wasm", "--bin", "build_wasm_releases", "--", "--output-path", args.runner_release_dir]) + if args.c_cpp_bindings_release_dir is not None: + os.makedirs(args.c_cpp_bindings_release_dir) + run_command(["cargo", "run", RELEASE_FLAG, "--timings", "--target", TARGET, "-p", "build-utils", "--bin", "build_c_cpp_bindings", "--", "--bindings-path", args.c_cpp_bindings_release_dir, "--target", TARGET]) + # Show sccache stats RUSTC_WRAPPER = os.getenv("RUSTC_WRAPPER", "") if "sccache" in RUSTC_WRAPPER: diff --git a/ci/trigger_cirrus_build.py b/ci/trigger_cirrus_build.py index 974df34..cf6ac4e 100644 --- a/ci/trigger_cirrus_build.py +++ b/ci/trigger_cirrus_build.py @@ -108,11 +108,13 @@ build_and_test_script: - source $HOME/.cargo/env - pip3 install toml maturin==0.14.13 - - python3 ci/build.py --target aarch64-apple-darwin --release --nightly --runner_release_dir $CIRRUS_WORKING_DIR/runner_releases + - python3 ci/build.py --target aarch64-apple-darwin --release --nightly --runner_release_dir $CIRRUS_WORKING_DIR/runner_releases --c_cpp_bindings_release_dir $CIRRUS_WORKING_DIR/bindings_releases binaries_artifacts: path: "runner_releases/*" wheels_artifacts: path: "target/wheels/*" + bindings_artifacts: + path: "bindings_releases/*" """ @@ -170,3 +172,13 @@ with zipfile.ZipFile("/tmp/wheels.zip", 'r') as zip_ref: zip_ref.extractall("/tmp") + + +print("Downloading bindings...") +res = requests.get(f"https://api.cirrus-ci.com/v1/artifact/build/{build_id}/bindings.zip", headers={"Authorization": CIRRUS_AUTH}) + +with open("/tmp/bindings.zip", "wb") as f: + f.write(res.content) + +with zipfile.ZipFile("/tmp/bindings.zip", 'r') as zip_ref: + zip_ref.extractall("/tmp") diff --git a/source/build-utils/Cargo.toml b/source/build-utils/Cargo.toml index 6e8b156..c95499b 100644 --- a/source/build-utils/Cargo.toml +++ b/source/build-utils/Cargo.toml @@ -8,3 +8,10 @@ publish = false escargot = "0.5.8" log = "0.4" cc = "1.0" +clap = { version = "4.0.29", features = ["derive"] } +env_logger = "0.9" +tempfile = "3.3.0" + +# Required by the bindings upload code +rust-s3 = { version = "0.32.3", features = ["tokio-rustls-tls"], default-features = false } +tokio = { version = "1", features = ["full"] } \ No newline at end of file diff --git a/source/build-utils/src/bin/build_c_cpp_bindings.rs b/source/build-utils/src/bin/build_c_cpp_bindings.rs new file mode 100644 index 0000000..2c1d4bc --- /dev/null +++ b/source/build-utils/src/bin/build_c_cpp_bindings.rs @@ -0,0 +1,118 @@ +// Copyright 2023 Vivek Panyam +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +use std::{ + path::{Path, PathBuf}, + process::Command, +}; + +use build_utils::{build_c_bindings, build_cpp_bindings}; +use clap::Parser; + +#[derive(Parser, Debug)] +struct Args { + /// The local folder to output bindings too + #[arg(long)] + bindings_path: PathBuf, + + /// The compilation target (used as a suffix for the bindings tar) + #[arg(long)] + target: String, +} + +fn main() { + // Logging + env_logger::Builder::from_env(env_logger::Env::default().default_filter_or("info")).init(); + + // Parse args + let args = Args::parse(); + + build_c_cpp_bindings(&args.bindings_path, &args.target); +} + +fn build_c_cpp_bindings(bindings_path: &Path, target: &str) { + let source_dir = PathBuf::from(env!("CARGO_MANIFEST_DIR")) + .parent() + .unwrap() + .to_path_buf(); + + let tempdir = tempfile::tempdir().unwrap(); + + // Build the C bindings and copy them into the output dir + let c_dir = tempdir.path().join("c"); + std::fs::create_dir(&c_dir).unwrap(); + + // Create lib and include dirs + let c_lib_dir = c_dir.join("lib"); + let c_include_dir = c_dir.join("include"); + std::fs::create_dir(&c_lib_dir).unwrap(); + std::fs::create_dir(&c_include_dir).unwrap(); + + // Build the C bindings and copy them to the lib dir + let c_bindings = build_c_bindings(); + std::fs::copy(c_bindings.shared_lib, c_lib_dir.join("libcarton_c.so")).unwrap(); + std::fs::copy(c_bindings.static_lib, c_lib_dir.join("libcarton_c.a")).unwrap(); + + // Copy the header to the include dir + std::fs::copy( + source_dir.join("carton-bindings-c/carton.h"), + c_include_dir.join("carton.h"), + ) + .unwrap(); + + // Make a tar file for the C bindings + assert!(Command::new("tar") + .arg("-cvzf") + .arg(bindings_path.join(format!("carton_c_{}.tar.gz", target))) + .arg(".") + .current_dir(c_dir) + .status() + .unwrap() + .success()); + + // Build the C++ bindings and copy them into the output dir + let cpp_dir = tempdir.path().join("cpp"); + std::fs::create_dir(&cpp_dir).unwrap(); + + // Create lib and include dirs + let cpp_lib_dir = cpp_dir.join("lib"); + let cpp_include_dir = cpp_dir.join("include"); + std::fs::create_dir(&cpp_lib_dir).unwrap(); + std::fs::create_dir(&cpp_include_dir).unwrap(); + + // Build the C++ bindings and put the files in the lib dir + build_cpp_bindings(&cpp_lib_dir); + + // Copy header files in + std::fs::copy( + source_dir.join("carton-bindings-cpp/src/carton.hh"), + &cpp_include_dir.join("carton.hh"), + ) + .unwrap(); + std::fs::copy( + source_dir.join("carton-bindings-cpp/src/carton_impl.hh"), + cpp_include_dir.join("carton_impl.hh"), + ) + .unwrap(); + + // Make a tar file for the C++ bindings + assert!(Command::new("tar") + .arg("-cvzf") + .arg(bindings_path.join(format!("carton_cpp_{}.tar.gz", target))) + .arg(".") + .current_dir(cpp_dir) + .status() + .unwrap() + .success()); +} diff --git a/source/build-utils/src/bin/upload_c_cpp_bindings.rs b/source/build-utils/src/bin/upload_c_cpp_bindings.rs new file mode 100644 index 0000000..7d9cfe0 --- /dev/null +++ b/source/build-utils/src/bin/upload_c_cpp_bindings.rs @@ -0,0 +1,71 @@ +// Copyright 2023 Vivek Panyam +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +use std::sync::Arc; + +use s3::{creds::Credentials, Bucket, Region}; + +/// Upload the C and C++ bindings in CI +#[tokio::main] +async fn main() { + let bucket = Arc::new( + Bucket::new( + &std::env::var("CARTON_NIGHTLY_S3_BUCKET").unwrap(), + Region::Custom { + region: std::env::var("CARTON_NIGHTLY_S3_REGION").unwrap(), + endpoint: std::env::var("CARTON_NIGHTLY_S3_ENDPOINT").unwrap(), + }, + Credentials::new( + Some(&std::env::var("CARTON_NIGHTLY_ACCESS_KEY_ID").unwrap()), + Some(&std::env::var("CARTON_NIGHTLY_SECRET_ACCESS_KEY").unwrap()), + None, + None, + None, + ) + .unwrap(), + ) + .unwrap(), + ); + + let handles: Vec<_> = [ + "/tmp/artifacts/c-cpp-bindings-linux", + "/tmp/artifacts/c-cpp-bindings-macos-aarch64", + "/tmp/artifacts/c-cpp-bindings-x86_64-apple-darwin", + ] + .into_iter() + .flat_map(|dir| { + std::fs::read_dir(dir) + .unwrap() + .into_iter() + .filter_map(|item| item.ok()) + .map(|item| (item.path(), item.file_name().to_str().unwrap().to_owned())) + }) + .map(|(path, filename)| { + let bucket = bucket.clone(); + tokio::spawn(async move { + let content = tokio::fs::read(path).await.unwrap(); + + // Upload the zip file + bucket + .put_object(format!("/bindings/{}", filename), &content) + .await + .unwrap(); + }) + }) + .collect(); + + for handle in handles { + handle.await.unwrap(); + } +} diff --git a/source/build-utils/src/lib.rs b/source/build-utils/src/lib.rs index dc114de..2b34605 100644 --- a/source/build-utils/src/lib.rs +++ b/source/build-utils/src/lib.rs @@ -17,8 +17,13 @@ use std::{ process::Command, }; +pub struct CBindings { + pub shared_lib: PathBuf, + pub static_lib: PathBuf, +} + /// Build the Carton C bindings -pub fn build_c_bindings() -> PathBuf { +pub fn build_c_bindings() -> CBindings { // Build the bindings log::info!("Building C bindings..."); let mut cargo_messages = escargot::CargoBuild::new() @@ -34,14 +39,49 @@ pub fn build_c_bindings() -> PathBuf { .find_map(|ref message| { let message = message.as_ref().unwrap(); let decoded = message.decode().unwrap(); - extract_lib(&decoded, "staticlib") + + match decoded { + escargot::format::Message::CompilerArtifact(art) => { + if !art.profile.test + && art.target.name == "carton-bindings-c" + && art.target.crate_types == ["staticlib", "cdylib"] + && art.target.kind == ["staticlib", "cdylib"] + { + if art + .filenames + .get(0) + .unwrap() + .extension() + .unwrap() + .to_str() + .unwrap() + == "so" + { + // Shared lib first + Some(CBindings { + shared_lib: art.filenames.get(0).unwrap().to_path_buf(), + static_lib: art.filenames.get(1).unwrap().to_path_buf(), + }) + } else { + // Static lib first + Some(CBindings { + shared_lib: art.filenames.get(1).unwrap().to_path_buf(), + static_lib: art.filenames.get(0).unwrap().to_path_buf(), + }) + } + } else { + None + } + } + _ => None, + } }) .unwrap() } /// Build the Carton C++ bindings -pub fn build_cpp_bindings(output_path: &Path) { - let c_bindings_path = build_c_bindings(); +pub fn build_cpp_bindings(output_folder: &Path) { + let c_bindings_path = build_c_bindings().static_lib; log::info!("Building C++ bindings..."); let manifest_dir = PathBuf::from(env!("CARGO_MANIFEST_DIR")); @@ -55,52 +95,49 @@ pub fn build_cpp_bindings(output_path: &Path) { .try_get_compiler() .unwrap(); + // Build a .o file + let tempdir = tempfile::tempdir().unwrap(); let mut command = Command::new(compiler.path()); - command.arg(manifest_dir.join("../carton-bindings-cpp/src/carton.cc")); - command.arg(c_bindings_path); - command.args(compiler.args()); - command.arg("-std=c++20"); command + .arg(manifest_dir.join("../carton-bindings-cpp/src/carton.cc")) + .args(compiler.args()) + .arg("-std=c++20") .arg("-I") - .arg(manifest_dir.join("../carton-bindings-c")); - command.arg("-shared"); + .arg(manifest_dir.join("../carton-bindings-c")) + .arg("-c") + .arg("-o") + .arg(tempdir.path().join("cartoncpp.o")); - #[cfg(not(target_os = "macos"))] - command.arg("-pthread").arg("-ldl"); + log::info!("Running command {command:?}"); + + let mut compiler_output = command.spawn().unwrap(); + assert!(compiler_output.wait().unwrap().success()); - #[cfg(target_os = "macos")] + // Build a static library + // TODO: this isn't ideal because it requires ar on the path + std::fs::copy(&c_bindings_path, output_folder.join("libcarton_cpp.a")).unwrap(); + let mut command = Command::new("ar"); command - .arg("-framework") - .arg("CoreFoundation") - .arg("-framework") - .arg("Security"); + .arg("-rv") + .arg(output_folder.join("libcarton_cpp.a")) + .arg(tempdir.path().join("cartoncpp.o")); - command.arg("-o").arg(output_path); + log::info!("Running command {command:?}"); + + let mut ar_output = command.spawn().unwrap(); + assert!(ar_output.wait().unwrap().success()); + + // Build a shared library + let mut command = Command::new(compiler.path()); + command + .arg("-shared") + .arg("-o") + .arg(output_folder.join("libcarton_cpp.so")) + .arg(tempdir.path().join("cartoncpp.o")) + .arg(c_bindings_path); log::info!("Running command {command:?}"); let mut compiler_output = command.spawn().unwrap(); assert!(compiler_output.wait().unwrap().success()); } - -/// Based on `extract_bin` within escargot -fn extract_lib(msg: &escargot::format::Message, desired_kind: &str) -> Option { - match msg { - escargot::format::Message::CompilerArtifact(art) => { - if !art.profile.test - && art.target.crate_types == [desired_kind] - && art.target.kind == [desired_kind] - { - Some( - art.filenames - .get(0) - .expect("files must exist") - .to_path_buf(), - ) - } else { - None - } - } - _ => None, - } -} diff --git a/source/carton-bindings-c/Cargo.toml b/source/carton-bindings-c/Cargo.toml index da479c7..601978b 100644 --- a/source/carton-bindings-c/Cargo.toml +++ b/source/carton-bindings-c/Cargo.toml @@ -11,7 +11,7 @@ keywords = [] categories = [] [lib] -crate-type = ["staticlib"] +crate-type = ["staticlib", "cdylib"] [dependencies] cxx = "1.0" diff --git a/source/carton-bindings-c/tests/test_c_examples.rs b/source/carton-bindings-c/tests/test_c_examples.rs index 8ec60e8..5e0f87d 100644 --- a/source/carton-bindings-c/tests/test_c_examples.rs +++ b/source/carton-bindings-c/tests/test_c_examples.rs @@ -20,7 +20,7 @@ fn test_c_examples() { env_logger::Builder::from_env(env_logger::Env::default().default_filter_or("info")).init(); // Build the bindings - let lib_path = build_utils::build_c_bindings(); + let lib_path = build_utils::build_c_bindings().shared_lib; // For each c file in the tests dir let dir = PathBuf::from(env!("CARGO_MANIFEST_DIR")) @@ -52,17 +52,6 @@ fn test_c_examples() { command.arg(lib_path.as_path()); command.args(compiler.args()); command.arg("-o").arg(tempdir.path().join("test")); - command.arg("-lm"); - - #[cfg(not(target_os = "macos"))] - command.arg("-pthread").arg("-ldl"); - - #[cfg(target_os = "macos")] - command - .arg("-framework") - .arg("CoreFoundation") - .arg("-framework") - .arg("Security"); let mut compiler_output = command.spawn().unwrap(); assert!(compiler_output.wait().unwrap().success()); diff --git a/source/carton-bindings-cpp/tests/test_cpp_examples.rs b/source/carton-bindings-cpp/tests/test_cpp_examples.rs index 7c917af..0137ede 100644 --- a/source/carton-bindings-cpp/tests/test_cpp_examples.rs +++ b/source/carton-bindings-cpp/tests/test_cpp_examples.rs @@ -21,7 +21,7 @@ fn test_cpp_examples() { // Build the bindings let bindings_dir = tempfile::tempdir().unwrap(); let bindings_path = bindings_dir.path().join("libcarton_cpp.so"); - build_utils::build_cpp_bindings(&bindings_path); + build_utils::build_cpp_bindings(&bindings_dir.path()); // For each cc file in the tests dir let dir = PathBuf::from(env!("CARGO_MANIFEST_DIR")) @@ -55,7 +55,6 @@ fn test_cpp_examples() { command.arg(bindings_path.as_path()); command.args(compiler.args()); command.arg("-o").arg(tempdir.path().join("test")); - command.arg("-lm"); let mut compiler_output = command.spawn().unwrap(); assert!(compiler_output.wait().unwrap().success());