diff options
Diffstat (limited to 'content/2022-05-30-cmake-cargo-example')
9 files changed, 139 insertions, 0 deletions
diff --git a/content/2022-05-30-cmake-cargo-example/.gitignore b/content/2022-05-30-cmake-cargo-example/.gitignore new file mode 100644 index 0000000..f2ce476 --- /dev/null +++ b/content/2022-05-30-cmake-cargo-example/.gitignore @@ -0,0 +1 @@ +/BUILD diff --git a/content/2022-05-30-cmake-cargo-example/CMakeLists.txt b/content/2022-05-30-cmake-cargo-example/CMakeLists.txt new file mode 100644 index 0000000..6444ed0 --- /dev/null +++ b/content/2022-05-30-cmake-cargo-example/CMakeLists.txt @@ -0,0 +1,11 @@ +cmake_minimum_required(VERSION 3.14) +project(calc) + +# Add libcalc (rust). +add_subdirectory(libcalc) + +# Build calc add_executable. +add_executable(calc calc.c) +target_compile_options(calc PRIVATE -Wall -Wextra) +# Link against rust lib. +target_link_libraries(calc libcalc) diff --git a/content/2022-05-30-cmake-cargo-example/Makefile b/content/2022-05-30-cmake-cargo-example/Makefile new file mode 100644 index 0000000..e269cb2 --- /dev/null +++ b/content/2022-05-30-cmake-cargo-example/Makefile @@ -0,0 +1,14 @@ +TYPE ?= Debug +BDIR := BUILD/$(TYPE) + +calc: config + cmake --build $(BDIR) --target calc + +config: CMakeLists.txt + cmake -B $(BDIR) -DCMAKE_BUILD_TYPE=$(TYPE) . + +run: calc + $(BDIR)/calc + +clean: + $(RM) -r BUILD diff --git a/content/2022-05-30-cmake-cargo-example/calc.c b/content/2022-05-30-cmake-cargo-example/calc.c new file mode 100644 index 0000000..27ca0a9 --- /dev/null +++ b/content/2022-05-30-cmake-cargo-example/calc.c @@ -0,0 +1,19 @@ +#include <stdio.h> +#include <limits.h> + +#include <libcalc.h> + +#define EVAL(expr) \ + printf("%s = %d\n", #expr, expr); + +int main() { + EVAL(wrap_add(1,2)); + EVAL(wrap_add(INT_MAX,0)); + EVAL(wrap_add(INT_MAX,1)); + + EVAL(sat_add(1,2)); + EVAL(sat_add(INT_MAX,0)); + EVAL(sat_add(INT_MAX,1)); + + return 0; +} diff --git a/content/2022-05-30-cmake-cargo-example/libcalc/.gitignore b/content/2022-05-30-cmake-cargo-example/libcalc/.gitignore new file mode 100644 index 0000000..008b9b4 --- /dev/null +++ b/content/2022-05-30-cmake-cargo-example/libcalc/.gitignore @@ -0,0 +1,3 @@ +/target +Cargo.lock +libcalc.h diff --git a/content/2022-05-30-cmake-cargo-example/libcalc/CMakeLists.txt b/content/2022-05-30-cmake-cargo-example/libcalc/CMakeLists.txt new file mode 100644 index 0000000..2abab17 --- /dev/null +++ b/content/2022-05-30-cmake-cargo-example/libcalc/CMakeLists.txt @@ -0,0 +1,48 @@ +cmake_minimum_required(VERSION 3.14) + +set(BDIR ${CMAKE_BINARY_DIR}/libcalc) + +# Define external project to build rust lib with cargo. +include(ExternalProject) +ExternalProject_Add( + ext_libcalc + # Always trigger build, let cargo decide if we want to rebuild. + BUILD_ALWAYS ON + CONFIGURE_COMMAND "" + # Can not pass arguments to build.rs and was not able to set env variables + # for the external build command, therefore use 'env' to setup env var. + BUILD_COMMAND env LIBCALC_BUILD_DIR=${BDIR} + cargo build --target-dir ${BDIR} "$<IF:$<CONFIG:Release>,--release,>" + BUILD_BYPRODUCTS ${BDIR}/$<IF:$<CONFIG:Release>,release,debug>/libcalc.a + ${BDIR}/libcalc.h + INSTALL_COMMAND "" + # Location of sources (since we don't download). + SOURCE_DIR "${CMAKE_CURRENT_SOURCE_DIR}" + # Build dir location used as CWD for build commands. + BINARY_DIR "${CMAKE_CURRENT_SOURCE_DIR}" + # Root directory for external project in cmake build dir. + PREFIX "libcalc" + # Log directory (relative to PREFIX). + LOG_DIR "log" + # Log build step. + LOG_BUILD ON + # In case of error output log on terminal. + LOG_OUTPUT_ON_FAILURE ON +) + +# Define pseudo target (import lib) for usage in cmake and let it depend on +# the cargo build. +add_library(libcalc STATIC IMPORTED GLOBAL) +add_dependencies(libcalc ext_libcalc) + +# Configure the import locations (libs) for the import lib. + +set_target_properties(libcalc PROPERTIES + IMPORTED_CONFIGURATIONS "Debug;Release" + IMPORTED_LOCATION "${BDIR}/release/libcalc.a" + IMPORTED_LOCATION_DEBUG "${BDIR}/debug/libcalc.a" +) + +# Configure the additional interface for they pseudo target. + +target_include_directories(libcalc INTERFACE "${BDIR}") diff --git a/content/2022-05-30-cmake-cargo-example/libcalc/Cargo.toml b/content/2022-05-30-cmake-cargo-example/libcalc/Cargo.toml new file mode 100644 index 0000000..23ea182 --- /dev/null +++ b/content/2022-05-30-cmake-cargo-example/libcalc/Cargo.toml @@ -0,0 +1,10 @@ +[package] +name = "calc" +version = "0.1.0" +edition = "2021" + +[lib] +crate-type = ["staticlib"] + +[build-dependencies] +cbindgen = "0.*" diff --git a/content/2022-05-30-cmake-cargo-example/libcalc/build.rs b/content/2022-05-30-cmake-cargo-example/libcalc/build.rs new file mode 100644 index 0000000..acfa6a7 --- /dev/null +++ b/content/2022-05-30-cmake-cargo-example/libcalc/build.rs @@ -0,0 +1,24 @@ +fn main() { + let crate_dir = std::env::var("CARGO_MANIFEST_DIR").unwrap(); + + let out_file = format!("{}/libcalc.h", std::env::var("LIBCALC_BUILD_DIR").unwrap_or(String::from("."))); + + let cfg = cbindgen::Config { + cpp_compat: true, + ..Default::default() + }; + + if std::path::Path::new(&out_file).exists() { + std::fs::remove_file(&out_file).unwrap(); + } + + let ok = cbindgen::Builder::new() + .with_config(cfg) + .with_crate(crate_dir) + .with_language(cbindgen::Language::C) + .with_include_guard("LIBCALC_H") + .generate() + .expect("Unable to generate bindings") + .write_to_file(&out_file); + assert!(ok); +} diff --git a/content/2022-05-30-cmake-cargo-example/libcalc/src/lib.rs b/content/2022-05-30-cmake-cargo-example/libcalc/src/lib.rs new file mode 100644 index 0000000..a36aace --- /dev/null +++ b/content/2022-05-30-cmake-cargo-example/libcalc/src/lib.rs @@ -0,0 +1,9 @@ +#[no_mangle] +pub extern "C" fn wrap_add(a: i32, b: i32) -> i32 { + a.wrapping_add(b) +} + +#[no_mangle] +pub extern "C" fn sat_add(a: i32, b: i32) -> i32 { + a.saturating_add(b) +} |