├── doc ├── .gitignore ├── book.toml └── src │ ├── SUMMARY.md │ ├── introduction.md │ ├── ffi_bindings.md │ ├── quick_start.md │ ├── setup_corrosion.md │ ├── advanced.md │ └── common_issues.md ├── .github ├── FUNDING.yml ├── scripts │ ├── toolchains │ │ ├── x86_64-unknown-linux-gnu-gcc.cmake │ │ ├── x86_64-unknown-linux-gnu-clang.cmake │ │ ├── i686-unknown-linux-gnu-gcc.cmake │ │ ├── aarch64-unknown-linux-gnu-gcc.cmake │ │ ├── i686-unknown-linux-gnu-clang.cmake │ │ ├── aarch64-unknown-linux-gnu-clang.cmake │ │ ├── x86_64-pc-windows-gnullvm.cmake │ │ ├── aarch64-apple-darwin-clang.cmake │ │ └── x86_64-apple-darwin-clang.cmake │ └── determine_compiler.sh ├── workflows │ ├── visual_studio.yaml │ ├── linux.yaml │ └── gh-pages.yaml └── ISSUE_TEMPLATE │ └── bug_report.yml ├── test ├── gensource │ ├── gensource │ │ ├── .gitignore │ │ ├── generator │ │ │ ├── CMakeLists.txt │ │ │ ├── Cargo.lock │ │ │ ├── Cargo.toml │ │ │ └── src │ │ │ │ └── main.rs │ │ ├── Cargo.lock │ │ ├── src │ │ │ └── lib.rs │ │ ├── Cargo.toml │ │ └── CMakeLists.txt │ └── CMakeLists.txt ├── nostd │ ├── CMakeLists.txt │ └── nostd │ │ ├── main.cpp │ │ ├── rust │ │ ├── Cargo.lock │ │ ├── src │ │ │ └── lib.rs │ │ └── Cargo.toml │ │ └── CMakeLists.txt ├── cbindgen │ ├── auto │ │ ├── rust │ │ │ ├── cbindgen.toml │ │ │ ├── src │ │ │ │ ├── other_mod │ │ │ │ │ └── mod.rs │ │ │ │ ├── ffi.rs │ │ │ │ └── lib.rs │ │ │ └── Cargo.toml │ │ ├── CMakeLists.txt │ │ └── main.cpp │ ├── manual │ │ ├── rust │ │ │ ├── cbindgen.toml │ │ │ ├── src │ │ │ │ ├── other_mod │ │ │ │ │ └── mod.rs │ │ │ │ ├── ffi.rs │ │ │ │ └── lib.rs │ │ │ └── Cargo.toml │ │ ├── main.cpp │ │ └── CMakeLists.txt │ ├── install_lib │ │ ├── rust_lib │ │ │ ├── src │ │ │ │ └── lib.rs │ │ │ └── Cargo.toml │ │ └── CMakeLists.txt │ └── CMakeLists.txt ├── workspace │ ├── workspace │ │ ├── member3 │ │ │ ├── src │ │ │ │ └── main.rs │ │ │ └── Cargo.toml │ │ ├── main.cpp │ │ ├── Cargo.toml │ │ ├── member1 │ │ │ ├── src │ │ │ │ └── lib.rs │ │ │ └── Cargo.toml │ │ ├── member2 │ │ │ ├── src │ │ │ │ └── lib.rs │ │ │ └── Cargo.toml │ │ ├── Cargo.lock │ │ └── CMakeLists.txt │ └── CMakeLists.txt ├── envvar │ ├── envvar │ │ ├── .cargo │ │ │ └── config.toml │ │ ├── main.cpp │ │ ├── src │ │ │ └── lib.rs │ │ ├── Cargo.lock │ │ ├── Cargo.toml │ │ ├── CMakeLists.txt │ │ └── build.rs │ └── CMakeLists.txt ├── rustflags │ ├── cargo_config_rustflags │ │ ├── .cargo │ │ │ └── config.toml │ │ ├── Cargo.toml │ │ ├── Cargo.lock │ │ ├── src │ │ │ └── main.rs │ │ └── CMakeLists.txt │ ├── rustflags │ │ ├── rust │ │ │ ├── some_dependency │ │ │ │ ├── Cargo.toml │ │ │ │ └── src │ │ │ │ │ └── lib.rs │ │ │ ├── Cargo.toml │ │ │ ├── Cargo.lock │ │ │ └── src │ │ │ │ └── lib.rs │ │ ├── main.cpp │ │ └── CMakeLists.txt │ └── CMakeLists.txt ├── custom_target │ ├── custom_target │ │ ├── rust │ │ │ ├── c_lib.c │ │ │ ├── src │ │ │ │ ├── bin.rs │ │ │ │ └── lib.rs │ │ │ ├── Cargo.toml │ │ │ ├── Cargo.lock │ │ │ └── build.rs │ │ ├── main.cpp │ │ └── CMakeLists.txt │ └── CMakeLists.txt ├── output directory │ ├── output directory │ │ ├── proj1 │ │ │ ├── src │ │ │ │ ├── lib.rs │ │ │ │ └── bin │ │ │ │ │ └── rust_bin1.rs │ │ │ ├── Cargo.lock │ │ │ └── Cargo.toml │ │ ├── proj2 │ │ │ ├── src │ │ │ │ ├── lib.rs │ │ │ │ └── bin │ │ │ │ │ └── rust_bin2.rs │ │ │ ├── Cargo.lock │ │ │ └── Cargo.toml │ │ ├── proj3 │ │ │ ├── src │ │ │ │ ├── lib.rs │ │ │ │ └── bin │ │ │ │ │ └── rust_bin3.rs │ │ │ ├── Cargo.lock │ │ │ └── Cargo.toml │ │ ├── consumer.cpp │ │ └── CMakeLists.txt │ ├── output_directory_config │ │ ├── proj1 │ │ │ ├── src │ │ │ │ ├── lib.rs │ │ │ │ └── bin │ │ │ │ │ └── rust_bin1.rs │ │ │ ├── Cargo.lock │ │ │ └── Cargo.toml │ │ ├── consumer.cpp │ │ └── CMakeLists.txt │ └── CMakeLists.txt ├── crate_type │ ├── crate_type │ │ ├── proj1 │ │ │ ├── src │ │ │ │ └── lib.rs │ │ │ ├── Cargo.toml │ │ │ └── Cargo.lock │ │ ├── proj2 │ │ │ ├── src │ │ │ │ └── lib.rs │ │ │ ├── Cargo.toml │ │ │ └── Cargo.lock │ │ ├── main.cpp │ │ └── CMakeLists.txt │ └── CMakeLists.txt ├── corrosion_install │ ├── install_lib │ │ ├── rust_lib │ │ │ ├── include │ │ │ │ └── rust_lib │ │ │ │ │ └── rust_lib.hpp │ │ │ ├── src │ │ │ │ └── lib.rs │ │ │ ├── Cargo.toml │ │ │ ├── Cargo.lock │ │ │ └── CMakeLists.txt │ │ ├── main.cpp │ │ └── CMakeLists.txt │ ├── install_rust_bin │ │ ├── rust_bin │ │ │ ├── Cargo.toml │ │ │ ├── Cargo.lock │ │ │ ├── src │ │ │ │ └── main.rs │ │ │ └── CMakeLists.txt │ │ └── CMakeLists.txt │ └── CMakeLists.txt ├── hostbuild │ ├── hostbuild │ │ ├── src │ │ │ ├── lib.c │ │ │ └── main.rs │ │ ├── Cargo.toml │ │ ├── CMakeLists.txt │ │ ├── build.rs │ │ └── Cargo.lock │ └── CMakeLists.txt ├── cargo_flags │ ├── cargo_flags │ │ ├── main.cpp │ │ ├── rust │ │ │ ├── Cargo.lock │ │ │ ├── Cargo.toml │ │ │ └── src │ │ │ │ └── lib.rs │ │ └── CMakeLists.txt │ └── CMakeLists.txt ├── cpp2rust │ ├── cpp2rust │ │ ├── lib.cpp │ │ ├── rust │ │ │ ├── rust_dependency │ │ │ │ ├── Cargo.toml │ │ │ │ └── src │ │ │ │ │ └── lib.rs │ │ │ ├── build.rs │ │ │ ├── Cargo.toml │ │ │ ├── Cargo.lock │ │ │ └── src │ │ │ │ └── bin │ │ │ │ └── rust-exe.rs │ │ ├── path with space │ │ │ └── lib3.cpp │ │ ├── lib2.cpp │ │ └── CMakeLists.txt │ └── CMakeLists.txt ├── cxxbridge │ ├── cxxbridge_circular │ │ ├── include │ │ │ └── cpplib.h │ │ ├── rust │ │ │ ├── Cargo.toml │ │ │ ├── src │ │ │ │ └── lib.rs │ │ │ └── Cargo.lock │ │ ├── main.cpp │ │ ├── cpplib.cpp │ │ └── CMakeLists.txt │ ├── cxxbridge_cpp2rust │ │ ├── include │ │ │ └── cpplib.h │ │ ├── rust │ │ │ ├── Cargo.toml │ │ │ ├── src │ │ │ │ ├── main.rs │ │ │ │ └── lib.rs │ │ │ └── Cargo.lock │ │ ├── cpplib.cpp │ │ └── CMakeLists.txt │ ├── cxxbridge_rust2cpp │ │ ├── rust │ │ │ ├── Cargo.toml │ │ │ ├── src │ │ │ │ ├── foo │ │ │ │ │ └── mod.rs │ │ │ │ └── lib.rs │ │ │ └── Cargo.lock │ │ ├── main.cpp │ │ └── CMakeLists.txt │ ├── cxxbridge_exported_impls │ │ ├── rust │ │ │ ├── Cargo.toml │ │ │ ├── src │ │ │ │ ├── bridge_b.rs │ │ │ │ ├── bridge_a.rs │ │ │ │ └── lib.rs │ │ │ └── Cargo.lock │ │ ├── main.cpp │ │ └── CMakeLists.txt │ └── CMakeLists.txt ├── multitarget │ ├── multitarget │ │ ├── lib.cpp │ │ ├── Cargo.lock │ │ ├── src │ │ │ ├── bin │ │ │ │ ├── bin1.rs │ │ │ │ ├── bin2.rs │ │ │ │ └── bin3.rs │ │ │ └── lib.rs │ │ ├── Cargo.toml │ │ └── CMakeLists.txt │ └── CMakeLists.txt ├── custom_profiles │ ├── basic_profiles │ │ ├── main.cpp │ │ ├── rust │ │ │ ├── Cargo.toml │ │ │ ├── Cargo.lock │ │ │ └── src │ │ │ │ └── lib.rs │ │ └── CMakeLists.txt │ ├── custom_profiles │ │ ├── main.cpp │ │ ├── rust │ │ │ ├── Cargo.lock │ │ │ ├── src │ │ │ │ └── lib.rs │ │ │ └── Cargo.toml │ │ └── CMakeLists.txt │ └── CMakeLists.txt ├── rust2cpp │ ├── rust2cpp │ │ ├── rust │ │ │ ├── Cargo.lock │ │ │ ├── build.rs │ │ │ ├── src │ │ │ │ └── lib.rs │ │ │ └── Cargo.toml │ │ ├── main.cpp │ │ └── CMakeLists.txt │ └── CMakeLists.txt ├── override_crate_type │ ├── override_crate_type │ │ ├── rust │ │ │ ├── Cargo.lock │ │ │ ├── build.rs │ │ │ ├── Cargo.toml │ │ │ └── src │ │ │ │ └── lib.rs │ │ ├── main.cpp │ │ └── CMakeLists.txt │ └── CMakeLists.txt ├── features │ ├── features │ │ ├── rust │ │ │ ├── Cargo.lock │ │ │ ├── Cargo.toml │ │ │ └── src │ │ │ │ └── lib.rs │ │ ├── main.cpp │ │ └── CMakeLists.txt │ └── CMakeLists.txt ├── config_discovery │ ├── config_discovery │ │ ├── CMakeLists.txt │ │ ├── .cargo │ │ │ └── config.toml │ │ ├── src │ │ │ └── main.rs │ │ ├── Cargo.toml │ │ └── Cargo.lock │ ├── CMakeLists.txt │ └── README.md ├── find_rust │ ├── CMakeLists.txt │ ├── find_rust │ │ └── CMakeLists.txt │ └── rustup_proxy │ │ └── CMakeLists.txt ├── parse_target_triple │ ├── parse_target_triple_should_fail │ │ └── CMakeLists.txt │ ├── CMakeLists.txt │ └── parse_target_triple │ │ └── CMakeLists.txt ├── README.md ├── TestFileExists.cmake ├── ConfigureAndBuild.cmake └── CMakeLists.txt ├── .gitignore ├── cmake └── CorrosionConfig.cmake.in ├── LICENSE ├── README.md ├── CMakeLists.txt └── CMakePresets.json /doc/.gitignore: -------------------------------------------------------------------------------- 1 | book 2 | -------------------------------------------------------------------------------- /.github/FUNDING.yml: -------------------------------------------------------------------------------- 1 | github: ["jschwe"] 2 | -------------------------------------------------------------------------------- /test/gensource/gensource/.gitignore: -------------------------------------------------------------------------------- 1 | src/foo.rs 2 | -------------------------------------------------------------------------------- /test/nostd/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | corrosion_tests_add_test(nostd "") 2 | -------------------------------------------------------------------------------- /test/cbindgen/auto/rust/cbindgen.toml: -------------------------------------------------------------------------------- 1 | language = "C++" 2 | include_version = true 3 | 4 | 5 | -------------------------------------------------------------------------------- /test/cbindgen/manual/rust/cbindgen.toml: -------------------------------------------------------------------------------- 1 | language = "C++" 2 | include_version = true 3 | 4 | 5 | -------------------------------------------------------------------------------- /test/cbindgen/auto/rust/src/other_mod/mod.rs: -------------------------------------------------------------------------------- 1 | pub const OTHER_MOD_MAGIC_NUMBER: u32 = 192312312; 2 | -------------------------------------------------------------------------------- /test/cbindgen/manual/rust/src/other_mod/mod.rs: -------------------------------------------------------------------------------- 1 | pub const OTHER_MOD_MAGIC_NUMBER: u32 = 192312312; 2 | -------------------------------------------------------------------------------- /test/workspace/workspace/member3/src/main.rs: -------------------------------------------------------------------------------- 1 | fn main() { 2 | println!("Hello, world!"); 3 | } 4 | -------------------------------------------------------------------------------- /test/envvar/envvar/.cargo/config.toml: -------------------------------------------------------------------------------- 1 | [env] 2 | COR_CONFIG_TOML_ENV_VAR = "EnvVariableSetViaConfig.toml" 3 | -------------------------------------------------------------------------------- /test/envvar/envvar/main.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | 3 | int main() { 4 | std::cout << "Ok"; 5 | } 6 | -------------------------------------------------------------------------------- /test/workspace/workspace/main.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | int main() { 3 | std::cout << "Ok"; 4 | } 5 | -------------------------------------------------------------------------------- /doc/book.toml: -------------------------------------------------------------------------------- 1 | [book] 2 | language = "en" 3 | multilingual = false 4 | src = "src" 5 | title = "Corrosion documentation" 6 | -------------------------------------------------------------------------------- /test/rustflags/cargo_config_rustflags/.cargo/config.toml: -------------------------------------------------------------------------------- 1 | [build] 2 | rustflags = ["--cfg=some_cargo_config_rustflag"] 3 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | 2 | **/target/ 3 | **/*.rs.bk 4 | build*/ 5 | .vscode 6 | .idea 7 | cmake-build-* 8 | test/test_header.cmake 9 | -------------------------------------------------------------------------------- /test/custom_target/custom_target/rust/c_lib.c: -------------------------------------------------------------------------------- 1 | #include 2 | 3 | uint32_t calculate_42(void) { 4 | return 42; 5 | } -------------------------------------------------------------------------------- /test/output directory/output directory/proj1/src/lib.rs: -------------------------------------------------------------------------------- 1 | #[no_mangle] 2 | pub extern "C" fn ret_12() -> u32 { 3 | 12 4 | } 5 | -------------------------------------------------------------------------------- /test/output directory/output directory/proj2/src/lib.rs: -------------------------------------------------------------------------------- 1 | #[no_mangle] 2 | pub extern "C" fn ret_12() -> u32 { 3 | 12 4 | } 5 | -------------------------------------------------------------------------------- /test/output directory/output directory/proj3/src/lib.rs: -------------------------------------------------------------------------------- 1 | #[no_mangle] 2 | pub extern "C" fn ret_12() -> u32 { 3 | 12 4 | } 5 | -------------------------------------------------------------------------------- /test/gensource/gensource/generator/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | corrosion_import_crate(MANIFEST_PATH Cargo.toml) 2 | corrosion_set_hostbuild(srcgen) 3 | -------------------------------------------------------------------------------- /test/output directory/output_directory_config/proj1/src/lib.rs: -------------------------------------------------------------------------------- 1 | #[no_mangle] 2 | pub extern "C" fn ret_12() -> u32 { 3 | 12 4 | } 5 | -------------------------------------------------------------------------------- /test/output directory/output directory/proj1/src/bin/rust_bin1.rs: -------------------------------------------------------------------------------- 1 | fn main() { 2 | println!("Hello, world from test rust binary"); 3 | } 4 | -------------------------------------------------------------------------------- /test/output directory/output directory/proj2/src/bin/rust_bin2.rs: -------------------------------------------------------------------------------- 1 | fn main() { 2 | println!("Hello, world from test rust binary"); 3 | } 4 | -------------------------------------------------------------------------------- /test/output directory/output directory/proj3/src/bin/rust_bin3.rs: -------------------------------------------------------------------------------- 1 | fn main() { 2 | println!("Hello, world from test rust binary"); 3 | } 4 | -------------------------------------------------------------------------------- /test/rustflags/cargo_config_rustflags/Cargo.toml: -------------------------------------------------------------------------------- 1 | [package] 2 | name = "cargo_config_rustflags" 3 | version = "0.1.0" 4 | edition = "2018" 5 | -------------------------------------------------------------------------------- /test/crate_type/crate_type/proj1/src/lib.rs: -------------------------------------------------------------------------------- 1 | #[no_mangle] 2 | pub extern "C" fn rust_function1() { 3 | println!("Hello from lib 1!"); 4 | } 5 | -------------------------------------------------------------------------------- /test/crate_type/crate_type/proj2/src/lib.rs: -------------------------------------------------------------------------------- 1 | #[no_mangle] 2 | pub extern "C" fn rust_function2() { 3 | println!("Hello from lib 2!"); 4 | } 5 | -------------------------------------------------------------------------------- /test/workspace/workspace/Cargo.toml: -------------------------------------------------------------------------------- 1 | [workspace] 2 | members=["member1", "member2", "member3"] 3 | 4 | [workspace.package] 5 | version = "0.1.0" 6 | -------------------------------------------------------------------------------- /test/cbindgen/install_lib/rust_lib/src/lib.rs: -------------------------------------------------------------------------------- 1 | 2 | #[no_mangle] 3 | pub extern "C" fn add(left: u64, right: u64) -> u64 { 4 | left + right 5 | } 6 | -------------------------------------------------------------------------------- /test/envvar/envvar/src/lib.rs: -------------------------------------------------------------------------------- 1 | #[cfg(test)] 2 | mod tests { 3 | #[test] 4 | fn it_works() { 5 | assert_eq!(2 + 2, 4); 6 | } 7 | } 8 | -------------------------------------------------------------------------------- /test/output directory/output_directory_config/proj1/src/bin/rust_bin1.rs: -------------------------------------------------------------------------------- 1 | fn main() { 2 | println!("Hello, world from test rust binary"); 3 | } 4 | -------------------------------------------------------------------------------- /test/corrosion_install/install_lib/rust_lib/include/rust_lib/rust_lib.hpp: -------------------------------------------------------------------------------- 1 | #include 2 | 3 | extern "C" uint64_t add(uint64_t left, uint64_t right); 4 | -------------------------------------------------------------------------------- /test/corrosion_install/install_lib/rust_lib/src/lib.rs: -------------------------------------------------------------------------------- 1 | 2 | #[no_mangle] 3 | pub extern "C" fn add(left: u64, right: u64) -> u64 { 4 | left + right 5 | } 6 | -------------------------------------------------------------------------------- /test/nostd/nostd/main.cpp: -------------------------------------------------------------------------------- 1 | extern "C" void rust_function(); 2 | 3 | extern "C" void cpp_function() { 4 | // Fail on linking issues 5 | rust_function(); 6 | } -------------------------------------------------------------------------------- /test/rustflags/rustflags/rust/some_dependency/Cargo.toml: -------------------------------------------------------------------------------- 1 | [package] 2 | name = "some_dependency" 3 | version = "0.1.0" 4 | license = "MIT" 5 | edition = "2018" 6 | 7 | -------------------------------------------------------------------------------- /test/workspace/workspace/member1/src/lib.rs: -------------------------------------------------------------------------------- 1 | #[cfg(test)] 2 | mod tests { 3 | #[test] 4 | fn it_works() { 5 | assert_eq!(2 + 2, 4); 6 | } 7 | } 8 | -------------------------------------------------------------------------------- /test/workspace/workspace/member2/src/lib.rs: -------------------------------------------------------------------------------- 1 | #[cfg(test)] 2 | mod tests { 3 | #[test] 4 | fn it_works() { 5 | assert_eq!(2 + 2, 4); 6 | } 7 | } 8 | -------------------------------------------------------------------------------- /test/hostbuild/hostbuild/src/lib.c: -------------------------------------------------------------------------------- 1 | #include 2 | 3 | void c_function(char const *name) { 4 | printf("Hello %s, I am an external C function\n", name); 5 | } 6 | -------------------------------------------------------------------------------- /.github/scripts/toolchains/x86_64-unknown-linux-gnu-gcc.cmake: -------------------------------------------------------------------------------- 1 | # Assumption: This is the native host target. 2 | set(CMAKE_C_COMPILER "gcc") 3 | set(CMAKE_CXX_COMPILER "g++") 4 | -------------------------------------------------------------------------------- /test/cargo_flags/cargo_flags/main.cpp: -------------------------------------------------------------------------------- 1 | extern "C" void rust_function(char const *name); 2 | 3 | 4 | int main(int argc, char **argv) { 5 | rust_function("Cxx"); 6 | } 7 | -------------------------------------------------------------------------------- /test/cbindgen/auto/rust/src/ffi.rs: -------------------------------------------------------------------------------- 1 | //! Just a module that contains some entries that should be parsed by cbindgen. 2 | 3 | pub const FFI_MAGIC_NUMBER: u64 = 0xFDA0_0184; 4 | -------------------------------------------------------------------------------- /test/cbindgen/manual/rust/src/ffi.rs: -------------------------------------------------------------------------------- 1 | //! Just a module that contains some entries that should be parsed by cbindgen. 2 | 3 | pub const FFI_MAGIC_NUMBER: u64 = 0xFDA0_0184; 4 | -------------------------------------------------------------------------------- /test/cpp2rust/cpp2rust/lib.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | 3 | extern "C" void cpp_function(char const *name) { 4 | std::cout << "Hello, " << name << "! I am Cpp!\n"; 5 | } 6 | -------------------------------------------------------------------------------- /test/custom_target/custom_target/main.cpp: -------------------------------------------------------------------------------- 1 | extern "C" void rust_function(char const *name); 2 | 3 | 4 | int main(int argc, char **argv) { 5 | rust_function("Cxx"); 6 | } 7 | -------------------------------------------------------------------------------- /test/cxxbridge/cxxbridge_circular/include/cpplib.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | #include "cxxbridge/lib.h" 3 | 4 | ::RsImage read_image(::rust::Str path); 5 | 6 | void assert_equality(); 7 | -------------------------------------------------------------------------------- /test/multitarget/multitarget/lib.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | 3 | extern "C" void cpp_function(char const *name) { 4 | std::cout << "Hello, " << name << "! I'm Cpp!\n"; 5 | } 6 | -------------------------------------------------------------------------------- /.github/scripts/toolchains/x86_64-unknown-linux-gnu-clang.cmake: -------------------------------------------------------------------------------- 1 | # Assumption: This is the native host target. 2 | set(CMAKE_C_COMPILER "clang") 3 | set(CMAKE_CXX_COMPILER "clang++") 4 | -------------------------------------------------------------------------------- /test/corrosion_install/install_rust_bin/rust_bin/Cargo.toml: -------------------------------------------------------------------------------- 1 | [package] 2 | name = "my_rust_bin" 3 | version = "0.1.0" 4 | edition = "2018" 5 | license = "MIT" 6 | 7 | [dependencies] 8 | -------------------------------------------------------------------------------- /test/custom_profiles/basic_profiles/main.cpp: -------------------------------------------------------------------------------- 1 | extern "C" void rust_function(char const *name); 2 | 3 | 4 | int main(int argc, char **argv) { 5 | rust_function("Cpp"); 6 | } 7 | -------------------------------------------------------------------------------- /test/custom_profiles/basic_profiles/rust/Cargo.toml: -------------------------------------------------------------------------------- 1 | [package] 2 | name = "cargo-profiles-lib" 3 | version = "0.1.0" 4 | edition = "2021" 5 | 6 | [lib] 7 | crate-type=["staticlib"] 8 | -------------------------------------------------------------------------------- /test/custom_profiles/custom_profiles/main.cpp: -------------------------------------------------------------------------------- 1 | extern "C" void rust_function(char const *name); 2 | 3 | 4 | int main(int argc, char **argv) { 5 | rust_function("Cpp"); 6 | } 7 | -------------------------------------------------------------------------------- /.github/scripts/toolchains/i686-unknown-linux-gnu-gcc.cmake: -------------------------------------------------------------------------------- 1 | set(CMAKE_C_COMPILER "i686-linux-gnu-gcc") 2 | set(CMAKE_CXX_COMPILER "i686-linux-gnu-g++") 3 | set(CMAKE_SYSTEM_NAME "Linux") 4 | -------------------------------------------------------------------------------- /test/cpp2rust/cpp2rust/rust/rust_dependency/Cargo.toml: -------------------------------------------------------------------------------- 1 | [package] 2 | name = "rust-dependency" 3 | version = "0.1.0" 4 | license = "MIT" 5 | edition = "2018" 6 | 7 | [dependencies] 8 | 9 | -------------------------------------------------------------------------------- /test/rust2cpp/rust2cpp/rust/Cargo.lock: -------------------------------------------------------------------------------- 1 | # This file is automatically @generated by Cargo. 2 | # It is not intended for manual editing. 3 | [[package]] 4 | name = "rust-lib" 5 | version = "0.1.0" 6 | -------------------------------------------------------------------------------- /.github/scripts/toolchains/aarch64-unknown-linux-gnu-gcc.cmake: -------------------------------------------------------------------------------- 1 | set(CMAKE_C_COMPILER "aarch64-linux-gnu-gcc") 2 | set(CMAKE_CXX_COMPILER "aarch64-linux-gnu-g++") 3 | set(CMAKE_SYSTEM_NAME "Linux") 4 | -------------------------------------------------------------------------------- /test/cpp2rust/cpp2rust/rust/build.rs: -------------------------------------------------------------------------------- 1 | // Build-scripts also need to be linked, so just add a dummy buildscript ensuring this works. 2 | fn main() { 3 | println!("Build-script is running.") 4 | } 5 | -------------------------------------------------------------------------------- /test/custom_target/custom_target/rust/src/bin.rs: -------------------------------------------------------------------------------- 1 | use rust_lib::calculate_42; 2 | 3 | fn main() { 4 | let answer = unsafe { calculate_42() } ; 5 | println!("The answer is {}", answer); 6 | } 7 | -------------------------------------------------------------------------------- /test/rust2cpp/rust2cpp/rust/build.rs: -------------------------------------------------------------------------------- 1 | // Build-scripts also need to be linked, so just add a dummy buildscript ensuring this works. 2 | fn main() { 3 | println!("Build-script is running.") 4 | } 5 | -------------------------------------------------------------------------------- /test/cargo_flags/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | corrosion_tests_add_test(cargo_flags "flags-exe") 2 | 3 | set_tests_properties("cargo_flags_run_flags-exe" PROPERTIES PASS_REGULAR_EXPRESSION [[Hello, Cxx! I am Rust!]]) 4 | -------------------------------------------------------------------------------- /test/cpp2rust/cpp2rust/rust/rust_dependency/src/lib.rs: -------------------------------------------------------------------------------- 1 | 2 | extern "C" { 3 | fn get_42() -> u32; 4 | } 5 | pub fn calls_ffi() { 6 | let res = unsafe { get_42()}; 7 | assert_eq!(res, 42); 8 | } 9 | -------------------------------------------------------------------------------- /test/crate_type/crate_type/proj2/Cargo.toml: -------------------------------------------------------------------------------- 1 | [package] 2 | name = "proj2" 3 | version = "0.1.0" 4 | edition = "2018" 5 | 6 | [dependencies] 7 | 8 | [lib] 9 | crate-type=["staticlib", "cdylib"] 10 | -------------------------------------------------------------------------------- /test/envvar/envvar/Cargo.lock: -------------------------------------------------------------------------------- 1 | # This file is automatically @generated by Cargo. 2 | # It is not intended for manual editing. 3 | [[package]] 4 | name = "rust-lib-requiring-envvar" 5 | version = "0.1.0" 6 | -------------------------------------------------------------------------------- /test/crate_type/crate_type/main.cpp: -------------------------------------------------------------------------------- 1 | extern "C" void rust_function1(); 2 | extern "C" void rust_function2(); 3 | 4 | int main() { 5 | rust_function1(); 6 | rust_function2(); 7 | return 0; 8 | } 9 | -------------------------------------------------------------------------------- /test/crate_type/crate_type/proj1/Cargo.toml: -------------------------------------------------------------------------------- 1 | [package] 2 | name = "proj1" 3 | version = "0.1.0" 4 | edition = "2018" 5 | 6 | [dependencies] 7 | 8 | [lib] 9 | crate-type=["staticlib", "cdylib"] 10 | 11 | -------------------------------------------------------------------------------- /test/workspace/workspace/member1/Cargo.toml: -------------------------------------------------------------------------------- 1 | [package] 2 | name = "member1" 3 | version = "0.1.0" 4 | edition = "2018" 5 | description = "descr;\"hello\\" 6 | 7 | [lib] 8 | crate-type = [ "lib", "cdylib" ] 9 | -------------------------------------------------------------------------------- /test/cbindgen/install_lib/rust_lib/Cargo.toml: -------------------------------------------------------------------------------- 1 | [package] 2 | name = "rust_lib" 3 | version = "0.1.0" 4 | edition = "2018" 5 | 6 | [dependencies] 7 | 8 | [lib] 9 | crate-type = ["staticlib", "cdylib"] 10 | -------------------------------------------------------------------------------- /test/cxxbridge/cxxbridge_cpp2rust/include/cpplib.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | #include "cxxbridge-cpp/lib.h" 3 | 4 | ::RsImage read_image(::rust::Str path); 5 | void write_image(::rust::Str path, ::RsImage const & image); 6 | -------------------------------------------------------------------------------- /test/gensource/gensource/Cargo.lock: -------------------------------------------------------------------------------- 1 | # This file is automatically @generated by Cargo. 2 | # It is not intended for manual editing. 3 | version = 3 4 | 5 | [[package]] 6 | name = "generated" 7 | version = "0.1.0" 8 | -------------------------------------------------------------------------------- /test/nostd/nostd/rust/Cargo.lock: -------------------------------------------------------------------------------- 1 | # This file is automatically @generated by Cargo. 2 | # It is not intended for manual editing. 3 | version = 3 4 | 5 | [[package]] 6 | name = "rust-nostd-lib" 7 | version = "0.1.0" 8 | -------------------------------------------------------------------------------- /test/workspace/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | corrosion_tests_add_test(workspace "my_program") 2 | 3 | set_tests_properties("workspace_run_my_program" PROPERTIES PASS_REGULAR_EXPRESSION 4 | "^Ok\r?\n$" 5 | ) 6 | 7 | -------------------------------------------------------------------------------- /test/corrosion_install/install_lib/rust_lib/Cargo.toml: -------------------------------------------------------------------------------- 1 | [package] 2 | name = "rust_lib" 3 | version = "0.1.0" 4 | edition = "2018" 5 | 6 | [dependencies] 7 | 8 | [lib] 9 | crate-type = ["staticlib", "cdylib"] 10 | -------------------------------------------------------------------------------- /test/crate_type/crate_type/proj1/Cargo.lock: -------------------------------------------------------------------------------- 1 | # This file is automatically @generated by Cargo. 2 | # It is not intended for manual editing. 3 | version = 3 4 | 5 | [[package]] 6 | name = "proj1" 7 | version = "0.1.0" 8 | -------------------------------------------------------------------------------- /test/crate_type/crate_type/proj2/Cargo.lock: -------------------------------------------------------------------------------- 1 | # This file is automatically @generated by Cargo. 2 | # It is not intended for manual editing. 3 | version = 3 4 | 5 | [[package]] 6 | name = "proj2" 7 | version = "0.1.0" 8 | -------------------------------------------------------------------------------- /test/cxxbridge/cxxbridge_cpp2rust/rust/Cargo.toml: -------------------------------------------------------------------------------- 1 | [package] 2 | name = "rust_bin" 3 | version = "0.1.0" 4 | edition = "2018" 5 | 6 | [lib] 7 | name = "cxxbridge_lib" 8 | 9 | [dependencies] 10 | cxx = "1.0" 11 | -------------------------------------------------------------------------------- /test/gensource/gensource/generator/Cargo.lock: -------------------------------------------------------------------------------- 1 | # This file is automatically @generated by Cargo. 2 | # It is not intended for manual editing. 3 | version = 3 4 | 5 | [[package]] 6 | name = "srcgen" 7 | version = "0.1.0" 8 | -------------------------------------------------------------------------------- /test/gensource/gensource/src/lib.rs: -------------------------------------------------------------------------------- 1 | mod foo; 2 | 3 | #[cfg(test)] 4 | mod tests { 5 | #[test] 6 | fn it_works() { 7 | let result = 2 + 2; 8 | assert_eq!(result, 4); 9 | } 10 | } 11 | -------------------------------------------------------------------------------- /test/override_crate_type/override_crate_type/rust/Cargo.lock: -------------------------------------------------------------------------------- 1 | # This file is automatically @generated by Cargo. 2 | # It is not intended for manual editing. 3 | [[package]] 4 | name = "rust-lib" 5 | version = "0.1.0" 6 | -------------------------------------------------------------------------------- /test/override_crate_type/override_crate_type/rust/build.rs: -------------------------------------------------------------------------------- 1 | // Build-scripts also need to be linked, so just add a dummy buildscript ensuring this works. 2 | fn main() { 3 | println!("Build-script is running.") 4 | } 5 | -------------------------------------------------------------------------------- /test/cargo_flags/cargo_flags/rust/Cargo.lock: -------------------------------------------------------------------------------- 1 | # This file is automatically @generated by Cargo. 2 | # It is not intended for manual editing. 3 | version = 3 4 | 5 | [[package]] 6 | name = "flags-lib" 7 | version = "0.1.0" 8 | -------------------------------------------------------------------------------- /test/features/features/rust/Cargo.lock: -------------------------------------------------------------------------------- 1 | # This file is automatically @generated by Cargo. 2 | # It is not intended for manual editing. 3 | version = 3 4 | 5 | [[package]] 6 | name = "rust-feature-lib" 7 | version = "0.1.0" 8 | -------------------------------------------------------------------------------- /test/hostbuild/hostbuild/Cargo.toml: -------------------------------------------------------------------------------- 1 | [package] 2 | name = "rust-host-program" 3 | version = "0.1.0" 4 | authors = ["Olivier Goffart "] 5 | edition = "2018" 6 | 7 | [build-dependencies] 8 | cc = "1.0" 9 | -------------------------------------------------------------------------------- /test/multitarget/multitarget/Cargo.lock: -------------------------------------------------------------------------------- 1 | # This file is automatically @generated by Cargo. 2 | # It is not intended for manual editing. 3 | version = 3 4 | 5 | [[package]] 6 | name = "multitarget-crate" 7 | version = "0.1.0" 8 | -------------------------------------------------------------------------------- /test/workspace/workspace/member2/Cargo.toml: -------------------------------------------------------------------------------- 1 | [package] 2 | name = "member2" 3 | version = "0.1.0" 4 | authors = ["Olivier Goffart "] 5 | edition = "2018" 6 | 7 | [lib] 8 | crate-type = ["staticlib"] 9 | -------------------------------------------------------------------------------- /test/config_discovery/config_discovery/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | cmake_minimum_required(VERSION 3.15) 2 | project(test_project VERSION 0.1.0) 3 | include(../../test_header.cmake) 4 | 5 | corrosion_import_crate(MANIFEST_PATH Cargo.toml) 6 | -------------------------------------------------------------------------------- /test/cxxbridge/cxxbridge_rust2cpp/rust/Cargo.toml: -------------------------------------------------------------------------------- 1 | [package] 2 | name = "cxxbridge-crate" 3 | version = "0.1.0" 4 | edition = "2018" 5 | 6 | [lib] 7 | crate-type = ["staticlib"] 8 | 9 | [dependencies] 10 | cxx = "1.0" 11 | -------------------------------------------------------------------------------- /test/multitarget/multitarget/src/bin/bin1.rs: -------------------------------------------------------------------------------- 1 | use multitarget_lib::hello_world; 2 | 3 | fn main() { 4 | hello_world(); 5 | unsafe { 6 | multitarget_lib::cpp_function("bin1\0".as_ptr() as *const _); 7 | } 8 | } 9 | -------------------------------------------------------------------------------- /test/multitarget/multitarget/src/bin/bin2.rs: -------------------------------------------------------------------------------- 1 | use multitarget_lib::hello_world; 2 | 3 | fn main() { 4 | hello_world(); 5 | unsafe { 6 | multitarget_lib::cpp_function("bin2\0".as_ptr() as *const _); 7 | } 8 | } 9 | -------------------------------------------------------------------------------- /test/multitarget/multitarget/src/bin/bin3.rs: -------------------------------------------------------------------------------- 1 | use multitarget_lib::hello_world; 2 | 3 | fn main() { 4 | hello_world(); 5 | unsafe { 6 | multitarget_lib::cpp_function("bin3\0".as_ptr() as *const _); 7 | } 8 | } 9 | -------------------------------------------------------------------------------- /test/multitarget/multitarget/src/lib.rs: -------------------------------------------------------------------------------- 1 | use std::os::raw::c_char; 2 | 3 | pub fn hello_world() { 4 | println!("Hello, world!"); 5 | } 6 | 7 | extern "C" { 8 | pub fn cpp_function(name: *const c_char); 9 | } 10 | -------------------------------------------------------------------------------- /test/corrosion_install/install_lib/rust_lib/Cargo.lock: -------------------------------------------------------------------------------- 1 | # This file is automatically @generated by Cargo. 2 | # It is not intended for manual editing. 3 | version = 3 4 | 5 | [[package]] 6 | name = "rust_lib" 7 | version = "0.1.0" 8 | -------------------------------------------------------------------------------- /.github/scripts/toolchains/i686-unknown-linux-gnu-clang.cmake: -------------------------------------------------------------------------------- 1 | set(CMAKE_C_COMPILER "clang") 2 | set(CMAKE_CXX_COMPILER "clang++") 3 | set(CMAKE_C_COMPILER_TARGET "i686-pc-linux-gnu") 4 | set(CMAKE_CXX_COMPILER_TARGET "i686-pc-linux-gnu") 5 | -------------------------------------------------------------------------------- /cmake/CorrosionConfig.cmake.in: -------------------------------------------------------------------------------- 1 | @PACKAGE_INIT@ 2 | 3 | if (Corrosion_FOUND) 4 | return() 5 | endif() 6 | 7 | list(APPEND CMAKE_MODULE_PATH "${PACKAGE_PREFIX_DIR}/@CMAKE_INSTALL_DATADIR@/cmake") 8 | 9 | include(Corrosion) 10 | -------------------------------------------------------------------------------- /test/corrosion_install/install_rust_bin/rust_bin/Cargo.lock: -------------------------------------------------------------------------------- 1 | # This file is automatically @generated by Cargo. 2 | # It is not intended for manual editing. 3 | version = 3 4 | 5 | [[package]] 6 | name = "my_rust_bin" 7 | version = "0.1.0" 8 | -------------------------------------------------------------------------------- /test/custom_profiles/basic_profiles/rust/Cargo.lock: -------------------------------------------------------------------------------- 1 | # This file is automatically @generated by Cargo. 2 | # It is not intended for manual editing. 3 | version = 3 4 | 5 | [[package]] 6 | name = "cargo-profiles-lib" 7 | version = "0.1.0" 8 | -------------------------------------------------------------------------------- /test/custom_profiles/custom_profiles/rust/Cargo.lock: -------------------------------------------------------------------------------- 1 | # This file is automatically @generated by Cargo. 2 | # It is not intended for manual editing. 3 | version = 3 4 | 5 | [[package]] 6 | name = "custom-profiles-lib" 7 | version = "0.1.0" 8 | -------------------------------------------------------------------------------- /test/nostd/nostd/rust/src/lib.rs: -------------------------------------------------------------------------------- 1 | #![no_std] 2 | use core::panic::PanicInfo; 3 | 4 | #[no_mangle] 5 | pub extern "C" fn rust_function() {} 6 | 7 | #[panic_handler] 8 | fn panic(_panic: &PanicInfo<'_>) -> ! { 9 | loop {} 10 | } -------------------------------------------------------------------------------- /test/output directory/output directory/proj1/Cargo.lock: -------------------------------------------------------------------------------- 1 | # This file is automatically @generated by Cargo. 2 | # It is not intended for manual editing. 3 | version = 3 4 | 5 | [[package]] 6 | name = "rust_package1" 7 | version = "0.1.0" 8 | -------------------------------------------------------------------------------- /test/output directory/output directory/proj2/Cargo.lock: -------------------------------------------------------------------------------- 1 | # This file is automatically @generated by Cargo. 2 | # It is not intended for manual editing. 3 | version = 3 4 | 5 | [[package]] 6 | name = "rust_package2" 7 | version = "0.1.0" 8 | -------------------------------------------------------------------------------- /test/output directory/output directory/proj3/Cargo.lock: -------------------------------------------------------------------------------- 1 | # This file is automatically @generated by Cargo. 2 | # It is not intended for manual editing. 3 | version = 3 4 | 5 | [[package]] 6 | name = "rust_package3" 7 | version = "0.1.0" 8 | -------------------------------------------------------------------------------- /test/rustflags/cargo_config_rustflags/Cargo.lock: -------------------------------------------------------------------------------- 1 | # This file is automatically @generated by Cargo. 2 | # It is not intended for manual editing. 3 | version = 3 4 | 5 | [[package]] 6 | name = "cargo_config_rustflags" 7 | version = "0.1.0" 8 | -------------------------------------------------------------------------------- /.github/scripts/toolchains/aarch64-unknown-linux-gnu-clang.cmake: -------------------------------------------------------------------------------- 1 | set(CMAKE_C_COMPILER "clang") 2 | set(CMAKE_CXX_COMPILER "clang++") 3 | set(CMAKE_C_COMPILER_TARGET "aarch64-linux-gnu") 4 | set(CMAKE_CXX_COMPILER_TARGET "aarch64-linux-gnu") 5 | -------------------------------------------------------------------------------- /.github/scripts/toolchains/x86_64-pc-windows-gnullvm.cmake: -------------------------------------------------------------------------------- 1 | set(CMAKE_C_COMPILER "clang") 2 | set(CMAKE_CXX_COMPILER "clang++") 3 | set(CMAKE_C_COMPILER_TARGET "x86_64-pc-windows-gnu") 4 | set(CMAKE_CXX_COMPILER_TARGET "x86_64-pc-windows-gnu") 5 | -------------------------------------------------------------------------------- /test/cargo_flags/cargo_flags/rust/Cargo.toml: -------------------------------------------------------------------------------- 1 | [package] 2 | name = "flags-lib" 3 | version = "0.1.0" 4 | edition = "2018" 5 | 6 | [lib] 7 | crate-type=["staticlib"] 8 | 9 | [features] 10 | 11 | one = [] 12 | two = [] 13 | three = [] 14 | -------------------------------------------------------------------------------- /test/corrosion_install/install_rust_bin/rust_bin/src/main.rs: -------------------------------------------------------------------------------- 1 | fn main() { 2 | println!( 3 | "#include 4 | int main() {{ 5 | std::cout << \"Hello World! I'm generated code\"; 6 | return 0; 7 | }}" 8 | ); 9 | } 10 | -------------------------------------------------------------------------------- /test/crate_type/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | corrosion_tests_add_test(crate_type "cpp-exe") 2 | 3 | 4 | set_tests_properties("crate_type_run_cpp-exe" PROPERTIES PASS_REGULAR_EXPRESSION 5 | "Hello from lib 1!\r?\nHello from lib 2!" 6 | ) 7 | -------------------------------------------------------------------------------- /test/cxxbridge/cxxbridge_circular/rust/Cargo.toml: -------------------------------------------------------------------------------- 1 | [package] 2 | name = "rust_lib" 3 | version = "0.1.0" 4 | edition = "2018" 5 | 6 | [lib] 7 | name = "rust_lib" 8 | crate-type = ["staticlib"] 9 | 10 | [dependencies] 11 | cxx = "1.0" 12 | -------------------------------------------------------------------------------- /test/output directory/output_directory_config/proj1/Cargo.lock: -------------------------------------------------------------------------------- 1 | # This file is automatically @generated by Cargo. 2 | # It is not intended for manual editing. 3 | version = 3 4 | 5 | [[package]] 6 | name = "rust_package1" 7 | version = "0.1.0" 8 | -------------------------------------------------------------------------------- /test/envvar/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | corrosion_tests_add_test(envvar "program_requiring_rust_lib_with_envvar") 2 | 3 | set_tests_properties("envvar_run_program_requiring_rust_lib_with_envvar" PROPERTIES PASS_REGULAR_EXPRESSION 4 | "Ok" 5 | ) 6 | -------------------------------------------------------------------------------- /test/gensource/gensource/generator/Cargo.toml: -------------------------------------------------------------------------------- 1 | [package] 2 | name = "srcgen" 3 | version = "0.1.0" 4 | edition = "2018" 5 | 6 | # See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html 7 | 8 | [dependencies] 9 | -------------------------------------------------------------------------------- /test/cxxbridge/cxxbridge_exported_impls/rust/Cargo.toml: -------------------------------------------------------------------------------- 1 | [package] 2 | name = "rust_lib" 3 | version = "0.1.0" 4 | edition = "2018" 5 | 6 | [lib] 7 | name = "rust_lib" 8 | crate-type = ["staticlib"] 9 | 10 | [dependencies] 11 | cxx = "1.0" 12 | -------------------------------------------------------------------------------- /test/cbindgen/auto/rust/Cargo.toml: -------------------------------------------------------------------------------- 1 | [package] 2 | name = "the_rust_package_name" 3 | version = "0.1.0" 4 | license = "MIT" 5 | edition = "2018" 6 | 7 | [dependencies] 8 | 9 | [lib] 10 | crate-type=["staticlib"] 11 | name = "the_rust_lib_crate_name" 12 | -------------------------------------------------------------------------------- /test/envvar/envvar/Cargo.toml: -------------------------------------------------------------------------------- 1 | [package] 2 | name = "rust-lib-requiring-envvar" 3 | version = "0.1.0" 4 | authors = ["Olivier Goffart "] 5 | edition = "2018" 6 | build = "build.rs" 7 | 8 | [lib] 9 | crate-type = [ "lib", "cdylib" ] 10 | -------------------------------------------------------------------------------- /test/output directory/output directory/proj1/Cargo.toml: -------------------------------------------------------------------------------- 1 | [package] 2 | name = "rust_package1" 3 | version = "0.1.0" 4 | edition = "2018" 5 | 6 | [lib] 7 | name = "rust_lib1" 8 | crate-type=["staticlib", "cdylib"] 9 | 10 | [[bin]] 11 | name = "rust_bin1" 12 | -------------------------------------------------------------------------------- /test/output directory/output directory/proj2/Cargo.toml: -------------------------------------------------------------------------------- 1 | [package] 2 | name = "rust_package2" 3 | version = "0.1.0" 4 | edition = "2018" 5 | 6 | [lib] 7 | name = "rust_lib2" 8 | crate-type=["staticlib", "cdylib"] 9 | 10 | [[bin]] 11 | name = "rust_bin2" 12 | -------------------------------------------------------------------------------- /test/output directory/output directory/proj3/Cargo.toml: -------------------------------------------------------------------------------- 1 | [package] 2 | name = "rust_package3" 3 | version = "0.1.0" 4 | edition = "2018" 5 | 6 | [lib] 7 | name = "rust_lib3" 8 | crate-type=["staticlib", "cdylib"] 9 | 10 | [[bin]] 11 | name = "rust_bin3" 12 | -------------------------------------------------------------------------------- /test/rust2cpp/rust2cpp/main.cpp: -------------------------------------------------------------------------------- 1 | extern "C" void rust_function(char const *name); 2 | 3 | int main(int argc, char **argv) { 4 | if (argc < 2) { 5 | rust_function("Cpp"); 6 | } else { 7 | rust_function(argv[1]); 8 | } 9 | } 10 | -------------------------------------------------------------------------------- /test/cbindgen/manual/rust/Cargo.toml: -------------------------------------------------------------------------------- 1 | [package] 2 | name = "the-rust-lib-package-name" 3 | version = "0.1.0" 4 | license = "MIT" 5 | edition = "2018" 6 | 7 | [dependencies] 8 | 9 | [lib] 10 | crate-type=["staticlib"] 11 | name = "the_actual_library_crate_name" 12 | -------------------------------------------------------------------------------- /test/find_rust/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | corrosion_tests_add_test(find_rust "") 2 | corrosion_tests_add_test(rustup_proxy "") 3 | 4 | find_program(rustup rustup) 5 | if(NOT rustup) 6 | set_tests_properties(rustup_proxy_build rustup_proxy_cleanup PROPERTIES DISABLED 1) 7 | endif() 8 | -------------------------------------------------------------------------------- /test/output directory/output_directory_config/proj1/Cargo.toml: -------------------------------------------------------------------------------- 1 | [package] 2 | name = "rust_package1" 3 | version = "0.1.0" 4 | edition = "2018" 5 | 6 | [lib] 7 | name = "rust_lib1" 8 | crate-type=["staticlib", "cdylib"] 9 | 10 | [[bin]] 11 | name = "rust_bin1" 12 | -------------------------------------------------------------------------------- /test/override_crate_type/override_crate_type/rust/Cargo.toml: -------------------------------------------------------------------------------- 1 | [package] 2 | name = "rust-lib" 3 | version = "0.1.0" 4 | authors = ["Andrew Gaspar "] 5 | license = "MIT" 6 | edition = "2018" 7 | 8 | 9 | [lib] 10 | name = "my_rust_lib" 11 | -------------------------------------------------------------------------------- /test/cpp2rust/cpp2rust/rust/Cargo.toml: -------------------------------------------------------------------------------- 1 | [package] 2 | name = "rust-exe" 3 | version = "0.1.0" 4 | authors = ["Andrew Gaspar "] 5 | license = "MIT" 6 | edition = "2018" 7 | 8 | [dependencies] 9 | rust-dependency = { path = "rust_dependency" } 10 | -------------------------------------------------------------------------------- /test/rust2cpp/rust2cpp/rust/src/lib.rs: -------------------------------------------------------------------------------- 1 | use std::os::raw::c_char; 2 | 3 | #[no_mangle] 4 | pub extern "C" fn rust_function(name: *const c_char) { 5 | let name = unsafe { std::ffi::CStr::from_ptr(name).to_str().unwrap() }; 6 | println!("Hello, {}! I'm Rust!", name); 7 | } 8 | -------------------------------------------------------------------------------- /test/rustflags/rustflags/rust/Cargo.toml: -------------------------------------------------------------------------------- 1 | [package] 2 | name = "rustflag-test-lib" 3 | version = "0.1.0" 4 | license = "MIT" 5 | edition = "2018" 6 | 7 | [dependencies] 8 | some_dependency = { path = "some_dependency" } 9 | 10 | [lib] 11 | crate-type=["staticlib"] 12 | -------------------------------------------------------------------------------- /test/config_discovery/config_discovery/.cargo/config.toml: -------------------------------------------------------------------------------- 1 | # Defines registry alias `my-registry` pointing to crates.io. 2 | # If not discovered cargo errors: "registry `my-registry` not found" 3 | [registries.my-registry] 4 | index = "https://github.com/rust-lang/crates.io-index" 5 | -------------------------------------------------------------------------------- /test/override_crate_type/override_crate_type/main.cpp: -------------------------------------------------------------------------------- 1 | extern "C" void rust_function(char const *name); 2 | 3 | int main(int argc, char **argv) { 4 | if (argc < 2) { 5 | rust_function("Cpp"); 6 | } else { 7 | rust_function(argv[1]); 8 | } 9 | } 10 | -------------------------------------------------------------------------------- /test/rust2cpp/rust2cpp/rust/Cargo.toml: -------------------------------------------------------------------------------- 1 | [package] 2 | name = "rust-lib" 3 | version = "0.1.0" 4 | authors = ["Andrew Gaspar "] 5 | license = "MIT" 6 | edition = "2018" 7 | 8 | [dependencies] 9 | 10 | [lib] 11 | crate-type=["staticlib", "cdylib"] 12 | -------------------------------------------------------------------------------- /test/hostbuild/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | corrosion_tests_add_test(hostbuild "rust-host-program" IS_HOSTBUILD) 2 | 3 | set_tests_properties("hostbuild_run_rust-host-program" PROPERTIES PASS_REGULAR_EXPRESSION 4 | "^ok\r?\nHello Rust Hostbuild, I am an external C function" 5 | ) 6 | 7 | -------------------------------------------------------------------------------- /test/hostbuild/hostbuild/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | cmake_minimum_required(VERSION 3.15) 2 | project(test_project VERSION 0.1.0) 3 | include(../../test_header.cmake) 4 | 5 | corrosion_import_crate(MANIFEST_PATH ${CMAKE_CURRENT_SOURCE_DIR}/Cargo.toml) 6 | 7 | corrosion_set_hostbuild(rust-host-program) 8 | -------------------------------------------------------------------------------- /.github/scripts/toolchains/aarch64-apple-darwin-clang.cmake: -------------------------------------------------------------------------------- 1 | set(CMAKE_C_COMPILER "clang") 2 | set(CMAKE_CXX_COMPILER "clang++") 3 | set(CMAKE_C_COMPILER_TARGET "aarch64-apple-darwin") 4 | set(CMAKE_CXX_COMPILER_TARGET "aarch64-apple-darwin") 5 | set(CMAKE_OSX_ARCHITECTURES "arm64" CACHE STRING "") 6 | -------------------------------------------------------------------------------- /test/custom_profiles/basic_profiles/rust/src/lib.rs: -------------------------------------------------------------------------------- 1 | use std::os::raw::c_char; 2 | 3 | #[no_mangle] 4 | pub extern "C" fn rust_function(name: *const c_char) { 5 | let name = unsafe { std::ffi::CStr::from_ptr(name).to_str().unwrap() }; 6 | println!("Hello, {}! I'm Rust!", name); 7 | } 8 | 9 | -------------------------------------------------------------------------------- /test/custom_target/custom_target/rust/Cargo.toml: -------------------------------------------------------------------------------- 1 | [package] 2 | name = "rust-lib" 3 | version = "0.1.0" 4 | edition = "2018" 5 | 6 | [lib] 7 | crate-type=["staticlib", "lib"] 8 | 9 | [[bin]] 10 | name = "rust-bin" 11 | path = "src/bin.rs" 12 | 13 | [build-dependencies] 14 | cc = "1" 15 | -------------------------------------------------------------------------------- /test/cxxbridge/cxxbridge_rust2cpp/rust/src/foo/mod.rs: -------------------------------------------------------------------------------- 1 | #[cxx::bridge(namespace = "foo")] 2 | mod bridge { 3 | extern "Rust" { 4 | fn print(slice: &[u64]); 5 | } 6 | } 7 | 8 | fn print(slice: &[u64]) { 9 | println!("Hello cxxbridge from foo/mod.rs! {:?}", slice); 10 | } 11 | -------------------------------------------------------------------------------- /test/gensource/gensource/Cargo.toml: -------------------------------------------------------------------------------- 1 | [package] 2 | name = "generated" 3 | version = "0.1.0" 4 | edition = "2018" 5 | 6 | [lib] 7 | crate-type = ["lib", "cdylib"] 8 | # See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html 9 | 10 | [dependencies] 11 | -------------------------------------------------------------------------------- /test/gensource/gensource/generator/src/main.rs: -------------------------------------------------------------------------------- 1 | use std::io::Write; 2 | fn main() -> Result<(), std::io::Error> { 3 | let out_name = std::env::args().skip(1).next().unwrap(); 4 | let mut out_file = std::fs::File::create(out_name)?; 5 | Ok(write!(out_file, "const _: () = ();")?) 6 | } 7 | -------------------------------------------------------------------------------- /test/cpp2rust/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | corrosion_tests_add_test(cpp2rust "rust-exe") 2 | 3 | set_tests_properties("cpp2rust_run_rust-exe" PROPERTIES PASS_REGULAR_EXPRESSION 4 | "Hello, Rust! I am Cpp!\r?\nHello, Rust! I am Cpp library Number 2!\r?\nHello, Rust! I am Cpp library Number 3!" 5 | ) 6 | -------------------------------------------------------------------------------- /test/cpp2rust/cpp2rust/path with space/lib3.cpp: -------------------------------------------------------------------------------- 1 | // Check that libraries located at a path containing a space can also be linked. 2 | 3 | #include 4 | 5 | extern "C" void cpp_function3(char const *name) { 6 | std::cout << "Hello, " << name << "! I am Cpp library Number 3!\n"; 7 | } 8 | 9 | -------------------------------------------------------------------------------- /test/override_crate_type/override_crate_type/rust/src/lib.rs: -------------------------------------------------------------------------------- 1 | use std::os::raw::c_char; 2 | 3 | #[no_mangle] 4 | pub extern "C" fn rust_function(name: *const c_char) { 5 | let name = unsafe { std::ffi::CStr::from_ptr(name).to_str().unwrap() }; 6 | println!("Hello, {}! I'm Rust!", name); 7 | } 8 | -------------------------------------------------------------------------------- /test/config_discovery/config_discovery/src/main.rs: -------------------------------------------------------------------------------- 1 | use bitflags::bitflags; 2 | 3 | bitflags! { 4 | struct TestFlags: u32 { 5 | const VALUE = 0b00000001; 6 | } 7 | } 8 | 9 | fn main() { 10 | let flags = TestFlags::VALUE; 11 | println!("Flag value: {}", flags.bits()); 12 | } 13 | -------------------------------------------------------------------------------- /test/corrosion_install/install_rust_bin/rust_bin/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | cmake_minimum_required(VERSION 3.22) 2 | project(test_rust_bin VERSION 0.1.0) 3 | include(../../../test_header.cmake) 4 | include(GNUInstallDirs) 5 | 6 | corrosion_import_crate(MANIFEST_PATH Cargo.toml) 7 | corrosion_install(TARGETS my_rust_bin) 8 | -------------------------------------------------------------------------------- /test/cxxbridge/cxxbridge_rust2cpp/rust/src/lib.rs: -------------------------------------------------------------------------------- 1 | mod foo; 2 | 3 | #[cxx::bridge(namespace = "lib")] 4 | mod bridge { 5 | extern "Rust" { 6 | fn print(slice: &[u64]); 7 | } 8 | } 9 | 10 | fn print(slice: &[u64]) { 11 | println!("Hello cxxbridge from lib.rs! {:?}", slice); 12 | } 13 | -------------------------------------------------------------------------------- /test/gensource/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | corrosion_tests_add_test(gensource "") 2 | 3 | #set_tests_properties("features_run_features-cpp-exe" PROPERTIES PASS_REGULAR_EXPRESSION 4 | # "Hello, Cpp! I'm Rust!\r?\nHello, Cpp again! I'm Rust again!\r?\nHello, Cpp again! I'm Rust again, third time the charm!" 5 | # ) -------------------------------------------------------------------------------- /test/hostbuild/hostbuild/src/main.rs: -------------------------------------------------------------------------------- 1 | use std::os::raw::c_char; 2 | 3 | extern "C" { 4 | fn c_function(name: *const c_char); 5 | } 6 | 7 | fn main() { 8 | println!("ok"); 9 | let name = b"Rust Hostbuild\0"; 10 | unsafe { 11 | c_function(name.as_ptr() as _); 12 | } 13 | } 14 | -------------------------------------------------------------------------------- /doc/src/SUMMARY.md: -------------------------------------------------------------------------------- 1 | # Summary 2 | 3 | - [Introduction](./introduction.md) 4 | - [Quick Start](./quick_start.md) 5 | - [Setup Corrosion](./setup_corrosion.md) 6 | - [Usage](./usage.md) 7 | - [Advanced](./advanced.md) 8 | - [FFI binding integrations](./ffi_bindings.md) 9 | - [Common Issues](./common_issues.md) 10 | -------------------------------------------------------------------------------- /test/cpp2rust/cpp2rust/lib2.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | 4 | extern "C" void cpp_function2(char const *name) { 5 | std::cout << "Hello, " << name << "! I am Cpp library Number 2!\n"; 6 | } 7 | 8 | extern "C" uint32_t get_42() { 9 | uint32_t v = 42; 10 | return v; 11 | } 12 | -------------------------------------------------------------------------------- /test/features/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | corrosion_tests_add_test(features "features-cpp-exe") 2 | 3 | set_tests_properties("features_run_features-cpp-exe" PROPERTIES PASS_REGULAR_EXPRESSION 4 | "Hello, Cpp! I'm Rust!\r?\nHello, Cpp again! I'm Rust again!\r?\nHello, Cpp again! I'm Rust again, third time the charm!" 5 | ) 6 | -------------------------------------------------------------------------------- /test/corrosion_install/install_lib/main.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | 5 | extern "C" uint64_t add(uint64_t a, uint64_t b); 6 | 7 | int main(int argc, char **argv) { 8 | uint64_t sum = add(5, 6); 9 | assert(sum == 11); 10 | std::cout << "The sum is " << sum << std::endl; 11 | } 12 | -------------------------------------------------------------------------------- /test/cxxbridge/cxxbridge_exported_impls/main.cpp: -------------------------------------------------------------------------------- 1 | #include "cxxbridge/lib.h" 2 | 3 | #include 4 | 5 | int main() 6 | { 7 | auto result = make_result(); 8 | 9 | std::cout << static_cast(result.ok->message) << std::endl; 10 | 11 | std::cout << "main function" << std::endl; 12 | 13 | return 0; 14 | } -------------------------------------------------------------------------------- /test/find_rust/find_rust/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | 2 | cmake_minimum_required(VERSION 3.15) 3 | project(FindRust LANGUAGES CXX) 4 | 5 | set(CMAKE_MODULE_PATH "${CMAKE_SOURCE_DIR}/../../../cmake" ${CMAKE_MODULE_PATH}) 6 | 7 | # make sure find_package(Rust) can be used more than once 8 | find_package(Rust REQUIRED) 9 | find_package(Rust REQUIRED) 10 | -------------------------------------------------------------------------------- /test/cpp2rust/cpp2rust/rust/Cargo.lock: -------------------------------------------------------------------------------- 1 | # This file is automatically @generated by Cargo. 2 | # It is not intended for manual editing. 3 | version = 3 4 | 5 | [[package]] 6 | name = "rust-dependency" 7 | version = "0.1.0" 8 | 9 | [[package]] 10 | name = "rust-exe" 11 | version = "0.1.0" 12 | dependencies = [ 13 | "rust-dependency", 14 | ] 15 | -------------------------------------------------------------------------------- /test/output directory/output directory/consumer.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | 4 | extern "C" unsigned int ret_12(); 5 | 6 | 7 | int main(int argc, char *argv[]) 8 | { 9 | std::cout << "HI\n"; 10 | unsigned int a = ret_12(); 11 | if (a != 12) { 12 | return -1; 13 | } 14 | 15 | return 0; 16 | } 17 | -------------------------------------------------------------------------------- /test/multitarget/multitarget/Cargo.toml: -------------------------------------------------------------------------------- 1 | [package] 2 | name = "multitarget-crate" 3 | version = "0.1.0" 4 | edition = "2018" 5 | 6 | [dependencies] 7 | 8 | [lib] 9 | name = "multitarget_lib" 10 | crate-type=["lib", "staticlib", "cdylib"] 11 | 12 | [[bin]] 13 | name = "bin1" 14 | 15 | [[bin]] 16 | name = "bin2" 17 | 18 | [[bin]] 19 | name = "bin3" 20 | -------------------------------------------------------------------------------- /test/rustflags/rustflags/rust/Cargo.lock: -------------------------------------------------------------------------------- 1 | # This file is automatically @generated by Cargo. 2 | # It is not intended for manual editing. 3 | version = 3 4 | 5 | [[package]] 6 | name = "rustflag-test-lib" 7 | version = "0.1.0" 8 | dependencies = [ 9 | "some_dependency", 10 | ] 11 | 12 | [[package]] 13 | name = "some_dependency" 14 | version = "0.1.0" 15 | -------------------------------------------------------------------------------- /test/rustflags/rustflags/rust/some_dependency/src/lib.rs: -------------------------------------------------------------------------------- 1 | //! Test that the local rustflags are only passed to the main crate and not to dependencies. 2 | #[cfg(test_local_rustflag1)] 3 | const _: [(); 1] = [(); 2]; 4 | 5 | #[cfg(test_local_rustflag2 = "value")] 6 | const _: [(); 1] = [(); 2]; 7 | 8 | pub fn some_function() -> u32 { 9 | 42 10 | } 11 | -------------------------------------------------------------------------------- /test/hostbuild/hostbuild/build.rs: -------------------------------------------------------------------------------- 1 | fn main() { 2 | let out_dir = std::env::var("OUT_DIR").unwrap(); 3 | cc::Build::new() 4 | .file("src/lib.c") 5 | .compile("hello"); 6 | 7 | println!("cargo:rustc-link-search=native={}", out_dir); 8 | println!("cargo:rustc-link-lib=hello"); 9 | println!("cargo:rerun-if-changed=src/lib.c"); 10 | } -------------------------------------------------------------------------------- /test/cxxbridge/cxxbridge_rust2cpp/main.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | 5 | int main(int argc, char **argv) 6 | { 7 | std::vector input = { 4, 5, 6}; 8 | rust::Slice slice{input.data(), input.size()}; 9 | lib::print(slice); 10 | foo::print(slice); 11 | } 12 | -------------------------------------------------------------------------------- /test/parse_target_triple/parse_target_triple_should_fail/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | # This test is supposed to ensure that the regex in _corrosion_parse_platform works as expected. 2 | cmake_minimum_required(VERSION 3.15) 3 | project(test_project VERSION 0.1.0) 4 | include(../../test_header.cmake) 5 | 6 | _corrosion_parse_target_triple("x86_64-unknown-linux-gnu-toomuch" arch vendor os env) 7 | -------------------------------------------------------------------------------- /test/config_discovery/config_discovery/Cargo.toml: -------------------------------------------------------------------------------- 1 | [package] 2 | name = "config_discovery" 3 | version = "0.1.0" 4 | edition = "2018" 5 | 6 | [dependencies] 7 | # Uses registry alias `my-registry`. If `.cargo/config.toml` is not discovered, the test will 8 | # fail wit the error: "registry `my-registry` not found" 9 | bitflags = { version = "1.3", registry = "my-registry" } 10 | -------------------------------------------------------------------------------- /.github/scripts/toolchains/x86_64-apple-darwin-clang.cmake: -------------------------------------------------------------------------------- 1 | set(CMAKE_C_COMPILER "clang") 2 | set(CMAKE_CXX_COMPILER "clang++") 3 | set(CMAKE_C_COMPILER_TARGET "x86_64-apple-darwin") 4 | set(CMAKE_CXX_COMPILER_TARGET "x86_64-apple-darwin") 5 | set(CMAKE_SYSTEM_NAME "Darwin") 6 | set(CMAKE_SYSTEM_VERSION ${CMAKE_HOST_SYSTEM_VERSION}) 7 | set(CMAKE_OSX_ARCHITECTURES "x86_64" CACHE STRING "") 8 | -------------------------------------------------------------------------------- /test/nostd/nostd/rust/Cargo.toml: -------------------------------------------------------------------------------- 1 | [package] 2 | name = "rust-nostd-lib" 3 | version = "0.1.0" 4 | edition = "2015" 5 | 6 | # See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html 7 | 8 | [dependencies] 9 | 10 | [lib] 11 | crate-type=["staticlib"] 12 | 13 | [profile.release] 14 | panic = "abort" 15 | 16 | [profile.dev] 17 | panic = "abort" 18 | -------------------------------------------------------------------------------- /test/rust2cpp/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | corrosion_tests_add_test(rust2cpp "cpp-exe;cpp-exe-shared") 2 | 3 | set_tests_properties("rust2cpp_run_cpp-exe" PROPERTIES PASS_REGULAR_EXPRESSION 4 | "^Hello, Cpp! I'm Rust!\r?\n$" 5 | ) 6 | 7 | set_tests_properties("rust2cpp_run_cpp-exe-shared" PROPERTIES PASS_REGULAR_EXPRESSION 8 | "^Hello, Cpp! I'm Rust!\r?\n$" 9 | ) 10 | -------------------------------------------------------------------------------- /test/workspace/workspace/Cargo.lock: -------------------------------------------------------------------------------- 1 | # This file is automatically @generated by Cargo. 2 | # It is not intended for manual editing. 3 | version = 3 4 | 5 | [[package]] 6 | name = "member1" 7 | version = "0.1.0" 8 | 9 | [[package]] 10 | name = "member2" 11 | version = "0.1.0" 12 | 13 | [[package]] 14 | name = "member3" 15 | version = "0.1.0" 16 | dependencies = [ 17 | "member1", 18 | ] 19 | -------------------------------------------------------------------------------- /test/output directory/output_directory_config/consumer.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | 4 | extern "C" unsigned int ret_12(); 5 | 6 | 7 | int main(int argc, char *argv[]) 8 | { 9 | std::cout << "Hello from output_directory_config_test_executable\n"; 10 | unsigned int a = ret_12(); 11 | if (a != 12) { 12 | return -1; 13 | } 14 | 15 | return 0; 16 | } 17 | -------------------------------------------------------------------------------- /test/workspace/workspace/member3/Cargo.toml: -------------------------------------------------------------------------------- 1 | [package] 2 | name = "member3" 3 | version = "0.1.0" 4 | authors = ["Olivier Goffart "] 5 | edition = "2018" 6 | 7 | # See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html 8 | 9 | [[bin]] 10 | name = "my_program" 11 | path = "src/main.rs" 12 | 13 | [dependencies] 14 | member1 = { path = "../member1" } 15 | -------------------------------------------------------------------------------- /test/features/features/rust/Cargo.toml: -------------------------------------------------------------------------------- 1 | [package] 2 | name = "rust-feature-lib" 3 | version = "0.1.0" 4 | authors = ["Andrew Gaspar "] 5 | license = "MIT" 6 | edition = "2018" 7 | 8 | [dependencies] 9 | 10 | [lib] 11 | crate-type=["staticlib"] 12 | 13 | [features] 14 | default = ["compile-breakage"] 15 | myfeature = [] 16 | secondfeature = [] 17 | thirdfeature = [] 18 | compile-breakage = [] -------------------------------------------------------------------------------- /test/cxxbridge/cxxbridge_circular/main.cpp: -------------------------------------------------------------------------------- 1 | #include "cpplib.h" 2 | 3 | #include 4 | 5 | int main(void) { 6 | std::cout << "Testing roundtrip..." << std::endl; 7 | 8 | try { 9 | assert_equality(); 10 | } catch (const std::exception &e) { 11 | std::cerr << "Error: " << e.what() << std::endl; 12 | return 1; 13 | } 14 | 15 | std::cout << "Roundtrip successful!"; 16 | return 0; 17 | } 18 | -------------------------------------------------------------------------------- /test/custom_profiles/custom_profiles/rust/src/lib.rs: -------------------------------------------------------------------------------- 1 | use std::os::raw::c_char; 2 | 3 | #[no_mangle] 4 | pub extern "C" fn rust_function(name: *const c_char) { 5 | let name = unsafe { std::ffi::CStr::from_ptr(name).to_str().unwrap() }; 6 | println!("Hello, {}! I'm Rust!", name); 7 | } 8 | 9 | 10 | #[cfg(debug_assertions)] 11 | const _: () = assert!(false, "Debug assertions where not disabled via custom profile!"); 12 | -------------------------------------------------------------------------------- /test/override_crate_type/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | corrosion_tests_add_test(override_crate_type "cpp-exe;cpp-exe-shared") 2 | 3 | set_tests_properties("override_crate_type_run_cpp-exe" PROPERTIES PASS_REGULAR_EXPRESSION 4 | "^Hello, Cpp! I'm Rust!\r?\n$" 5 | ) 6 | 7 | set_tests_properties("override_crate_type_run_cpp-exe-shared" PROPERTIES PASS_REGULAR_EXPRESSION 8 | "^Hello, Cpp! I'm Rust!\r?\n$" 9 | ) 10 | -------------------------------------------------------------------------------- /test/custom_target/custom_target/rust/src/lib.rs: -------------------------------------------------------------------------------- 1 | use std::os::raw::c_char; 2 | 3 | extern "C" { 4 | pub fn calculate_42() -> u32; 5 | } 6 | 7 | #[no_mangle] 8 | pub extern "C" fn rust_function(name: *const c_char) { 9 | let name = unsafe { std::ffi::CStr::from_ptr(name).to_str().unwrap() }; 10 | let res = unsafe { calculate_42() }; 11 | assert_eq!(res, 42); 12 | println!("Hello, {}! I am Rust!", name); 13 | } 14 | -------------------------------------------------------------------------------- /test/rust2cpp/rust2cpp/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | cmake_minimum_required(VERSION 3.15) 2 | project(test_project VERSION 0.1.0) 3 | include(../../test_header.cmake) 4 | 5 | corrosion_import_crate(MANIFEST_PATH rust/Cargo.toml) 6 | 7 | add_executable(cpp-exe main.cpp) 8 | target_link_libraries(cpp-exe PUBLIC rust_lib) 9 | 10 | add_executable(cpp-exe-shared main.cpp) 11 | target_link_libraries(cpp-exe-shared 12 | PUBLIC rust_lib-shared) 13 | -------------------------------------------------------------------------------- /test/rustflags/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | corrosion_tests_add_test(rustflags "rustflags-cpp-exe") 2 | 3 | set_tests_properties("rustflags_run_rustflags-cpp-exe" PROPERTIES PASS_REGULAR_EXPRESSION 4 | "Hello, Cpp! I'm Rust!\r?\nHello, Cpp again! I'm Rust in (Debug|Release) mode again!\r?\nHello, Cpp again! I'm Rust again, third time the charm!\r?\n$" 5 | ) 6 | 7 | corrosion_tests_add_test(cargo_config_rustflags "cargo_config_rustflags") 8 | -------------------------------------------------------------------------------- /test/README.md: -------------------------------------------------------------------------------- 1 | # Corrosion Tests 2 | 3 | Corrosions tests are run via ctest. The tests themselves utilize CMake script mode 4 | to configure and build a test project, which allows for great flexibility. 5 | Using ctest properties such as `PASS_REGULAR_EXPRESSION` or `FAIL_REGULAR_EXPRESSION` 6 | can be used to confirm that built executable targets run as expected, but can also 7 | be used to fail tests if Corrosion warnings appear in the configure output. -------------------------------------------------------------------------------- /test/cxxbridge/cxxbridge_cpp2rust/rust/src/main.rs: -------------------------------------------------------------------------------- 1 | use cxxbridge_lib::ffi::{RsImage,Rgba,read_image}; 2 | 3 | fn main() { 4 | println!("main function"); 5 | let expected = RsImage { width: 1, height: 1, raster: Rgba { 6 | r: 1.0, 7 | g: 2.0, 8 | b: 3.0, 9 | a: 4.0, 10 | }}; 11 | let actual = read_image("dummy path"); 12 | println!("returned from C++"); 13 | assert_eq!(actual, expected) 14 | } -------------------------------------------------------------------------------- /test/rustflags/cargo_config_rustflags/src/main.rs: -------------------------------------------------------------------------------- 1 | 2 | #[cfg(some_cargo_config_rustflag)] 3 | fn print_line() { 4 | println!("Rustflag is enabled"); 5 | } 6 | 7 | // test that local rustflags don't override global rustflags set via `.cargo/config` 8 | #[cfg(local_rustflag)] 9 | fn test_local_rustflag() { 10 | println!("local_rustflag was enabled"); 11 | } 12 | 13 | fn main() { 14 | print_line(); 15 | test_local_rustflag(); 16 | } 17 | -------------------------------------------------------------------------------- /test/cxxbridge/cxxbridge_cpp2rust/cpplib.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include "cpplib.h" 3 | #include "cxxbridge-cpp/lib.h" 4 | #include "rust/cxx.h" 5 | 6 | RsImage read_image(rust::Str path) { 7 | std::cout << "read_image called" << std::endl; 8 | std::cout << path << std::endl; 9 | Rgba c = { 1.0, 2.0, 3.0, 4.0}; 10 | RsImage v = { 1, 1, c}; 11 | return v; 12 | } 13 | void write_image(::rust::Str path, ::RsImage const & image) { 14 | 15 | } 16 | -------------------------------------------------------------------------------- /test/features/features/main.cpp: -------------------------------------------------------------------------------- 1 | extern "C" void rust_function(char const *name); 2 | extern "C" void rust_second_function(char const *name); 3 | extern "C" void rust_third_function(char const *name); 4 | 5 | int main(int argc, char **argv) { 6 | if (argc < 2) { 7 | rust_function("Cpp"); 8 | rust_second_function("Cpp again"); 9 | rust_third_function("Cpp again"); 10 | } else { 11 | rust_function(argv[1]); 12 | } 13 | } 14 | -------------------------------------------------------------------------------- /test/rustflags/rustflags/main.cpp: -------------------------------------------------------------------------------- 1 | extern "C" void rust_function(char const *name); 2 | extern "C" void rust_second_function(char const *name); 3 | extern "C" void rust_third_function(char const *name); 4 | 5 | int main(int argc, char **argv) { 6 | if (argc < 2) { 7 | rust_function("Cpp"); 8 | rust_second_function("Cpp again"); 9 | rust_third_function("Cpp again"); 10 | } else { 11 | rust_function(argv[1]); 12 | } 13 | } 14 | -------------------------------------------------------------------------------- /test/nostd/nostd/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | cmake_minimum_required(VERSION 3.15) 2 | project(test_project VERSION 0.1.0) 3 | include(../../test_header.cmake) 4 | 5 | corrosion_import_crate(MANIFEST_PATH rust/Cargo.toml NO_STD) 6 | 7 | set(CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} -nostdlib") 8 | list(REMOVE_ITEM CMAKE_CXX_IMPLICIT_LINK_LIBRARIES stdc++) 9 | 10 | add_library(nostd-cpp-lib STATIC main.cpp) 11 | target_link_libraries(nostd-cpp-lib PUBLIC rust-nostd-lib) 12 | -------------------------------------------------------------------------------- /test/custom_target/custom_target/rust/Cargo.lock: -------------------------------------------------------------------------------- 1 | # This file is automatically @generated by Cargo. 2 | # It is not intended for manual editing. 3 | version = 3 4 | 5 | [[package]] 6 | name = "cc" 7 | version = "1.0.0" 8 | source = "registry+https://github.com/rust-lang/crates.io-index" 9 | checksum = "7db2f146208d7e0fbee761b09cd65a7f51ccc38705d4e7262dad4d73b12a76b1" 10 | 11 | [[package]] 12 | name = "rust-lib" 13 | version = "0.1.0" 14 | dependencies = [ 15 | "cc", 16 | ] 17 | -------------------------------------------------------------------------------- /test/hostbuild/hostbuild/Cargo.lock: -------------------------------------------------------------------------------- 1 | # This file is automatically @generated by Cargo. 2 | # It is not intended for manual editing. 3 | version = 3 4 | 5 | [[package]] 6 | name = "cc" 7 | version = "1.0.73" 8 | source = "registry+https://github.com/rust-lang/crates.io-index" 9 | checksum = "2fff2a6927b3bb87f9595d67196a70493f627687a71d87a0d692242c33f58c11" 10 | 11 | [[package]] 12 | name = "rust-host-program" 13 | version = "0.1.0" 14 | dependencies = [ 15 | "cc", 16 | ] 17 | -------------------------------------------------------------------------------- /test/config_discovery/config_discovery/Cargo.lock: -------------------------------------------------------------------------------- 1 | # This file is automatically @generated by Cargo. 2 | # It is not intended for manual editing. 3 | version = 3 4 | 5 | [[package]] 6 | name = "bitflags" 7 | version = "1.3.2" 8 | source = "registry+https://github.com/rust-lang/crates.io-index" 9 | checksum = "bef38d45163c2f1dde094a7dfd33ccf595c92905c8f8f4fdc18d06fb1037718a" 10 | 11 | [[package]] 12 | name = "config_discovery" 13 | version = "0.1.0" 14 | dependencies = [ 15 | "bitflags", 16 | ] 17 | -------------------------------------------------------------------------------- /test/override_crate_type/override_crate_type/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | cmake_minimum_required(VERSION 3.15) 2 | project(test_project VERSION 0.1.0) 3 | include(../../test_header.cmake) 4 | 5 | corrosion_import_crate(MANIFEST_PATH rust/Cargo.toml OVERRIDE_CRATE_TYPE my_rust_lib=staticlib,cdylib) 6 | 7 | add_executable(cpp-exe main.cpp) 8 | target_link_libraries(cpp-exe PUBLIC my_rust_lib) 9 | 10 | add_executable(cpp-exe-shared main.cpp) 11 | target_link_libraries(cpp-exe-shared 12 | PUBLIC my_rust_lib-shared) 13 | -------------------------------------------------------------------------------- /test/custom_target/custom_target/rust/build.rs: -------------------------------------------------------------------------------- 1 | fn main() { 2 | let mut builder = cc::Build::new(); 3 | // We override the target here, purely to make the testcase simpler. 4 | // In a real-world project, the custom rust .json target triple file 5 | // should have a filename matching the target-triple the c-compiler understands 6 | // (if the c/c++ toolchain is llvm based) 7 | builder.target(&std::env::var("HOST").unwrap()); 8 | 9 | builder.file("c_lib.c").compile("custom_target"); 10 | } -------------------------------------------------------------------------------- /test/multitarget/multitarget/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | cmake_minimum_required(VERSION 3.15) 2 | project(test_project VERSION 0.1.0) 3 | include(../../test_header.cmake) 4 | 5 | corrosion_import_crate(MANIFEST_PATH Cargo.toml) 6 | 7 | add_library(cpp-lib4 lib.cpp) 8 | target_compile_features(cpp-lib4 PRIVATE cxx_std_14) 9 | set_property(TARGET cpp-lib4 PROPERTY POSITION_INDEPENDENT_CODE ON) 10 | corrosion_link_libraries(bin1 cpp-lib4) 11 | corrosion_link_libraries(bin2 cpp-lib4) 12 | corrosion_link_libraries(bin3 cpp-lib4) 13 | -------------------------------------------------------------------------------- /test/cbindgen/auto/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | cmake_minimum_required(VERSION 3.15) 2 | project(test_project VERSION 0.1.0) 3 | 4 | set(CORROSION_TOOLS_RUST_TOOLCHAIN "stable") 5 | include(../../test_header.cmake) 6 | corrosion_import_crate(MANIFEST_PATH rust/Cargo.toml) 7 | corrosion_experimental_cbindgen(TARGET the_rust_lib_crate_name HEADER_NAME "rust-lib.h") 8 | 9 | add_executable(cpp-exe main.cpp) 10 | set_property(TARGET cpp-exe PROPERTY CXX_STANDARD 11) 11 | target_link_libraries(cpp-exe PUBLIC the_rust_lib_crate_name) 12 | -------------------------------------------------------------------------------- /test/custom_profiles/basic_profiles/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | cmake_minimum_required(VERSION 3.15) 2 | project(test_project VERSION 0.1.0) 3 | include(../../test_header.cmake) 4 | 5 | if(NOT DEFINED CARGO_PROFILE) 6 | message(FATAL_ERROR "Test internal error. The test should be called with the CARGO_PROFILE parameter.") 7 | endif() 8 | 9 | corrosion_import_crate(MANIFEST_PATH rust/Cargo.toml PROFILE ${CARGO_PROFILE}) 10 | 11 | add_executable(${CARGO_PROFILE}_bin main.cpp) 12 | target_link_libraries(${CARGO_PROFILE}_bin PUBLIC cargo_profiles_lib) 13 | -------------------------------------------------------------------------------- /test/cxxbridge/cxxbridge_circular/cpplib.cpp: -------------------------------------------------------------------------------- 1 | #include "cpplib.h" 2 | #include "cxxbridge/lib.h" 3 | #include "rust/cxx.h" 4 | #include 5 | 6 | RsImage read_image(rust::Str path) { 7 | std::cout << "read_image called" << std::endl; 8 | std::cout << path << std::endl; 9 | Rgba c = {1.0, 2.0, 3.0, 4.0}; 10 | RsImage v = {1, 1, c}; 11 | return v; 12 | } 13 | 14 | void assert_equality() { 15 | if (!read_image("dummy_path").equal_to("dummy path")) { 16 | throw std::runtime_error("equality_check failed"); 17 | } 18 | } 19 | -------------------------------------------------------------------------------- /test/rustflags/cargo_config_rustflags/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | cmake_minimum_required(VERSION 3.15) 2 | project(test_project VERSION 0.1.0) 3 | include(../../test_header.cmake) 4 | 5 | corrosion_import_crate(MANIFEST_PATH Cargo.toml) 6 | 7 | # Do not use `corrosion_add_target_rustflags()` here, since we want to test if the rustflag from `.cargo/config.toml` 8 | # is picked up. 9 | 10 | # Local rustflags should not interfere with `.cargo/config.toml`, so enable one. 11 | corrosion_add_target_local_rustflags(cargo_config_rustflags "--cfg=local_rustflag") 12 | -------------------------------------------------------------------------------- /test/cargo_flags/cargo_flags/rust/src/lib.rs: -------------------------------------------------------------------------------- 1 | use std::os::raw::c_char; 2 | 3 | #[no_mangle] 4 | pub extern "C" fn rust_function(name: *const c_char) { 5 | let name = unsafe { std::ffi::CStr::from_ptr(name).to_str().unwrap() }; 6 | println!("Hello, {}! I am Rust!", name); 7 | 8 | #[cfg(not(feature = "one"))] 9 | compile_error!("Feature one is not enabled"); 10 | #[cfg(not(feature = "two"))] 11 | compile_error!("Feature two is not enabled"); 12 | #[cfg(not(feature = "three"))] 13 | compile_error!("Feature three is not enabled"); 14 | } 15 | -------------------------------------------------------------------------------- /test/parse_target_triple/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | corrosion_tests_add_test(parse_target_triple "") 2 | corrosion_tests_add_test(parse_target_triple_should_fail "") 3 | 4 | set_tests_properties("parse_target_triple_build" PROPERTIES FAIL_REGULAR_EXPRESSION 5 | "CMake Warning at [^\r\n]*FindRust\.cmake:.*(\r)?\n[ \t]*Failed to parse target-triple `" 6 | ) 7 | 8 | set_tests_properties("parse_target_triple_should_fail_build" PROPERTIES PASS_REGULAR_EXPRESSION 9 | "CMake Warning at [^\r\n]*FindRust\.cmake:.*(\r)?\n[ \t]*Failed to parse target-triple `" 10 | ) 11 | -------------------------------------------------------------------------------- /test/cxxbridge/cxxbridge_exported_impls/rust/src/bridge_b.rs: -------------------------------------------------------------------------------- 1 | #[cxx::bridge] 2 | pub mod ffi { 3 | 4 | #[derive(Clone)] 5 | pub struct NewVal { 6 | pub value: bool, 7 | pub message: String, 8 | } 9 | 10 | impl SharedPtr {} 11 | 12 | extern "Rust" { 13 | fn make_new_val() -> SharedPtr; 14 | } 15 | } 16 | 17 | pub fn make_new_val() -> cxx::SharedPtr { 18 | let now = std::time::Instant::now(); 19 | let ok = ffi::NewVal { value: true, message: format!("{:#?}", now)}; 20 | cxx::SharedPtr::new(ok) 21 | } -------------------------------------------------------------------------------- /test/cargo_flags/cargo_flags/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | cmake_minimum_required(VERSION 3.15) 2 | project(test_project VERSION 0.1.0) 3 | include(../../test_header.cmake) 4 | 5 | corrosion_import_crate(MANIFEST_PATH rust/Cargo.toml FLAGS --features one) 6 | 7 | add_executable(flags-exe main.cpp) 8 | target_link_libraries(flags-exe PUBLIC flags_lib) 9 | corrosion_set_cargo_flags(flags_lib --features two) 10 | corrosion_set_cargo_flags(flags_lib $) 11 | 12 | set_property( 13 | TARGET flags_lib 14 | APPEND 15 | PROPERTY more_flags --features three 16 | ) 17 | -------------------------------------------------------------------------------- /test/crate_type/crate_type/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | cmake_minimum_required(VERSION 3.15) 2 | project(test_project VERSION 0.1.0) 3 | include(../../test_header.cmake) 4 | 5 | # Add --crate-type to ensure that only the specified type of library is built and no error is thrown 6 | corrosion_import_crate(MANIFEST_PATH proj1/Cargo.toml CRATE_TYPES staticlib FLAGS --crate-type=staticlib) 7 | corrosion_import_crate(MANIFEST_PATH proj2/Cargo.toml CRATE_TYPES cdylib FLAGS --crate-type=cdylib) 8 | 9 | add_executable(cpp-exe main.cpp) 10 | target_link_libraries(cpp-exe proj1) 11 | target_link_libraries(cpp-exe proj2) 12 | -------------------------------------------------------------------------------- /test/cbindgen/auto/main.cpp: -------------------------------------------------------------------------------- 1 | #include "rust-lib.h" 2 | #include 3 | 4 | int main(int argc, char **argv) { 5 | assert(is_magic_number(MAGIC_NUMBER)); 6 | struct Point p1, p2; 7 | p1.x = 54; 8 | p2.x = 46; 9 | p1.y = 34; 10 | p2.y = 66; 11 | add_point(&p1, &p2); 12 | assert(p1.x == 100); 13 | assert(p2.x == 46); 14 | assert(p1.y == 100); 15 | assert(p2.y == 66); 16 | add_point(&p1, NULL); 17 | assert(p1.x == 100); 18 | assert(p1.y == 100); 19 | 20 | assert(OTHER_MOD_MAGIC_NUMBER == 192312312); 21 | assert(FFI_MAGIC_NUMBER == 0xFDA00184); 22 | } 23 | -------------------------------------------------------------------------------- /test/cxxbridge/cxxbridge_cpp2rust/rust/src/lib.rs: -------------------------------------------------------------------------------- 1 | #[cxx::bridge] 2 | pub mod ffi 3 | { 4 | #[derive(Debug, PartialEq)] 5 | pub struct Rgba 6 | { 7 | r: f32, 8 | g: f32, 9 | b: f32, 10 | a: f32, 11 | } 12 | 13 | #[derive(Debug,PartialEq)] 14 | pub struct RsImage 15 | { 16 | width: usize, 17 | height: usize, 18 | raster: Rgba, 19 | } 20 | unsafe extern "C++" 21 | { 22 | include!("cpplib.h"); 23 | pub fn read_image(path: &str) -> RsImage; 24 | fn write_image(path: &str, image: &RsImage); 25 | } 26 | } -------------------------------------------------------------------------------- /test/cbindgen/manual/main.cpp: -------------------------------------------------------------------------------- 1 | #include "rust-lib.h" 2 | #include 3 | 4 | int main(int argc, char **argv) { 5 | assert(is_magic_number(MAGIC_NUMBER)); 6 | struct Point p1, p2; 7 | p1.x = 54; 8 | p2.x = 46; 9 | p1.y = 34; 10 | p2.y = 66; 11 | add_point(&p1, &p2); 12 | assert(p1.x == 100); 13 | assert(p2.x == 46); 14 | assert(p1.y == 100); 15 | assert(p2.y == 66); 16 | add_point(&p1, NULL); 17 | assert(p1.x == 100); 18 | assert(p1.y == 100); 19 | 20 | assert(OTHER_MOD_MAGIC_NUMBER == 192312312); 21 | assert(FFI_MAGIC_NUMBER == 0xFDA00184); 22 | } 23 | -------------------------------------------------------------------------------- /test/custom_profiles/custom_profiles/rust/Cargo.toml: -------------------------------------------------------------------------------- 1 | [package] 2 | name = "custom-profiles-lib" 3 | version = "0.1.0" 4 | edition = "2021" 5 | 6 | [lib] 7 | crate-type=["staticlib"] 8 | 9 | # Test if neither release or debug where selected by only disabling debug-assertions in the inherited profile. 10 | [profile.release] 11 | debug-assertions = true 12 | 13 | [profile.dev-without-dbg] 14 | inherits = "dev" 15 | debug-assertions = false 16 | 17 | [profile.release-without-dbg] 18 | inherits = "release" 19 | debug-assertions = false 20 | 21 | [profile.custom-without-dbg] 22 | inherits = "release" 23 | opt-level = 1 24 | debug-assertions = false 25 | -------------------------------------------------------------------------------- /test/cxxbridge/cxxbridge_exported_impls/rust/src/bridge_a.rs: -------------------------------------------------------------------------------- 1 | #[cxx::bridge] 2 | pub mod ffi { 3 | pub struct OkResult { 4 | pub value: bool, 5 | pub message: String, 6 | } 7 | 8 | pub struct TestResult { 9 | pub ok: SharedPtr, 10 | } 11 | 12 | impl SharedPtr {} 13 | 14 | extern "Rust" { 15 | fn make_result() -> Result; 16 | } 17 | } 18 | 19 | pub fn make_result() -> Result { 20 | let now = std::time::Instant::now(); 21 | let ok = ffi::OkResult { value: true, message: format!("{:#?}", now)}; 22 | Ok(ffi::TestResult { ok: cxx::SharedPtr::new(ok)} ) 23 | } 24 | 25 | -------------------------------------------------------------------------------- /test/cxxbridge/cxxbridge_rust2cpp/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | cmake_minimum_required(VERSION 3.15) 2 | project(test_project VERSION 0.1.0) 3 | include(../../test_header.cmake) 4 | set(CMAKE_CXX_STANDARD 11) 5 | set(CMAKE_CXX_STANDARD_REQUIRED 1) 6 | 7 | corrosion_import_crate(MANIFEST_PATH rust/Cargo.toml) 8 | corrosion_add_cxxbridge(cxxbridge-cpp CRATE cxxbridge_crate FILES lib.rs foo/mod.rs) 9 | 10 | add_executable(cxxbridge-exe main.cpp) 11 | target_link_libraries(cxxbridge-exe PUBLIC cxxbridge-cpp) 12 | 13 | if(MSVC) 14 | # Note: This is required because we use `cxx` which uses `cc` to compile and link C++ code. 15 | corrosion_set_env_vars(cxxbridge_crate "CFLAGS=-MDd" "CXXFLAGS=-MDd") 16 | endif() 17 | -------------------------------------------------------------------------------- /test/cxxbridge/cxxbridge_exported_impls/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | cmake_minimum_required(VERSION 3.24) 2 | project(test_project VERSION 0.1.0 LANGUAGES CXX) 3 | include(../../test_header.cmake) 4 | set(CMAKE_CXX_STANDARD 11) 5 | set(CMAKE_CXX_STANDARD_REQUIRED 1) 6 | 7 | corrosion_import_crate(MANIFEST_PATH rust/Cargo.toml) 8 | corrosion_add_cxxbridge(cxxbridge 9 | CRATE rust_lib 10 | FILES 11 | bridge_a.rs 12 | bridge_b.rs 13 | lib.rs 14 | ) 15 | 16 | if(MSVC) 17 | set_target_properties(cxxbridge PROPERTIES MSVC_RUNTIME_LIBRARY "MultiThreadedDLL") 18 | endif() 19 | 20 | add_executable(test_main 21 | main.cpp 22 | ) 23 | 24 | target_link_libraries(test_main 25 | cxxbridge 26 | ) -------------------------------------------------------------------------------- /test/cpp2rust/cpp2rust/rust/src/bin/rust-exe.rs: -------------------------------------------------------------------------------- 1 | use std::os::raw::c_char; 2 | 3 | extern "C" { 4 | fn cpp_function(name: *const c_char); 5 | fn cpp_function2(name: *const c_char); 6 | fn cpp_function3(name: *const c_char); 7 | 8 | } 9 | 10 | fn greeting(name: &str) { 11 | let name = std::ffi::CString::new(name).unwrap(); 12 | unsafe { 13 | cpp_function(name.as_ptr()); 14 | cpp_function2(name.as_ptr()); 15 | cpp_function3(name.as_ptr()); 16 | } 17 | } 18 | 19 | fn main() { 20 | let args = std::env::args().skip(1).collect::>(); 21 | if args.len() >= 1 { 22 | greeting(&args[0]); 23 | } else { 24 | greeting("Rust"); 25 | } 26 | rust_dependency::calls_ffi(); 27 | } 28 | -------------------------------------------------------------------------------- /test/config_discovery/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | # The `.cargo/config.toml` file registers the `my-registry` index. If Cargo fails to 2 | # discover the config file, the build will fail with: 3 | # "registry index was not found in any configuration: `my-registry`" 4 | corrosion_tests_add_test(config_discovery "config_discovery") 5 | 6 | # Run the `cargo-clean` target to verify `.cargo/config.toml` discovery. 7 | add_test(NAME "config_discovery_run_cargo_clean" 8 | COMMAND "${CMAKE_COMMAND}" --build "${CMAKE_CURRENT_BINARY_DIR}/build-config_discovery" --target cargo-clean 9 | ) 10 | set_tests_properties("config_discovery_run_cargo_clean" PROPERTIES 11 | FIXTURES_REQUIRED "build_fixture_config_discovery" 12 | DEPENDS "config_discovery_run_config_discovery" 13 | ) 14 | -------------------------------------------------------------------------------- /test/config_discovery/README.md: -------------------------------------------------------------------------------- 1 | # Cargo Configuration Discovery Test 2 | 3 | This test verifies that `cargo` correctly discovers configuration files such as `.cargo/config.toml` and `toolchain.toml` in the source tree. 4 | 5 | ## What's Being Tested 6 | 7 | Cargo discovers configuration files by searching the current working directory and its parent directories. Therefore, Corrosion must set the correct `WORKING_DIRECTORY` for all `cargo` invocations. 8 | 9 | ## How the Test Works 10 | 11 | The test uses a `.cargo/config.toml` that defines a custom registry alias `my-registry`. A dependency in `Cargo.toml` references this alias via `registry = "my-registry"`. 12 | 13 | If `cargo` does not find `.cargo/config.toml`, the `registry = "my-registry"` entry will cause an error during manifest parsing. 14 | -------------------------------------------------------------------------------- /test/features/features/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | cmake_minimum_required(VERSION 3.15) 2 | project(test_project VERSION 0.1.0) 3 | include(../../test_header.cmake) 4 | 5 | corrosion_import_crate(MANIFEST_PATH rust/Cargo.toml FEATURES thirdfeature ALL_FEATURES) 6 | 7 | add_executable(features-cpp-exe main.cpp) 8 | target_link_libraries(features-cpp-exe PUBLIC rust_feature_lib) 9 | 10 | corrosion_set_features(rust_feature_lib 11 | ALL_FEATURES OFF 12 | NO_DEFAULT_FEATURES 13 | FEATURES 14 | $ 15 | ) 16 | 17 | set_property( 18 | TARGET features-cpp-exe 19 | APPEND 20 | PROPERTY app_features myfeature 21 | ) 22 | set_property( 23 | TARGET features-cpp-exe 24 | APPEND 25 | PROPERTY app_features secondfeature 26 | ) 27 | 28 | -------------------------------------------------------------------------------- /test/cxxbridge/cxxbridge_circular/rust/src/lib.rs: -------------------------------------------------------------------------------- 1 | #[cxx::bridge] 2 | pub mod ffi { 3 | #[derive(Debug, PartialEq)] 4 | pub struct Rgba { 5 | r: f32, 6 | g: f32, 7 | b: f32, 8 | a: f32, 9 | } 10 | 11 | #[derive(Debug, PartialEq)] 12 | pub struct RsImage { 13 | width: usize, 14 | height: usize, 15 | raster: Rgba, 16 | } 17 | unsafe extern "C++" { 18 | include!("cpplib.h"); 19 | pub fn read_image(path: &str) -> RsImage; 20 | } 21 | 22 | extern "Rust" { 23 | pub fn equal_to(self: &RsImage, other: &str) -> bool; 24 | } 25 | } 26 | 27 | use ffi::*; 28 | 29 | impl RsImage { 30 | pub fn equal_to(&self, path: &str) -> bool { 31 | println!("equal_to"); 32 | *self == read_image(path) 33 | } 34 | } 35 | -------------------------------------------------------------------------------- /test/multitarget/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | corrosion_tests_add_test(multitarget "bin1;bin2;bin3") 2 | 3 | # Don't run this test in parallel with others, since the target directory size may cause issues. 4 | set_tests_properties("multitarget_build" PROPERTIES RUN_SERIAL TRUE) 5 | 6 | set_tests_properties("multitarget_run_bin1" PROPERTIES PASS_REGULAR_EXPRESSION 7 | "Hello, world!\r?\nHello, bin1! I'm Cpp!" 8 | RUN_SERIAL 9 | TRUE 10 | ) 11 | 12 | set_tests_properties("multitarget_run_bin2" PROPERTIES PASS_REGULAR_EXPRESSION 13 | "Hello, world!\r?\nHello, bin2! I'm Cpp!" 14 | RUN_SERIAL 15 | TRUE 16 | ) 17 | 18 | set_tests_properties("multitarget_run_bin3" PROPERTIES PASS_REGULAR_EXPRESSION 19 | "Hello, world!\r?\nHello, bin3! I'm Cpp!" 20 | RUN_SERIAL 21 | TRUE 22 | ) 23 | -------------------------------------------------------------------------------- /test/envvar/envvar/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | cmake_minimum_required(VERSION 3.15) 2 | project(test_project VERSION 0.1.0) 3 | include(../../test_header.cmake) 4 | 5 | corrosion_import_crate(MANIFEST_PATH Cargo.toml) 6 | 7 | corrosion_set_env_vars(rust_lib_requiring_envvar 8 | "ANOTHER_VARIABLE=ANOTHER_VALUE" 9 | "$" 10 | "COR_CARGO_VERSION_MAJOR=${Rust_CARGO_VERSION_MAJOR}" 11 | "COR_CARGO_VERSION_MINOR=${Rust_CARGO_VERSION_MINOR}" 12 | ) 13 | 14 | add_executable(program_requiring_rust_lib_with_envvar main.cpp) 15 | 16 | set_property( 17 | TARGET program_requiring_rust_lib_with_envvar 18 | APPEND 19 | PROPERTY INDIRECT_VAR_TEST 20 | "REQUIRED_VARIABLE=EXPECTED_VALUE" 21 | ) 22 | 23 | target_link_libraries(program_requiring_rust_lib_with_envvar PUBLIC rust_lib_requiring_envvar) 24 | -------------------------------------------------------------------------------- /test/custom_profiles/custom_profiles/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | cmake_minimum_required(VERSION 3.15) 2 | project(test_project VERSION 0.1.0) 3 | include(../../test_header.cmake) 4 | 5 | set(_release_profile $,release-without-dbg,custom-without-dbg>) 6 | set(custom_profile $,dev-without-dbg,${_release_profile}>) 7 | 8 | if(CORROSION_TEST_USE_TARGET_SPECIFIC_OVERRIDE) 9 | # Select "wrong" profile here on purpose. 10 | corrosion_import_crate(MANIFEST_PATH rust/Cargo.toml PROFILE dev) 11 | set_target_properties(custom_profiles_lib 12 | PROPERTIES 13 | INTERFACE_CORROSION_CARGO_PROFILE "${custom_profile}" 14 | ) 15 | else() 16 | corrosion_import_crate(MANIFEST_PATH rust/Cargo.toml PROFILE ${custom_profile}) 17 | endif() 18 | 19 | add_executable(custom-profile-exe main.cpp) 20 | target_link_libraries(custom-profile-exe PUBLIC custom_profiles_lib) 21 | -------------------------------------------------------------------------------- /test/cbindgen/auto/rust/src/lib.rs: -------------------------------------------------------------------------------- 1 | pub const MAGIC_NUMBER: u64 = 0xABCD_EFAB; 2 | 3 | pub mod ffi; 4 | pub mod other_mod; 5 | 6 | #[derive(Debug)] 7 | #[repr(C)] 8 | pub struct Point { 9 | x: u64, 10 | y: u64, 11 | } 12 | 13 | impl Point { 14 | pub(crate) fn add(&mut self, rhs: &Point) { 15 | self.x = self.x.wrapping_add(rhs.x); 16 | self.y = self.y.wrapping_add(rhs.y); 17 | } 18 | } 19 | 20 | #[no_mangle] 21 | pub extern "C" fn add_point(lhs: Option<&mut Point>, rhs: Option<&Point>) { 22 | if let (Some(p1), Some(p2)) = (lhs, rhs) { 23 | p1.add(p2); 24 | // Print something so we can let Ctest assert the output. 25 | println!("add_point Result: {:?}", p1); 26 | } 27 | } 28 | 29 | // simple test if the constant was exported by cbindgen correctly 30 | #[no_mangle] 31 | pub extern "C" fn is_magic_number(num: u64) -> bool { 32 | num == MAGIC_NUMBER 33 | } 34 | -------------------------------------------------------------------------------- /test/cbindgen/manual/rust/src/lib.rs: -------------------------------------------------------------------------------- 1 | pub const MAGIC_NUMBER: u64 = 0xABCD_EFAB; 2 | 3 | pub mod ffi; 4 | pub mod other_mod; 5 | 6 | #[derive(Debug)] 7 | #[repr(C)] 8 | pub struct Point { 9 | x: u64, 10 | y: u64, 11 | } 12 | 13 | impl Point { 14 | pub(crate) fn add(&mut self, rhs: &Point) { 15 | self.x = self.x.wrapping_add(rhs.x); 16 | self.y = self.y.wrapping_add(rhs.y); 17 | } 18 | } 19 | 20 | #[no_mangle] 21 | pub extern "C" fn add_point(lhs: Option<&mut Point>, rhs: Option<&Point>) { 22 | if let (Some(p1), Some(p2)) = (lhs, rhs) { 23 | p1.add(p2); 24 | // Print something so we can let Ctest assert the output. 25 | println!("add_point Result: {:?}", p1); 26 | } 27 | } 28 | 29 | // simple test if the constant was exported by cbindgen correctly 30 | #[no_mangle] 31 | pub extern "C" fn is_magic_number(num: u64) -> bool { 32 | num == MAGIC_NUMBER 33 | } 34 | -------------------------------------------------------------------------------- /test/envvar/envvar/build.rs: -------------------------------------------------------------------------------- 1 | fn main() { 2 | assert_eq!(env!("REQUIRED_VARIABLE"), "EXPECTED_VALUE"); 3 | assert_eq!(std::env::var("ANOTHER_VARIABLE").unwrap(), "ANOTHER_VALUE"); 4 | let cargo_major = env!("COR_CARGO_VERSION_MAJOR") 5 | .parse::() 6 | .expect("Invalid Major version"); 7 | let cargo_minor = env!("COR_CARGO_VERSION_MINOR") 8 | .parse::() 9 | .expect("Invalid Minor version"); 10 | 11 | // The `[env]` section in `.cargo/config.toml` was added in version 1.56. 12 | if cargo_major > 1 || (cargo_major == 1 && cargo_minor >= 56) { 13 | // Check if cargo picks up the config.toml, which sets this additional env variable. 14 | let env_value = option_env!("COR_CONFIG_TOML_ENV_VAR") 15 | .expect("Test failure! Cargo >= 1.56.0 should set this environment variable"); 16 | assert_eq!(env_value, "EnvVariableSetViaConfig.toml"); 17 | } 18 | } 19 | -------------------------------------------------------------------------------- /test/rustflags/rustflags/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | cmake_minimum_required(VERSION 3.15) 2 | project(test_project VERSION 0.1.0) 3 | include(../../test_header.cmake) 4 | 5 | corrosion_import_crate(MANIFEST_PATH rust/Cargo.toml) 6 | 7 | add_executable(rustflags-cpp-exe main.cpp) 8 | target_link_libraries(rustflags-cpp-exe PUBLIC rustflag_test_lib) 9 | 10 | # Test --cfg=key="value" rustflag. 11 | corrosion_add_target_rustflags(rustflag_test_lib --cfg=test_rustflag_cfg1="test_rustflag_cfg1_value") 12 | 13 | # Test using a generator expression to produce a rustflag and passing multiple rustflags. 14 | corrosion_add_target_rustflags(rustflag_test_lib 15 | --cfg=test_rustflag_cfg2="$,$>,debug,release>" 16 | "--cfg=test_rustflag_cfg3" 17 | ) 18 | 19 | corrosion_add_target_local_rustflags(rustflag_test_lib "--cfg=test_local_rustflag1") 20 | corrosion_add_target_local_rustflags(rustflag_test_lib --cfg=test_local_rustflag2="value") 21 | -------------------------------------------------------------------------------- /test/corrosion_install/install_lib/rust_lib/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | cmake_minimum_required(VERSION 3.15) 2 | project(test_project VERSION 0.1.0) 3 | include(../../../test_header.cmake) 4 | 5 | corrosion_import_crate(MANIFEST_PATH Cargo.toml) 6 | 7 | if("${CMAKE_SYSTEM_NAME}" STREQUAL "Linux") 8 | corrosion_add_target_local_rustflags(rust_lib "-Clink-arg=-Wl,-soname,librust_lib.so") 9 | set_target_properties(rust_lib-shared PROPERTIES IMPORTED_SONAME librust_lib.so) 10 | elseif("${CMAKE_SYSTEM_NAME}" STREQUAL "Darwin") 11 | corrosion_add_target_local_rustflags(rust_lib -Clink-arg=-Wl,-install_name,@rpath/librust_lib.dylib,-current_version,1.0,-compatibility_version,1.0) 12 | set_target_properties(rust_lib-shared PROPERTIES IMPORTED_NO_SONAME 0) 13 | set_target_properties(rust_lib-shared PROPERTIES IMPORTED_SONAME librust_lib.dylib) 14 | endif() 15 | 16 | target_sources(rust_lib INTERFACE include/rust_lib/rust_lib.hpp) 17 | 18 | corrosion_install(TARGETS rust_lib) 19 | -------------------------------------------------------------------------------- /test/cpp2rust/cpp2rust/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | cmake_minimum_required(VERSION 3.15) 2 | project(test_project VERSION 0.1.0) 3 | include(../../test_header.cmake) 4 | 5 | corrosion_import_crate(MANIFEST_PATH rust/Cargo.toml) 6 | 7 | add_library(cpp-lib lib.cpp) 8 | target_compile_features(cpp-lib PRIVATE cxx_std_14) 9 | set_target_properties( 10 | cpp-lib 11 | PROPERTIES 12 | POSITION_INDEPENDENT_CODE ON 13 | ) 14 | 15 | add_library(cpp-lib2 lib2.cpp) 16 | target_compile_features(cpp-lib2 PRIVATE cxx_std_14) 17 | set_target_properties( 18 | cpp-lib2 19 | PROPERTIES 20 | POSITION_INDEPENDENT_CODE ON 21 | OUTPUT_NAME cpp-lib-renamed 22 | ) 23 | 24 | add_library(cpp-lib3 "path with space/lib3.cpp" ) 25 | target_compile_features(cpp-lib3 PRIVATE cxx_std_14) 26 | set_target_properties( 27 | cpp-lib3 28 | PROPERTIES 29 | POSITION_INDEPENDENT_CODE ON 30 | ) 31 | 32 | corrosion_link_libraries(rust-exe cpp-lib cpp-lib2 cpp-lib3) 33 | -------------------------------------------------------------------------------- /test/cxxbridge/cxxbridge_exported_impls/rust/src/lib.rs: -------------------------------------------------------------------------------- 1 | pub mod bridge_a; 2 | pub mod bridge_b; 3 | // pub use bridge_a::combine_result; 4 | 5 | #[cxx::bridge] 6 | pub mod ffi { 7 | 8 | extern "C++" { 9 | include!("cxxbridge/bridge_a.h"); 10 | include!("cxxbridge/bridge_b.h"); 11 | 12 | type TestResult = crate::bridge_a::ffi::TestResult; 13 | type NewVal = crate::bridge_b::ffi::NewVal; 14 | } 15 | 16 | extern "Rust" { 17 | fn combine_result(other: SharedPtr) -> Result; 18 | } 19 | 20 | } 21 | 22 | pub fn combine_result(other: cxx::SharedPtr) -> Result { 23 | if let Some(crate::bridge_b::ffi::NewVal { value, message }) = other.as_ref().cloned() { 24 | let result = crate::bridge_a::ffi::TestResult { ok: cxx::SharedPtr::new(crate::bridge_a::ffi::OkResult { value, message }) }; 25 | Ok(result) 26 | } 27 | else { 28 | crate::bridge_a::make_result() 29 | } 30 | } -------------------------------------------------------------------------------- /test/custom_target/custom_target/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | cmake_minimum_required(VERSION 3.15) 2 | project(test_project VERSION 0.1.0 LANGUAGES C CXX) 3 | # The outer test driver gives the file a useless name 4 | # Supress the warning, since we don't rely on this information anyway. 5 | set(CORROSION_NO_WARN_PARSE_TARGET_TRIPLE_FAILED ON) 6 | include(../../test_header.cmake) 7 | 8 | if(NOT "${Rust_CARGO_TARGET}" MATCHES ".json") 9 | message(FATAL_ERROR "This test project expects to be configured with a custom rust target!" 10 | "Actual target: ${Rust_CARGO_TARGET}" 11 | ) 12 | endif() 13 | 14 | corrosion_import_crate(MANIFEST_PATH rust/Cargo.toml) 15 | corrosion_set_cargo_flags(rust_lib "-Zbuild-std") 16 | # custom target triples require nightly features 17 | corrosion_set_env_vars(rust_lib RUSTC_BOOTSTRAP=1) 18 | 19 | corrosion_set_cargo_flags(rust-bin "-Zbuild-std") 20 | corrosion_set_env_vars(rust-bin RUSTC_BOOTSTRAP=1) 21 | 22 | add_executable(test-exe main.cpp) 23 | target_link_libraries(test-exe PUBLIC rust_lib) 24 | -------------------------------------------------------------------------------- /test/cbindgen/install_lib/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | cmake_minimum_required(VERSION 3.15) 2 | project(test_project VERSION 0.1.0) 3 | 4 | set(CORROSION_TOOLS_RUST_TOOLCHAIN "stable") 5 | include(../../test_header.cmake) 6 | 7 | corrosion_import_crate(MANIFEST_PATH rust_lib/Cargo.toml) 8 | 9 | if("${CMAKE_SYSTEM_NAME}" STREQUAL "Linux") 10 | corrosion_add_target_local_rustflags(rust_lib "-Clink-arg=-Wl,-soname,librust_lib.so") 11 | set_target_properties(rust_lib-shared PROPERTIES IMPORTED_SONAME librust_lib.so) 12 | elseif("${CMAKE_SYSTEM_NAME}" STREQUAL "Darwin") 13 | corrosion_add_target_local_rustflags(rust_lib -Clink-arg=-Wl,-install_name,@rpath/librust_lib.dylib,-current_version,1.0,-compatibility_version,1.0) 14 | set_target_properties(rust_lib-shared PROPERTIES IMPORTED_NO_SONAME 0) 15 | set_target_properties(rust_lib-shared PROPERTIES IMPORTED_SONAME librust_lib.dylib) 16 | endif() 17 | 18 | corrosion_experimental_cbindgen(TARGET rust_lib HEADER_NAME "rust-lib.h") 19 | 20 | corrosion_install(TARGETS rust_lib LIBRARY PUBLIC_HEADER) 21 | -------------------------------------------------------------------------------- /test/cbindgen/manual/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | cmake_minimum_required(VERSION 3.15) 2 | project(test_project VERSION 0.1.0) 3 | 4 | set(CORROSION_TOOLS_RUST_TOOLCHAIN "stable") 5 | include(../../test_header.cmake) 6 | corrosion_import_crate(MANIFEST_PATH rust/Cargo.toml) 7 | 8 | add_library(cbindgen_rust_lib INTERFACE) 9 | corrosion_experimental_cbindgen(MANIFEST_DIRECTORY rust 10 | CARGO_PACKAGE the-rust-lib-package-name 11 | BINDINGS_TARGET cbindgen_rust_lib 12 | HEADER_NAME "rust-lib.h") 13 | 14 | # The interface library for the generated headers should link to the actual rust library 15 | target_link_libraries(cbindgen_rust_lib INTERFACE the_actual_library_crate_name) 16 | 17 | add_executable(cpp-exe main.cpp) 18 | set_property(TARGET cpp-exe PROPERTY CXX_STANDARD 11) 19 | # The C/C++ bin needs to link to the cbindgen library with the generated sources. 20 | target_link_libraries(cpp-exe PUBLIC cbindgen_rust_lib) 21 | #add_dependencies(cpp-exe cbindgen_rust_lib) 22 | -------------------------------------------------------------------------------- /test/features/features/rust/src/lib.rs: -------------------------------------------------------------------------------- 1 | #[cfg(feature = "myfeature")] 2 | use std::os::raw::c_char; 3 | 4 | #[no_mangle] 5 | #[cfg(feature = "myfeature")] 6 | pub extern "C" fn rust_function(name: *const c_char) { 7 | let name = unsafe { std::ffi::CStr::from_ptr(name).to_str().unwrap() }; 8 | println!("Hello, {}! I'm Rust!", name); 9 | } 10 | 11 | #[no_mangle] 12 | #[cfg(feature = "secondfeature")] 13 | pub extern "C" fn rust_second_function(name: *const c_char) { 14 | let name = unsafe { std::ffi::CStr::from_ptr(name).to_str().unwrap() }; 15 | println!("Hello, {}! I'm Rust again!", name); 16 | } 17 | 18 | #[no_mangle] 19 | #[cfg(feature = "thirdfeature")] 20 | pub extern "C" fn rust_third_function(name: *const c_char) { 21 | let name = unsafe { std::ffi::CStr::from_ptr(name).to_str().unwrap() }; 22 | println!("Hello, {}! I'm Rust again, third time the charm!", name); 23 | } 24 | 25 | #[cfg(feature = "compile-breakage")] 26 | const _: [(); 1] = [(); 2]; // Trigger a compile error to make sure that we succeeded in de-activating this feature 27 | -------------------------------------------------------------------------------- /doc/src/introduction.md: -------------------------------------------------------------------------------- 1 | ## About Corrosion 2 | 3 | Corrosion, formerly known as cmake-cargo, is a tool for integrating Rust into an existing CMake 4 | project. Corrosion is capable of automatically importing executables, static libraries, and 5 | dynamic libraries from a Rust package or workspace as CMake targets. 6 | 7 | The imported static and dynamic library types can be linked into C/C++ CMake targets using the usual 8 | CMake functions such as [`target_link_libraries()`]. 9 | For rust executables and dynamic libraries corrosion provides a `corrosion_link_libraries` 10 | helper function to conveniently add the necessary flags to link C/C++ libraries into 11 | the rust target. 12 | 13 | ## Requirements 14 | 15 | - The latest release (v0.6) of Corrosion currently requires CMake 3.22 or newer. 16 | - The previous v0.5 release supports CMake 3.15 or newer. If you are using the v0.5 release, please 17 | view [the documentation here](./v0.5/introduction.md). 18 | 19 | [`target_link_libraries()`]: https://cmake.org/cmake/help/latest/command/target_link_libraries.html 20 | -------------------------------------------------------------------------------- /test/output directory/output_directory_config/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | cmake_minimum_required(VERSION 3.15) 2 | project(test_project VERSION 0.1.0) 3 | include(../../test_header.cmake) 4 | 5 | corrosion_import_crate(MANIFEST_PATH proj1/Cargo.toml) 6 | 7 | # Note: The output directories defined here must be manually kept in sync with the expected test location. 8 | set_target_properties(rust_bin1 9 | PROPERTIES 10 | RUNTIME_OUTPUT_DIRECTORY "${CMAKE_CURRENT_BINARY_DIR}/$/bin" 11 | PDB_OUTPUT_DIRECTORY "${CMAKE_CURRENT_BINARY_DIR}/$/bin" 12 | ) 13 | 14 | set_target_properties(rust_lib1 PROPERTIES ARCHIVE_OUTPUT_DIRECTORY "${CMAKE_CURRENT_BINARY_DIR}/$/lib") 15 | set_target_properties(rust_lib1 16 | PROPERTIES 17 | LIBRARY_OUTPUT_DIRECTORY "${CMAKE_CURRENT_BINARY_DIR}/$/lib" 18 | PDB_OUTPUT_DIRECTORY "${CMAKE_CURRENT_BINARY_DIR}/$/lib" 19 | ) 20 | 21 | add_executable(consumer consumer.cpp) 22 | add_dependencies(consumer cargo-build_rust_lib1) 23 | target_link_libraries(consumer rust_lib1) 24 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2018 Andrew Gaspar 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /test/gensource/gensource/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | cmake_minimum_required(VERSION 3.15) 2 | project(test_project VERSION 0.1.0) 3 | include(../../test_header.cmake) 4 | 5 | add_subdirectory(generator) 6 | 7 | add_custom_command( 8 | OUTPUT "${CMAKE_CURRENT_SOURCE_DIR}/src/foo.rs" 9 | DEPENDS $ 10 | COMMAND $ "${CMAKE_CURRENT_SOURCE_DIR}/src/foo.rs" 11 | ) 12 | 13 | add_custom_target(after_generation DEPENDS "${CMAKE_CURRENT_SOURCE_DIR}/src/foo.rs") 14 | add_custom_target(genexdebug COMMAND ${CMAKE_COMMAND} -E echo "Config DEBUG: $ Config Release: $ IMPORTED_LOCATION: $") 15 | 16 | corrosion_import_crate(MANIFEST_PATH ${CMAKE_CURRENT_SOURCE_DIR}/Cargo.toml) 17 | add_dependencies(cargo-prebuild_generated after_generation) 18 | 19 | # Simple test for corrosion_parse_package_version 20 | corrosion_parse_package_version("${CMAKE_CURRENT_SOURCE_DIR}/Cargo.toml" srcgen_version) 21 | if (NOT "${srcgen_version}" VERSION_EQUAL "0.1.0") 22 | message(FATAL_ERROR "Test failed to parse expected version") 23 | endif() 24 | -------------------------------------------------------------------------------- /test/TestFileExists.cmake: -------------------------------------------------------------------------------- 1 | # CMake script to test if a file exists. Errors if the file does not exist. 2 | # Expect actual arguments to start at index 3 (cmake -P ) 3 | 4 | # Expect one argument 5 | if(NOT (CMAKE_ARGC EQUAL "4")) 6 | message(FATAL_ERROR "Test Internal Error: Unexpected ARGC Value: ${CMAKE_ARGC}.") 7 | endif() 8 | 9 | set(FILE_PATH "${CMAKE_ARGV3}") 10 | 11 | if(NOT ( EXISTS "${FILE_PATH}" )) 12 | set(error_details "File `${FILE_PATH}` does not exist!\n") 13 | set(PARENT_TREE "${FILE_PATH}") 14 | cmake_path(HAS_PARENT_PATH PARENT_TREE has_parent) 15 | while(has_parent) 16 | cmake_path(GET PARENT_TREE PARENT_PATH PARENT_TREE) 17 | cmake_path(HAS_PARENT_PATH PARENT_TREE has_parent) 18 | if(EXISTS "${PARENT_TREE}") 19 | file(GLOB dir_contents LIST_DIRECTORIES true "${PARENT_TREE}/*") 20 | list(APPEND error_details "Found Parent directory `${PARENT_TREE}` exists and contains:\n" ${dir_contents}) 21 | break() 22 | else() 23 | list(APPEND error_details "Parent directory `${PARENT_TREE}` also does not exist!") 24 | endif() 25 | endwhile() 26 | message(FATAL_ERROR "Test failed: ${error_details}") 27 | endif() 28 | -------------------------------------------------------------------------------- /test/custom_target/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | # Create a custom target triple, by taking the default host triple target spec. 2 | # This way we don't actually need to cross-compile and just check if we can handle 3 | # custom json target triples. 4 | # Note: dashes and not underscore is important, at least if cc-rs is used by dependencies, 5 | # since cc-rs will attempt to parse the target triple. 6 | # A real-world toolchain .json file should be named the same as the corresponding c/c++ compiler target, 7 | # in order for cc-rs to choose the correct target by default. 8 | set(target_spec_file "${CMAKE_CURRENT_BINARY_DIR}/custom-target-triple.json") 9 | execute_process(COMMAND 10 | ${CMAKE_COMMAND} -E env RUSTC_BOOTSTRAP=1 11 | ${_CORROSION_RUSTC} -Z unstable-options --print target-spec-json 12 | OUTPUT_FILE "${target_spec_file}" 13 | COMMAND_ERROR_IS_FATAL ANY 14 | ) 15 | 16 | set(Rust_CARGO_TARGET "${target_spec_file}") 17 | corrosion_tests_add_test(custom_target "test-exe;rust-bin") 18 | 19 | set_tests_properties("custom_target_run_test-exe" PROPERTIES PASS_REGULAR_EXPRESSION [[Hello, Cxx! I am Rust!]]) 20 | set_tests_properties("custom_target_run_rust-bin" PROPERTIES PASS_REGULAR_EXPRESSION [[The answer is 42]]) 21 | 22 | -------------------------------------------------------------------------------- /test/workspace/workspace/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | cmake_minimum_required(VERSION 3.15) 2 | project(test_project VERSION 0.1.0) 3 | include(../../test_header.cmake) 4 | 5 | corrosion_import_crate( 6 | MANIFEST_PATH ${CMAKE_CURRENT_SOURCE_DIR}/Cargo.toml 7 | CRATES member1 member2 8 | IMPORTED_CRATES imported_crate_list 9 | ) 10 | 11 | #NOTE: member3 also contains a binary called my_program, but that shouldn't be a problem since it is not imported 12 | add_executable(my_program main.cpp) 13 | target_link_libraries(my_program PUBLIC member1 member2) 14 | 15 | # Test that the list of imported crates matches our expectations. 16 | if(NOT DEFINED imported_crate_list) 17 | message(FATAL_ERROR "Corrosion failed to set the variable passed via IMPORTED_CRATES.") 18 | endif() 19 | set(expected_crates member1 member2) 20 | foreach(crate ${expected_crates}) 21 | if(NOT "${crate}" IN_LIST imported_crate_list) 22 | message(FATAL_ERROR "Expected ${crate} to be imported, but it wasn't. Imported crate list:\n" 23 | "${imported_crate_list}" 24 | ) 25 | endif() 26 | endforeach() 27 | set(additional_crates ${imported_crate_list}) 28 | list(REMOVE_ITEM additional_crates ${expected_crates}) 29 | if(additional_crates) 30 | message(FATAL_ERROR "Corrosion unexpectedly imported the following crates: ${additional_crates}") 31 | endif() 32 | 33 | -------------------------------------------------------------------------------- /test/corrosion_install/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | if(NOT (CMAKE_CROSSCOMPILING AND MSVC)) 2 | # When using MSVC the cmake build via ExternalProject seems to inherit the target architecture, 3 | # which breaks the test. Since we practically don't care about this, and we just want to ensure 4 | # that installing an executable works, skipping this test when cross-compiling is fine. 5 | corrosion_tests_add_test(install_rust_bin "generated_from_installed_bin") 6 | 7 | set_tests_properties("install_rust_bin_run_generated_from_installed_bin" 8 | PROPERTIES PASS_REGULAR_EXPRESSION 9 | "Hello World! I'm generated code" 10 | ) 11 | endif() 12 | 13 | # Todo: Fix and re-enable tests on Windows 14 | if(NOT CMAKE_CROSSCOMPILING AND NOT WIN32) 15 | corrosion_tests_add_test(install_lib "main-static;main-shared") 16 | 17 | set_tests_properties("install_lib_run_main-static" "install_lib_run_main-shared" 18 | PROPERTIES PASS_REGULAR_EXPRESSION 19 | "The sum is 11" 20 | ) 21 | endif() 22 | 23 | # Further tests we should add: 24 | # - Test installing a Rust executable, that requires a (C/C++) shared library at runtime. 25 | # Note: We should delete the build directory of the subproject 26 | # before running the installed rust executable, to insure the shared library is loaded from the 27 | # installed location and not from the build dir. -------------------------------------------------------------------------------- /test/corrosion_install/install_rust_bin/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | cmake_minimum_required(VERSION 3.22) 2 | project(test_project VERSION 0.1.0) 3 | 4 | # Note: Corrosion supports `hostbuild`, so building a Rust binary in a subproject 5 | # like this doesn't offer any benefit over using the hostbuild option. 6 | # However, this is a reasonable way to test that installing Rust binaries via 7 | # corrosion_install works as expected. 8 | include(ExternalProject) 9 | 10 | set(bin_suffix "") 11 | if(CMAKE_HOST_WIN32) 12 | set(bin_suffix ".exe") 13 | endif() 14 | set(generator_bin_path "${CMAKE_CURRENT_BINARY_DIR}/rust_bin/bin/my_rust_bin${bin_suffix}") 15 | 16 | ExternalProject_Add( 17 | rust_bin 18 | PREFIX "${CMAKE_CURRENT_BINARY_DIR}/rust_bin" 19 | SOURCE_DIR "${CMAKE_CURRENT_SOURCE_DIR}/rust_bin" 20 | CMAKE_ARGS "-DCMAKE_INSTALL_PREFIX=${CMAKE_CURRENT_BINARY_DIR}/rust_bin" 21 | ) 22 | 23 | # This custom command is the main part of the test: 24 | # We test that corrosion (in the CMake of the ExternalProject) properly installed 25 | # a Rust executable to the location we specified by running the executable, which generates some cpp code. 26 | add_custom_command( 27 | OUTPUT generated_main.cpp 28 | COMMAND "${generator_bin_path}" > "${CMAKE_CURRENT_BINARY_DIR}/generated_main.cpp" 29 | DEPENDS rust_bin 30 | ) 31 | 32 | add_executable(generated_from_installed_bin ${CMAKE_CURRENT_BINARY_DIR}/generated_main.cpp) 33 | -------------------------------------------------------------------------------- /test/find_rust/rustup_proxy/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | cmake_minimum_required(VERSION 3.15) 2 | project(RustupProxy LANGUAGES CXX) 3 | 4 | set(CMAKE_MODULE_PATH "${CMAKE_SOURCE_DIR}/../../../cmake" ${CMAKE_MODULE_PATH}) 5 | 6 | function(_assert_is_rustup_proxy executable_path) 7 | execute_process( 8 | COMMAND 9 | ${CMAKE_COMMAND} -E env 10 | RUSTUP_FORCE_ARG0=rustup 11 | "${executable_path}" --version 12 | OUTPUT_VARIABLE _VERSION_RAW 13 | ERROR_VARIABLE _VERSION_STDERR 14 | RESULT_VARIABLE _VERSION_RESULT 15 | ) 16 | 17 | if(NOT _VERSION_RESULT EQUAL "0") 18 | message(FATAL_ERROR "`${executable_path} --version` failed with ${_VERSION_RESULT}\n" 19 | "stderr:\n${_VERSION_STDERR}" 20 | ) 21 | endif() 22 | 23 | if (NOT _VERSION_RAW MATCHES "rustup [0-9\\.]+") 24 | message(FATAL_ERROR "`${executable_path} --version` output does not match rustup: ${_VERSION_RAW}\n") 25 | endif() 26 | endfunction() 27 | 28 | set(Rust_RESOLVE_RUSTUP_TOOLCHAINS OFF CACHE BOOL "" FORCE) 29 | find_package(Rust REQUIRED) 30 | 31 | if (NOT Rust_FOUND) 32 | message(FATAL_ERROR "Rustup not found") 33 | endif() 34 | 35 | get_property( 36 | RUSTC_EXECUTABLE 37 | TARGET Rust::Rustc PROPERTY IMPORTED_LOCATION 38 | ) 39 | 40 | _assert_is_rustup_proxy(${RUSTC_EXECUTABLE}) 41 | 42 | get_property( 43 | CARGO_EXECUTABLE 44 | TARGET Rust::Cargo PROPERTY IMPORTED_LOCATION 45 | ) 46 | 47 | _assert_is_rustup_proxy(${CARGO_EXECUTABLE}) 48 | -------------------------------------------------------------------------------- /test/custom_profiles/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | # The tests in this folder test specifying the cargo profile name via the --profile option. 2 | # The built-in `test` and `bench` profiles are _not_ supported, because they output 3 | # artifacts to a different location and add a hash to the artifact name. 4 | if(Rust_VERSION VERSION_GREATER_EQUAL 1.57.0) 5 | 6 | corrosion_tests_add_test(custom_profiles_global "custom-profile-exe" TEST_SRC_DIR custom_profiles) 7 | corrosion_tests_add_test(custom_profiles_target_specific "custom-profile-exe" 8 | TEST_SRC_DIR custom_profiles 9 | PASS_THROUGH_ARGS -DCORROSION_TEST_USE_TARGET_SPECIFIC_OVERRIDE=ON 10 | ) 11 | corrosion_tests_add_test(dev_profile "dev_bin" TEST_SRC_DIR basic_profiles CARGO_PROFILE dev) 12 | corrosion_tests_add_test(release_profile "release_bin" TEST_SRC_DIR basic_profiles CARGO_PROFILE release) 13 | 14 | set_tests_properties("custom_profiles_global_run_custom-profile-exe" PROPERTIES PASS_REGULAR_EXPRESSION 15 | "^Hello, Cpp! I'm Rust!\r?\n$" 16 | ) 17 | set_tests_properties("custom_profiles_target_specific_run_custom-profile-exe" PROPERTIES PASS_REGULAR_EXPRESSION 18 | "^Hello, Cpp! I'm Rust!\r?\n$" 19 | ) 20 | set_tests_properties("dev_profile_run_dev_bin" PROPERTIES PASS_REGULAR_EXPRESSION 21 | "^Hello, Cpp! I'm Rust!\r?\n$" 22 | ) 23 | set_tests_properties("release_profile_run_release_bin" PROPERTIES PASS_REGULAR_EXPRESSION 24 | "^Hello, Cpp! I'm Rust!\r?\n$" 25 | ) 26 | 27 | endif() 28 | -------------------------------------------------------------------------------- /doc/src/ffi_bindings.md: -------------------------------------------------------------------------------- 1 | # Integrating Automatically Generated FFI Bindings 2 | 3 | There are a number of tools to automatically generate bindings between Rust and different 4 | foreign languages. 5 | 6 | 1. [bindgen](#bindgen) 7 | 2. [cbindgen](#cbindgen-integration) 8 | 3. [cxx](#cxx-integration) 9 | 10 | ## bindgen 11 | 12 | [bindgen] is a tool to automatically generate Rust bindings from C headers. 13 | As such, integrating bindgen [via a build-script](https://rust-lang.github.io/rust-bindgen/library-usage.html) 14 | works well and their doesn't seem to be a need to create CMake rules for 15 | generating the bindings. 16 | 17 | [bindgen]: https://github.com/rust-lang/rust-bindgen 18 | 19 | ## cbindgen integration 20 | 21 | ⚠️⚠️⚠️ **EXPERIMENTAL** ⚠️⚠️⚠️ 22 | 23 | [cbindgen] is a tool that generates C/C++ headers from Rust code. When compiling C/C++ 24 | code that `#include`s such generated headers the buildsystem must be aware of the dependencies. 25 | Generating the headers via a build-script is possible, but Corrosion offers no guidance here. 26 | 27 | Instead, Corrosion offers an experimental function to add CMake rules using cbindgen to generate 28 | the headers. 29 | This is not available on a stable released version yet, and the details are subject to change. 30 | {{#include ../../cmake/Corrosion.cmake:corrosion_cbindgen}} 31 | 32 | ## cxx integration 33 | 34 | ⚠️⚠️⚠️ **EXPERIMENTAL** ⚠️⚠️⚠️ 35 | 36 | [cxx] is a tool which generates bindings for C++/Rust interop. 37 | 38 | {{#include ../../cmake/Corrosion.cmake:corrosion_add_cxxbridge}} 39 | -------------------------------------------------------------------------------- /test/rustflags/rustflags/rust/src/lib.rs: -------------------------------------------------------------------------------- 1 | #[cfg(test_rustflag_cfg1 = "test_rustflag_cfg1_value")] 2 | use std::os::raw::c_char; 3 | 4 | #[no_mangle] 5 | #[cfg(test_rustflag_cfg1 = "test_rustflag_cfg1_value")] 6 | pub extern "C" fn rust_function(name: *const c_char) { 7 | let name = unsafe { std::ffi::CStr::from_ptr(name).to_str().unwrap() }; 8 | println!("Hello, {}! I'm Rust!", name); 9 | } 10 | 11 | #[no_mangle] 12 | #[cfg(all(debug_assertions, test_rustflag_cfg2 = "debug"))] 13 | pub extern "C" fn rust_second_function(name: *const c_char) { 14 | let name = unsafe { std::ffi::CStr::from_ptr(name).to_str().unwrap() }; 15 | println!("Hello, {}! I'm Rust in Debug mode again!", name); 16 | } 17 | 18 | #[no_mangle] 19 | #[cfg(all(not(debug_assertions), test_rustflag_cfg2 = "release"))] 20 | pub extern "C" fn rust_second_function(name: *const c_char) { 21 | let name = unsafe { std::ffi::CStr::from_ptr(name).to_str().unwrap() }; 22 | println!("Hello, {}! I'm Rust in Release mode again!", name); 23 | } 24 | 25 | #[no_mangle] 26 | #[cfg(test_rustflag_cfg3)] 27 | pub extern "C" fn rust_third_function(name: *const c_char) { 28 | let name = unsafe { std::ffi::CStr::from_ptr(name).to_str().unwrap() }; 29 | println!("Hello, {}! I'm Rust again, third time the charm!", name); 30 | assert_eq!(some_dependency::some_function(), 42); 31 | } 32 | 33 | #[cfg(not(test_rustflag_cfg3))] 34 | const _: [(); 1] = [(); 2]; 35 | 36 | #[cfg(not(test_local_rustflag1))] 37 | const _: [(); 1] = [(); 2]; 38 | 39 | #[cfg(not(test_local_rustflag2 = "value"))] 40 | const _: [(); 1] = [(); 2]; 41 | -------------------------------------------------------------------------------- /test/cxxbridge/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | if(CORROSION_TESTS_CXXBRIDGE) 2 | corrosion_tests_add_test(cxxbridge_cpp2rust_1 "rust_bin" 3 | TEST_SRC_DIR cxxbridge_cpp2rust 4 | PASS_THROUGH_ARGS -DTEST_CXXBRIDGE_VARIANT1=ON 5 | ) 6 | corrosion_tests_add_test(cxxbridge_cpp2rust_2 "rust_bin" 7 | TEST_SRC_DIR cxxbridge_cpp2rust 8 | PASS_THROUGH_ARGS -DTEST_CXXBRIDGE_VARIANT2=ON 9 | ) 10 | corrosion_tests_add_test(cxxbridge_rust2cpp "cxxbridge-exe") 11 | if (CMAKE_VERSION VERSION_GREATER_EQUAL "3.24.0" AND CMAKE_LINK_GROUP_USING_RESCAN_SUPPORTED) 12 | corrosion_tests_add_test(cxxbridge_circular_link_group "cpp_bin" 13 | TEST_SRC_DIR cxxbridge_circular 14 | PASS_THROUGH_ARGS -DTEST_CXXBRIDGE_VARIANT1=ON 15 | ) 16 | endif() 17 | corrosion_tests_add_test(cxxbridge_circular_mutual_link "cpp_bin" 18 | TEST_SRC_DIR cxxbridge_circular 19 | PASS_THROUGH_ARGS -DTEST_CXXBRIDGE_VARIANT2=ON 20 | ) 21 | 22 | set_tests_properties("cxxbridge_cpp2rust_1_run_rust_bin" 23 | PROPERTIES PASS_REGULAR_EXPRESSION 24 | "main function" 25 | ) 26 | set_tests_properties("cxxbridge_rust2cpp_run_cxxbridge-exe" 27 | PROPERTIES PASS_REGULAR_EXPRESSION 28 | "Hello cxxbridge from lib.rs! \\[4, 5, 6\\]\r?\nHello cxxbridge from foo/mod.rs! \\[4, 5, 6\\]" 29 | ) 30 | 31 | if(NOT WIN32) 32 | corrosion_tests_add_test(cxxbridge_exported_impls "test_main") 33 | set_tests_properties("cxxbridge_exported_impls_run_test_main" 34 | PROPERTIES PASS_REGULAR_EXPRESSION 35 | "main function" 36 | ) 37 | endif() 38 | endif() 39 | -------------------------------------------------------------------------------- /test/cxxbridge/cxxbridge_cpp2rust/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | cmake_minimum_required(VERSION 3.15) 2 | project(test_project VERSION 0.1.0 LANGUAGES CXX) 3 | include(../../test_header.cmake) 4 | set(CMAKE_CXX_STANDARD 11) 5 | set(CMAKE_CXX_STANDARD_REQUIRED 1) 6 | 7 | corrosion_import_crate(MANIFEST_PATH rust/Cargo.toml) 8 | corrosion_add_cxxbridge(cxxbridge-cpp CRATE rust_bin FILES lib.rs) 9 | target_include_directories(cxxbridge-cpp PRIVATE "include") 10 | 11 | if(CMAKE_SYSTEM_NAME STREQUAL "Linux" 12 | OR (CMAKE_SYSTEM_NAME STREQUAL "Windows" 13 | AND (CMAKE_CXX_COMPILER_ID STREQUAL "GNU" OR CMAKE_CXX_COMPILER_ID MATCHES "Clang") 14 | ) 15 | ) 16 | corrosion_add_target_local_rustflags(rust_bin "-Clink-arg=-fuse-ld=lld") 17 | endif() 18 | 19 | if(MSVC) 20 | set_target_properties(cxxbridge-cpp PROPERTIES MSVC_RUNTIME_LIBRARY "MultiThreadedDLL") 21 | endif() 22 | 23 | if(TEST_CXXBRIDGE_VARIANT1) 24 | # Variant 1: Merge the C++ User sources into the generated library target. 25 | target_sources(cxxbridge-cpp PRIVATE cpplib.cpp) 26 | corrosion_link_libraries(rust_bin cxxbridge-cpp) 27 | elseif(TEST_CXXBRIDGE_VARIANT2) 28 | # Variant 2: Create a separate C++ library and link both the User library and 29 | # the generated library into rust 30 | add_library(cpp_lib STATIC cpplib.cpp) 31 | target_include_directories(cpp_lib PUBLIC "${CMAKE_CURRENT_LIST_DIR}/include") 32 | target_link_libraries(cpp_lib PUBLIC cxxbridge-cpp) 33 | corrosion_link_libraries(rust_bin cpp_lib cxxbridge-cpp) 34 | if(MSVC) 35 | set_target_properties(cpp_lib PROPERTIES MSVC_RUNTIME_LIBRARY "MultiThreadedDLL") 36 | endif() 37 | else() 38 | message(FATAL_ERROR "Internal test error - required option not defined") 39 | endif() 40 | -------------------------------------------------------------------------------- /doc/src/quick_start.md: -------------------------------------------------------------------------------- 1 | # Quick Start 2 | 3 | You can add corrosion to your project via the `FetchContent` CMake module or one of the other methods 4 | described in the [Setup chapter](setup_corrosion.md). 5 | Afterwards you can import Rust targets defined in a `Cargo.toml` manifest file by using 6 | `corrosion_import_crate`. This will add CMake targets with names matching the crate names defined 7 | in the Cargo.toml manifest. These targets can then subsequently be used, e.g. to link the imported 8 | target into a regular C/C++ target. 9 | 10 | The example below shows how to add Corrosion to your project via `FetchContent` 11 | and how to import a rust library and link it into a regular C/C++ CMake target. 12 | 13 | ```cmake 14 | include(FetchContent) 15 | 16 | FetchContent_Declare( 17 | Corrosion 18 | GIT_REPOSITORY https://github.com/corrosion-rs/corrosion.git 19 | GIT_TAG v0.6 # Optionally specify a commit hash, version tag or branch here 20 | ) 21 | # Set any global configuration variables such as `Rust_TOOLCHAIN` before this line! 22 | FetchContent_MakeAvailable(Corrosion) 23 | 24 | # Import targets defined in a package or workspace manifest `Cargo.toml` file 25 | corrosion_import_crate(MANIFEST_PATH rust-lib/Cargo.toml) 26 | 27 | add_executable(your_cool_cpp_bin main.cpp) 28 | 29 | # In this example the the `Cargo.toml` file passed to `corrosion_import_crate` is assumed to have 30 | # defined a static (`staticlib`) or shared (`cdylib`) rust library with the name "rust-lib". 31 | # A target with the same name is now available in CMake and you can use it to link the rust library into 32 | # your C/C++ CMake target(s). 33 | target_link_libraries(your_cool_cpp_bin PUBLIC rust-lib) 34 | ``` 35 | 36 | 37 | Please see the [Usage chapter](usage.md) for a complete discussion of possible configuration options. 38 | -------------------------------------------------------------------------------- /test/corrosion_install/install_lib/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | cmake_minimum_required(VERSION 3.15) 2 | project(test_project VERSION 0.1.0) 3 | include(ExternalProject) 4 | 5 | add_library(static_lib STATIC IMPORTED) 6 | add_library(shared_lib SHARED IMPORTED) 7 | set(install_prefix "${CMAKE_CURRENT_BINARY_DIR}/rust_lib") 8 | set(static_lib_install_path "${install_prefix}/lib/${CMAKE_STATIC_LIBRARY_PREFIX}rust_lib${CMAKE_STATIC_LIBRARY_SUFFIX}") 9 | set(shared_lib_install_path "${install_prefix}/lib/${CMAKE_SHARED_LIBRARY_PREFIX}rust_lib${CMAKE_SHARED_LIBRARY_SUFFIX}") 10 | 11 | 12 | set_target_properties(static_lib PROPERTIES 13 | IMPORTED_LOCATION 14 | "${static_lib_install_path}") 15 | 16 | set_target_properties(shared_lib PROPERTIES 17 | IMPORTED_LOCATION 18 | "${shared_lib_install_path}") 19 | 20 | add_executable(main-static main.cpp) 21 | target_link_libraries(main-static PRIVATE static_lib) 22 | 23 | ExternalProject_Add( 24 | rust_lib 25 | PREFIX "${CMAKE_CURRENT_BINARY_DIR}/rust_lib" 26 | SOURCE_DIR "${CMAKE_CURRENT_SOURCE_DIR}/rust_lib" 27 | CMAKE_ARGS "-DCMAKE_INSTALL_PREFIX=${install_prefix}" 28 | # INSTALL_BYPRODUCTS "${static_lib_install_path}" 29 | ) 30 | 31 | # Dummy target since INSTALL_BYPRODUCTS requires CMake 3.26 32 | add_custom_target(build_rust_project_dummy 33 | COMMAND echo dummy 34 | BYPRODUCTS "${static_lib_install_path}" "${shared_lib_install_path}" 35 | DEPENDS rust_lib) 36 | 37 | add_dependencies(main-static build_rust_project_dummy) 38 | 39 | set(CMAKE_BUILD_RPATH ${install_prefix}/lib) 40 | add_executable(main-shared main.cpp) 41 | target_link_libraries(main-shared 42 | PUBLIC shared_lib) 43 | 44 | add_dependencies(main-shared build_rust_project_dummy) 45 | -------------------------------------------------------------------------------- /.github/scripts/determine_compiler.sh: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bash 2 | 3 | compiler_kind="$1" 4 | runner_os="$2" 5 | target_abi="$3" 6 | target_system_name="$4" 7 | target_arch="$5" 8 | 9 | set -e 10 | 11 | if [[ -z "$GITHUB_OUTPUT" ]]; then 12 | echo "Error: This script should only be run in github actions environment" 13 | exit 1 14 | fi 15 | if [[ -z "${runner_os}" || -z "${target_abi}" || -z "${target_arch}" ]]; then 16 | echo "Error: Not all required parameters where set" 17 | exit 1 18 | fi 19 | if [[ -z "${compiler_kind}" || "${compiler_kind}" == "default" ]]; then 20 | echo "compiler option was not set. Determining default compiler." 21 | if [[ "${runner_os}" == "Windows" ]]; then 22 | if [[ "${target_abi}" == "msvc" ]]; then 23 | compiler_kind=msvc 24 | elif [[ "${target_abi}" == "gnu" ]]; then 25 | compiler_kind=gcc 26 | else 27 | echo "Unknown abi for Windows: ${target_abi}" 28 | exit 1 29 | fi 30 | elif [[ "${runner_os}" == "macOS" ]]; then 31 | compiler_kind="clang" 32 | elif [[ "${runner_os}" == "Linux" ]]; then 33 | compiler_kind="gcc" 34 | else 35 | echo "Unknown Runner OS: ${runner_os}" 36 | exit 1 37 | fi 38 | fi 39 | echo "Compiler Family: '${compiler_kind}'" 40 | 41 | if [[ "${compiler_kind}" == "clang" ]]; then 42 | c_compiler="clang" 43 | cxx_compiler="clang++" 44 | elif [[ "${compiler_kind}" == "msvc" ]]; then 45 | c_compiler="cl" 46 | cxx_compiler="cl" 47 | elif [[ "${compiler_kind}" == "gcc" ]]; then 48 | if [[ -z "${target_system_name}" ]]; then 49 | c_compiler="gcc" 50 | cxx_compiler="g++" 51 | else 52 | c_compiler="${target_arch}-linux-gnu-gcc" 53 | cxx_compiler="${target_arch}-linux-gnu-g++" 54 | fi 55 | fi 56 | echo "Chose C compiler: '${c_compiler}'" 57 | echo "Chose C++ compiler: '${cxx_compiler}'" 58 | echo "c_compiler=-DCMAKE_C_COMPILER=${c_compiler}" >> $GITHUB_OUTPUT 59 | echo "cxx_compiler=-DCMAKE_CXX_COMPILER=${cxx_compiler}" >> $GITHUB_OUTPUT 60 | -------------------------------------------------------------------------------- /.github/workflows/visual_studio.yaml: -------------------------------------------------------------------------------- 1 | name: Corrosion with Visual Studio 2 | 3 | on: 4 | workflow_call: 5 | inputs: 6 | vs_version: 7 | required: true 8 | type: string 9 | default: 2022 10 | cmake: 11 | required: false 12 | type: string 13 | default: "3.22.6" 14 | rust: 15 | required: false 16 | type: string 17 | default: 1.46.0 18 | target_arch: 19 | required: false 20 | type: string 21 | default: x86_64 22 | 23 | jobs: 24 | visual_studio: 25 | name: Test Visual Studio ${{ inputs.vs_version }} 26 | runs-on: "windows-${{ inputs.vs_version }}" 27 | steps: 28 | - uses: actions/checkout@v4 29 | - name: Install CMake 30 | uses: lukka/get-cmake@519de0c7b4812477d74976b2523a9417f552d126 31 | with: 32 | cmakeVersion: "${{ inputs.cmake }}" 33 | ninjaVersion: "~1.10.0" 34 | - name: Install Rust 35 | id: install_rust 36 | uses: dtolnay/rust-toolchain@master 37 | with: 38 | toolchain: ${{inputs.rust}} 39 | targets: ${{inputs.target_arch}}-pc-windows-msvc 40 | components: rust-src 41 | # The initial configure for MSVC is quite slow, so we cache the build directory 42 | # (including the build directories of the tests) since reconfiguring is 43 | # significantly faster. 44 | # - name: Cache MSVC build directory 45 | # id: cache-msvc-builddir 46 | # uses: actions/cache@v4 47 | # with: 48 | # path: build 49 | # key: ${{ inputs.os }}-${{ inputs.target_arch }}-${{ inputs.rust }}-msvc-${{ inputs.vs_version}}-build 50 | - name: Configure 51 | run: cmake -S. -Bbuild -DCORROSION_TESTS_KEEP_BUILDDIRS=ON "-DRust_TOOLCHAIN=${{steps.install_rust.outputs.name}}" --preset "vs-${{ inputs.vs_version }}-${{ inputs.target_arch }}" 52 | - name: Run Tests 53 | working-directory: build 54 | run: ctest --output-on-failure --build-config Debug -j 3 55 | -------------------------------------------------------------------------------- /.github/workflows/linux.yaml: -------------------------------------------------------------------------------- 1 | # Workflow file for Linux hosts 2 | name: Corrosion on Linux 3 | on: 4 | workflow_call: 5 | inputs: 6 | ubuntu_version: 7 | required: false 8 | type: string 9 | default: "latest" 10 | cmake: 11 | required: false 12 | type: string 13 | default: "3.22.6" 14 | generator: 15 | required: true 16 | type: string 17 | c_compiler: 18 | required: true 19 | type: string 20 | rust: 21 | required: false 22 | type: string 23 | default: 1.46.0 24 | target_arch: 25 | required: false 26 | type: string 27 | default: x86_64 28 | 29 | jobs: 30 | linux: 31 | name: Test Linux 32 | runs-on: ubuntu-${{ inputs.ubuntu_version }} 33 | steps: 34 | - uses: actions/checkout@v4 35 | - name: Install CMake 36 | uses: lukka/get-cmake@519de0c7b4812477d74976b2523a9417f552d126 37 | with: 38 | cmakeVersion: "${{ inputs.cmake }}" 39 | ninjaVersion: "~1.10.0" 40 | - name: Install Rust 41 | id: install_rust 42 | uses: dtolnay/rust-toolchain@master 43 | with: 44 | toolchain: ${{inputs.rust}} 45 | targets: ${{inputs.target_arch}}-unknown-linux-gnu 46 | components: rust-src 47 | - name: Install Cross Compiler 48 | shell: bash 49 | run: | 50 | echo "::group::apt-install" 51 | sudo apt-get update 52 | sudo apt-get install -y "g++-${{inputs.target_arch}}-linux-gnu" 53 | echo "::endgroup::" 54 | if: ${{ 'Linux' == runner.os && inputs.target_arch != 'x86_64' }} 55 | - name: Configure Corrosion 56 | run: cmake -S. -Bbuild -G "${{ inputs.generator }}" "-DRust_TOOLCHAIN=${{steps.install_rust.outputs.name}}" --preset "${{ inputs.target_arch }}-unknown-linux-gnu-${{ inputs.c_compiler }}" 57 | - name: Run Tests 58 | working-directory: build 59 | run: ctest --output-on-failure --build-config Debug -j 3 60 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # Corrosion 2 | [![Build Status](https://github.com/corrosion-rs/corrosion/actions/workflows/test.yaml/badge.svg)](https://github.com/corrosion-rs/corrosion/actions?query=branch%3Amaster) 3 | [![Documentation](https://img.shields.io/badge/docs-latest-blue.svg)](https://corrosion-rs.github.io/corrosion/) 4 | ![License](https://img.shields.io/badge/license-MIT-blue) 5 | 6 | Corrosion, formerly known as cmake-cargo, is a tool for integrating Rust into an existing CMake 7 | project. Corrosion can automatically import executables, static libraries, and dynamic libraries 8 | from a workspace or package manifest (`Cargo.toml` file). 9 | 10 | ## Features 11 | - Automatic Import of Executable, Static, and Shared Libraries from Rust Crate 12 | - Easy Installation of Rust Executables 13 | - Trivially Link Rust Executables to C/C++ Libraries in Tree 14 | - Multi-Config Generator Support 15 | - Simple Cross-Compilation 16 | 17 | ## Sample Usage with FetchContent 18 | 19 | Using the CMake `FetchContent` module allows you to easily integrate corrosion into your build. 20 | Other methods including installing corrosion or adding it as a subdirectory are covered in the 21 | [setup chapter](https://corrosion-rs.github.io/corrosion/setup_corrosion.html) of the 22 | corrosion [documentation](https://corrosion-rs.github.io/corrosion/). 23 | 24 | ```cmake 25 | include(FetchContent) 26 | 27 | FetchContent_Declare( 28 | Corrosion 29 | GIT_REPOSITORY https://github.com/corrosion-rs/corrosion.git 30 | GIT_TAG v0.6 # Optionally specify a commit hash, version tag or branch here 31 | ) 32 | FetchContent_MakeAvailable(Corrosion) 33 | 34 | # Import targets defined in a package or workspace manifest `Cargo.toml` file 35 | corrosion_import_crate(MANIFEST_PATH rust-lib/Cargo.toml) 36 | 37 | add_executable(your_cpp_bin main.cpp) 38 | target_link_libraries(your_cpp_bin PUBLIC rust-lib) 39 | ``` 40 | 41 | ## Requirements 42 | 43 | ### v0.6 Release 44 | 45 | - CMake 3.22 or newer 46 | 47 | ### v0.5 Release (Critical backports only) 48 | 49 | - CMake 3.15 or newer. Some features may only be available on more recent CMake versions 50 | - Rust 1.46 or newer. Some platforms / features may require more recent Rust versions 51 | -------------------------------------------------------------------------------- /test/cxxbridge/cxxbridge_circular/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | # This CMake project tests the setup for circular dependencies that involve a CXX bridge 2 | # While circular dependencies are usually discouraged, with CXX they are reasonbly natural, 3 | # as ideally, Rust should be able to call C++ freely and vice-versa. 4 | # 5 | # The way this project is set up, the rust_lib target acts as the one target that includes 6 | # the mixed C++ and Rust code with the cpp_lib and cxxbridge targets as implementation details, 7 | # which shouldn't be used individually. 8 | cmake_minimum_required(VERSION 3.24) 9 | project(test_project VERSION 0.1.0 LANGUAGES CXX) 10 | include(../../test_header.cmake) 11 | set(CMAKE_CXX_STANDARD 11) 12 | set(CMAKE_CXX_STANDARD_REQUIRED 1) 13 | 14 | corrosion_import_crate(MANIFEST_PATH rust/Cargo.toml) 15 | corrosion_add_cxxbridge(cxxbridge CRATE rust_lib FILES lib.rs) 16 | 17 | if(MSVC) 18 | set_target_properties(cxxbridge PROPERTIES MSVC_RUNTIME_LIBRARY "MultiThreadedDLL") 19 | endif() 20 | 21 | add_library(cpp_lib STATIC cpplib.cpp) 22 | target_include_directories(cpp_lib PUBLIC "${CMAKE_CURRENT_LIST_DIR}/include") 23 | 24 | # Make sure the cpp library can access the headers from the bridge and vice-versa 25 | target_link_libraries(cpp_lib PUBLIC cxxbridge) 26 | target_link_libraries(cxxbridge PRIVATE cpp_lib) 27 | 28 | # The 3 libraries (rust, cpp, cxx) have a circular dependency, set this up in the linker 29 | # so that the rust_lib target links to everything and circular references are resolved. 30 | if(TEST_CXXBRIDGE_VARIANT1) 31 | if (NOT CMAKE_LINK_GROUP_USING_RESCAN_SUPPORTED) 32 | message(FATAL_ERROR "Cannot run this test case without Cmake 3.24 or higher") 33 | endif() 34 | target_link_libraries(rust_lib INTERFACE 35 | "$") 36 | elseif(TEST_CXXBRIDGE_VARIANT2) 37 | target_link_libraries(rust_lib INTERFACE cxxbridge cpp_lib) 38 | endif() 39 | 40 | add_executable(cpp_bin main.cpp) 41 | target_link_libraries(cpp_bin cpp_lib) 42 | 43 | if(MSVC) 44 | set_target_properties(cpp_lib PROPERTIES MSVC_RUNTIME_LIBRARY "MultiThreadedDLL") 45 | set_target_properties(cxxbridge PROPERTIES MSVC_RUNTIME_LIBRARY "MultiThreadedDLL") 46 | set_target_properties(cpp_bin PROPERTIES MSVC_RUNTIME_LIBRARY "MultiThreadedDLL") 47 | endif() 48 | -------------------------------------------------------------------------------- /.github/ISSUE_TEMPLATE/bug_report.yml: -------------------------------------------------------------------------------- 1 | name: Bug Report 2 | description: File a bug report 3 | title: "[Bug]: " 4 | labels: ["bug", "triage"] 5 | assignees: 6 | - jschwe 7 | body: 8 | - type: markdown 9 | attributes: 10 | value: | 11 | Thanks for taking the time to fill out this bug report! 12 | - type: textarea 13 | attributes: 14 | label: Current Behavior 15 | description: A concise description of what you're experiencing. 16 | validations: 17 | required: false 18 | - type: textarea 19 | attributes: 20 | label: Expected Behavior 21 | description: A concise description of what you expected to happen. 22 | validations: 23 | required: false 24 | - type: textarea 25 | attributes: 26 | label: Steps To Reproduce 27 | description: Steps to reproduce the behavior. 28 | placeholder: | 29 | 1. In this environment... 30 | 2. With this config... 31 | 3. Run '...' 32 | 4. See error... 33 | validations: 34 | required: false 35 | - type: textarea 36 | attributes: 37 | label: Environment 38 | description: | 39 | examples: 40 | - **OS**: Ubuntu 22.04 41 | - **CMake**: 3.22.0 42 | - **CMake Generator**: Ninja 1.11 43 | value: | 44 | - OS: 45 | - CMake: 46 | - CMake Generator: 47 | render: markdown 48 | validations: 49 | required: false 50 | - type: textarea 51 | attributes: 52 | label: CMake configure log with Debug log-level 53 | description: | 54 | Output when configuring with `cmake -S -B --log-level=DEBUG `: 55 |
CMake configure log 56 |

57 | 58 | ``` 59 | 60 | ``` 61 | 62 |

63 |
64 | validations: 65 | required: false 66 | - type: textarea 67 | attributes: 68 | label: CMake Build step log 69 | description: | 70 | Output when building with `cmake --build --verbose`: 71 |
CMake build log 72 |

73 | 74 | ``` 75 | 76 | ``` 77 | 78 |

79 |
80 | validations: 81 | required: false 82 | -------------------------------------------------------------------------------- /CMakeLists.txt: -------------------------------------------------------------------------------- 1 | cmake_minimum_required(VERSION 3.22) 2 | project(Corrosion 3 | VERSION 0.6.0 4 | LANGUAGES NONE 5 | HOMEPAGE_URL "https://corrosion-rs.github.io/corrosion/" 6 | ) 7 | 8 | # ==== Corrosion Configuration ==== 9 | 10 | option( 11 | CORROSION_BUILD_TESTS 12 | "Build Corrosion test project" 13 | ${PROJECT_IS_TOP_LEVEL} 14 | ) 15 | 16 | if (PROJECT_IS_TOP_LEVEL) 17 | # We need to enable a language for corrosions test to work. 18 | # For projects using corrosion this is not needed 19 | enable_language(C) 20 | endif() 21 | 22 | # This little bit self-hosts the Corrosion toolchain to build the generator 23 | # tool. 24 | # 25 | # It is strongly encouraged to install Corrosion separately and use 26 | # `find_package(Corrosion REQUIRED)` instead if that works with your workflow. 27 | option(CORROSION_INSTALL_ONLY "Only add rules for installing Corrosion itself." OFF) 28 | if (NOT CORROSION_INSTALL_ONLY) 29 | list(APPEND CMAKE_MODULE_PATH ${CMAKE_CURRENT_SOURCE_DIR}/cmake) 30 | include(Corrosion) 31 | endif() 32 | 33 | # Testing 34 | if (CORROSION_BUILD_TESTS) 35 | include(CTest) 36 | add_subdirectory(test) 37 | endif() 38 | 39 | # If Corrosion is a subdirectory, do not enable its install code 40 | if (NOT PROJECT_IS_TOP_LEVEL) 41 | return() 42 | endif() 43 | 44 | # Installation 45 | 46 | include(GNUInstallDirs) 47 | 48 | # Generate the Config file 49 | include(CMakePackageConfigHelpers) 50 | 51 | configure_package_config_file( 52 | cmake/CorrosionConfig.cmake.in CorrosionConfig.cmake 53 | INSTALL_DESTINATION 54 | "${CMAKE_INSTALL_FULL_LIBDIR}/cmake/Corrosion" 55 | ) 56 | 57 | write_basic_package_version_file( 58 | "${CMAKE_CURRENT_BINARY_DIR}/CorrosionConfigVersion.cmake" 59 | VERSION ${PROJECT_VERSION} 60 | COMPATIBILITY 61 | SameMajorVersion 62 | ARCH_INDEPENDENT 63 | ) 64 | 65 | install( 66 | FILES 67 | "${CMAKE_CURRENT_BINARY_DIR}/CorrosionConfig.cmake" 68 | "${CMAKE_CURRENT_BINARY_DIR}/CorrosionConfigVersion.cmake" 69 | DESTINATION 70 | "${CMAKE_INSTALL_FULL_LIBDIR}/cmake/Corrosion" 71 | ) 72 | 73 | # These CMake scripts are needed both for the install and as a subdirectory 74 | install( 75 | FILES 76 | cmake/Corrosion.cmake 77 | cmake/CorrosionGenerator.cmake 78 | cmake/FindRust.cmake 79 | DESTINATION 80 | "${CMAKE_INSTALL_FULL_DATADIR}/cmake" 81 | ) 82 | -------------------------------------------------------------------------------- /test/cbindgen/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | corrosion_tests_add_test(cbindgen_rust2cpp_auto "cpp-exe" TEST_SRC_DIR auto) 2 | corrosion_tests_add_test(cbindgen_manual "cpp-exe" TEST_SRC_DIR manual) 3 | 4 | set_tests_properties(cbindgen_rust2cpp_auto_run_cpp-exe cbindgen_manual_run_cpp-exe 5 | PROPERTIES PASS_REGULAR_EXPRESSION 6 | "^add_point Result: Point { x: 100, y: 100 }\r?\n$" 7 | ) 8 | 9 | add_test(NAME "cbindgen_install_configure" 10 | COMMAND 11 | ${CMAKE_COMMAND} 12 | -S "${CMAKE_CURRENT_SOURCE_DIR}/install_lib" 13 | -B "${CMAKE_CURRENT_BINARY_DIR}/build_install_lib" 14 | "-G${CMAKE_GENERATOR}" 15 | --install-prefix "${CMAKE_CURRENT_BINARY_DIR}/build_install_lib/test_install_lib_install_dir" 16 | 17 | COMMAND_EXPAND_LISTS 18 | ) 19 | 20 | add_test(NAME "cbindgen_install" 21 | COMMAND 22 | ${CMAKE_COMMAND} 23 | --build "${CMAKE_CURRENT_BINARY_DIR}/build_install_lib" 24 | --target install 25 | --config Debug 26 | ) 27 | 28 | add_test(NAME cbindgen_install_check_header_installed 29 | COMMAND 30 | "${CMAKE_COMMAND}" 31 | -P "${CMAKE_CURRENT_SOURCE_DIR}/../TestFileExists.cmake" 32 | "${CMAKE_CURRENT_BINARY_DIR}/build_install_lib/test_install_lib_install_dir/include/rust-lib.h" 33 | ) 34 | 35 | add_test(NAME cbindgen_install_clean 36 | COMMAND 37 | "${CMAKE_COMMAND}" 38 | -E remove_directory "${CMAKE_CURRENT_BINARY_DIR}/build_install_lib/" 39 | ) 40 | set_tests_properties("cbindgen_install_configure" PROPERTIES FIXTURES_SETUP "configure_fixture_cbindgen_install") 41 | set_tests_properties("cbindgen_install" PROPERTIES FIXTURES_REQUIRED "configure_fixture_cbindgen_install") 42 | 43 | set_tests_properties("cbindgen_install" PROPERTIES FIXTURES_SETUP "install_fixture_cbindgen_install") 44 | set_tests_properties("cbindgen_install_check_header_installed" PROPERTIES FIXTURES_REQUIRED "install_fixture_cbindgen_install") 45 | set_tests_properties("cbindgen_install_check_header_installed" PROPERTIES FIXTURES_SETUP "fx_check_header_installed") 46 | set_tests_properties(cbindgen_install_clean PROPERTIES FIXTURES_CLEANUP "configure_fixture_cbindgen_install;install_fixture_cbindgen_install;fx_check_header_installed") 47 | 48 | # Todo: We also should add a cpp2rust test with the following setup: 49 | # - A rust lib that is used by a rust executable 50 | # - cbindgen creates bindings for the rust-lib 51 | # - c++ code uses the rust lib and is used in turn by the rust bin. 52 | 53 | # todo: add a test for the DEPFILE and correct regenerating if the sources are touched. 54 | -------------------------------------------------------------------------------- /test/cxxbridge/cxxbridge_circular/rust/Cargo.lock: -------------------------------------------------------------------------------- 1 | # This file is automatically @generated by Cargo. 2 | # It is not intended for manual editing. 3 | version = 3 4 | 5 | [[package]] 6 | name = "cc" 7 | version = "1.0.78" 8 | source = "registry+https://github.com/rust-lang/crates.io-index" 9 | checksum = "a20104e2335ce8a659d6dd92a51a767a0c062599c73b343fd152cb401e828c3d" 10 | 11 | [[package]] 12 | name = "cxx" 13 | version = "1.0.86" 14 | source = "registry+https://github.com/rust-lang/crates.io-index" 15 | checksum = "51d1075c37807dcf850c379432f0df05ba52cc30f279c5cfc43cc221ce7f8579" 16 | dependencies = [ 17 | "cc", 18 | "cxxbridge-flags", 19 | "cxxbridge-macro", 20 | "link-cplusplus", 21 | ] 22 | 23 | [[package]] 24 | name = "cxxbridge-flags" 25 | version = "1.0.86" 26 | source = "registry+https://github.com/rust-lang/crates.io-index" 27 | checksum = "61b50bc93ba22c27b0d31128d2d130a0a6b3d267ae27ef7e4fae2167dfe8781c" 28 | 29 | [[package]] 30 | name = "cxxbridge-macro" 31 | version = "1.0.86" 32 | source = "registry+https://github.com/rust-lang/crates.io-index" 33 | checksum = "39e61fda7e62115119469c7b3591fd913ecca96fb766cfd3f2e2502ab7bc87a5" 34 | dependencies = [ 35 | "proc-macro2", 36 | "quote", 37 | "syn", 38 | ] 39 | 40 | [[package]] 41 | name = "link-cplusplus" 42 | version = "1.0.8" 43 | source = "registry+https://github.com/rust-lang/crates.io-index" 44 | checksum = "ecd207c9c713c34f95a097a5b029ac2ce6010530c7b49d7fea24d977dede04f5" 45 | dependencies = [ 46 | "cc", 47 | ] 48 | 49 | [[package]] 50 | name = "proc-macro2" 51 | version = "1.0.50" 52 | source = "registry+https://github.com/rust-lang/crates.io-index" 53 | checksum = "6ef7d57beacfaf2d8aee5937dab7b7f28de3cb8b1828479bb5de2a7106f2bae2" 54 | dependencies = [ 55 | "unicode-ident", 56 | ] 57 | 58 | [[package]] 59 | name = "quote" 60 | version = "1.0.23" 61 | source = "registry+https://github.com/rust-lang/crates.io-index" 62 | checksum = "8856d8364d252a14d474036ea1358d63c9e6965c8e5c1885c18f73d70bff9c7b" 63 | dependencies = [ 64 | "proc-macro2", 65 | ] 66 | 67 | [[package]] 68 | name = "rust_lib" 69 | version = "0.1.0" 70 | dependencies = [ 71 | "cxx", 72 | ] 73 | 74 | [[package]] 75 | name = "syn" 76 | version = "1.0.107" 77 | source = "registry+https://github.com/rust-lang/crates.io-index" 78 | checksum = "1f4064b5b16e03ae50984a5a8ed5d4f8803e6bc1fd170a3cda91a1be4b18e3f5" 79 | dependencies = [ 80 | "proc-macro2", 81 | "quote", 82 | "unicode-ident", 83 | ] 84 | 85 | [[package]] 86 | name = "unicode-ident" 87 | version = "1.0.6" 88 | source = "registry+https://github.com/rust-lang/crates.io-index" 89 | checksum = "84a22b9f218b40614adcb3f4ff08b703773ad44fa9423e4e0d346d5db86e4ebc" 90 | -------------------------------------------------------------------------------- /test/cxxbridge/cxxbridge_cpp2rust/rust/Cargo.lock: -------------------------------------------------------------------------------- 1 | # This file is automatically @generated by Cargo. 2 | # It is not intended for manual editing. 3 | version = 3 4 | 5 | [[package]] 6 | name = "cc" 7 | version = "1.0.78" 8 | source = "registry+https://github.com/rust-lang/crates.io-index" 9 | checksum = "a20104e2335ce8a659d6dd92a51a767a0c062599c73b343fd152cb401e828c3d" 10 | 11 | [[package]] 12 | name = "cxx" 13 | version = "1.0.86" 14 | source = "registry+https://github.com/rust-lang/crates.io-index" 15 | checksum = "51d1075c37807dcf850c379432f0df05ba52cc30f279c5cfc43cc221ce7f8579" 16 | dependencies = [ 17 | "cc", 18 | "cxxbridge-flags", 19 | "cxxbridge-macro", 20 | "link-cplusplus", 21 | ] 22 | 23 | [[package]] 24 | name = "cxxbridge-flags" 25 | version = "1.0.86" 26 | source = "registry+https://github.com/rust-lang/crates.io-index" 27 | checksum = "61b50bc93ba22c27b0d31128d2d130a0a6b3d267ae27ef7e4fae2167dfe8781c" 28 | 29 | [[package]] 30 | name = "cxxbridge-macro" 31 | version = "1.0.86" 32 | source = "registry+https://github.com/rust-lang/crates.io-index" 33 | checksum = "39e61fda7e62115119469c7b3591fd913ecca96fb766cfd3f2e2502ab7bc87a5" 34 | dependencies = [ 35 | "proc-macro2", 36 | "quote", 37 | "syn", 38 | ] 39 | 40 | [[package]] 41 | name = "link-cplusplus" 42 | version = "1.0.8" 43 | source = "registry+https://github.com/rust-lang/crates.io-index" 44 | checksum = "ecd207c9c713c34f95a097a5b029ac2ce6010530c7b49d7fea24d977dede04f5" 45 | dependencies = [ 46 | "cc", 47 | ] 48 | 49 | [[package]] 50 | name = "proc-macro2" 51 | version = "1.0.50" 52 | source = "registry+https://github.com/rust-lang/crates.io-index" 53 | checksum = "6ef7d57beacfaf2d8aee5937dab7b7f28de3cb8b1828479bb5de2a7106f2bae2" 54 | dependencies = [ 55 | "unicode-ident", 56 | ] 57 | 58 | [[package]] 59 | name = "quote" 60 | version = "1.0.23" 61 | source = "registry+https://github.com/rust-lang/crates.io-index" 62 | checksum = "8856d8364d252a14d474036ea1358d63c9e6965c8e5c1885c18f73d70bff9c7b" 63 | dependencies = [ 64 | "proc-macro2", 65 | ] 66 | 67 | [[package]] 68 | name = "rust_bin" 69 | version = "0.1.0" 70 | dependencies = [ 71 | "cxx", 72 | ] 73 | 74 | [[package]] 75 | name = "syn" 76 | version = "1.0.107" 77 | source = "registry+https://github.com/rust-lang/crates.io-index" 78 | checksum = "1f4064b5b16e03ae50984a5a8ed5d4f8803e6bc1fd170a3cda91a1be4b18e3f5" 79 | dependencies = [ 80 | "proc-macro2", 81 | "quote", 82 | "unicode-ident", 83 | ] 84 | 85 | [[package]] 86 | name = "unicode-ident" 87 | version = "1.0.6" 88 | source = "registry+https://github.com/rust-lang/crates.io-index" 89 | checksum = "84a22b9f218b40614adcb3f4ff08b703773ad44fa9423e4e0d346d5db86e4ebc" 90 | -------------------------------------------------------------------------------- /test/cxxbridge/cxxbridge_rust2cpp/rust/Cargo.lock: -------------------------------------------------------------------------------- 1 | # This file is automatically @generated by Cargo. 2 | # It is not intended for manual editing. 3 | version = 3 4 | 5 | [[package]] 6 | name = "cc" 7 | version = "1.0.78" 8 | source = "registry+https://github.com/rust-lang/crates.io-index" 9 | checksum = "a20104e2335ce8a659d6dd92a51a767a0c062599c73b343fd152cb401e828c3d" 10 | 11 | [[package]] 12 | name = "cxx" 13 | version = "1.0.86" 14 | source = "registry+https://github.com/rust-lang/crates.io-index" 15 | checksum = "51d1075c37807dcf850c379432f0df05ba52cc30f279c5cfc43cc221ce7f8579" 16 | dependencies = [ 17 | "cc", 18 | "cxxbridge-flags", 19 | "cxxbridge-macro", 20 | "link-cplusplus", 21 | ] 22 | 23 | [[package]] 24 | name = "cxxbridge-crate" 25 | version = "0.1.0" 26 | dependencies = [ 27 | "cxx", 28 | ] 29 | 30 | [[package]] 31 | name = "cxxbridge-flags" 32 | version = "1.0.86" 33 | source = "registry+https://github.com/rust-lang/crates.io-index" 34 | checksum = "61b50bc93ba22c27b0d31128d2d130a0a6b3d267ae27ef7e4fae2167dfe8781c" 35 | 36 | [[package]] 37 | name = "cxxbridge-macro" 38 | version = "1.0.86" 39 | source = "registry+https://github.com/rust-lang/crates.io-index" 40 | checksum = "39e61fda7e62115119469c7b3591fd913ecca96fb766cfd3f2e2502ab7bc87a5" 41 | dependencies = [ 42 | "proc-macro2", 43 | "quote", 44 | "syn", 45 | ] 46 | 47 | [[package]] 48 | name = "link-cplusplus" 49 | version = "1.0.8" 50 | source = "registry+https://github.com/rust-lang/crates.io-index" 51 | checksum = "ecd207c9c713c34f95a097a5b029ac2ce6010530c7b49d7fea24d977dede04f5" 52 | dependencies = [ 53 | "cc", 54 | ] 55 | 56 | [[package]] 57 | name = "proc-macro2" 58 | version = "1.0.50" 59 | source = "registry+https://github.com/rust-lang/crates.io-index" 60 | checksum = "6ef7d57beacfaf2d8aee5937dab7b7f28de3cb8b1828479bb5de2a7106f2bae2" 61 | dependencies = [ 62 | "unicode-ident", 63 | ] 64 | 65 | [[package]] 66 | name = "quote" 67 | version = "1.0.23" 68 | source = "registry+https://github.com/rust-lang/crates.io-index" 69 | checksum = "8856d8364d252a14d474036ea1358d63c9e6965c8e5c1885c18f73d70bff9c7b" 70 | dependencies = [ 71 | "proc-macro2", 72 | ] 73 | 74 | [[package]] 75 | name = "syn" 76 | version = "1.0.107" 77 | source = "registry+https://github.com/rust-lang/crates.io-index" 78 | checksum = "1f4064b5b16e03ae50984a5a8ed5d4f8803e6bc1fd170a3cda91a1be4b18e3f5" 79 | dependencies = [ 80 | "proc-macro2", 81 | "quote", 82 | "unicode-ident", 83 | ] 84 | 85 | [[package]] 86 | name = "unicode-ident" 87 | version = "1.0.6" 88 | source = "registry+https://github.com/rust-lang/crates.io-index" 89 | checksum = "84a22b9f218b40614adcb3f4ff08b703773ad44fa9423e4e0d346d5db86e4ebc" 90 | -------------------------------------------------------------------------------- /test/output directory/output directory/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | cmake_minimum_required(VERSION 3.15) 2 | project(test_project VERSION 0.1.0) 3 | include(../../test_header.cmake) 4 | 5 | corrosion_import_crate(MANIFEST_PATH proj1/Cargo.toml) 6 | 7 | # Note: The output directories defined here must be manually kept in sync with the expected test location. 8 | set_target_properties(rust_bin1 9 | PROPERTIES 10 | RUNTIME_OUTPUT_DIRECTORY "${CMAKE_CURRENT_BINARY_DIR}/custom_bin_targetprop" 11 | PDB_OUTPUT_DIRECTORY "${CMAKE_CURRENT_BINARY_DIR}/custom_bin_pdb_targetprop" 12 | 13 | ) 14 | set_target_properties(rust_lib1 PROPERTIES ARCHIVE_OUTPUT_DIRECTORY "${CMAKE_CURRENT_BINARY_DIR}/custom_archive_targetprop") 15 | set_target_properties(rust_lib1 16 | PROPERTIES 17 | LIBRARY_OUTPUT_DIRECTORY "${CMAKE_CURRENT_BINARY_DIR}/custom_lib_targetprop" 18 | PDB_OUTPUT_DIRECTORY "${CMAKE_CURRENT_BINARY_DIR}/custom_lib_pdb_targetprop" 19 | ) 20 | 21 | add_custom_command(TARGET cargo-build_rust_bin1 POST_BUILD 22 | COMMAND 23 | ${CMAKE_COMMAND} -E make_directory "${CMAKE_CURRENT_BINARY_DIR}/another_dir" 24 | COMMAND 25 | ${CMAKE_COMMAND} -E copy_if_different "$>" "${CMAKE_CURRENT_BINARY_DIR}/another_dir/moved_bin" 26 | ) 27 | 28 | set(CMAKE_RUNTIME_OUTPUT_DIRECTORY "${CMAKE_CURRENT_BINARY_DIR}/custom_bin_var") 29 | set(CMAKE_PDB_OUTPUT_DIRECTORY "${CMAKE_CURRENT_BINARY_DIR}/custom_binlib_pdb_var") 30 | set(CMAKE_ARCHIVE_OUTPUT_DIRECTORY "${CMAKE_CURRENT_BINARY_DIR}/custom_archive_var") 31 | set(CMAKE_LIBRARY_OUTPUT_DIRECTORY "${CMAKE_CURRENT_BINARY_DIR}/custom_lib_var") 32 | 33 | corrosion_import_crate(MANIFEST_PATH proj2/Cargo.toml) 34 | 35 | unset(CMAKE_RUNTIME_OUTPUT_DIRECTORY) 36 | unset(CMAKE_PDB_OUTPUT_DIRECTORY) 37 | unset(CMAKE_ARCHIVE_OUTPUT_DIRECTORY) 38 | unset(CMAKE_LIBRARY_OUTPUT_DIRECTORY) 39 | unset(CMAKE_PDB_OUTPUT_DIRECTORY) 40 | 41 | add_executable(consumer consumer.cpp) 42 | add_dependencies(consumer cargo-build_rust_lib1 cargo-build_rust_lib2) 43 | 44 | target_link_libraries(consumer rust_lib1 rust_lib2) 45 | 46 | 47 | corrosion_import_crate(MANIFEST_PATH proj3/Cargo.toml) 48 | 49 | # Note: The output directories defined here must be manually kept in sync with the expected test location. 50 | set_target_properties(rust_bin3 51 | PROPERTIES 52 | RUNTIME_OUTPUT_DIRECTORY "${CMAKE_CURRENT_BINARY_DIR}/custom_bin_targetprop_pdb_fallback" 53 | ) 54 | set_target_properties(rust_lib3 55 | PROPERTIES 56 | ARCHIVE_OUTPUT_DIRECTORY "${CMAKE_CURRENT_BINARY_DIR}/custom_archive_targetprop_pdb_fallback" 57 | LIBRARY_OUTPUT_DIRECTORY "${CMAKE_CURRENT_BINARY_DIR}/custom_lib_targetprop_pdb_fallback" 58 | ) 59 | -------------------------------------------------------------------------------- /.github/workflows/gh-pages.yaml: -------------------------------------------------------------------------------- 1 | name: Deploy GH pages 2 | on: 3 | push: 4 | branches: 5 | - master 6 | # Allows you to run this workflow manually from the Actions tab 7 | workflow_dispatch: 8 | 9 | # Sets permissions of the GITHUB_TOKEN to allow deployment to GitHub Pages 10 | permissions: 11 | contents: read 12 | pages: write 13 | id-token: write 14 | 15 | # Allow one concurrent deployment 16 | concurrency: 17 | group: "pages" 18 | cancel-in-progress: true 19 | 20 | jobs: 21 | # Build and deploy the documentation of master and the stable/v0.5 branch 22 | deploy: 23 | runs-on: ubuntu-latest 24 | environment: 25 | name: github-pages 26 | url: ${{ steps.deployment.outputs.page_url }} 27 | steps: 28 | - name: Install mdbook 29 | env: 30 | MDBOOK_VERSION: 'v0.4.27' 31 | run: | 32 | mkdir mdbook 33 | curl -sSL https://github.com/rust-lang/mdBook/releases/download/${MDBOOK_VERSION}/mdbook-${MDBOOK_VERSION}-x86_64-unknown-linux-gnu.tar.gz | tar -xz --directory=./mdbook 34 | echo `pwd`/mdbook >> $GITHUB_PATH 35 | - name: Checkout master 36 | uses: actions/checkout@v4 37 | with: 38 | path: main 39 | - name: Checkout stable/v0.5 40 | uses: actions/checkout@v4 41 | with: 42 | path: stable-v0.5 43 | ref: 'stable/v0.5' 44 | - name: Setup Pages 45 | uses: actions/configure-pages@v5 46 | - name: Build mdbook for main branch 47 | working-directory: 'main/doc' 48 | run: mdbook build 49 | - name: Build mdbook for stable/v0.5 branch 50 | working-directory: 'stable-v0.5/doc' 51 | run: mdbook build 52 | # Override mdbooks default highlight.js with a custom version containing CMake support. 53 | - uses: actions/checkout@v4 54 | with: 55 | repository: 'highlightjs/highlight.js' 56 | # mdbook currently (as of v0.4.27) does not support v11 yet. 57 | ref: '10.7.3' 58 | path: highlightjs 59 | - name: Build custom highlight.js 60 | run: | 61 | npm install 62 | node tools/build.js :common cmake yaml 63 | working-directory: highlightjs 64 | - name: Override highlightjs 65 | run: | 66 | cp highlightjs/build/highlight.min.js main/doc/book/highlight.js 67 | cp highlightjs/build/highlight.min.js stable-v0.5/doc/book/highlight.js 68 | - name: Copy stable doc into main 69 | run: mkdir main/doc/book/v0.5 && cp -a stable-v0.5/doc/book/. main/doc/book/v0.5/ 70 | - name: Debug print 71 | run: ls -la main/doc/book/v0.5 72 | - name: Upload artifact 73 | uses: actions/upload-pages-artifact@v3 74 | with: 75 | path: 'main/doc/book' 76 | - name: Deploy to GitHub Pages 77 | id: deployment 78 | uses: actions/deploy-pages@v4 79 | -------------------------------------------------------------------------------- /doc/src/setup_corrosion.md: -------------------------------------------------------------------------------- 1 | # Adding Corrosion to your project 2 | 3 | There are two fundamental installation methods that are supported by Corrosion - installation as a 4 | CMake package or using it as a subdirectory in an existing CMake project. For CMake versions below 5 | 3.19 Corrosion strongly recommends installing the package, either via a package manager or manually 6 | using CMake's installation facilities. 7 | If you have CMake 3.19 or newer, we recommend to use either the [FetchContent](#fetchcontent) or the 8 | [Subdirectory](#subdirectory) method to integrate Corrosion. 9 | 10 | ## FetchContent 11 | If you are using CMake >= 3.19 or installation is difficult or not feasible in 12 | your environment, you can use the 13 | [FetchContent](https://cmake.org/cmake/help/latest/module/FetchContent.html) module to include 14 | Corrosion. This will download Corrosion and use it as if it were a subdirectory at configure time. 15 | 16 | In your CMakeLists.txt: 17 | ```cmake 18 | include(FetchContent) 19 | 20 | FetchContent_Declare( 21 | Corrosion 22 | GIT_REPOSITORY https://github.com/corrosion-rs/corrosion.git 23 | # v0.6 will be updated to point to the latest patch version. 24 | # Use v0.6. or the commit hash to prevent such auto updates. 25 | GIT_TAG v0.6 26 | ) 27 | # Set any global configuration variables such as `Rust_TOOLCHAIN` before this line! 28 | FetchContent_MakeAvailable(Corrosion) 29 | ``` 30 | 31 | ## Subdirectory 32 | Corrosion can also be used directly as a subdirectory. This solution may work well for small 33 | projects, but it's discouraged for large projects with many dependencies, especially those which may 34 | themselves use Corrosion. Either copy the Corrosion library into your source tree, being sure to 35 | preserve the `LICENSE` file, or add this repository as a git submodule: 36 | ```bash 37 | git submodule add https://github.com/corrosion-rs/corrosion.git 38 | ``` 39 | 40 | From there, using Corrosion is easy. In your CMakeLists.txt: 41 | ```cmake 42 | add_subdirectory(path/to/corrosion) 43 | ``` 44 | 45 | ## Installation 46 | 47 | 48 | Installation will pre-build all of Corrosion's native tooling (required only for CMake versions 49 | below 3.19) and install it together with Corrosions CMake files into a standard location. 50 | On CMake >= 3.19 installing Corrosion does not offer any speed advantages, unless the native 51 | tooling option is explicitly enabled. 52 | 53 | ### Install from source 54 | 55 | First, download and install Corrosion: 56 | ```bash 57 | git clone https://github.com/corrosion-rs/corrosion.git 58 | # Optionally, specify -DCMAKE_INSTALL_PREFIX= to specify a 59 | # custom installation directory 60 | cmake -Scorrosion -Bbuild -DCMAKE_BUILD_TYPE=Release 61 | cmake --build build --config Release 62 | # This next step may require sudo or admin privileges if you're installing to a system location, 63 | # which is the default. 64 | cmake --install build --config Release 65 | ``` 66 | 67 | You'll want to ensure that the install directory is available in your `PATH` or `CMAKE_PREFIX_PATH` 68 | environment variable. This is likely to already be the case by default on a Unix system, but on 69 | Windows it will install to `C:\Program Files (x86)\Corrosion` by default, which will not be in your 70 | `PATH` or `CMAKE_PREFIX_PATH` by default. 71 | 72 | Once Corrosion is installed, and you've ensured the package is available in your `PATH`, you 73 | can use it from your own project like any other package from your CMakeLists.txt: 74 | ```cmake 75 | find_package(Corrosion REQUIRED) 76 | ``` 77 | 78 | ### Package Manager 79 | 80 | #### Homebrew (unofficial) 81 | 82 | Corrosion is available via Homebrew and can be installed via 83 | 84 | ```bash 85 | brew install corrosion 86 | ``` 87 | 88 | Please note that this package is community maintained. Please also keep in mind that Corrosion follows 89 | semantic versioning and minor version bumps (i.e. `0.3` -> `0.4`) may contain breaking changes, while 90 | Corrosion is still pre `1.0`. 91 | Please read the release notes when upgrading Corrosion. 92 | -------------------------------------------------------------------------------- /test/ConfigureAndBuild.cmake: -------------------------------------------------------------------------------- 1 | # CMake script to configure and build a test project 2 | 3 | set(TEST_ARG_LIST) 4 | 5 | # Expect actual arguments to start at index 3 (cmake -P ) 6 | foreach(ARG_INDEX RANGE 3 ${CMAKE_ARGC}) 7 | list(APPEND TEST_ARG_LIST "${CMAKE_ARGV${ARG_INDEX}}") 8 | endforeach() 9 | 10 | set(options "USE_INSTALLED_CORROSION") 11 | set(oneValueArgs 12 | SOURCE_DIR 13 | BINARY_DIR 14 | GENERATOR 15 | GENERATOR_PLATFORM 16 | RUST_TOOLCHAIN 17 | CARGO_TARGET 18 | C_COMPILER 19 | CXX_COMPILER 20 | C_COMPILER_TARGET 21 | CXX_COMPILER_TARGET 22 | SYSTEM_NAME 23 | CARGO_PROFILE 24 | OSX_ARCHITECTURES 25 | OSX_SYSROOT 26 | TOOLCHAIN_FILE 27 | ) 28 | set(multiValueArgs "PASS_THROUGH_ARGS") 29 | cmake_parse_arguments(TEST "${options}" "${oneValueArgs}" 30 | "${multiValueArgs}" ${TEST_ARG_LIST} ) 31 | 32 | set(configure_args "") 33 | if(TEST_CARGO_TARGET) 34 | list(APPEND configure_args "-DRust_CARGO_TARGET=${TEST_CARGO_TARGET}") 35 | endif() 36 | if(TEST_USE_INSTALLED_CORROSION) 37 | list(APPEND configure_args "-DCORROSION_TESTS_FIND_CORROSION=ON") 38 | endif() 39 | if(TEST_GENERATOR_PLATFORM) 40 | list(APPEND configure_args "-A${TEST_GENERATOR_PLATFORM}") 41 | endif() 42 | if(TEST_C_COMPILER) 43 | list(APPEND configure_args "-DCMAKE_C_COMPILER=${TEST_C_COMPILER}") 44 | endif() 45 | if(TEST_CXX_COMPILER) 46 | list(APPEND configure_args "-DCMAKE_CXX_COMPILER=${TEST_CXX_COMPILER}") 47 | endif() 48 | if(TEST_C_COMPILER_TARGET) 49 | list(APPEND configure_args "-DCMAKE_C_COMPILER_TARGET=${TEST_C_COMPILER_TARGET}") 50 | endif() 51 | if(TEST_CXX_COMPILER_TARGET) 52 | list(APPEND configure_args "-DCMAKE_CXX_COMPILER_TARGET=${TEST_CXX_COMPILER_TARGET}") 53 | endif() 54 | if(TEST_SYSTEM_NAME) 55 | list(APPEND configure_args "-DCMAKE_SYSTEM_NAME=${TEST_SYSTEM_NAME}") 56 | endif() 57 | if(TEST_OSX_ARCHITECTURES) 58 | list(APPEND configure_args "-DCMAKE_OSX_ARCHITECTURES=${TEST_OSX_ARCHITECTURES}") 59 | endif() 60 | if(TEST_OSX_SYSROOT) 61 | list(APPEND configure_args "-DCMAKE_OSX_SYSROOT=${TEST_OSX_SYSROOT}") 62 | endif() 63 | if(TEST_TOOLCHAIN_FILE) 64 | list(APPEND configure_args "-DCMAKE_TOOLCHAIN_FILE=${TEST_TOOLCHAIN_FILE}") 65 | endif() 66 | if(TEST_CARGO_PROFILE) 67 | list(APPEND configure_args "-DCARGO_PROFILE=${TEST_CARGO_PROFILE}") 68 | endif() 69 | 70 | # Remove old binary directory 71 | file(REMOVE_RECURSE "${TEST_BINARY_DIR}") 72 | 73 | file(MAKE_DIRECTORY "${TEST_BINARY_DIR}") 74 | 75 | message(STATUS "TEST_BINARY_DIRECTORY: ${TEST_BINARY_DIR}") 76 | 77 | execute_process( 78 | COMMAND 79 | "${CMAKE_COMMAND}" 80 | "-G${TEST_GENERATOR}" 81 | "-DRust_TOOLCHAIN=${TEST_RUST_TOOLCHAIN}" 82 | --log-level Debug 83 | ${configure_args} 84 | ${TEST_PASS_THROUGH_ARGS} 85 | -S "${TEST_SOURCE_DIR}" 86 | -B "${TEST_BINARY_DIR}" 87 | COMMAND_ECHO STDOUT 88 | RESULT_VARIABLE EXIT_CODE 89 | ) 90 | 91 | if (NOT "${EXIT_CODE}" EQUAL 0) 92 | message(FATAL_ERROR "Configure step failed. Exit code: `${EXIT_CODE}`") 93 | endif() 94 | 95 | if ("${TEST_GENERATOR}" STREQUAL "Ninja Multi-Config" 96 | OR "${TEST_GENERATOR}" MATCHES "Visual Studio" 97 | ) 98 | foreach(config Debug Release RelWithDebInfo) 99 | execute_process( 100 | COMMAND "${CMAKE_COMMAND}" 101 | --build "${TEST_BINARY_DIR}" 102 | --config "${config}" 103 | COMMAND_ECHO STDOUT 104 | RESULT_VARIABLE EXIT_CODE 105 | ) 106 | if (NOT "${EXIT_CODE}" EQUAL 0) 107 | message(FATAL_ERROR "Build step failed for config `${config}`. " 108 | "Exit code: `${EXIT_CODE}`") 109 | endif() 110 | endforeach() 111 | else() 112 | execute_process( 113 | COMMAND "${CMAKE_COMMAND}" --build "${TEST_BINARY_DIR}" 114 | COMMAND_ECHO STDOUT 115 | RESULT_VARIABLE EXIT_CODE 116 | ) 117 | if (NOT "${EXIT_CODE}" EQUAL 0) 118 | message(FATAL_ERROR "Build step failed. Exit code: `${EXIT_CODE}`") 119 | endif() 120 | endif() 121 | 122 | 123 | -------------------------------------------------------------------------------- /test/parse_target_triple/parse_target_triple/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | # This test is supposed to ensure that the regex in _corrosion_parse_platform works as expected. 2 | cmake_minimum_required(VERSION 3.15) 3 | project(test_project VERSION 0.1.0) 4 | include(../../test_header.cmake) 5 | 6 | # Todo: Test if the output matches expectations. 7 | _corrosion_parse_target_triple("../../blah/x86_64-unknown-custom-gnu.json" arch vendor os env) 8 | _corrosion_parse_target_triple("x86_64-unknown-custom-gnu.json" arch vendor os env) 9 | _corrosion_parse_target_triple("/path/to/x86_64-unknown-custom-musl.json" arch vendor os env) 10 | _corrosion_parse_target_triple("../../blah/x86_64-custom_os.json" arch vendor os env) 11 | 12 | # List of builtin targets aquired via `rustup target list` with rust 1.64 on Linux. 13 | set(rustup_shipped_targets 14 | "aarch64-apple-darwin" 15 | "aarch64-apple-ios" 16 | "aarch64-apple-ios-sim" 17 | "aarch64-fuchsia" 18 | "aarch64-linux-android" 19 | "aarch64-pc-windows-msvc" 20 | "aarch64-unknown-linux-gnu" 21 | "aarch64-unknown-linux-musl" 22 | "aarch64-unknown-none" 23 | "aarch64-unknown-none-softfloat" 24 | "arm-linux-androideabi" 25 | "arm-unknown-linux-gnueabi" 26 | "arm-unknown-linux-gnueabihf" 27 | "arm-unknown-linux-musleabi" 28 | "arm-unknown-linux-musleabihf" 29 | "armebv7r-none-eabi" 30 | "armebv7r-none-eabihf" 31 | "armv5te-unknown-linux-gnueabi" 32 | "armv5te-unknown-linux-musleabi" 33 | "armv7-linux-androideabi" 34 | "armv7-unknown-linux-gnueabi" 35 | "armv7-unknown-linux-gnueabihf" 36 | "armv7-unknown-linux-musleabi" 37 | "armv7-unknown-linux-musleabihf" 38 | "armv7a-none-eabi" 39 | "armv7r-none-eabi" 40 | "armv7r-none-eabihf" 41 | "asmjs-unknown-emscripten" 42 | "i586-pc-windows-msvc" 43 | "i586-unknown-linux-gnu" 44 | "i586-unknown-linux-musl" 45 | "i686-linux-android" 46 | "i686-pc-windows-gnu" 47 | "i686-pc-windows-msvc" 48 | "i686-unknown-freebsd" 49 | "i686-unknown-linux-gnu" 50 | "i686-unknown-linux-musl" 51 | "mips-unknown-linux-gnu" 52 | "mips-unknown-linux-musl" 53 | "mips64-unknown-linux-gnuabi64" 54 | "mips64-unknown-linux-muslabi64" 55 | "mips64el-unknown-linux-gnuabi64" 56 | "mips64el-unknown-linux-muslabi64" 57 | "mipsel-unknown-linux-gnu" 58 | "mipsel-unknown-linux-musl" 59 | "nvptx64-nvidia-cuda" 60 | "powerpc-unknown-linux-gnu" 61 | "powerpc64-unknown-linux-gnu" 62 | "powerpc64le-unknown-linux-gnu" 63 | "riscv32i-unknown-none-elf" 64 | "riscv32imac-unknown-none-elf" 65 | "riscv32imc-unknown-none-elf" 66 | "riscv64gc-unknown-linux-gnu" 67 | "riscv64gc-unknown-none-elf" 68 | "riscv64imac-unknown-none-elf" 69 | "s390x-unknown-linux-gnu" 70 | "sparc64-unknown-linux-gnu" 71 | "sparcv9-sun-solaris" 72 | "thumbv6m-none-eabi" 73 | "thumbv7em-none-eabi" 74 | "thumbv7em-none-eabihf" 75 | "thumbv7m-none-eabi" 76 | "thumbv7neon-linux-androideabi" 77 | "thumbv7neon-unknown-linux-gnueabihf" 78 | "thumbv8m.base-none-eabi" 79 | "thumbv8m.main-none-eabi" 80 | "thumbv8m.main-none-eabihf" 81 | "wasm32-unknown-emscripten" 82 | "wasm32-unknown-unknown" 83 | "wasm32-wasi" 84 | "x86_64-apple-darwin" 85 | "x86_64-apple-ios" 86 | "x86_64-fortanix-unknown-sgx" 87 | "x86_64-fuchsia" 88 | "x86_64-linux-android" 89 | "x86_64-pc-solaris" 90 | "x86_64-pc-windows-gnu" 91 | "x86_64-pc-windows-msvc" 92 | "x86_64-sun-solaris" 93 | "x86_64-unknown-freebsd" 94 | "x86_64-unknown-illumos" 95 | "x86_64-unknown-linux-gnu" 96 | "x86_64-unknown-linux-gnux32" 97 | "x86_64-unknown-linux-musl" 98 | "x86_64-unknown-netbsd" 99 | "x86_64-unknown-none" 100 | "x86_64-unknown-redox" 101 | ) 102 | set(other_targets riscv32imc-esp-espidf xtensa-esp32s3-none-elf) 103 | 104 | foreach(target ${rustup_shipped_targets} ${other_targets}) 105 | _corrosion_parse_target_triple("${target}" arch vendor os env) 106 | endforeach() 107 | -------------------------------------------------------------------------------- /doc/src/advanced.md: -------------------------------------------------------------------------------- 1 | ## What does corrosion do? 2 | 3 | The specifics of what corrosion does should be regarded as an implementation detail and not relied on 4 | when writing user code. However, a basic understanding of what corrosion does may be helpful when investigating 5 | issues. 6 | 7 | ### FindRust 8 | 9 | Corrosion maintains a CMake module `FindRust` which is executed when Corrosion is loaded, i.e. at the time 10 | of `find_package(corrosion)`, `FetchContent_MakeAvailable(corrosion)` or `add_subdirectory(corrosion)` depending 11 | on the method used to include Corrosion. 12 | 13 | `FindRust` will search for installed rust toolchains, respecting the options prefixed with `Rust_` documented in 14 | the [Usage](usage.md#corrosion-options) chapter. 15 | It will select _one_ Rust toolchain to be used for the compilation of Rust code. Toolchains managed by `rustup` 16 | will be resolved and corrosion will always select a specific toolchain, not a `rustup` proxy. 17 | 18 | 19 | ### Importing Rust crates 20 | 21 | Corrosion's main function is `corrosion_import_crate`, which internally will call `cargo metadata` to provide 22 | structured information based on the `Cargo.toml` manifest. 23 | Corrosion will then iterate over all workspace and/or package members and find all rust crates that are either 24 | a static (`staticlib`) or shared (`cdylib`) library or a `bin` target and create CMake targets matching the 25 | crate name. Additionally, a build target is created for each imported target, containing the required build 26 | command to create the imported artifact. This build command can be influenced by various arguments to 27 | `corrosion_import_crate` as well as corrosion specific target properties which are documented int the 28 | [Usage](usage.md) chapter. 29 | Corrosion adds the necessary dependencies and also copies the target artifacts out of the cargo build tree 30 | to standard CMake locations, even respecting `OUTPUT_DIRECTORY` target properties if set. 31 | 32 | ### Linking 33 | 34 | Depending on the type of the crate the linker will either be invoked by CMake or by `rustc`. 35 | Rust `staticlib`s are linked into C/C++ code via `target_link_libraries()` and the linker is 36 | invoked by CMake. 37 | For rust `cdylib`s and `bin`s, the linker is invoked via `rustc` and CMake just gets the final artifact. 38 | 39 | #### CMake invokes the linker 40 | 41 | When CMake invokes the linker, everything is as usual. CMake will call the linker with 42 | the compiler as the linker driver and users can just use the regular CMake functions to 43 | modify linking behaviour. `corrosion_set_linker()` has **no effect**. 44 | As a convenience, `corrosion_link_libraries()` will forward its arguments to `target_link_libraries()`. 45 | 46 | #### Rustc invokes the linker 47 | 48 | Rust `cdylib`s and `bin`s are linked via `rustc`. Corrosion provides several helper functions 49 | to influence the linker invocation for such targets. 50 | 51 | `corrosion_link_libraries()` is a limited version of `target_link_libraries()` 52 | for rust `cdylib` or `bin` targets. 53 | Under the hood this function passes `-l` and `-L` flags to the linker invocation and 54 | ensures the linked libraries are built first. 55 | Much of the advanced functionality available in `target_link_libraries()` is not implemented yet, 56 | but pull-requests are welcome! In the meantime, users may want to use 57 | `corrosion_add_target_local_rustflags()` to pass customized linking flags. 58 | 59 | `corrosion_set_linker()` can be used to specify a custom linker, in case the default one 60 | chosen by corrosion is not what you want. 61 | Corrosion currently instructs `rustc` to use the C/C++ compiler as the linker driver. 62 | This is done because: 63 | - For C++ code we must link with `libstdc++` or `libc++` (depending on the compiler), so we must 64 | either specify the library on the link line or use a `c++` compiler as the linker driver. 65 | - `Rustc`s default linker selection currently is not so great. For a number of platforms 66 | `rustc` will fallback to `cc` as the linker driver. When cross-compiling, this leads 67 | to linking failures, since the linker driver is for the host architecture. 68 | Corrosion avoids this by specifying the C/C++ compiler as the linker driver. 69 | 70 | 71 | In some cases, especially in older rust versions (pre 1.68), the linker flavor detection 72 | of `rustc` is also not correct, so when setting a custom linker you may want to pass the 73 | [`-C linker-flavor`](https://doc.rust-lang.org/rustc/codegen-options/index.html#linker-flavor) 74 | rustflag via `corrosion_add_target_local_rustflags()`. 75 | 76 | ## FFI bindings 77 | 78 | For interaction between Rust and other languages there need to be some FFI bindings of some sort. 79 | For simple cases manually defining the interfaces may be sufficient, but in many cases users 80 | wish to use tools like [bindgen], [cbindgen], [cxx] or [autocxx] to automate the generating of 81 | bindings. 82 | 83 | In principle there are two different ways to generate the bindings: 84 | - use a `build.rs` script to generate the bindings when cargo is invoked, using 85 | library versions of the tools to generate the bindings. 86 | - use the cli versions of the tools and setup custom CMake targets/commands to 87 | generate the bindings. This approach should be preferred if the bindings are needed 88 | by the C/C++ side. 89 | 90 | Corrosion currently provides 2 experimental functions to integrate cbindgen and cxx into 91 | the build process. They are not 100% production ready yet, but should work well as a 92 | template on how to integrate generating bindings into your build process. 93 | 94 | Todo: expand this documentation and link to other resources. 95 | 96 | [bindgen]: https://rust-lang.github.io/rust-bindgen/ 97 | [cbindgen]: https://github.com/eqrion/cbindgen 98 | [cxx]: https://cxx.rs/ 99 | [autocxx]: https://google.github.io/autocxx/index.html 100 | -------------------------------------------------------------------------------- /doc/src/common_issues.md: -------------------------------------------------------------------------------- 1 | # Commonly encountered (Non-Corrosion) Issues 2 | 3 | ## Table of Contents 4 | 5 | - [Linking Debug C/C++ libraries into Rust fails on Windows MSVC targets](#linking-debug-cc-libraries-into-rust-fails-on-windows-msvc-targets) 6 | - [Linking Rust static libraries into Debug C/C++ binaries fails on Windows MSVC targets](#linking-rust-static-libraries-into-debug-cc-binaries-fails-on-windows-msvc-targets) 7 | - [Missing `soname` on Linux for `cdylibs`](#missing-soname-on-linux-for-cdylibs) 8 | - [Missing `install_name` on MacOS for `ccdylibs` / Hardcoded references to the build-directory](#missing-installname-on-macos-for-ccdylibs--hardcoded-references-to-the-build-directory) 9 | - [CMake Error (target_link_libraries): Cannot find source file](#cmake-error-target_link_libraries-cannot-find-source-file) 10 | 11 | ## Linking Debug C/C++ libraries into Rust fails on Windows MSVC targets 12 | 13 | `rustc` always links against the non-debug Windows runtime on `*-msvc` targets. 14 | This is tracked [in this issue](https://github.com/rust-lang/rust/issues/39016) 15 | and could be fixed upstream. 16 | 17 | A typical error message for this issue is: 18 | 19 | ``` 20 | Compiling rust_bin v0.1.0 (D:\a\corrosion\corrosion\test\cxxbridge\cxxbridge_cpp2rust\rust) 21 | error: linking with `link.exe` failed: exit code: 1319 22 | [ redacted ] 23 | = note: cxxbridge-cpp.lib(lib.cpp.obj) : error LNK2038: mismatch detected for '_ITERATOR_DEBUG_LEVEL': value '2' doesn't match value '0' in libcxx-bafec361a1a30317.rlib(cxx.o) 24 | 25 | cxxbridge-cpp.lib(lib.cpp.obj) : error LNK2038: mismatch detected for 'RuntimeLibrary': value 'MDd_DynamicDebug' doesn't match value 'MD_DynamicRelease' in libcxx-bafec361a1a30317.rlib(cxx.o) 26 | 27 | cpp_lib.lib(cpplib.cpp.obj) : error LNK2038: mismatch detected for '_ITERATOR_DEBUG_LEVEL': value '2' doesn't match value '0' in libcxx-bafec361a1a30317.rlib(cxx.o) 28 | 29 | cpp_lib.lib(cpplib.cpp.obj) : error LNK2038: mismatch detected for 'RuntimeLibrary': value 'MDd_DynamicDebug' doesn't match value 'MD_DynamicRelease' in libcxx-bafec361a1a30317.rlib(cxx.o) 30 | 31 | msvcrt.lib(initializers.obj) : warning LNK4098: defaultlib 'msvcrtd.lib' conflicts with use of other libs; use /NODEFAULTLIB:library 32 | ``` 33 | 34 | ### Solutions 35 | 36 | One solution is to also use the non-debug version when building the C/C++ libraries. 37 | You can set the [MSVC_RUNTIME_LIBRARY] target properties of your C/C++ libraries to the non-debug variants. 38 | By default you will probably want to select the `MultiThreadedDLL` variant, unless you specified 39 | [`-Ctarget-feature=+crt-static`](https://rust-lang.github.io/rfcs/1721-crt-static.html) in your 40 | `RUSTFLAGS`. 41 | 42 | 43 | [MSVC_RUNTIME_LIBRARY]: https://cmake.org/cmake/help/latest/prop_tgt/MSVC_RUNTIME_LIBRARY.html#prop_tgt:MSVC_RUNTIME_LIBRARY 44 | 45 | ## Linking Rust static libraries into Debug C/C++ binaries fails on Windows MSVC targets 46 | 47 | This issue is quite similar to the previous one, except that this time it's a Rust library being linked 48 | into a C/C++ target. If it's 100% only Rust code you likely won't even have any issues. 49 | However, if somewhere in the dependency graph C/C++ code is built and linked into your Rust library, 50 | you will likely encounter this issue. Please note, that using [cxx] counts as using C++ code and will 51 | lead to this issue. 52 | 53 | The previous solution should also work for this case, but additionally you [may also 54 | have success](https://github.com/rust-lang/rust/issues/39016#issuecomment-853964918) by using 55 | `corrosion_set_env_vars(your_rust_lib "CFLAGS=-MDd" "CXXFLAGS=-MDd")` (or `-MTd` for a statically linked 56 | runtime). 57 | For debug builds, this is likely to be the preferable solution. It assumes that downstream C/C++ code 58 | is built by the `cc` crate, which respects the `CFLAGS` and `CXXFLAGS` environment variables. 59 | 60 | [cxx]: https://github.com/dtolnay/cxx 61 | 62 | 63 | ## Missing `soname` on Linux for `cdylibs` 64 | 65 | Cargo doesn't support setting the `soname` field for cdylib, which may cause issues. 66 | You can set the soname manually by passing a linker-flag such as `-Clink-arg=-Wl,-soname,libyour_crate.so` 67 | to the linker via `corrosion_add_target_local_rustflags()` and additionally seting the `IMPORTED_SONAME` 68 | property on the import CMake target: 69 | ``` 70 | set_target_properties(your_crate-shared PROPERTIES IMPORTED_SONAME libyour_crate.so) 71 | ``` 72 | Replace `your_crate` with the name of your shared library as defined in the `[lib]` section of your Cargo.toml 73 | Manifest file. 74 | 75 | Attention: The Linux section may not be entirely correct, maybe `$ORIGIN` needs to be added to the linker arguments. 76 | Feel free to open a pull-request with corrections. 77 | 78 | ## Missing `install_name` on MacOS for `ccdylibs` / Hardcoded references to the build-directory 79 | 80 | The solution here is essentially the same as in the previous section. 81 | ``` 82 | corrosion_add_target_local_rustflags(your_crate -Clink-arg=-Wl,-install_name,@rpath/libyour_crate.dylib,-current_version,${PROJECT_VERSION_MAJOR}.${PROJECT_VERSION_MINOR},-compatibility_version,${PROJECT_VERSION_MAJOR}.0) 83 | set_target_properties(your_crate-shared PROPERTIES IMPORTED_NO_SONAME 0) 84 | set_target_properties(your_crate-shared PROPERTIES IMPORTED_SONAME libyour_crate.dylib) 85 | ``` 86 | When building binaries using this shared library, you should set the build rpath to the output directory of 87 | your shared library, e.g. by setting `set(CMAKE_BUILD_RPATH ${YOUR_CUSTOM_OUTPUT_DIRECTORY})` before adding 88 | executables. 89 | For a practical example, you may look at [Slint PR 2455](https://github.com/slint-ui/slint/pull/2455). 90 | 91 | ## CMake Error (target_link_libraries): Cannot find source file 92 | 93 | When using `corrosion_add_cxxbridge`, you may encounter an error similar to this in targets that depend on the cxxbridge target: 94 | 95 | ```diff 96 | - CMake Error at ...../CMakeLists.txt:61 (target_link_libraries): 97 | - Cannot find source file: 98 | - 99 | - ...../corrosion_generated/..../somefile.h 100 | - 101 | - Tried extensions .c .C .c++ .cc .cpp .cxx .cu .mpp .m .M .mm .ixx .cppm 102 | - .ccm .cxxm .c++m .h .hh .h++ .hm .hpp .hxx .in .txx .f .F .for .f77 .f90 103 | - .f95 .f03 .hip .ispc 104 | ``` 105 | 106 | Where `somefile.h` should be generated by CXX via `corrosion_add_cxxbridge`. 107 | In theory, CMake should already know that this is a generated file and just generate it when needed. 108 | 109 | However, in older versions of CMake the `GENERATED` property isn't correctly propagated. 110 | See also: [https://gitlab.kitware.com/cmake/cmake/-/issues/18399](https://gitlab.kitware.com/cmake/cmake/-/issues/18399) 111 | 112 | This has since been fixed with CMake 3.20: [https://cmake.org/cmake/help/v3.20/policy/CMP0118.html](https://cmake.org/cmake/help/latest/command/cmake_policy.html#version) 113 | However, the CMake policy CMP0118 must be enabled **in any dependent CMakeLists.txt** for the fix to work. 114 | 115 | The best fix is to call: 116 | ```cmake 117 | cmake_minimium_required(VERSION 3.20 FATAL_ERROR) 118 | # (or any other version above 3.20) 119 | ``` 120 | As described [here](https://cmake.org/cmake/help/latest/command/cmake_policy.html#version), this implies a call to `cmake_policy` which enables CMP0118. 121 | 122 | Unfortunately this must be done in all (transitive) downstream dependencies that link to the bridge target, so cannot be done from within corrosion automatically. 123 | -------------------------------------------------------------------------------- /test/output directory/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | set(configure_cmake_args) 2 | if(CMAKE_C_COMPILER) 3 | list(APPEND configure_cmake_args "C_COMPILER" "${CMAKE_C_COMPILER}") 4 | endif() 5 | if(CMAKE_CXX_COMPILER) 6 | list(APPEND configure_cmake_args "CXX_COMPILER" "${CMAKE_CXX_COMPILER}") 7 | endif() 8 | if(CMAKE_C_COMPILER_TARGET) 9 | list(APPEND configure_cmake_args "C_COMPILER_TARGET" "${CMAKE_C_COMPILER_TARGET}") 10 | endif() 11 | if(CMAKE_CXX_COMPILER_TARGET) 12 | list(APPEND configure_cmake_args "CXX_COMPILER_TARGET" "${CMAKE_CXX_COMPILER_TARGET}") 13 | endif() 14 | if(CMAKE_GENERATOR_PLATFORM) 15 | list(APPEND configure_cmake_args "GENERATOR_PLATFORM" "${CMAKE_GENERATOR_PLATFORM}") 16 | endif() 17 | if(CMAKE_OSX_ARCHITECTURES) 18 | list(APPEND configure_cmake_args OSX_ARCHITECTURES "${CMAKE_OSX_ARCHITECTURES}") 19 | endif() 20 | if(CMAKE_OSX_SYSROOT) 21 | list(APPEND configure_cmake_args OSX_SYSROOT "${CMAKE_OSX_SYSROOT}") 22 | endif() 23 | if(CMAKE_TOOLCHAIN_FILE) 24 | list(APPEND configure_cmake_args TOOLCHAIN_FILE "${CMAKE_TOOLCHAIN_FILE}") 25 | endif() 26 | 27 | add_test(NAME "output_directory_build" 28 | COMMAND 29 | ${CMAKE_COMMAND} 30 | -P "${CMAKE_SOURCE_DIR}/test/ConfigureAndBuild.cmake" 31 | SOURCE_DIR "${CMAKE_CURRENT_SOURCE_DIR}/output directory" 32 | BINARY_DIR "${CMAKE_CURRENT_BINARY_DIR}/build" 33 | GENERATOR "${CMAKE_GENERATOR}" 34 | RUST_TOOLCHAIN "${Rust_TOOLCHAIN}" 35 | CARGO_TARGET "${Rust_CARGO_TARGET}" 36 | SYSTEM_NAME "${CMAKE_SYSTEM_NAME}" 37 | ${configure_cmake_args} 38 | COMMAND_EXPAND_LISTS 39 | ) 40 | set_tests_properties("output_directory_build" PROPERTIES FIXTURES_SETUP "build_fixture_output_directory") 41 | if(CORROSION_TESTS_INSTALL_CORROSION) 42 | set_tests_properties("output_directory_build" PROPERTIES FIXTURES_REQUIRED "fixture_corrosion_install") 43 | endif() 44 | 45 | get_cmake_property(IS_MULTI_CONFIG GENERATOR_IS_MULTI_CONFIG) 46 | 47 | if (IS_MULTI_CONFIG) 48 | set(config_path_str "$/") 49 | else() 50 | set(config_path_str "") 51 | endif() 52 | 53 | foreach(output_approach targetprop var targetprop_pdb_fallback) 54 | if(output_approach STREQUAL "targetprop") 55 | set(rust_proj_suffix "1") 56 | elseif(output_approach STREQUAL "var") 57 | set(rust_proj_suffix "2") 58 | elseif(output_approach STREQUAL "targetprop_pdb_fallback") 59 | set(rust_proj_suffix "3") 60 | else() 61 | message(FATAL_ERROR "specify rust project suffix for new output approach ${output_approach}") 62 | endif() 63 | 64 | set(bin_name "rust_bin${rust_proj_suffix}${CMAKE_EXECUTABLE_SUFFIX}") 65 | 66 | add_test(NAME output_directory_bin_${output_approach} 67 | COMMAND 68 | "${CMAKE_COMMAND}" 69 | -P "${CMAKE_CURRENT_SOURCE_DIR}/../TestFileExists.cmake" 70 | "${CMAKE_CURRENT_BINARY_DIR}/build/custom_bin_${output_approach}/${config_path_str}${bin_name}" 71 | ) 72 | set_tests_properties("output_directory_bin_${output_approach}" PROPERTIES FIXTURES_REQUIRED "build_fixture_output_directory") 73 | 74 | set(lib_name "rust_lib${rust_proj_suffix}") 75 | 76 | set(static_lib_name "${CMAKE_STATIC_LIBRARY_PREFIX}${lib_name}${CMAKE_STATIC_LIBRARY_SUFFIX}") 77 | 78 | add_test(NAME output_directory_staticlib_${output_approach} 79 | COMMAND 80 | "${CMAKE_COMMAND}" 81 | -P "${CMAKE_CURRENT_SOURCE_DIR}/../TestFileExists.cmake" 82 | "${CMAKE_CURRENT_BINARY_DIR}/build/custom_archive_${output_approach}/${config_path_str}${static_lib_name}" 83 | ) 84 | set_tests_properties("output_directory_staticlib_${output_approach}" PROPERTIES FIXTURES_REQUIRED "build_fixture_output_directory") 85 | 86 | if(MINGW) 87 | # Windows-GNU defines "lib" as prefix for DLLs, but cargo creates foo.dll instead of libfoo.dll 88 | set(dynamic_lib_prefix "") 89 | else() 90 | set(dynamic_lib_prefix "${CMAKE_SHARED_LIBRARY_PREFIX}") 91 | endif() 92 | set(dynamic_lib_name "${dynamic_lib_prefix}${lib_name}${CMAKE_SHARED_LIBRARY_SUFFIX}") 93 | 94 | add_test(NAME output_directory_cdylib_${output_approach} 95 | COMMAND 96 | "${CMAKE_COMMAND}" 97 | -P "${CMAKE_CURRENT_SOURCE_DIR}/../TestFileExists.cmake" 98 | "${CMAKE_CURRENT_BINARY_DIR}/build/custom_lib_${output_approach}/${config_path_str}${dynamic_lib_name}" 99 | ) 100 | set_tests_properties("output_directory_cdylib_${output_approach}" PROPERTIES FIXTURES_REQUIRED "build_fixture_output_directory") 101 | 102 | if(WIN32) 103 | set(implib_name ${CMAKE_IMPORT_LIBRARY_PREFIX}${lib_name}${CMAKE_IMPORT_LIBRARY_SUFFIX}) 104 | 105 | add_test(NAME output_directory_implib_${output_approach} 106 | COMMAND 107 | "${CMAKE_COMMAND}" 108 | -P "${CMAKE_CURRENT_SOURCE_DIR}/../TestFileExists.cmake" 109 | # Implib is an ARCHIVE artifact, see: 110 | # https://cmake.org/cmake/help/v3.25/manual/cmake-buildsystem.7.html#archive-output-artifacts 111 | "${CMAKE_CURRENT_BINARY_DIR}/build/custom_archive_${output_approach}/${config_path_str}${implib_name}" 112 | ) 113 | set_tests_properties("output_directory_implib_${output_approach}" PROPERTIES FIXTURES_REQUIRED "build_fixture_output_directory") 114 | 115 | if(MSVC) 116 | if(output_approach STREQUAL "targetprop") 117 | set(expected_lib_pdb_path "custom_lib_pdb_targetprop") 118 | set(expected_bin_pdb_path "custom_bin_pdb_targetprop") 119 | elseif(output_approach STREQUAL "var") 120 | # When using a CMAKE_ variable instead of a target property, both targets 121 | # end up in the same directory. 122 | set(expected_lib_pdb_path "custom_binlib_pdb_var") 123 | set(expected_bin_pdb_path "custom_binlib_pdb_var") 124 | elseif(output_approach STREQUAL "targetprop_pdb_fallback") 125 | set(expected_lib_pdb_path "custom_lib_targetprop_pdb_fallback") 126 | set(expected_bin_pdb_path "custom_bin_targetprop_pdb_fallback") 127 | else() 128 | message(FATAL_ERROR "specify rust project suffix for new output approach ${output_approach}") 129 | endif() 130 | 131 | set(lib_pdb_name "${lib_name}.pdb") 132 | add_test(NAME output_directory_cdylib_pdb_${output_approach} 133 | COMMAND 134 | "${CMAKE_COMMAND}" 135 | -P "${CMAKE_CURRENT_SOURCE_DIR}/../TestFileExists.cmake" 136 | "${CMAKE_CURRENT_BINARY_DIR}/build/${expected_lib_pdb_path}/${config_path_str}${lib_pdb_name}" 137 | ) 138 | set_tests_properties("output_directory_cdylib_pdb_${output_approach}" PROPERTIES FIXTURES_REQUIRED "build_fixture_output_directory") 139 | 140 | set(bin_pdb_name "rust_bin${rust_proj_suffix}.pdb") 141 | add_test(NAME output_directory_bin_pdb_${output_approach} 142 | COMMAND 143 | "${CMAKE_COMMAND}" 144 | -P "${CMAKE_CURRENT_SOURCE_DIR}/../TestFileExists.cmake" 145 | "${CMAKE_CURRENT_BINARY_DIR}/build/${expected_bin_pdb_path}/${config_path_str}${bin_pdb_name}" 146 | ) 147 | set_tests_properties("output_directory_bin_pdb_${output_approach}" PROPERTIES FIXTURES_REQUIRED "build_fixture_output_directory") 148 | endif() 149 | endif() 150 | 151 | endforeach() 152 | 153 | add_test(NAME postbuild_custom_command 154 | COMMAND 155 | "${CMAKE_COMMAND}" 156 | -P "${CMAKE_CURRENT_SOURCE_DIR}/../TestFileExists.cmake" 157 | "${CMAKE_CURRENT_BINARY_DIR}/build/another_dir/moved_bin" 158 | ) 159 | set_tests_properties("postbuild_custom_command" PROPERTIES FIXTURES_REQUIRED "build_fixture_output_directory") 160 | 161 | add_test(NAME "output_directory_cleanup" COMMAND "${CMAKE_COMMAND}" -E remove_directory "${CMAKE_CURRENT_BINARY_DIR}/build") 162 | set_tests_properties("output_directory_cleanup" PROPERTIES FIXTURES_CLEANUP "build_fixture_output_directory") 163 | 164 | #################################### 165 | # output_directory_config 166 | #################################### 167 | 168 | 169 | corrosion_tests_add_test(output_directory_config "consumer") 170 | 171 | set_tests_properties("output_directory_config_run_consumer" PROPERTIES PASS_REGULAR_EXPRESSION 172 | "^Hello from output_directory_config_test_executable" 173 | ) 174 | 175 | -------------------------------------------------------------------------------- /test/cxxbridge/cxxbridge_exported_impls/rust/Cargo.lock: -------------------------------------------------------------------------------- 1 | # This file is automatically @generated by Cargo. 2 | # It is not intended for manual editing. 3 | version = 4 4 | 5 | [[package]] 6 | name = "anstyle" 7 | version = "1.0.11" 8 | source = "registry+https://github.com/rust-lang/crates.io-index" 9 | checksum = "862ed96ca487e809f1c8e5a8447f6ee2cf102f846893800b20cebdf541fc6bbd" 10 | 11 | [[package]] 12 | name = "cc" 13 | version = "1.2.39" 14 | source = "registry+https://github.com/rust-lang/crates.io-index" 15 | checksum = "e1354349954c6fc9cb0deab020f27f783cf0b604e8bb754dc4658ecf0d29c35f" 16 | dependencies = [ 17 | "find-msvc-tools", 18 | "shlex", 19 | ] 20 | 21 | [[package]] 22 | name = "clap" 23 | version = "4.5.48" 24 | source = "registry+https://github.com/rust-lang/crates.io-index" 25 | checksum = "e2134bb3ea021b78629caa971416385309e0131b351b25e01dc16fb54e1b5fae" 26 | dependencies = [ 27 | "clap_builder", 28 | ] 29 | 30 | [[package]] 31 | name = "clap_builder" 32 | version = "4.5.48" 33 | source = "registry+https://github.com/rust-lang/crates.io-index" 34 | checksum = "c2ba64afa3c0a6df7fa517765e31314e983f51dda798ffba27b988194fb65dc9" 35 | dependencies = [ 36 | "anstyle", 37 | "clap_lex", 38 | "strsim", 39 | ] 40 | 41 | [[package]] 42 | name = "clap_lex" 43 | version = "0.7.5" 44 | source = "registry+https://github.com/rust-lang/crates.io-index" 45 | checksum = "b94f61472cee1439c0b966b47e3aca9ae07e45d070759512cd390ea2bebc6675" 46 | 47 | [[package]] 48 | name = "codespan-reporting" 49 | version = "0.12.0" 50 | source = "registry+https://github.com/rust-lang/crates.io-index" 51 | checksum = "fe6d2e5af09e8c8ad56c969f2157a3d4238cebc7c55f0a517728c38f7b200f81" 52 | dependencies = [ 53 | "serde", 54 | "termcolor", 55 | "unicode-width", 56 | ] 57 | 58 | [[package]] 59 | name = "cxx" 60 | version = "1.0.186" 61 | source = "registry+https://github.com/rust-lang/crates.io-index" 62 | checksum = "4e9c4fe7f2f5dc5c62871a1b43992d197da6fa1394656a94276ac2894a90a6fe" 63 | dependencies = [ 64 | "cc", 65 | "cxx-build", 66 | "cxxbridge-cmd", 67 | "cxxbridge-flags", 68 | "cxxbridge-macro", 69 | "foldhash", 70 | "link-cplusplus", 71 | ] 72 | 73 | [[package]] 74 | name = "cxx-build" 75 | version = "1.0.186" 76 | source = "registry+https://github.com/rust-lang/crates.io-index" 77 | checksum = "b5cf2909d37d80633ddd208676fc27c2608a7f035fff69c882421168038b26dd" 78 | dependencies = [ 79 | "cc", 80 | "codespan-reporting", 81 | "indexmap", 82 | "proc-macro2", 83 | "quote", 84 | "scratch", 85 | "syn", 86 | ] 87 | 88 | [[package]] 89 | name = "cxxbridge-cmd" 90 | version = "1.0.186" 91 | source = "registry+https://github.com/rust-lang/crates.io-index" 92 | checksum = "077f5ee3d3bfd8d27f83208fdaa96ddd50af7f096c77077cc4b94da10bfacefd" 93 | dependencies = [ 94 | "clap", 95 | "codespan-reporting", 96 | "indexmap", 97 | "proc-macro2", 98 | "quote", 99 | "syn", 100 | ] 101 | 102 | [[package]] 103 | name = "cxxbridge-flags" 104 | version = "1.0.186" 105 | source = "registry+https://github.com/rust-lang/crates.io-index" 106 | checksum = "b0108748615125b9f2e915dfafdffcbdabbca9b15102834f6d7e9a768f2f2864" 107 | 108 | [[package]] 109 | name = "cxxbridge-macro" 110 | version = "1.0.186" 111 | source = "registry+https://github.com/rust-lang/crates.io-index" 112 | checksum = "e6e896681ef9b8dc462cfa6961d61909704bde0984b30bcb4082fe102b478890" 113 | dependencies = [ 114 | "indexmap", 115 | "proc-macro2", 116 | "quote", 117 | "rustversion", 118 | "syn", 119 | ] 120 | 121 | [[package]] 122 | name = "equivalent" 123 | version = "1.0.2" 124 | source = "registry+https://github.com/rust-lang/crates.io-index" 125 | checksum = "877a4ace8713b0bcf2a4e7eec82529c029f1d0619886d18145fea96c3ffe5c0f" 126 | 127 | [[package]] 128 | name = "find-msvc-tools" 129 | version = "0.1.2" 130 | source = "registry+https://github.com/rust-lang/crates.io-index" 131 | checksum = "1ced73b1dacfc750a6db6c0a0c3a3853c8b41997e2e2c563dc90804ae6867959" 132 | 133 | [[package]] 134 | name = "foldhash" 135 | version = "0.2.0" 136 | source = "registry+https://github.com/rust-lang/crates.io-index" 137 | checksum = "77ce24cb58228fbb8aa041425bb1050850ac19177686ea6e0f41a70416f56fdb" 138 | 139 | [[package]] 140 | name = "hashbrown" 141 | version = "0.16.0" 142 | source = "registry+https://github.com/rust-lang/crates.io-index" 143 | checksum = "5419bdc4f6a9207fbeba6d11b604d481addf78ecd10c11ad51e76c2f6482748d" 144 | 145 | [[package]] 146 | name = "indexmap" 147 | version = "2.11.4" 148 | source = "registry+https://github.com/rust-lang/crates.io-index" 149 | checksum = "4b0f83760fb341a774ed326568e19f5a863af4a952def8c39f9ab92fd95b88e5" 150 | dependencies = [ 151 | "equivalent", 152 | "hashbrown", 153 | ] 154 | 155 | [[package]] 156 | name = "link-cplusplus" 157 | version = "1.0.12" 158 | source = "registry+https://github.com/rust-lang/crates.io-index" 159 | checksum = "7f78c730aaa7d0b9336a299029ea49f9ee53b0ed06e9202e8cb7db9bae7b8c82" 160 | dependencies = [ 161 | "cc", 162 | ] 163 | 164 | [[package]] 165 | name = "proc-macro2" 166 | version = "1.0.101" 167 | source = "registry+https://github.com/rust-lang/crates.io-index" 168 | checksum = "89ae43fd86e4158d6db51ad8e2b80f313af9cc74f5c0e03ccb87de09998732de" 169 | dependencies = [ 170 | "unicode-ident", 171 | ] 172 | 173 | [[package]] 174 | name = "quote" 175 | version = "1.0.40" 176 | source = "registry+https://github.com/rust-lang/crates.io-index" 177 | checksum = "1885c039570dc00dcb4ff087a89e185fd56bae234ddc7f056a945bf36467248d" 178 | dependencies = [ 179 | "proc-macro2", 180 | ] 181 | 182 | [[package]] 183 | name = "rust_lib" 184 | version = "0.1.0" 185 | dependencies = [ 186 | "cxx", 187 | ] 188 | 189 | [[package]] 190 | name = "rustversion" 191 | version = "1.0.22" 192 | source = "registry+https://github.com/rust-lang/crates.io-index" 193 | checksum = "b39cdef0fa800fc44525c84ccb54a029961a8215f9619753635a9c0d2538d46d" 194 | 195 | [[package]] 196 | name = "scratch" 197 | version = "1.0.9" 198 | source = "registry+https://github.com/rust-lang/crates.io-index" 199 | checksum = "d68f2ec51b097e4c1a75b681a8bec621909b5e91f15bb7b840c4f2f7b01148b2" 200 | 201 | [[package]] 202 | name = "serde" 203 | version = "1.0.228" 204 | source = "registry+https://github.com/rust-lang/crates.io-index" 205 | checksum = "9a8e94ea7f378bd32cbbd37198a4a91436180c5bb472411e48b5ec2e2124ae9e" 206 | dependencies = [ 207 | "serde_core", 208 | "serde_derive", 209 | ] 210 | 211 | [[package]] 212 | name = "serde_core" 213 | version = "1.0.228" 214 | source = "registry+https://github.com/rust-lang/crates.io-index" 215 | checksum = "41d385c7d4ca58e59fc732af25c3983b67ac852c1a25000afe1175de458b67ad" 216 | dependencies = [ 217 | "serde_derive", 218 | ] 219 | 220 | [[package]] 221 | name = "serde_derive" 222 | version = "1.0.228" 223 | source = "registry+https://github.com/rust-lang/crates.io-index" 224 | checksum = "d540f220d3187173da220f885ab66608367b6574e925011a9353e4badda91d79" 225 | dependencies = [ 226 | "proc-macro2", 227 | "quote", 228 | "syn", 229 | ] 230 | 231 | [[package]] 232 | name = "shlex" 233 | version = "1.3.0" 234 | source = "registry+https://github.com/rust-lang/crates.io-index" 235 | checksum = "0fda2ff0d084019ba4d7c6f371c95d8fd75ce3524c3cb8fb653a3023f6323e64" 236 | 237 | [[package]] 238 | name = "strsim" 239 | version = "0.11.1" 240 | source = "registry+https://github.com/rust-lang/crates.io-index" 241 | checksum = "7da8b5736845d9f2fcb837ea5d9e2628564b3b043a70948a3f0b778838c5fb4f" 242 | 243 | [[package]] 244 | name = "syn" 245 | version = "2.0.106" 246 | source = "registry+https://github.com/rust-lang/crates.io-index" 247 | checksum = "ede7c438028d4436d71104916910f5bb611972c5cfd7f89b8300a8186e6fada6" 248 | dependencies = [ 249 | "proc-macro2", 250 | "quote", 251 | "unicode-ident", 252 | ] 253 | 254 | [[package]] 255 | name = "termcolor" 256 | version = "1.4.1" 257 | source = "registry+https://github.com/rust-lang/crates.io-index" 258 | checksum = "06794f8f6c5c898b3275aebefa6b8a1cb24cd2c6c79397ab15774837a0bc5755" 259 | dependencies = [ 260 | "winapi-util", 261 | ] 262 | 263 | [[package]] 264 | name = "unicode-ident" 265 | version = "1.0.19" 266 | source = "registry+https://github.com/rust-lang/crates.io-index" 267 | checksum = "f63a545481291138910575129486daeaf8ac54aee4387fe7906919f7830c7d9d" 268 | 269 | [[package]] 270 | name = "unicode-width" 271 | version = "0.2.1" 272 | source = "registry+https://github.com/rust-lang/crates.io-index" 273 | checksum = "4a1a07cc7db3810833284e8d372ccdc6da29741639ecc70c9ec107df0fa6154c" 274 | 275 | [[package]] 276 | name = "winapi-util" 277 | version = "0.1.11" 278 | source = "registry+https://github.com/rust-lang/crates.io-index" 279 | checksum = "c2a7b1c03c876122aa43f3020e6c3c3ee5c05081c9a00739faf7503aeba10d22" 280 | dependencies = [ 281 | "windows-sys", 282 | ] 283 | 284 | [[package]] 285 | name = "windows-link" 286 | version = "0.2.0" 287 | source = "registry+https://github.com/rust-lang/crates.io-index" 288 | checksum = "45e46c0661abb7180e7b9c281db115305d49ca1709ab8242adf09666d2173c65" 289 | 290 | [[package]] 291 | name = "windows-sys" 292 | version = "0.61.1" 293 | source = "registry+https://github.com/rust-lang/crates.io-index" 294 | checksum = "6f109e41dd4a3c848907eb83d5a42ea98b3769495597450cf6d153507b166f0f" 295 | dependencies = [ 296 | "windows-link", 297 | ] 298 | -------------------------------------------------------------------------------- /test/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | # This option is currently used to prevent recursion 2 | option(CORROSION_TESTS "Enable Corrosion tests" ON) 3 | mark_as_advanced(CORROSION_TESTS) 4 | if(NOT CORROSION_TESTS) 5 | return() 6 | endif() 7 | 8 | option(CORROSION_TESTS_CXXBRIDGE 9 | "Build cxxbridge tests which requires cxxbridge executable being available" 10 | OFF) 11 | option(CORROSION_TESTS_KEEP_BUILDDIRS 12 | "By default corrosion tests will cleanup after themselves. This option limits the cleaning up to the 13 | target directories and will keep the build directories, which may be useful for caching." 14 | OFF) 15 | mark_as_advanced(CORROSION_TESTS_NO_CLEANUP) 16 | 17 | set(test_install_path "${CMAKE_CURRENT_BINARY_DIR}/test-install-corrosion") 18 | file(REAL_PATH "${CMAKE_CURRENT_SOURCE_DIR}/.." corrosion_source_dir) 19 | set(test_header_contents 20 | "option(CORROSION_TESTS_FIND_CORROSION \"Use Corrosion as a subdirectory\" OFF)" 21 | "if (CORROSION_TESTS_FIND_CORROSION)" 22 | " set(CMAKE_PREFIX_PATH \"${test_install_path}\" CACHE INTERNAL \"\" FORCE)" 23 | " find_package(Corrosion REQUIRED PATHS \"${test_install_path}\" NO_CMAKE_SYSTEM_PATH)" 24 | "else()" 25 | " add_subdirectory(\"${corrosion_source_dir}\" corrosion)" 26 | "endif()" 27 | ) 28 | 29 | string(REPLACE ";" "\n" test_header_contents "${test_header_contents}") 30 | 31 | file(WRITE test_header.cmake "${test_header_contents}") 32 | 33 | option(CORROSION_TESTS_INSTALL_CORROSION 34 | "Install Corrosion to a test directory and let tests use the installed Corrosion" 35 | OFF) 36 | if(CORROSION_TESTS_INSTALL_CORROSION) 37 | add_test(NAME "install_corrosion_configure" 38 | COMMAND 39 | ${CMAKE_COMMAND} 40 | -S "${CMAKE_CURRENT_SOURCE_DIR}/.." 41 | -B "${CMAKE_CURRENT_BINARY_DIR}/build-corrosion" 42 | -DCORROSION_VERBOSE_OUTPUT=ON 43 | -DCORROSION_TESTS=OFF 44 | -DCMAKE_BUILD_TYPE=Release 45 | -G${CMAKE_GENERATOR} 46 | "-DCMAKE_INSTALL_PREFIX=${test_install_path}" 47 | ) 48 | add_test(NAME "install_corrosion_build" 49 | COMMAND 50 | ${CMAKE_COMMAND} --build "${CMAKE_CURRENT_BINARY_DIR}/build-corrosion" --config Release 51 | ) 52 | add_test(NAME "install_corrosion_install" 53 | COMMAND 54 | ${CMAKE_COMMAND} --install "${CMAKE_CURRENT_BINARY_DIR}/build-corrosion" --config Release 55 | ) 56 | set_tests_properties("install_corrosion_configure" PROPERTIES FIXTURES_SETUP "fixture_corrosion_configure") 57 | set_tests_properties("install_corrosion_build" PROPERTIES FIXTURES_SETUP "fixture_corrosion_build") 58 | set_tests_properties("install_corrosion_build" PROPERTIES FIXTURES_REQUIRED "fixture_corrosion_configure") 59 | set_tests_properties("install_corrosion_install" PROPERTIES FIXTURES_REQUIRED "fixture_corrosion_build") 60 | set_tests_properties("install_corrosion_install" PROPERTIES FIXTURES_SETUP "fixture_corrosion_install") 61 | 62 | add_test(NAME "install_corrosion_build_cleanup" COMMAND "${CMAKE_COMMAND}" -E remove_directory "${CMAKE_CURRENT_BINARY_DIR}/build-corrosion") 63 | set_tests_properties("install_corrosion_build_cleanup" PROPERTIES 64 | FIXTURES_CLEANUP 65 | "fixture_corrosion_configure;fixture_corrosion_build" 66 | ) 67 | 68 | add_test(NAME "install_corrosion_cleanup" COMMAND "${CMAKE_COMMAND}" -E remove_directory "${test_install_path}") 69 | set_tests_properties("install_corrosion_cleanup" PROPERTIES 70 | FIXTURES_CLEANUP 71 | "fixture_corrosion_configure;fixture_corrosion_build;fixture_corrosion_install" 72 | ) 73 | endif() 74 | 75 | function(corrosion_tests_add_test test_name bin_names) 76 | set(options "IS_HOSTBUILD") 77 | set(one_value_kewords "TEST_SRC_DIR") 78 | set(multi_value_keywords "") 79 | cmake_parse_arguments(PARSE_ARGV 2 TST "${options}" "${one_value_kewords}" "${multi_value_keywords}") 80 | set(pass_through_arguments "${TST_UNPARSED_ARGUMENTS}") 81 | 82 | # In the future we could add multiple tests here for different configurations (generator, build mode, rust version ...) 83 | # which would allow us to simplify the github job matrix 84 | if(TST_TEST_SRC_DIR) 85 | set(test_dir "${TST_TEST_SRC_DIR}") 86 | else() 87 | set(test_dir "${test_name}") 88 | endif() 89 | 90 | set(configure_cmake_args) 91 | if(CMAKE_C_COMPILER) 92 | list(APPEND configure_cmake_args "C_COMPILER" "${CMAKE_C_COMPILER}") 93 | endif() 94 | if(CMAKE_CXX_COMPILER) 95 | list(APPEND configure_cmake_args "CXX_COMPILER" "${CMAKE_CXX_COMPILER}") 96 | endif() 97 | if(CMAKE_C_COMPILER_TARGET) 98 | list(APPEND configure_cmake_args "C_COMPILER_TARGET" "${CMAKE_C_COMPILER_TARGET}") 99 | endif() 100 | if(CMAKE_CXX_COMPILER_TARGET) 101 | list(APPEND configure_cmake_args "CXX_COMPILER_TARGET" "${CMAKE_CXX_COMPILER_TARGET}") 102 | endif() 103 | if(CMAKE_GENERATOR_PLATFORM) 104 | list(APPEND configure_cmake_args "GENERATOR_PLATFORM" "${CMAKE_GENERATOR_PLATFORM}") 105 | endif() 106 | if(CMAKE_CROSSCOMPILING) 107 | list(APPEND configure_cmake_args SYSTEM_NAME "${CMAKE_SYSTEM_NAME}") 108 | endif() 109 | if(CMAKE_OSX_ARCHITECTURES) 110 | list(APPEND configure_cmake_args OSX_ARCHITECTURES "${CMAKE_OSX_ARCHITECTURES}") 111 | endif() 112 | if(CMAKE_OSX_SYSROOT) 113 | list(APPEND configure_cmake_args OSX_SYSROOT "${CMAKE_OSX_SYSROOT}") 114 | endif() 115 | if(CMAKE_TOOLCHAIN_FILE) 116 | list(APPEND configure_cmake_args TOOLCHAIN_FILE "${CMAKE_TOOLCHAIN_FILE}") 117 | endif() 118 | 119 | add_test(NAME "${test_name}_build" 120 | COMMAND 121 | ${CMAKE_COMMAND} 122 | -P "${CMAKE_SOURCE_DIR}/test/ConfigureAndBuild.cmake" 123 | SOURCE_DIR "${CMAKE_CURRENT_LIST_DIR}/${test_dir}" 124 | BINARY_DIR "${CMAKE_CURRENT_BINARY_DIR}/build-${test_name}" 125 | GENERATOR "${CMAKE_GENERATOR}" 126 | RUST_TOOLCHAIN "${Rust_TOOLCHAIN}" 127 | CARGO_TARGET "${Rust_CARGO_TARGET}" 128 | ${configure_cmake_args} 129 | ${pass_through_arguments} 130 | 131 | COMMAND_EXPAND_LISTS 132 | ) 133 | set_tests_properties("${test_name}_build" PROPERTIES FIXTURES_SETUP "build_fixture_${test_name}") 134 | if(CORROSION_TESTS_INSTALL_CORROSION) 135 | set_tests_properties("${test_name}_build" PROPERTIES FIXTURES_REQUIRED "fixture_corrosion_install") 136 | endif() 137 | foreach(bin ${bin_names}) 138 | if(WIN32) 139 | set(bin_filename "${bin}.exe") 140 | else() 141 | set(bin_filename "${bin}") 142 | endif() 143 | add_test(NAME "${test_name}_run_${bin}" COMMAND "${CMAKE_CURRENT_BINARY_DIR}/build-${test_name}/${bin_filename}") 144 | set_tests_properties("${test_name}_run_${bin}" PROPERTIES FIXTURES_REQUIRED "build_fixture_${test_name}") 145 | # CMAKE_CROSSCOMPILING is not set when cross-compiling with VS (via -A flag). 146 | # Todo: We could run x86 binaries on x64 hosts. 147 | if((CMAKE_CROSSCOMPILING OR CMAKE_VS_PLATFORM_NAME) AND NOT "${TST_IS_HOSTBUILD}") 148 | # Todo: In the future we could potentially run some tests with qemu. 149 | set_tests_properties("${test_name}_run_${bin}" PROPERTIES DISABLED TRUE) 150 | endif() 151 | endforeach() 152 | 153 | if(CORROSION_TESTS_KEEP_BUILDDIRS) 154 | add_test(NAME "${test_name}_cleanup_artifacts" 155 | COMMAND "${CMAKE_COMMAND}" --build "${CMAKE_CURRENT_BINARY_DIR}/build-${test_name}" --target clean 156 | ) 157 | add_test(NAME "${test_name}_cleanup_cargo" 158 | COMMAND "${CMAKE_COMMAND}" -E remove_directory "${CMAKE_CURRENT_BINARY_DIR}/build-${test_name}/cargo" 159 | ) 160 | set_tests_properties("${test_name}_cleanup_artifacts" PROPERTIES FIXTURES_CLEANUP "build_fixture_${test_name}") 161 | set_tests_properties("${test_name}_cleanup_cargo" PROPERTIES FIXTURES_CLEANUP "build_fixture_${test_name}") 162 | else() 163 | add_test(NAME "${test_name}_cleanup" COMMAND "${CMAKE_COMMAND}" -E remove_directory "${CMAKE_CURRENT_BINARY_DIR}/build-${test_name}") 164 | set_tests_properties("${test_name}_cleanup" PROPERTIES FIXTURES_CLEANUP "build_fixture_${test_name}") 165 | endif() 166 | endfunction() 167 | 168 | # Please keep this in alphabetical order. 169 | add_subdirectory(config_discovery) 170 | add_subdirectory(cargo_flags) 171 | add_subdirectory(cpp2rust) 172 | if(Rust_VERSION VERSION_GREATER_EQUAL "1.64.0") 173 | # Flag `--crate-type` is only supported since Rust 1.64.0 174 | add_subdirectory(crate_type) 175 | add_subdirectory(override_crate_type) 176 | endif() 177 | add_subdirectory(custom_profiles) 178 | if(NOT Rust_CROSSCOMPILING AND Rust_VERSION VERSION_GREATER_EQUAL "1.60.0") 179 | add_subdirectory(custom_target) 180 | endif() 181 | add_subdirectory(cbindgen) 182 | add_subdirectory(corrosion_install) 183 | add_subdirectory(cxxbridge) 184 | add_subdirectory(envvar) 185 | add_subdirectory(features) 186 | add_subdirectory(find_rust) 187 | add_subdirectory(gensource) 188 | add_subdirectory(hostbuild) 189 | add_subdirectory(multitarget) 190 | add_subdirectory(nostd) 191 | add_subdirectory("output directory") 192 | add_subdirectory(parse_target_triple) 193 | add_subdirectory(rust2cpp) 194 | add_subdirectory(rustflags) 195 | add_subdirectory(workspace) 196 | -------------------------------------------------------------------------------- /CMakePresets.json: -------------------------------------------------------------------------------- 1 | { 2 | "version": 3, 3 | "cmakeMinimumRequired": { 4 | "major": 3, 5 | "minor": 22, 6 | "patch": 0 7 | }, 8 | "configurePresets": [ 9 | { 10 | "name": "ninja", 11 | "hidden": true, 12 | "generator": "Ninja" 13 | }, 14 | { 15 | "name": "ninja-mc", 16 | "hidden": true, 17 | "generator": "Ninja Multi-Config" 18 | }, 19 | { 20 | "name": "make", 21 | "hidden": true, 22 | "generator": "Unix Makefiles" 23 | }, 24 | { 25 | "name": "vs-2019", 26 | "hidden": true, 27 | "generator": "Visual Studio 16 2019" 28 | }, 29 | { 30 | "name": "vs-2022", 31 | "hidden": true, 32 | "generator": "Visual Studio 17 2022" 33 | }, 34 | { 35 | "name": "windows-only", 36 | "hidden": true, 37 | "condition": { 38 | "type": "equals", 39 | "lhs": "${hostSystemName}", 40 | "rhs": "Windows" 41 | } 42 | }, 43 | { 44 | "name": "windows-10-cross", 45 | "hidden": true, 46 | "cacheVariables": { 47 | "CMAKE_SYSTEM_NAME": "Windows", 48 | "CMAKE_SYSTEM_VERSION": "10.0" 49 | }, 50 | "condition": { 51 | "type": "equals", 52 | "lhs": "${hostSystemName}", 53 | "rhs": "Windows" 54 | } 55 | }, 56 | { 57 | "name": "x86_64-pc-windows-msvc", 58 | "hidden": true, 59 | "inherits": ["windows-only"], 60 | "cacheVariables": { 61 | "Rust_CARGO_TARGET": "x86_64-pc-windows-msvc" 62 | } 63 | }, 64 | { 65 | "name": "i686-pc-windows-msvc", 66 | "hidden": true, 67 | "cacheVariables": { 68 | "Rust_CARGO_TARGET": "i686-pc-windows-msvc" 69 | } 70 | }, 71 | { 72 | "name": "aarch64-pc-windows-msvc", 73 | "hidden": true, 74 | "cacheVariables": { 75 | "Rust_CARGO_TARGET": "aarch64-pc-windows-msvc" 76 | } 77 | }, 78 | { 79 | "name": "x86_64-unknown-linux-gnu", 80 | "hidden": true, 81 | "cacheVariables": { 82 | "Rust_CARGO_TARGET": "x86_64-unknown-linux-gnu" 83 | } 84 | }, 85 | { 86 | "name": "i686-unknown-linux-gnu", 87 | "hidden": true, 88 | "cacheVariables": { 89 | "Rust_CARGO_TARGET": "i686-unknown-linux-gnu" 90 | } 91 | }, 92 | { 93 | "name": "aarch64-unknown-linux-gnu", 94 | "hidden": true, 95 | "cacheVariables": { 96 | "Rust_CARGO_TARGET": "aarch64-unknown-linux-gnu" 97 | } 98 | }, 99 | { 100 | "name": "x86_64-apple-darwin", 101 | "hidden": true, 102 | "cacheVariables": { 103 | "Rust_CARGO_TARGET": "x86_64-apple-darwin" 104 | } 105 | }, 106 | { 107 | "name": "aarch64-apple-darwin", 108 | "hidden": true, 109 | "cacheVariables": { 110 | "Rust_CARGO_TARGET": "aarch64-apple-darwin" 111 | } 112 | }, 113 | { 114 | "name": "vs-platform-arm64", 115 | "hidden": true, 116 | "inherits": ["aarch64-pc-windows-msvc","windows-10-cross"], 117 | "architecture": { 118 | "value": "ARM64" 119 | } 120 | }, 121 | { 122 | "name": "vs-platform-x64", 123 | "hidden": true, 124 | "inherits": ["x86_64-pc-windows-msvc"], 125 | "architecture": { 126 | "value": "x64" 127 | } 128 | }, 129 | { 130 | "name": "vs-platform-i686", 131 | "hidden": true, 132 | "inherits": ["i686-pc-windows-msvc", "windows-10-cross"], 133 | "architecture": { 134 | "value": "Win32" 135 | } 136 | }, 137 | { 138 | "name": "vs-2019-x86_64", 139 | "inherits": ["vs-platform-x64", "vs-2019"] 140 | }, 141 | { 142 | "name": "vs-2022-x86_64", 143 | "inherits": ["vs-platform-x64", "vs-2022"] 144 | }, 145 | { 146 | "name": "vs-2019-i686", 147 | "inherits": ["vs-platform-i686", "vs-2019"] 148 | }, 149 | { 150 | "name": "vs-2022-i686", 151 | "inherits": ["vs-platform-i686", "vs-2022"] 152 | }, 153 | { 154 | "name": "vs-2019-aarch64", 155 | "inherits": ["vs-platform-arm64", "vs-2019"] 156 | }, 157 | { 158 | "name": "vs-2022-aarch64", 159 | "inherits": ["vs-platform-arm64", "vs-2022"] 160 | }, 161 | { 162 | "name": "clang", 163 | "hidden": true, 164 | "cacheVariables": { 165 | "CMAKE_C_COMPILER": "clang", 166 | "CMAKE_CXX_COMPILER": "clang++" 167 | } 168 | }, 169 | { 170 | "name": "host-gcc", 171 | "hidden": true, 172 | "cacheVariables": { 173 | "CMAKE_C_COMPILER": "gcc", 174 | "CMAKE_CXX_COMPILER": "g++" 175 | } 176 | }, 177 | { 178 | "name": "clang-cl", 179 | "hidden": true, 180 | "inherits": ["windows-only"], 181 | "cacheVariables": { 182 | "CMAKE_C_COMPILER": "clang-cl", 183 | "CMAKE_CXX_COMPILER": "clang-cl" 184 | } 185 | }, 186 | { 187 | "name": "cl", 188 | "hidden": true, 189 | "inherits": ["windows-only"], 190 | "cacheVariables": { 191 | "CMAKE_C_COMPILER": "cl", 192 | "CMAKE_CXX_COMPILER": "cl" 193 | } 194 | }, 195 | { 196 | "name": "ninja-x86_64-pc-windows-msvc-cl", 197 | "inherits": ["ninja", "x86_64-pc-windows-msvc", "cl"] 198 | }, 199 | { 200 | "name": "ninja-x86_64-pc-windows-msvc-clang-cl", 201 | "inherits": ["ninja", "x86_64-pc-windows-msvc", "clang-cl"] 202 | }, 203 | { 204 | "name": "ninja-x86_64-pc-windows-msvc-clang", 205 | "inherits": ["ninja", "x86_64-pc-windows-msvc", "clang"] 206 | }, 207 | { 208 | "name": "ninja-i686-pc-windows-msvc-cl", 209 | "inherits": ["ninja", "i686-pc-windows-msvc", "cl", "windows-10-cross"] 210 | }, 211 | { 212 | "name": "ninja-i686-pc-windows-msvc-clang-cl", 213 | "inherits": ["ninja", "i686-pc-windows-msvc", "clang-cl", "windows-10-cross"] 214 | }, 215 | { 216 | "name": "ninja-i686-pc-windows-msvc-clang", 217 | "inherits": ["ninja", "i686-pc-windows-msvc", "clang", "windows-10-cross"] 218 | }, 219 | { 220 | "name": "ninja-aarch64-pc-windows-msvc-cl", 221 | "inherits": ["ninja", "aarch64-pc-windows-msvc", "cl", "windows-10-cross"] 222 | }, 223 | { 224 | "name": "ninja-aarch64-pc-windows-msvc-clang-cl", 225 | "inherits": ["ninja", "aarch64-pc-windows-msvc", "clang-cl", "windows-10-cross"] 226 | }, 227 | { 228 | "name": "ninja-aarch64-pc-windows-msvc-clang", 229 | "inherits": ["ninja", "aarch64-pc-windows-msvc", "clang", "windows-10-cross"] 230 | }, 231 | { 232 | "name": "ninja-x86_64-pc-windows-gnullvm", 233 | "inherits": ["ninja", "windows-only", "clang"], 234 | "toolchainFile": "${sourceDir}/.github/scripts/toolchains/x86_64-pc-windows-gnullvm.cmake" 235 | }, 236 | { 237 | "name": "make-x86_64-pc-windows-gnullvm", 238 | "inherits": ["make", "windows-only", "clang"], 239 | "toolchainFile": "${sourceDir}/.github/scripts/toolchains/x86_64-pc-windows-gnullvm.cmake" 240 | }, 241 | { 242 | "name": "ninja-x86_64-pc-windows-gnu-gcc", 243 | "inherits": ["ninja", "host-gcc", "windows-only"] 244 | }, 245 | { 246 | "name": "make-x86_64-pc-windows-gnu-gcc", 247 | "inherits": ["make", "host-gcc", "windows-only"] 248 | }, 249 | { 250 | "name": "x86_64-unknown-linux-gnu-clang", 251 | "inherits": ["x86_64-unknown-linux-gnu"], 252 | "toolchainFile": "${sourceDir}/.github/scripts/toolchains/${presetName}.cmake" 253 | }, 254 | { 255 | "name": "x86_64-unknown-linux-gnu-gcc", 256 | "inherits": ["x86_64-unknown-linux-gnu"], 257 | "toolchainFile": "${sourceDir}/.github/scripts/toolchains/${presetName}.cmake" 258 | }, 259 | { 260 | "name": "i686-unknown-linux-gnu-clang", 261 | "inherits": ["i686-unknown-linux-gnu"], 262 | "toolchainFile": "${sourceDir}/.github/scripts/toolchains/${presetName}.cmake" 263 | }, 264 | { 265 | "name": "i686-unknown-linux-gnu-gcc", 266 | "inherits": ["i686-unknown-linux-gnu"], 267 | "toolchainFile": "${sourceDir}/.github/scripts/toolchains/${presetName}.cmake" 268 | }, 269 | { 270 | "name": "aarch64-unknown-linux-gnu-clang", 271 | "inherits": ["aarch64-unknown-linux-gnu"], 272 | "toolchainFile": "${sourceDir}/.github/scripts/toolchains/${presetName}.cmake" 273 | }, 274 | { 275 | "name": "aarch64-unknown-linux-gnu-gcc", 276 | "inherits": ["aarch64-unknown-linux-gnu"], 277 | "toolchainFile": "${sourceDir}/.github/scripts/toolchains/${presetName}.cmake" 278 | }, 279 | { 280 | "name": "x86_64-apple-darwin-clang", 281 | "inherits": ["x86_64-apple-darwin", "clang"], 282 | "toolchainFile": "${sourceDir}/.github/scripts/toolchains/${presetName}.cmake" 283 | }, 284 | { 285 | "name": "aarch64-apple-darwin-clang", 286 | "inherits": ["aarch64-apple-darwin"], 287 | "toolchainFile": "${sourceDir}/.github/scripts/toolchains/${presetName}.cmake" 288 | } 289 | ] 290 | } 291 | --------------------------------------------------------------------------------