Skip to content
Draft
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
85 changes: 72 additions & 13 deletions cmake/Corrosion.cmake
Original file line number Diff line number Diff line change
Expand Up @@ -718,14 +718,25 @@ function(_add_cargo_build out_cargo_build_out_dir)
set(if_not_host_build_condition "$<NOT:${hostbuild_override}>")

set(corrosion_link_args "$<${if_not_host_build_condition}:${corrosion_link_args}>")
# We always set `--target`, so that cargo always places artifacts into a directory with the
# target triple.
set(cargo_target_option "--target=$<IF:${hostbuild_override},${_CORROSION_RUST_CARGO_HOST_TARGET},${_CORROSION_RUST_CARGO_TARGET}>")

# The target may be a filepath to custom target json file. For host targets we assume that they are built-in targets.
_corrosion_strip_target_triple("${_CORROSION_RUST_CARGO_TARGET}" stripped_target_triple)
_corrosion_strip_target_triple("${_CORROSION_RUST_CARGO_TARGET_UPPER}" stripped_target_triple_upper)
set(target_artifact_dir "$<IF:${hostbuild_override},${_CORROSION_RUST_CARGO_HOST_TARGET},${stripped_target_triple}>")
if(CORROSION_XCODE_DYNAMIC_TARGET)
# Defer target selection to the build command / wrapper script
set(cargo_target_option "") # Will be set in the build command
set(CORROSION_XCODE_NEEDS_DYNAMIC_TARGET TRUE)

# For Xcode dynamic targets, we can't predict the exact directory at configure time
# We'll need to handle this in the post-build copy step
set(target_artifact_dir "$<IF:${hostbuild_override},${_CORROSION_RUST_CARGO_HOST_TARGET},current>")
else()
# We set `--target` so that cargo always places artifacts into a directory with the target triple
set(cargo_target_option "--target=$<IF:${hostbuild_override},${_CORROSION_RUST_CARGO_HOST_TARGET},${_CORROSION_RUST_CARGO_TARGET}>")
set(CORROSION_XCODE_NEEDS_DYNAMIC_TARGET FALSE)

# The target may be a filepath to custom target json file. For host targets we assume that they are built-in targets.
_corrosion_strip_target_triple("${_CORROSION_RUST_CARGO_TARGET}" stripped_target_triple)
_corrosion_strip_target_triple("${_CORROSION_RUST_CARGO_TARGET_UPPER}" stripped_target_triple_upper)
set(target_artifact_dir "$<IF:${hostbuild_override},${_CORROSION_RUST_CARGO_HOST_TARGET},${stripped_target_triple}>")
endif()

set(flags_genex "$<GENEX_EVAL:$<TARGET_PROPERTY:${target_name},INTERFACE_CORROSION_CARGO_FLAGS>>")

Expand Down Expand Up @@ -756,10 +767,24 @@ function(_add_cargo_build out_cargo_build_out_dir)
endif()
endif()

# Build a list of custom Debug configuration expressions
list(APPEND DEBUG_EXPRESSIONS "$<CONFIG:Debug>")
# Include an empty config name for backwards compatibility
list(APPEND DEBUG_EXPRESSIONS "$<CONFIG:>")
# Append any user specified debug configurations
foreach(cfg IN LISTS _CORROSION_DEBUG_CONFIGS)
list(APPEND DEBUG_EXPRESSIONS "$<CONFIG:${cfg}>")
endforeach()
list(REMOVE_DUPLICATES DEBUG_EXPRESSIONS)

# combine DEBUG_EXPRESSIONS into a single OR expression
string(JOIN "," DEBUG_OR ${DEBUG_EXPRESSIONS})
set(IS_DEBUG_EXPR "$<OR:${DEBUG_OR}>")

set(cargo_profile_set "$<BOOL:${cargo_profile_target_property}>")
# In the default case just specify --release or nothing to stay compatible with
# older rust versions.
set(default_profile_option "$<$<NOT:$<OR:$<CONFIG:Debug>,$<CONFIG:>>>:--release>")
set(default_profile_option "$<$<NOT:${IS_DEBUG_EXPR}>:--release>")
# evaluates to either `--profile=<custom_profile>`, `--release` or nothing (for debug).
set(cargo_profile "$<IF:${cargo_profile_set},--profile=${cargo_profile_target_property},${default_profile_option}>")

Expand All @@ -769,7 +794,7 @@ function(_add_cargo_build out_cargo_build_out_dir)
set(profile_dir_is_overridden "$<BOOL:${profile_dir_override}>")
set(custom_profile_build_type_dir "$<IF:${profile_dir_is_overridden},${profile_dir_override},${cargo_profile_target_property}>")

set(default_build_type_dir "$<IF:$<OR:$<CONFIG:Debug>,$<CONFIG:>>,debug,release>")
set(default_build_type_dir "$<IF:${IS_DEBUG_EXPR},debug,release>")
set(build_type_dir "$<IF:${cargo_profile_set},${custom_profile_build_type_dir},${default_build_type_dir}>")

# We set a target folder based on the manifest path so if you build multiple workspaces (or standalone projects
Expand Down Expand Up @@ -871,9 +896,28 @@ function(_add_cargo_build out_cargo_build_out_dir)
message(DEBUG "TARGET ${target_name} produces byproducts ${build_byproducts}")
message(DEBUG "corrosion_cc_rs_flags: ${corrosion_cc_rs_flags}")

# Set up command and arguments based on whether we need dynamic target selection
if(CORROSION_XCODE_NEEDS_DYNAMIC_TARGET)
# Use the external wrapper script for Xcode builds
set(xcode_cargo_wrapper_template "${CMAKE_CURRENT_FUNCTION_LIST_DIR}/xcode_cargo_wrapper.sh.in")
set(xcode_cargo_wrapper "${CMAKE_CURRENT_BINARY_DIR}/xcode_cargo_wrapper_${target_name}.sh")

# Copy the template to the build directory and make it executable
configure_file("${xcode_cargo_wrapper_template}" "${xcode_cargo_wrapper}" COPYONLY)
execute_process(COMMAND chmod +x "${xcode_cargo_wrapper}")

# Use cargo rustc with wrapper script for dynamic target selection
# Dynamic rustflags (arch, SDK) must be handled at build time via environment variables
set(cargo_command "${xcode_cargo_wrapper}" "${cargo_bin}")
set(cargo_target_arg "") # Handled dynamically by wrapper script
else()
# Use cargo rustc directly
set(cargo_command "${cargo_bin}")
set(cargo_target_arg ${cargo_target_option})
endif()

add_custom_target(
_cargo-build_${target_name}
# Build crate
COMMAND
${CMAKE_COMMAND} -E env
"${build_env_variable_genex}"
Expand All @@ -884,10 +928,10 @@ function(_add_cargo_build out_cargo_build_out_dir)
"${cargo_library_path}"
"CORROSION_BUILD_DIR=${CMAKE_CURRENT_BINARY_DIR}"
"CARGO_BUILD_RUSTC=${rustc_bin}"
"${cargo_bin}"
rustc
${cargo_command}
"rustc"
${cargo_rustc_filter}
${cargo_target_option}
${cargo_target_arg}
${_CORROSION_VERBOSE_OUTPUT_FLAG}
${all_features_arg}
${no_default_features_arg}
Expand Down Expand Up @@ -916,6 +960,16 @@ function(_add_cargo_build out_cargo_build_out_dir)
COMMAND_EXPAND_LISTS
VERBATIM
)

# Set Xcode-specific properties if using dynamic target selection
if(CORROSION_XCODE_NEEDS_DYNAMIC_TARGET)
set_target_properties(_cargo-build_${target_name} PROPERTIES
XCODE_ATTRIBUTE_ARCHS "$(ARCHS_STANDARD)"
XCODE_ATTRIBUTE_ONLY_ACTIVE_ARCH "YES"
XCODE_ATTRIBUTE_SDKROOT "auto"
XCODE_ATTRIBUTE_SUPPORTED_PLATFORMS "iphoneos iphonesimulator macosx xros xrsimulator"
)
endif()

# User exposed custom target, that depends on the internal target.
# Corrosion post build steps are added on the internal target, which
Expand Down Expand Up @@ -2325,6 +2379,11 @@ function(_corrosion_initialize_properties target_name)
endforeach()
endfunction()

# Helper function to set the list of debug configurations for Corrosion. Must be called before the call to `corrosion_import_crate`.
function(corrosion_set_debug_config_list configs)
set(_CORROSION_DEBUG_CONFIGS "${configs}" PARENT_SCOPE)
endfunction()

# Helper macro to pass through an optional `OPTION` argument parsed via `cmake_parse_arguments`
# to another function that takes the same OPTION.
# If the option was set, then the variable <var_name> will be set to the same option name again,
Expand Down
12 changes: 12 additions & 0 deletions cmake/FindRust.cmake
Original file line number Diff line number Diff line change
Expand Up @@ -764,6 +764,18 @@ if (NOT Rust_CARGO_TARGET_CACHED)
if(_RUST_OHOS_TARGET)
set(Rust_CARGO_TARGET_CACHED "${_RUST_OHOS_TARGET}" CACHE STRING "Target triple")
endif()
elseif(CMAKE_GENERATOR STREQUAL "Xcode")
# For Xcode, we need to defer target selection to build time since SDK and architecture
# are determined dynamically by the build system.

# Set a default target that will be overridden by the dynamic selection logic
# This ensures we have a valid target for configure-time operations
set(Rust_CARGO_TARGET_CACHED "aarch64-apple-darwin" CACHE STRING "Target triple (may be dynamically adjusted by Xcode)")

# Mark this as an Xcode build that needs dynamic target selection
set(CORROSION_XCODE_DYNAMIC_TARGET TRUE CACHE INTERNAL "Enable dynamic target selection for Xcode")

message(STATUS "Xcode generator detected - Rust target will be dynamically selected based on SDK and architecture at build time")
endif()
# Fallback to the default host target
if(NOT Rust_CARGO_TARGET_CACHED)
Expand Down
Loading
Loading