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

Add NO_STD switch #154

Merged
merged 8 commits into from
Mar 27, 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
3 changes: 3 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -183,6 +183,9 @@ That's equivalent to calling `cargo build --features chocolate vanilla`.
It is also possible to specify the features as a target list property on the CMake target created
by `corrosion_import_crate`. The property is called `CORROSION_FEATURES`.

To disable linking against system libraries - appropiate when building `no_std` crates - use
the `NO_STD` parameter for `corrosion_import_crate`.

Finally, regarding features, cargo offers the ability to turn off default features or enable all
features, with the `--all-features` and `--no-default-features` options. Corrosion offers corresponding
parameters for `corrosion_import_crate` called `ALL_FEATURES` and `NO_DEFAULT_FEATURES`. The corresponding
Expand Down
6 changes: 5 additions & 1 deletion cmake/Corrosion.cmake
Original file line number Diff line number Diff line change
Expand Up @@ -195,6 +195,9 @@ function(_add_cargo_build)
if(COR_NO_DEFAULT_FEATURES)
set(no_default_features_arg --no-default-features)
endif()
if(COR_NO_STD)
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
Expand Down Expand Up @@ -290,6 +293,7 @@ function(_add_cargo_build)
${features_args}
${all_features_arg}
${no_default_features_arg}
${no_default_libraries_arg}
${features_genex}
${cargo_target_option}
${rustflags_genex}
Expand Down Expand Up @@ -321,7 +325,7 @@ function(_add_cargo_build)
endfunction(_add_cargo_build)

function(corrosion_import_crate)
set(OPTIONS ALL_FEATURES NO_DEFAULT_FEATURES)
set(OPTIONS ALL_FEATURES NO_DEFAULT_FEATURES NO_STD)
set(ONE_VALUE_KEYWORDS MANIFEST_PATH PROFILE)
set(MULTI_VALUE_KEYWORDS CRATES FEATURES)
cmake_parse_arguments(COR "${OPTIONS}" "${ONE_VALUE_KEYWORDS}" "${MULTI_VALUE_KEYWORDS}" ${ARGN})
Expand Down
34 changes: 23 additions & 11 deletions cmake/CorrosionGenerator.cmake
Original file line number Diff line number Diff line change
Expand Up @@ -39,32 +39,44 @@ function(_generator_parse_platform manifest version target)
if(os STREQUAL "windows")
set(is_windows TRUE)

list(APPEND libs "advapi32" "userenv" "ws2_32")
if(NOT COR_NO_STD)
list(APPEND libs "advapi32" "userenv" "ws2_32")
endif()

if(env STREQUAL "msvc")
set(is_windows_msvc TRUE)

list(APPEND libs_debug "msvcrtd")
list(APPEND libs_release "msvcrt")
if(NOT COR_NO_STD)
list(APPEND libs_debug "msvcrtd")
list(APPEND libs_release "msvcrt")
endif()
elseif(env STREQUAL "gnu")
set(is_windows_gnu TRUE)

list(APPEND libs "gcc_eh" "pthread")
if(NOT COR_NO_STD)
list(APPEND libs "gcc_eh" "pthread")
endif()
endif()

if(version VERSION_LESS "1.33.0")
list(APPEND libs "shell32" "kernel32")
endif()
if(NOT COR_NO_STD)
if(version VERSION_LESS "1.33.0")
list(APPEND libs "shell32" "kernel32")
endif()

if(version VERSION_GREATER_EQUAL "1.57.0")
list(APPEND libs "bcrypt")
if(version VERSION_GREATER_EQUAL "1.57.0")
list(APPEND libs "bcrypt")
endif()
endif()
elseif(os STREQUAL "apple" AND env STREQUAL "darwin")
set(is_macos TRUE)

list(APPEND libs "System" "resolv" "c" "m")
if(NOT COR_NO_STD)
list(APPEND libs "System" "resolv" "c" "m")
endif()
elseif(os STREQUAL "linux")
list(APPEND libs "dl" "rt" "pthread" "gcc_s" "c" "m" "util")
if(NOT COR_NO_STD)
list(APPEND libs "dl" "rt" "pthread" "gcc_s" "c" "m" "util")
endif()
endif()

set_source_files_properties(
Expand Down
35 changes: 24 additions & 11 deletions generator/src/subcommands/build_crate.rs
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@ const RUSTFLAGS: &str = "rustflags";
const FEATURES: &str = "features";
const ALL_FEATURES: &str = "all-features";
const NO_DEFAULT_FEATURES: &str = "no-default-features";
const NO_DEFAULT_LIBRARIES: &str = "no-default-libraries";

pub fn subcommand() -> App<'static, 'static> {
SubCommand::with_name(BUILD_CRATE)
Expand All @@ -24,7 +25,7 @@ pub fn subcommand() -> App<'static, 'static> {
.long("profile")
.takes_value(true)
.help("The cargo profile to build with, e.g. 'dev' or 'release'")
.conflicts_with(RELEASE)
.conflicts_with(RELEASE),
)
.arg(
Arg::with_name(TARGET)
Expand All @@ -40,12 +41,13 @@ pub fn subcommand() -> App<'static, 'static> {
.required(true)
.help("The name of the package being built with cargo"),
)
.arg(Arg::with_name(RUSTFLAGS)
.long(RUSTFLAGS)
.value_name("RUSTFLAGS")
.takes_value(true)
.multiple(false)
.help("The RUSTFLAGS to pass to rustc.")
.arg(
Arg::with_name(RUSTFLAGS)
.long(RUSTFLAGS)
.value_name("RUSTFLAGS")
.takes_value(true)
.multiple(false)
.help("The RUSTFLAGS to pass to rustc."),
)
.arg(
Arg::with_name(FEATURES)
Expand All @@ -58,14 +60,19 @@ pub fn subcommand() -> App<'static, 'static> {
)
.arg(
Arg::with_name(ALL_FEATURES)
.long(ALL_FEATURES)
.long(ALL_FEATURES)
.help("Specifies that all features of the crate are to be activated"),
)
.arg(
Arg::with_name(NO_DEFAULT_FEATURES)
.long(NO_DEFAULT_FEATURES)
.long(NO_DEFAULT_FEATURES)
.help("Specifies that the default features of the crate are to be disabled"),
)
.arg(
Arg::with_name(NO_DEFAULT_LIBRARIES)
.long(NO_DEFAULT_LIBRARIES)
.help("Disables linking against any default libraries"),
)
}

pub fn invoke(
Expand Down Expand Up @@ -124,7 +131,9 @@ pub fn invoke(
.collect();

if !languages.is_empty() {
rustflags += " -Cdefault-linker-libraries=yes";
if !matches.is_present(NO_DEFAULT_LIBRARIES) {
rustflags += " -Cdefault-linker-libraries=yes";
}

// This loop gets the highest preference link language to use for the linker
let mut highest_preference: Option<(Option<i32>, &str)> = None;
Expand Down Expand Up @@ -174,7 +183,11 @@ pub fn invoke(

let rustflags_trimmed = rustflags.trim();
if args.verbose {
println!("Rustflags for package {} are: `{}`", matches.value_of(PACKAGE).unwrap(), rustflags_trimmed);
println!(
"Rustflags for package {} are: `{}`",
matches.value_of(PACKAGE).unwrap(),
rustflags_trimmed
);
}
cargo.env("RUSTFLAGS", rustflags_trimmed);
}
Expand Down
22 changes: 18 additions & 4 deletions generator/src/subcommands/gen_cmake.rs
Original file line number Diff line number Diff line change
Expand Up @@ -6,8 +6,8 @@ use std::{
};

use clap::{App, Arg, ArgMatches, SubCommand};
use semver::Version;
use platforms::Platform;
use semver::Version;

mod platform;
mod target;
Expand All @@ -24,6 +24,7 @@ const TARGET: &str = "target";
const CARGO_VERSION: &str = "cargo-version";
const PROFILE: &str = "profile";
const CRATES: &str = "crates";
const NO_DEFAULT_LIBRARIES: &str = "no-default-libraries";

pub fn subcommand() -> App<'static, 'static> {
SubCommand::with_name(GEN_CMAKE)
Expand Down Expand Up @@ -89,7 +90,7 @@ pub fn subcommand() -> App<'static, 'static> {
.long(PROFILE)
.value_name("PROFILE")
.required(false)
.help("Custom cargo profile to select.")
.help("Custom cargo profile to select."),
)
.arg(
Arg::with_name(OUT_FILE)
Expand All @@ -98,6 +99,13 @@ pub fn subcommand() -> App<'static, 'static> {
.value_name("FILE")
.help("Output CMake file name. Defaults to stdout."),
)
.arg(
Arg::with_name(NO_DEFAULT_LIBRARIES)
.long(NO_DEFAULT_LIBRARIES)
.help(
"Do not include libraries usually included by default. Use for no-std crates",
),
)
}

pub fn invoke(
Expand Down Expand Up @@ -183,11 +191,17 @@ cmake_minimum_required(VERSION 3.12)
})
.collect();

let cargo_profile = matches.value_of(PROFILE);
let cargo_profile = matches.value_of(PROFILE);

for target in &targets {
target
.emit_cmake_target(&mut out_file, &cargo_platform, &cargo_version, cargo_profile)
.emit_cmake_target(
&mut out_file,
&cargo_platform,
&cargo_version,
cargo_profile,
!matches.is_present(NO_DEFAULT_LIBRARIES),
)
.unwrap();
}

Expand Down
56 changes: 28 additions & 28 deletions generator/src/subcommands/gen_cmake/target.rs
Original file line number Diff line number Diff line change
Expand Up @@ -104,6 +104,7 @@ impl CargoTarget {
platform: &super::platform::Platform,
cargo_version: &semver::Version,
cargo_profile: Option<&str>,
include_platform_libs: bool,
) -> Result<(), Box<dyn Error>> {
// This bit aggregates the byproducts of "cargo build", which is needed for generators like Ninja.
let mut byproducts = vec![];
Expand Down Expand Up @@ -172,10 +173,7 @@ _add_cargo_build(
",
self.cargo_package.name,
self.cargo_target.name,
self.cargo_package
.manifest_path
.as_str()
.replace("\\", "/"),
self.cargo_package.manifest_path.as_str().replace("\\", "/"),
byproducts.join(" "),
cargo_build_profile_option
)?;
Expand All @@ -195,37 +193,39 @@ _add_cargo_build(
self.cargo_target.name
)?;

if !platform.libs.is_empty() {
writeln!(
out_file,
"set_property(TARGET {0}-static PROPERTY INTERFACE_LINK_LIBRARIES \
{1})",
self.cargo_target.name,
platform.libs.join(" ")
)?;
}

if !platform.libs_debug.is_empty() {
writeln!(
out_file,
"set_property(TARGET {0}-static PROPERTY \
INTERFACE_LINK_LIBRARIES_DEBUG {1})",
self.cargo_target.name,
platform.libs_debug.join(" ")
)?;
}
if include_platform_libs {
if !platform.libs.is_empty() {
writeln!(
out_file,
"set_property(TARGET {0}-static PROPERTY INTERFACE_LINK_LIBRARIES \
{1})",
self.cargo_target.name,
platform.libs.join(" ")
)?;
}

if !platform.libs_release.is_empty() {
for config in &["RELEASE", "MINSIZEREL", "RELWITHDEBINFO"] {
if !platform.libs_debug.is_empty() {
writeln!(
out_file,
"set_property(TARGET {0}-static PROPERTY \
INTERFACE_LINK_LIBRARIES_{2} {1})",
INTERFACE_LINK_LIBRARIES_DEBUG {1})",
self.cargo_target.name,
platform.libs_release.join(" "),
config
platform.libs_debug.join(" ")
)?;
}

if !platform.libs_release.is_empty() {
for config in &["RELEASE", "MINSIZEREL", "RELWITHDEBINFO"] {
writeln!(
out_file,
"set_property(TARGET {0}-static PROPERTY \
INTERFACE_LINK_LIBRARIES_{2} {1})",
self.cargo_target.name,
platform.libs_release.join(" "),
config
)?;
}
}
}
}

Expand Down
1 change: 1 addition & 0 deletions test/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@ add_subdirectory(cpp2rust)
add_subdirectory(rust2cpp)
add_subdirectory(workspace)
add_subdirectory(rustflags)
add_subdirectory(nostd)
if (CMAKE_VERSION VERSION_GREATER_EQUAL 3.19.0)
add_subdirectory(envvar)
add_subdirectory(hostbuild)
Expand Down
7 changes: 7 additions & 0 deletions test/nostd/CMakeLists.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
corrosion_import_crate(MANIFEST_PATH rust/Cargo.toml NO_STD)

set(CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} -nostdlib")
list(REMOVE_ITEM CMAKE_CXX_IMPLICIT_LINK_LIBRARIES stdc++)

add_library(nostd-cpp-lib STATIC main.cpp)
target_link_libraries(nostd-cpp-lib PUBLIC rust-nostd-lib)
6 changes: 6 additions & 0 deletions test/nostd/main.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
extern "C" void rust_function();

extern "C" void cpp_function() {
// Fail on linking issues
rust_function();
}
7 changes: 7 additions & 0 deletions test/nostd/rust/Cargo.lock

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

17 changes: 17 additions & 0 deletions test/nostd/rust/Cargo.toml
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
[package]
name = "rust-nostd-lib"
version = "0.1.0"
edition = "2015"

# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html

[dependencies]

[lib]
crate-type=["staticlib"]

[profile.release]
panic = "abort"

[profile.dev]
panic = "abort"
10 changes: 10 additions & 0 deletions test/nostd/rust/src/lib.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
#![no_std]
use core::panic::PanicInfo;

#[no_mangle]
pub extern "C" fn rust_function() {}

#[panic_handler]
fn panic(_panic: &PanicInfo<'_>) -> ! {
loop {}
}