corrosion icon indicating copy to clipboard operation
corrosion copied to clipboard

Adding a crate that exposes a binary and a library breaks corrosion

Open lrittel opened this issue 3 years ago • 2 comments

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:

  1. create a rust crate with a library and a binary (e.g. by adding a main.rs to a lib crate)
  2. add it to a CMakeLists.txt, e.g. the crate bing in the rust/ subdirectory
    add_subdirectory(corrosion)
    corrosion_import_crate(MANIFEST_PATH rust/Cargo.toml)
    
  3. try to build it

This happens on the latest release (e1144c4b7aa44004a8b8c6cd254c63420ce3e309) and on the current master (c6b793604d5cdb8e688cc2f627f034865a50327d).

lrittel avatar Oct 05 '22 19:10 lrittel

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).

lrittel avatar Oct 05 '22 20:10 lrittel

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).

jschwe avatar Oct 06 '22 05:10 jschwe

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 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.

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 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.

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 :)

lrittel avatar Oct 18 '22 21:10 lrittel

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.

jschwe avatar Oct 20 '22 06:10 jschwe