Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Support "local" rustflags only affecting the main crate #215

Merged
merged 4 commits into from
Sep 10, 2022
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
11 changes: 11 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -220,6 +220,11 @@ Some configuration options can be specified individually for each target. You ca
the `RUSTFLAGS` environment variable will contain the flags added via this function. Please note that any
dependencies (built by cargo) will also see these flags. In the future corrosion may offer a second function
to allow specifying flags only for the target in question, utilizing `cargo rustc` instead of `cargo build`.
- `corrosion_add_target_local_rustflags(target_name rustc_flag [more_flags ...])`: Support setting
rustflags for only the main target (crate ) and none of it's dependencies.
This is useful in cases where you only need rustflags on the main-crate, but need to set different
flags for different targets. Without "local" Rustflags this would require rebuilds of the
dependencies when switching targets.
- `corrosion_set_hostbuild(<target_name>)`: The target should be compiled for the Host target and ignore any
cross-compile configuration.
- `corrosion_set_features(<target_name> [ALL_FEATURES <Bool>] [NO_DEFAULT_FEATURES] [FEATURES <feature1> ... ])`:
Expand All @@ -229,6 +234,12 @@ Some configuration options can be specified individually for each target. You ca
- `corrosion_set_flags(<target_name> <flag1> ...])`:
For a given target, add options and flags at the end of `cargo build` invocation. This will be appended after any
arguments passed through the `FLAGS` during the crate import.
- `corrosion_set_linker(target_name linker)`: Use `linker` to link the target.
Please note that this only has an effect for targets where the final linker invocation is done
by cargo, i.e. targets where foreign code is linked into rust code and not the other way around.
Please also note that if you are cross-compiling and specify a linker such as `clang`, you are
responsible for also adding a rustflag which adds the necessary `--target=` argument for the
linker.

### Selecting a custom cargo profile

Expand Down
26 changes: 23 additions & 3 deletions RELEASES.md
Original file line number Diff line number Diff line change
@@ -1,21 +1,41 @@
# Unreleased

# Breaking
## Breaking

- The minimum supported rust version was increased to 1.46, due to a cargo issue that recently
surfaced on CI when using crates.io.
- Increase the minimum required CMake version to 3.15 (may be bumped to 3.16 before the next release).

# Potentially breaking
## Potentially breaking

- The working directory when invoking `cargo build` was changed to the directory of the Manifest
file. This now allows cargo to pick up `.cargo/config.toml` files located in the source tree.
([205](https://github.com/corrosion-rs/corrosion/pull/205))
- Corrosion internally invokes `cargo build`. When passing arguments to `cargo build`, Corrosion
now uses the CMake `VERBATIM` option. In rare cases this may require you to change how you quote
parameters passed to corrosion (e.g. via `corrosion_add_target_rustflags()`).
For example setting a `cfg` option previously required double escaping the rustflag like this
`"--cfg=something=\\\"value\\\""`, but now it can be passed to corrosion without any escapes:
`--cfg=something="value"`.


## New features

- Support setting rustflags for only the main target and none of it's dependencies ([215](https://github.com/corrosion-rs/corrosion/pull/215)).
A new function `corrosion_add_target_local_rustflags(target_name rustc_flag [more_flags ...])`
is added for this purpose.
This is useful in cases where you only need rustflags on the main-crate, but need to set different
flags for different targets. Without "local" Rustflags this would require rebuilds of the
dependencies when switching targets.
- Support explicitly selecting a linker ([208](https://github.com/corrosion-rs/corrosion/pull/208)).
The linker can be selected via `corrosion_set_linker(target_name linker)`.
Please note that this only has an effect for targets, where the final linker invocation is done
by cargo, i.e. targets where foreign code is linked into rust code and not the other way around.

## Fixes

- Fix a CMake developer Warning when a Multi-Config Generator and Rust executable targets
([#213](https://github.com/corrosion-rs/corrosion/pull/213)).

# 0.2.2 (2022-09-01)

## Fixes
Expand Down
50 changes: 36 additions & 14 deletions cmake/Corrosion.cmake
Original file line number Diff line number Diff line change
Expand Up @@ -252,10 +252,8 @@ function(_add_cargo_build)
set(no_default_libraries_arg --no-default-libraries)
endif()

set(rustflags_target_property "$<TARGET_GENEX_EVAL:${target_name},$<TARGET_PROPERTY:${target_name},INTERFACE_CORROSION_RUSTFLAGS>>")
# `rustflags_target_property` may contain multiple arguments and double quotes, so we _should_ single quote it to
# preserve any double quotes and keep it as one argument value. However single quotes don't work on windows, so we
# can only add double quotes here. Any double quotes _in_ the rustflags must be escaped like `\\\"`.
set(global_rustflags_target_property "$<TARGET_GENEX_EVAL:${target_name},$<TARGET_PROPERTY:${target_name},INTERFACE_CORROSION_RUSTFLAGS>>")
set(local_rustflags_target_property "$<TARGET_GENEX_EVAL:${target_name},$<TARGET_PROPERTY:${target_name},INTERFACE_CORROSION_LOCAL_RUSTFLAGS>>")

set(features_target_property "$<GENEX_EVAL:$<TARGET_PROPERTY:${target_name},${_CORR_PROP_FEATURES}>>")
set(features_genex "$<$<BOOL:${features_target_property}>:--features=$<JOIN:${features_target_property},$<COMMA>>>")
Expand Down Expand Up @@ -349,17 +347,20 @@ function(_add_cargo_build)
list(APPEND corrosion_cc_rs_flags "SDKROOT=${CMAKE_OSX_SYSROOT}")
endif()

corrosion_add_target_rustflags("${target_name}" "$<$<BOOL:${corrosion_link_args}>:-Clink-args=${corrosion_link_args}>")
corrosion_add_target_local_rustflags("${target_name}" "$<$<BOOL:${corrosion_link_args}>:-Clink-args=${corrosion_link_args}>")

# todo: this should probably also be guarded by if_not_host_build_condition.
if(COR_NO_STD)
corrosion_add_target_rustflags("${target_name}" "-Cdefault-linker-libraries=no")
corrosion_add_target_local_rustflags("${target_name}" "-Cdefault-linker-libraries=no")
else()
corrosion_add_target_rustflags("${target_name}" "-Cdefault-linker-libraries=yes")
corrosion_add_target_local_rustflags("${target_name}" "-Cdefault-linker-libraries=yes")
endif()

set(joined_rustflags "$<JOIN:${rustflags_target_property}, >")
set(rustflags_genex "$<$<BOOL:${rustflags_target_property}>:RUSTFLAGS=${joined_rustflags}>")
set(global_joined_rustflags "$<JOIN:${global_rustflags_target_property}, >")
set(global_rustflags_genex "$<$<BOOL:${global_rustflags_target_property}>:RUSTFLAGS=${global_joined_rustflags}>")
set(local_rustflags_delimiter "$<$<BOOL:${local_rustflags_target_property}>:-->")
set(local_rustflags_genex "$<$<BOOL:${local_rustflags_target_property}>:${local_rustflags_target_property}>")


# Used to set a linker for a specific target-triple.
set(cargo_target_linker_var "CARGO_TARGET_${_CORROSION_RUST_CARGO_TARGET_UPPER}_LINKER")
Expand All @@ -378,7 +379,7 @@ function(_add_cargo_build)
# Skip adding the linker argument, if the linker is explicitly set, since the
# explicit_linker_property will not be set when this function runs.
# Passing this rustflag is necessary for clang.
corrosion_add_target_rustflags("${target_name}" "$<$<NOT:$<BOOL:${explicit_linker_property}>>:${rustflag_linker_arg}>")
corrosion_add_target_local_rustflags("${target_name}" "$<$<NOT:$<BOOL:${explicit_linker_property}>>:${rustflag_linker_arg}>")
endif()
else()
message(DEBUG "No linker preference for target ${target_name} could be detected.")
Expand All @@ -397,14 +398,14 @@ function(_add_cargo_build)
COMMAND
${CMAKE_COMMAND} -E env
"${build_env_variable_genex}"
"${rustflags_genex}"
"${global_rustflags_genex}"
"${cargo_target_linker}"
"${corrosion_cc_rs_flags}"
"${cargo_library_path}"
"CORROSION_BUILD_DIR=${CMAKE_CURRENT_BINARY_DIR}"
"CARGO_BUILD_RUSTC=${_CORROSION_RUSTC}"
"${_CORROSION_CARGO}"
build
rustc
${cargo_target_option}
${_CORROSION_VERBOSE_OUTPUT_FLAG}
# Global --features arguments added via corrosion_import_crate()
Expand All @@ -419,6 +420,9 @@ function(_add_cargo_build)
${cargo_profile}
${flag_args}
${flags_genex}
# Any arguments to cargo must be placed before this line
${local_rustflags_delimiter}
${local_rustflags_genex}

# Copy crate artifacts to the binary dir
COMMAND
Expand Down Expand Up @@ -604,6 +608,12 @@ function(corrosion_set_hostbuild target_name)
)
endfunction()

# Add flags for rustc (RUSTFLAGS) which affect the target and all of it's Rust dependencies
#
# Additional rustflags may be passed as optional parameters after rustflag.
# Please note, that if you import multiple targets from a package or workspace, but set different
# Rustflags via this function, the Rust dependencies will have to be rebuilt when changing targets.
# Consider `corrosion_add_target_local_rustflags()` as an alternative to avoid this.
function(corrosion_add_target_rustflags target_name rustflag)
# Additional rustflags may be passed as optional parameters after rustflag.
set_property(
Expand All @@ -613,6 +623,18 @@ function(corrosion_add_target_rustflags target_name rustflag)
)
endfunction()

# Add flags for rustc (RUSTFLAGS) which only affect the target, but none of it's (Rust) dependencies
#
# Additional rustflags may be passed as optional parameters after rustc_flag.
function(corrosion_add_target_local_rustflags target_name rustc_flag)
# Set Rustflags via `cargo rustc` which only affect the current crate, but not dependencies.
set_property(
TARGET ${target_name}
APPEND
PROPERTY INTERFACE_CORROSION_LOCAL_RUSTFLAGS ${rustc_flag} ${ARGN}
)
endfunction()

function(corrosion_set_env_vars target_name env_var)
# Additional environment variables may be passed as optional parameters after env_var.
set_property(
Expand Down Expand Up @@ -682,8 +704,8 @@ function(corrosion_link_libraries target_name)
$<TARGET_PROPERTY:${library},LINKER_LANGUAGE>
)

corrosion_add_target_rustflags(${target_name} "-L$<TARGET_LINKER_FILE_DIR:${library}>")
corrosion_add_target_rustflags(${target_name} "-l$<TARGET_LINKER_FILE_BASE_NAME:${library}>")
corrosion_add_target_local_rustflags(${target_name} "-L$<TARGET_LINKER_FILE_DIR:${library}>")
corrosion_add_target_local_rustflags(${target_name} "-l$<TARGET_LINKER_FILE_BASE_NAME:${library}>")
endforeach()
endfunction(corrosion_link_libraries)

Expand Down
7 changes: 7 additions & 0 deletions test/custom_profiles/rust/Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

3 changes: 3 additions & 0 deletions test/rustflags/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -11,3 +11,6 @@ corrosion_add_target_rustflags(rustflag-test-lib
--cfg=test_rustflag_cfg2="$<IF:$<OR:$<CONFIG:Debug>,$<CONFIG:>>,debug,release>"
"--cfg=test_rustflag_cfg3"
)

corrosion_add_target_local_rustflags(rustflag-test-lib "--cfg=test_local_rustflag1")
corrosion_add_target_local_rustflags(rustflag-test-lib --cfg=test_local_rustflag2="value")
7 changes: 7 additions & 0 deletions test/rustflags/rust/Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

1 change: 1 addition & 0 deletions test/rustflags/rust/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ license = "MIT"
edition = "2018"

[dependencies]
some_dependency = { path = "some_dependency" }

[lib]
crate-type=["staticlib"]
6 changes: 6 additions & 0 deletions test/rustflags/rust/some_dependency/Cargo.toml
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
[package]
name = "some_dependency"
version = "0.1.0"
license = "MIT"
edition = "2018"

10 changes: 10 additions & 0 deletions test/rustflags/rust/some_dependency/src/lib.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
//! Test that the local rustflags are only passed to the main crate and not to dependencies.
#[cfg(test_local_rustflag1)]
const _: [(); 1] = [(); 2];

#[cfg(test_local_rustflag2 = "value")]
const _: [(); 1] = [(); 2];

pub fn some_function() -> u32 {
42
}
7 changes: 7 additions & 0 deletions test/rustflags/rust/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,14 @@ pub extern "C" fn rust_second_function(name: *const c_char) {
pub extern "C" fn rust_third_function(name: *const c_char) {
let name = unsafe { std::ffi::CStr::from_ptr(name).to_str().unwrap() };
println!("Hello, {}! I'm Rust again, third time the charm!", name);
assert_eq!(some_dependency::some_function(), 42);
}

#[cfg(not(test_rustflag_cfg3))]
const _: [(); 1] = [(); 2];

#[cfg(not(test_local_rustflag1))]
const _: [(); 1] = [(); 2];

#[cfg(not(test_local_rustflag2 = "value"))]
const _: [(); 1] = [(); 2];