Adding a crate that exposes a binary and a library breaks corrosion
Building a crate which contains a lib.rs and a main.rs (and therefore builds a library and an executable) results in the following errors:
$ cmake .. && make # in the build subdirectory
-- Rust Toolchain: stable-x86_64-unknown-linux-gnu
-- Rust Target: x86_64-unknown-linux-gnu
-- Defaulting Cargo to build debug
-- Using Corrosion as a subdirectory
CMake Error at corrosion/cmake/CorrosionGenerator.cmake:318 (add_executable):
add_executable cannot create imported target "rust-lib" because another
target with the same name already exists.
Call Stack (most recent call first):
corrosion/cmake/CorrosionGenerator.cmake:479 (_generator_add_target)
corrosion/cmake/Corrosion.cmake:491 (_generator_add_cargo_targets)
CMakeLists.txt:8 (corrosion_import_crate)
CMake Error at corrosion/cmake/Corrosion.cmake:337 (add_custom_target):
add_custom_target cannot create target "cargo-build_rust-lib" because
another target with the same name already exists. The existing target is a
custom target created in source directory
"$HOME/dev/test/2022-09-19 Rust OCCT Integration". See
documentation for policy CMP0002 for more details.
Call Stack (most recent call first):
corrosion/cmake/CorrosionGenerator.cmake:329 (_add_cargo_build)
corrosion/cmake/CorrosionGenerator.cmake:479 (_generator_add_target)
corrosion/cmake/Corrosion.cmake:491 (_generator_add_cargo_targets)
CMakeLists.txt:8 (corrosion_import_crate)
-- Configuring incomplete, errors occurred!
See also "$HOME/dev/test/2022-09-19 Rust OCCT Integration/build/CMakeFiles/CMakeOutput.log".
The crate was called rust-lib in this example.
Steps to reproduce:
- create a rust crate with a library and a binary (e.g. by adding a main.rs to a lib crate)
- add it to a
CMakeLists.txt, e.g. the crate bing in therust/subdirectoryadd_subdirectory(corrosion) corrosion_import_crate(MANIFEST_PATH rust/Cargo.toml) - try to build it
This happens on the latest release (e1144c4b7aa44004a8b8c6cd254c63420ce3e309) and on the current master (c6b793604d5cdb8e688cc2f627f034865a50327d).
In this code fragment, the executable and library targets are created:
https://github.com/corrosion-rs/corrosion/blob/f6d2ab78b79a62a5e60b9d68cd6896a529028143/cmake/CorrosionGenerator.cmake#L58-L91
My guess is that both marked paths are triggered when a crate contains both a library and an executable. Both branches create a target with the name ${target_name}.
Is it possible to append a -bin suffix to the executable target and/or a -lib suffix to the library target? I'd create a PR, but idk what I'd break (and it would probably be a breaking change).
Hi, Thanks for the report.
Is it possible to append a -bin suffix to the executable target and/or a -lib suffix to the library target?
This would be a breaking change affecting basically all users, so I'm not super enthusiastic about it.
Both branches create a target with the name ${target_name}.
The names can be distinct, as you can choose the name of your bin crate and the name of your lib crate. It's just that for a single bin crate with a lib crate both inherit the package name by default.
What you can do is use the name key in your packages Cargo.toml to give the binary/binaries and the lib distinct names. Example Cargo.toml.
This should be a solution for you, unless the Cargo.tom is not under your control.
This happens on the latest release (https://github.com/corrosion-rs/corrosion/commit/e1144c4b7aa44004a8b8c6cd254c63420ce3e309) and on the current master
If you have more than one target per crate you will need to use the latest master though. The released versions do not support more than one target per crate (this was added rather recently).
Sorry for the late response.
Hi, Thanks for the report.
Is it possible to append a -bin suffix to the executable target and/or a -lib suffix to the library target?
This would be a breaking change affecting basically all users, so I'm not super enthusiastic about it.
Yeah, that's what I imagined. And lib and bin targets seem to be a rather niche case (I came across this on accident). How about a better error message? Maybe emitting a warning when an existing target with the same same exists?
Both branches create a target with the name ${target_name}.
The names can be distinct, as you can choose the name of your
bincrate and the name of yourlibcrate. It's just that for a single bin crate with a lib crate both inherit the package name by default.
That totally makes sense in hindsight. Maybe it was just an unfortunate combination of an my (limited) understanding of Cargo and an error message that didn't really direct me towards the issue.
What you can do is use the
namekey in your packages Cargo.toml to give the binary/binaries and the lib distinct names. Example Cargo.toml. This should be a solution for you, unless theCargo.tomis not under your control.
Ah, ty :) .
This happens on the latest release (e1144c4) and on the current master
If you have more than one target per crate you will need to use the latest master though. The released versions do not support more than one target per crate (this was added rather recently).
That's fine, the bin was by accident :)
How about a better error message? Maybe emitting a warning when an existing target with the same same exists?
I guess emitting a warning and skipping the target is better than just failing. I'll add a warning with a hopefully helpful message.