From ff32d25fa6b970262f27434279ebbd9e2d2ccd5c Mon Sep 17 00:00:00 2001 From: ApparentlyPlus Date: Fri, 11 Sep 2026 16:12:04 +0300 Subject: [PATCH 1/3] Replace eval with arrays in native build scripts --- eng/native/build-commons.sh | 72 ++++++++++++++++----------------- src/coreclr/build-runtime.sh | 12 +++--- src/native/corehost/build.sh | 8 ++-- src/native/libs/build-native.sh | 36 ++++++++--------- src/tests/build.sh | 8 ++-- 5 files changed, 68 insertions(+), 68 deletions(-) diff --git a/eng/native/build-commons.sh b/eng/native/build-commons.sh index fdf156b16fec2e..6ae4db70da8caa 100755 --- a/eng/native/build-commons.sh +++ b/eng/native/build-commons.sh @@ -49,7 +49,7 @@ check_prereqs() build_native() { if [[ ! -e "$__RepoRootDir/artifacts/obj/_version.c" ]]; then - eval "$__RepoRootDir/eng/native/version/copy_version_files.sh" + "$__RepoRootDir/eng/native/version/copy_version_files.sh" fi targetOS="$1" @@ -57,8 +57,9 @@ build_native() cmakeDir="$3" intermediatesDir="$4" target="$5" - cmakeArgs="$6" - message="$7" + message="$6" + shift 6 + cmakeArgs=("$@") # When sccache is enabled, use it as the compiler launcher. # On macOS, CMake wraps PCH includes with -Xarch_ which sccache @@ -69,7 +70,7 @@ build_native() if [[ "$targetOS" == osx || "$targetOS" == maccatalyst ]]; then __sccacheLauncher="$__RepoRootDir/eng/native/sccache-xarch-wrapper.sh" fi - cmakeArgs="-DCMAKE_C_COMPILER_LAUNCHER=$__sccacheLauncher -DCMAKE_CXX_COMPILER_LAUNCHER=$__sccacheLauncher $cmakeArgs" + cmakeArgs=("-DCMAKE_C_COMPILER_LAUNCHER=$__sccacheLauncher" "-DCMAKE_CXX_COMPILER_LAUNCHER=$__sccacheLauncher" "${cmakeArgs[@]}") fi # All set to commence the build @@ -91,9 +92,9 @@ build_native() if [[ "$targetOS" == osx || "$targetOS" == maccatalyst ]]; then if [[ "$hostArch" == x64 ]]; then - cmakeArgs="-DCMAKE_OSX_ARCHITECTURES=\"x86_64\" $cmakeArgs" + cmakeArgs=(-DCMAKE_OSX_ARCHITECTURES=x86_64 "${cmakeArgs[@]}") elif [[ "$hostArch" == arm64 ]]; then - cmakeArgs="-DCMAKE_OSX_ARCHITECTURES=\"arm64\" $cmakeArgs" + cmakeArgs=(-DCMAKE_OSX_ARCHITECTURES=arm64 "${cmakeArgs[@]}") else echo "Error: Unknown OSX architecture $hostArch." exit 1 @@ -101,14 +102,14 @@ build_native() fi if [[ "$targetOS" == maccatalyst ]]; then - cmakeArgs="-C $__RepoRootDir/eng/native/tryrun_ios_tvos.cmake $cmakeArgs" + cmakeArgs=(-C "$__RepoRootDir/eng/native/tryrun_ios_tvos.cmake" "${cmakeArgs[@]}") # Intentionally do not set CMAKE_OSX_DEPLOYMENT_TARGET for maccatalyst here: # - CMake interprets CMAKE_OSX_DEPLOYMENT_TARGET as a macOS minimum version # instead of MacCatalyst, causing newer clang to reject it as invalid. # - The effective Catalyst minimum version is enforced via the # -target *-apple-ios-macabi flag in eng/native/configurecompiler.cmake - cmakeArgs="-DCMAKE_SYSTEM_NAME=Darwin -DCMAKE_OSX_SYSROOT=macosx -DCMAKE_SYSTEM_VARIANT=maccatalyst $cmakeArgs" + cmakeArgs=(-DCMAKE_SYSTEM_NAME=Darwin -DCMAKE_OSX_SYSROOT=macosx -DCMAKE_SYSTEM_VARIANT=maccatalyst "${cmakeArgs[@]}") fi if [[ "$targetOS" == android || "$targetOS" == linux-bionic ]]; then @@ -119,72 +120,72 @@ build_native() exit 1 fi - cmakeArgs="-DANDROID_BUILD=1 -C $__RepoRootDir/eng/native/tryrun.cmake $cmakeArgs" - cmakeArgs="-DCMAKE_TOOLCHAIN_FILE=$ANDROID_NDK_ROOT/build/cmake/android.toolchain.cmake -DANDROID_PLATFORM=android-${ANDROID_API_LEVEL} -DANDROID_NATIVE_API_LEVEL=${ANDROID_API_LEVEL} $cmakeArgs" + cmakeArgs=(-DANDROID_BUILD=1 -C "$__RepoRootDir/eng/native/tryrun.cmake" "${cmakeArgs[@]}") + cmakeArgs=("-DCMAKE_TOOLCHAIN_FILE=$ANDROID_NDK_ROOT/build/cmake/android.toolchain.cmake" "-DANDROID_PLATFORM=android-${ANDROID_API_LEVEL}" "-DANDROID_NATIVE_API_LEVEL=${ANDROID_API_LEVEL}" "${cmakeArgs[@]}") # Don't try to set CC/CXX in init-compiler.sh - it's handled in android.toolchain.cmake already __Compiler="default" if [[ "$hostArch" == x64 ]]; then - cmakeArgs="-DANDROID_ABI=x86_64 $cmakeArgs" + cmakeArgs=(-DANDROID_ABI=x86_64 "${cmakeArgs[@]}") elif [[ "$hostArch" == x86 ]]; then - cmakeArgs="-DANDROID_ABI=x86 $cmakeArgs" + cmakeArgs=(-DANDROID_ABI=x86 "${cmakeArgs[@]}") elif [[ "$hostArch" == arm64 ]]; then - cmakeArgs="-DANDROID_ABI=arm64-v8a $cmakeArgs" + cmakeArgs=(-DANDROID_ABI=arm64-v8a "${cmakeArgs[@]}") elif [[ "$hostArch" == arm ]]; then - cmakeArgs="-DANDROID_ABI=armeabi-v7a $cmakeArgs" + cmakeArgs=(-DANDROID_ABI=armeabi-v7a "${cmakeArgs[@]}") else echo "Error: Unknown Android architecture $hostArch." exit 1 fi elif [[ "$targetOS" == iossimulator ]]; then - cmakeArgs="-C $__RepoRootDir/eng/native/tryrun_ios_tvos.cmake $cmakeArgs" + cmakeArgs=(-C "$__RepoRootDir/eng/native/tryrun_ios_tvos.cmake" "${cmakeArgs[@]}") # set default iOS simulator deployment target # keep in sync with SetOSTargetMinVersions in the root Directory.Build.props - cmakeArgs="-DCMAKE_SYSTEM_NAME=iOS -DCMAKE_OSX_SYSROOT=iphonesimulator -DCMAKE_OSX_DEPLOYMENT_TARGET=13.0 $cmakeArgs" + cmakeArgs=(-DCMAKE_SYSTEM_NAME=iOS -DCMAKE_OSX_SYSROOT=iphonesimulator -DCMAKE_OSX_DEPLOYMENT_TARGET=13.0 "${cmakeArgs[@]}") if [[ "$__TargetArch" == x64 ]]; then - cmakeArgs="-DCMAKE_OSX_ARCHITECTURES=\"x86_64\" $cmakeArgs" + cmakeArgs=(-DCMAKE_OSX_ARCHITECTURES=x86_64 "${cmakeArgs[@]}") elif [[ "$__TargetArch" == arm64 ]]; then - cmakeArgs="-DCMAKE_OSX_ARCHITECTURES=\"arm64\" $cmakeArgs" + cmakeArgs=(-DCMAKE_OSX_ARCHITECTURES=arm64 "${cmakeArgs[@]}") else echo "Error: Unknown iOS Simulator architecture $__TargetArch." exit 1 fi elif [[ "$targetOS" == ios ]]; then - cmakeArgs="-C $__RepoRootDir/eng/native/tryrun_ios_tvos.cmake $cmakeArgs" + cmakeArgs=(-C "$__RepoRootDir/eng/native/tryrun_ios_tvos.cmake" "${cmakeArgs[@]}") # set default iOS device deployment target # keep in sync with SetOSTargetMinVersions in the root Directory.Build.props - cmakeArgs="-DCMAKE_SYSTEM_NAME=iOS -DCMAKE_OSX_SYSROOT=iphoneos -DCMAKE_OSX_DEPLOYMENT_TARGET=13.0 $cmakeArgs" + cmakeArgs=(-DCMAKE_SYSTEM_NAME=iOS -DCMAKE_OSX_SYSROOT=iphoneos -DCMAKE_OSX_DEPLOYMENT_TARGET=13.0 "${cmakeArgs[@]}") if [[ "$__TargetArch" == arm64 ]]; then - cmakeArgs="-DCMAKE_OSX_ARCHITECTURES=\"arm64\" $cmakeArgs" + cmakeArgs=(-DCMAKE_OSX_ARCHITECTURES=arm64 "${cmakeArgs[@]}") else echo "Error: Unknown iOS architecture $__TargetArch." exit 1 fi elif [[ "$targetOS" == tvossimulator ]]; then - cmakeArgs="-C $__RepoRootDir/eng/native/tryrun_ios_tvos.cmake $cmakeArgs" + cmakeArgs=(-C "$__RepoRootDir/eng/native/tryrun_ios_tvos.cmake" "${cmakeArgs[@]}") # set default tvOS simulator deployment target # keep in sync with SetOSTargetMinVersions in the root Directory.Build.props - cmakeArgs="-DCMAKE_SYSTEM_NAME=tvOS -DCMAKE_OSX_SYSROOT=appletvsimulator -DCMAKE_OSX_DEPLOYMENT_TARGET=13.0 $cmakeArgs" + cmakeArgs=(-DCMAKE_SYSTEM_NAME=tvOS -DCMAKE_OSX_SYSROOT=appletvsimulator -DCMAKE_OSX_DEPLOYMENT_TARGET=13.0 "${cmakeArgs[@]}") if [[ "$__TargetArch" == x64 ]]; then - cmakeArgs="-DCMAKE_OSX_ARCHITECTURES=\"x86_64\" $cmakeArgs" + cmakeArgs=(-DCMAKE_OSX_ARCHITECTURES=x86_64 "${cmakeArgs[@]}") elif [[ "$__TargetArch" == arm64 ]]; then - cmakeArgs="-DCMAKE_OSX_ARCHITECTURES=\"arm64\" $cmakeArgs" + cmakeArgs=(-DCMAKE_OSX_ARCHITECTURES=arm64 "${cmakeArgs[@]}") else echo "Error: Unknown tvOS Simulator architecture $__TargetArch." exit 1 fi elif [[ "$targetOS" == tvos ]]; then - cmakeArgs="-C $__RepoRootDir/eng/native/tryrun_ios_tvos.cmake $cmakeArgs" + cmakeArgs=(-C "$__RepoRootDir/eng/native/tryrun_ios_tvos.cmake" "${cmakeArgs[@]}") # set default tvOS device deployment target # keep in sync with SetOSTargetMinVersions in the root Directory.Build.props - cmakeArgs="-DCMAKE_SYSTEM_NAME=tvOS -DCMAKE_OSX_SYSROOT=appletvos -DCMAKE_OSX_DEPLOYMENT_TARGET=13.0 $cmakeArgs" + cmakeArgs=(-DCMAKE_SYSTEM_NAME=tvOS -DCMAKE_OSX_SYSROOT=appletvos -DCMAKE_OSX_DEPLOYMENT_TARGET=13.0 "${cmakeArgs[@]}") if [[ "$__TargetArch" == arm64 ]]; then - cmakeArgs="-DCMAKE_OSX_ARCHITECTURES=\"arm64\" $cmakeArgs" + cmakeArgs=(-DCMAKE_OSX_ARCHITECTURES=arm64 "${cmakeArgs[@]}") else echo "Error: Unknown tvOS architecture $__TargetArch." exit 1 @@ -204,9 +205,8 @@ build_native() scan_build=scan-build fi - nextCommand="\"$__RepoRootDir/eng/native/gen-buildsys.sh\" \"$cmakeDir\" \"$intermediatesDir\" $hostArch $targetOS $__Compiler $__BuildType \"$generator\" $scan_build $cmakeArgs" - echo "Invoking $nextCommand" - eval $nextCommand + echo "Invoking \"$__RepoRootDir/eng/native/gen-buildsys.sh\" \"$cmakeDir\" \"$intermediatesDir\" $hostArch $targetOS $__Compiler $__BuildType \"$generator\" $scan_build ${cmakeArgs[*]}" + "$__RepoRootDir/eng/native/gen-buildsys.sh" "$cmakeDir" "$intermediatesDir" "$hostArch" "$targetOS" "$__Compiler" "$__BuildType" "$generator" $scan_build ${cmakeArgs[@]+"${cmakeArgs[@]}"} local exit_code="$?" if [[ "$exit_code" != 0 ]]; then @@ -389,7 +389,7 @@ while :; do cmakeargs|-cmakeargs) if [[ -n "$2" ]]; then - __CMakeArgs="$2 $__CMakeArgs" + __CMakeArgs=("$2" ${__CMakeArgs[@]+"${__CMakeArgs[@]}"}) shift else echo "ERROR: 'cmakeargs' requires a non-empty option argument" @@ -416,17 +416,17 @@ while :; do ;; keepnativesymbols|-keepnativesymbols) - __CMakeArgs="$__CMakeArgs -DCLR_CMAKE_KEEP_NATIVE_SYMBOLS=true" + __CMakeArgs=(${__CMakeArgs[@]+"${__CMakeArgs[@]}"} -DCLR_CMAKE_KEEP_NATIVE_SYMBOLS=true) ;; -fsanitize) - __CMakeArgs="$__CMakeArgs -DCLR_CMAKE_ENABLE_SANITIZERS=$2" + __CMakeArgs=(${__CMakeArgs[@]+"${__CMakeArgs[@]}"} "-DCLR_CMAKE_ENABLE_SANITIZERS=$2") EnableNativeSanitizers=$2 shift ;; -fsanitize=*) sanitizers="${lowerI/#-fsanitize=/}" # -fsanitize=address => address - __CMakeArgs="$__CMakeArgs -DCLR_CMAKE_ENABLE_SANITIZERS=$sanitizers" + __CMakeArgs=(${__CMakeArgs[@]+"${__CMakeArgs[@]}"} "-DCLR_CMAKE_ENABLE_SANITIZERS=$sanitizers") EnableNativeSanitizers=$sanitizers ;; @@ -597,7 +597,7 @@ elif [[ "$__TargetOS" == android ]]; then # nothing to do here true else - __CMakeArgs="-DFEATURE_DISTRO_AGNOSTIC_SSL=$__PortableBuild $__CMakeArgs" + __CMakeArgs=("-DFEATURE_DISTRO_AGNOSTIC_SSL=$__PortableBuild" ${__CMakeArgs[@]+"${__CMakeArgs[@]}"}) fi # Configure environment if we are doing a cross compile. diff --git a/src/coreclr/build-runtime.sh b/src/coreclr/build-runtime.sh index 6809330b216d33..0edc76329ba99d 100755 --- a/src/coreclr/build-runtime.sh +++ b/src/coreclr/build-runtime.sh @@ -100,7 +100,7 @@ __SourceDir="$__ProjectDir/src" __StaticAnalyzer=0 __UnprocessedBuildArgs= __VerboseBuild=0 -__CMakeArgs="" +__CMakeArgs=() __RequestedBuildComponents="" __SubDir="" @@ -154,10 +154,10 @@ export MSBUILDDEBUGPATH check_prereqs # Build the coreclr (native) components. -__CMakeArgs="-DCLR_CMAKE_PGO_INSTRUMENT=$__PgoInstrument -DCLR_CMAKE_OPTDATA_PATH=$__PgoOptDataPath -DCLR_CMAKE_PGO_OPTIMIZE=$__PgoOptimize -DCLI_CMAKE_FALLBACK_OS=\"$__HostFallbackOS\" $__CMakeArgs" +__CMakeArgs=("-DCLR_CMAKE_PGO_INSTRUMENT=$__PgoInstrument" "-DCLR_CMAKE_OPTDATA_PATH=$__PgoOptDataPath" "-DCLR_CMAKE_PGO_OPTIMIZE=$__PgoOptimize" "-DCLI_CMAKE_FALLBACK_OS=$__HostFallbackOS" ${__CMakeArgs[@]+"${__CMakeArgs[@]}"}) if [[ "$__SkipConfigure" == 0 && "$__CodeCoverage" == 1 ]]; then - __CMakeArgs="-DCLR_CMAKE_ENABLE_CODE_COVERAGE=1 $__CMakeArgs" + __CMakeArgs=(-DCLR_CMAKE_ENABLE_CODE_COVERAGE=1 ${__CMakeArgs[@]+"${__CMakeArgs[@]}"}) fi __CMakeTarget="" @@ -170,12 +170,12 @@ if [[ -z "$__CMakeTarget" ]]; then fi if [[ "$__TargetArch" != "$__HostArch" ]]; then - __CMakeArgs="-DCLR_CMAKE_TARGET_ARCH=$__TargetArch $__CMakeArgs" + __CMakeArgs=("-DCLR_CMAKE_TARGET_ARCH=$__TargetArch" ${__CMakeArgs[@]+"${__CMakeArgs[@]}"}) fi -eval "$__RepoRootDir/eng/native/version/copy_version_files.sh" +"$__RepoRootDir/eng/native/version/copy_version_files.sh" -build_native "$__HostOS" "$__HostArch" "$__ProjectRoot" "$__IntermediatesDir" "$__CMakeTarget" "$__CMakeArgs" "CoreCLR component" +build_native "$__HostOS" "$__HostArch" "$__ProjectRoot" "$__IntermediatesDir" "$__CMakeTarget" "CoreCLR component" ${__CMakeArgs[@]+"${__CMakeArgs[@]}"} # Build complete diff --git a/src/native/corehost/build.sh b/src/native/corehost/build.sh index b1bd4983b7973b..6919507a48ab34 100755 --- a/src/native/corehost/build.sh +++ b/src/native/corehost/build.sh @@ -14,7 +14,7 @@ __RepoRootDir="$(cd "$__scriptpath"/../../..; pwd -P)" __TargetArch=x64 __TargetOS=linux __BuildType=Debug -__CMakeArgs="" +__CMakeArgs=() __Compiler=clang __CrossBuild=0 __PortableBuild=1 @@ -59,10 +59,10 @@ __IntermediatesDir="$__RootBinDir/obj/$__TargetRid.$__BuildType" export __BinDir __IntermediatesDir __RuntimeFlavor -__CMakeArgs="-DCLI_CMAKE_FALLBACK_OS=\"$__HostFallbackOS\" -DCLI_CMAKE_COMMIT_HASH=\"$__commit_hash\" $__CMakeArgs" +__CMakeArgs=("-DCLI_CMAKE_FALLBACK_OS=$__HostFallbackOS" "-DCLI_CMAKE_COMMIT_HASH=$__commit_hash" ${__CMakeArgs[@]+"${__CMakeArgs[@]}"}) if [[ "$__TargetOS" != osx ]]; then - __CMakeArgs="-DFEATURE_DISTRO_AGNOSTIC_SSL=$__PortableBuild $__CMakeArgs" + __CMakeArgs=("-DFEATURE_DISTRO_AGNOSTIC_SSL=$__PortableBuild" ${__CMakeArgs[@]+"${__CMakeArgs[@]}"}) fi # Specify path to be set for CMAKE_INSTALL_PREFIX. @@ -77,4 +77,4 @@ setup_dirs check_prereqs # Build the installer native components. -build_native "$__TargetOS" "$__TargetArch" "$__scriptpath" "$__IntermediatesDir" "install" "$__CMakeArgs" "installer component" +build_native "$__TargetOS" "$__TargetArch" "$__scriptpath" "$__IntermediatesDir" "install" "installer component" ${__CMakeArgs[@]+"${__CMakeArgs[@]}"} diff --git a/src/native/libs/build-native.sh b/src/native/libs/build-native.sh index 05b77499d7d40a..f7c744cc7f74fe 100755 --- a/src/native/libs/build-native.sh +++ b/src/native/libs/build-native.sh @@ -29,7 +29,7 @@ handle_arguments() { __TargetArch=x64 __TargetOS=linux __BuildType=Debug -__CMakeArgs="" +__CMakeArgs=() __Compiler=clang __CrossBuild=0 __PortableBuild=1 @@ -55,8 +55,8 @@ elif [[ "$__TargetOS" == android && -z "$ROOTFS_DIR" ]]; then # nothing to do here true else - __CMakeArgs="-DFEATURE_DISTRO_AGNOSTIC_SSL=$__PortableBuild $__CMakeArgs" - __CMakeArgs="-DCMAKE_STATIC_LIB_LINK=$__StaticLibLink $__CMakeArgs" + __CMakeArgs=("-DFEATURE_DISTRO_AGNOSTIC_SSL=$__PortableBuild" ${__CMakeArgs[@]+"${__CMakeArgs[@]}"}) + __CMakeArgs=("-DCMAKE_STATIC_LIB_LINK=$__StaticLibLink" ${__CMakeArgs[@]+"${__CMakeArgs[@]}"}) if [[ "$__TargetOS" != linux-bionic && "$__TargetArch" != x86 && "$__TargetArch" != x64 && "$__TargetArch" != "$__HostArch" ]]; then __CrossBuild=1 @@ -66,20 +66,20 @@ fi if [[ "$__TargetOS" == android && -z "$ROOTFS_DIR" ]]; then # Android SDK defaults to c++_static; we only need C support - __CMakeArgs="-DANDROID_STL=none $__CMakeArgs" + __CMakeArgs=(-DANDROID_STL=none ${__CMakeArgs[@]+"${__CMakeArgs[@]}"}) elif [[ "$__TargetOS" == linux-bionic && -z "$ROOTFS_DIR" ]]; then # Android SDK defaults to c++_static; we only need C support - __CMakeArgs="-DFORCE_ANDROID_OPENSSL=1 -DANDROID_STL=none -DANDROID_FORCE_ICU_DATA_DIR=1 $__CMakeArgs" + __CMakeArgs=(-DFORCE_ANDROID_OPENSSL=1 -DANDROID_STL=none -DANDROID_FORCE_ICU_DATA_DIR=1 ${__CMakeArgs[@]+"${__CMakeArgs[@]}"}) elif [[ "$__TargetOS" == iossimulator ]]; then # set default iOS simulator deployment target # keep in sync with SetOSTargetMinVersions in the root Directory.Build.props - __CMakeArgs="-DCMAKE_SYSTEM_NAME=iOS -DCMAKE_OSX_SYSROOT=iphonesimulator -DCMAKE_OSX_DEPLOYMENT_TARGET=13.0 $__CMakeArgs" + __CMakeArgs=(-DCMAKE_SYSTEM_NAME=iOS -DCMAKE_OSX_SYSROOT=iphonesimulator -DCMAKE_OSX_DEPLOYMENT_TARGET=13.0 ${__CMakeArgs[@]+"${__CMakeArgs[@]}"}) if [[ "$__TargetArch" == x64 ]]; then - __CMakeArgs="-DCMAKE_OSX_ARCHITECTURES=\"x86_64\" $__CMakeArgs" + __CMakeArgs=(-DCMAKE_OSX_ARCHITECTURES=x86_64 ${__CMakeArgs[@]+"${__CMakeArgs[@]}"}) elif [[ "$__TargetArch" == x86 ]]; then - __CMakeArgs="-DCMAKE_OSX_ARCHITECTURES=\"i386\" $__CMakeArgs" + __CMakeArgs=(-DCMAKE_OSX_ARCHITECTURES=i386 ${__CMakeArgs[@]+"${__CMakeArgs[@]}"}) elif [[ "$__TargetArch" == arm64 ]]; then - __CMakeArgs="-DCMAKE_OSX_ARCHITECTURES=\"arm64\" $__CMakeArgs" + __CMakeArgs=(-DCMAKE_OSX_ARCHITECTURES=arm64 ${__CMakeArgs[@]+"${__CMakeArgs[@]}"}) else echo "Error: Unknown iOS Simulator architecture $__TargetArch." exit 1 @@ -87,11 +87,11 @@ elif [[ "$__TargetOS" == iossimulator ]]; then elif [[ "$__TargetOS" == ios ]]; then # set default iOS device deployment target # keep in sync with SetOSTargetMinVersions in the root Directory.Build.props - __CMakeArgs="-DCMAKE_SYSTEM_NAME=iOS -DCMAKE_OSX_SYSROOT=iphoneos -DCMAKE_OSX_DEPLOYMENT_TARGET=13.0 $__CMakeArgs" + __CMakeArgs=(-DCMAKE_SYSTEM_NAME=iOS -DCMAKE_OSX_SYSROOT=iphoneos -DCMAKE_OSX_DEPLOYMENT_TARGET=13.0 ${__CMakeArgs[@]+"${__CMakeArgs[@]}"}) if [[ "$__TargetArch" == arm64 ]]; then - __CMakeArgs="-DCMAKE_OSX_ARCHITECTURES=\"arm64\" $__CMakeArgs" + __CMakeArgs=(-DCMAKE_OSX_ARCHITECTURES=arm64 ${__CMakeArgs[@]+"${__CMakeArgs[@]}"}) elif [[ "$__TargetArch" == arm ]]; then - __CMakeArgs="-DCMAKE_OSX_ARCHITECTURES=\"armv7;armv7s\" $__CMakeArgs" + __CMakeArgs=("-DCMAKE_OSX_ARCHITECTURES=armv7;armv7s" ${__CMakeArgs[@]+"${__CMakeArgs[@]}"}) else echo "Error: Unknown iOS architecture $__TargetArch." exit 1 @@ -99,11 +99,11 @@ elif [[ "$__TargetOS" == ios ]]; then elif [[ "$__TargetOS" == tvossimulator ]]; then # set default tvOS simulator deployment target # keep in sync with SetOSTargetMinVersions in the root Directory.Build.props - __CMakeArgs="-DCMAKE_SYSTEM_NAME=tvOS -DCMAKE_OSX_SYSROOT=appletvsimulator -DCMAKE_OSX_DEPLOYMENT_TARGET=13.0 $__CMakeArgs" + __CMakeArgs=(-DCMAKE_SYSTEM_NAME=tvOS -DCMAKE_OSX_SYSROOT=appletvsimulator -DCMAKE_OSX_DEPLOYMENT_TARGET=13.0 ${__CMakeArgs[@]+"${__CMakeArgs[@]}"}) if [[ "$__TargetArch" == x64 ]]; then - __CMakeArgs="-DCMAKE_OSX_ARCHITECTURES=\"x86_64\" $__CMakeArgs" + __CMakeArgs=(-DCMAKE_OSX_ARCHITECTURES=x86_64 ${__CMakeArgs[@]+"${__CMakeArgs[@]}"}) elif [[ "$__TargetArch" == arm64 ]]; then - __CMakeArgs="-DCMAKE_OSX_ARCHITECTURES=\"arm64\" $__CMakeArgs" + __CMakeArgs=(-DCMAKE_OSX_ARCHITECTURES=arm64 ${__CMakeArgs[@]+"${__CMakeArgs[@]}"}) else echo "Error: Unknown tvOS Simulator architecture $__TargetArch." exit 1 @@ -111,9 +111,9 @@ elif [[ "$__TargetOS" == tvossimulator ]]; then elif [[ "$__TargetOS" == tvos ]]; then # set default tvOS device deployment target # keep in sync with the root Directory.Build.props - __CMakeArgs="-DCMAKE_SYSTEM_NAME=tvOS -DCMAKE_OSX_SYSROOT=appletvos -DCMAKE_OSX_DEPLOYMENT_TARGET=13.0 $__CMakeArgs" + __CMakeArgs=(-DCMAKE_SYSTEM_NAME=tvOS -DCMAKE_OSX_SYSROOT=appletvos -DCMAKE_OSX_DEPLOYMENT_TARGET=13.0 ${__CMakeArgs[@]+"${__CMakeArgs[@]}"}) if [[ "$__TargetArch" == arm64 ]]; then - __CMakeArgs="-DCMAKE_OSX_ARCHITECTURES=\"arm64\" $__CMakeArgs" + __CMakeArgs=(-DCMAKE_OSX_ARCHITECTURES=arm64 ${__CMakeArgs[@]+"${__CMakeArgs[@]}"}) else echo "Error: Unknown tvOS architecture $__TargetArch." exit 1 @@ -137,4 +137,4 @@ setup_dirs check_prereqs # Build the corefx native components. -build_native "$__TargetOS" "$__TargetArch" "$__nativeroot" "$__IntermediatesDir" "install" "$__CMakeArgs" "native libraries component" +build_native "$__TargetOS" "$__TargetArch" "$__nativeroot" "$__IntermediatesDir" "install" "native libraries component" ${__CMakeArgs[@]+"${__CMakeArgs[@]}"} diff --git a/src/tests/build.sh b/src/tests/build.sh index 3f3e8b74360300..9afdfb80d811e4 100755 --- a/src/tests/build.sh +++ b/src/tests/build.sh @@ -60,7 +60,7 @@ build_Tests() if [[ "$__SkipNative" != 1 && "$__GenerateLayoutOnly" != 1 && "$__CopyNativeTestBinaries" != 1 && \ "$__TargetOS" != "android" && "$__TargetOS" != "ios" && "$__TargetOS" != "iossimulator" && "$__TargetOS" != "tvos" && "$__TargetOS" != "tvossimulator" ]]; then - build_native "$__TargetOS" "$__TargetArch" "$__TestDir" "$__NativeTestIntermediatesDir" "install" "$__CMakeArgs" "CoreCLR test component" + build_native "$__TargetOS" "$__TargetArch" "$__TestDir" "$__NativeTestIntermediatesDir" "install" "CoreCLR test component" ${__CMakeArgs[@]+"${__CMakeArgs[@]}"} if [[ "$?" -ne 0 ]]; then echo "${__ErrMsgPrefix}${__MsgPrefix}Error: native test build failed. Refer to the build log files for details (above)" @@ -370,7 +370,7 @@ __SkipRestorePackages=0 __SourceDir="$__ProjectDir/src" __UnprocessedBuildArgs=() __VerboseBuild=0 -__CMakeArgs="" +__CMakeArgs=() __Priority=0 __Mono=0 __MonoAot=0 @@ -391,10 +391,10 @@ fi if [[ $__Mono -eq 1 ]]; then __RuntimeFlavor="mono" - __CMakeArgs="-DCMAKE_BUILD_RUNTIME_FLAVOR=Mono $__CMakeArgs" + __CMakeArgs=(-DCMAKE_BUILD_RUNTIME_FLAVOR=Mono ${__CMakeArgs[@]+"${__CMakeArgs[@]}"}) else __RuntimeFlavor="coreclr" - __CMakeArgs="-DCMAKE_BUILD_RUNTIME_FLAVOR=CoreCLR $__CMakeArgs" + __CMakeArgs=(-DCMAKE_BUILD_RUNTIME_FLAVOR=CoreCLR ${__CMakeArgs[@]+"${__CMakeArgs[@]}"}) fi # Get the number of processors available to the scheduler From 1b41fec6a52ea6075d3b61baa0dc9a89a0588fdf Mon Sep 17 00:00:00 2001 From: ApparentlyPlus Date: Tue, 15 Sep 2026 15:44:42 +0300 Subject: [PATCH 2/3] Split user CMakeArgs into separate items --- src/coreclr/runtime.proj | 2 +- src/native/corehost/corehost.proj | 6 +++++- src/native/libs/build-native.proj | 6 +++++- 3 files changed, 11 insertions(+), 3 deletions(-) diff --git a/src/coreclr/runtime.proj b/src/coreclr/runtime.proj index b20e9a35fc87ab..da62330489286e 100644 --- a/src/coreclr/runtime.proj +++ b/src/coreclr/runtime.proj @@ -22,7 +22,7 @@ DependsOnTargets="$(BuildRuntimeDependsOnTargets)" BeforeTargets="Build"> - <_CMakeArgs Include="$(CMakeArgs)" /> + <_CMakeArgs Include="$([MSBuild]::Unescape($(CMakeArgs.Trim().Replace(' ', ';'))))" /> <_CoreClrBuildArg Include="@(_CMakeArgs->'-cmakeargs "%(Identity)"')" /> <_CoreClrBuildArg Condition="'$(TargetArchitecture)' != ''" Include="-$(TargetArchitecture)" /> <_CoreClrBuildArg Include="-$(Configuration.ToLower())" /> diff --git a/src/native/corehost/corehost.proj b/src/native/corehost/corehost.proj index 6c0160c61aa655..9a3ebe2cfee87d 100644 --- a/src/native/corehost/corehost.proj +++ b/src/native/corehost/corehost.proj @@ -77,13 +77,17 @@ $(BuildArgs) -cmakeargs -DCLR_CMAKE_CXX_ABI_LIBRARY=$(CxxAbiLibrary) + + <_UserCMakeArgs Include="$([MSBuild]::Unescape($(CMakeArgs.Trim().Replace(' ', ';'))))" /> + + $(BuildArgs) -configureonly $(BuildArgs) -portablebuild=false $(BuildArgs) -keepnativesymbols $(BuildArgs) -cross $(BuildArgs) $(CppCompilerAndLinker) - $(BuildArgs) -cmakeargs "$(CMakeArgs)" + $(BuildArgs) @(_UserCMakeArgs->'-cmakeargs "%(Identity)"', ' ') $(BuildArgs) -ninja $(BuildArgs) -ninja false $(BuildArgs) -runtimeflavor $(RuntimeFlavor) diff --git a/src/native/libs/build-native.proj b/src/native/libs/build-native.proj index ac7308eb4e0f25..752a2b368599de 100644 --- a/src/native/libs/build-native.proj +++ b/src/native/libs/build-native.proj @@ -2,6 +2,10 @@ + + <_UserCMakeArgs Include="$([MSBuild]::Unescape($(CMakeArgs.Trim().Replace(' ', ';'))))" /> + + $(ArtifactsObjDir)_version.h @@ -14,7 +18,7 @@ <_BuildNativeArgs Condition="'$(EnableNativeSanitizers)' != ''">$(_BuildNativeArgs) -fsanitize=$(EnableNativeSanitizers) <_BuildNativeArgs Condition="'$(OfficialBuildId)' != ''">$(_BuildNativeArgs) /p:OfficialBuildId="$(OfficialBuildId)" - <_CMakeArgs Condition="'$(CMakeArgs)' != ''"> -cmakeargs "$(CMakeArgs)" + <_CMakeArgs Condition="'$(CMakeArgs)' != ''"> @(_UserCMakeArgs->'-cmakeargs "%(Identity)"', ' ') <_CMakeArgs Condition="'$(WasmEnableThreads)' == 'true'">$(_CMakeArgs) -cmakeargs "-DCLR_CMAKE_WASM_ENABLE_THREADS=1" <_BuildNativeArgs>$(_BuildNativeArgs)$(_CMakeArgs) @(NativeCMakeArg, ' ') From 12d886d1baf33b95c73a212442027a2fa06ed459 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Alexander=20K=C3=B6plinger?= Date: Thu, 24 Sep 2026 13:25:22 +0200 Subject: [PATCH 3/3] Preserve CMake argument quoting and order through native builds Forward Unix user arguments after -- instead of splitting them on whitespace in MSBuild. Preserve command-line property escaping, remove obsolete host-path quoting, and cover all three native build routes with regression tests. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> Copilot-Session: 83232ab6-2c12-470f-9469-6d702d797065 --- docs/workflow/building/coreclr/README.md | 14 ++++++++++++++ eng/build.sh | 6 ++++-- eng/native/build-commons.sh | 9 ++++++++- src/coreclr/runtime.proj | 6 +++--- src/native/corehost/corehost.proj | 9 ++------- src/native/libs/build-native.proj | 8 ++------ 6 files changed, 33 insertions(+), 19 deletions(-) diff --git a/docs/workflow/building/coreclr/README.md b/docs/workflow/building/coreclr/README.md index a9ddf55587034b..7a868ab78dddbe 100644 --- a/docs/workflow/building/coreclr/README.md +++ b/docs/workflow/building/coreclr/README.md @@ -121,6 +121,20 @@ To use *Ninja* instead of *Make* on non-Windows: You can also pass some extra compiler/linker flags to the CoreCLR build. Set the `EXTRA_CFLAGS`, `EXTRA_CXXFLAGS`, and `EXTRA_LDFLAGS` as you see fit for this purpose. The build script will consume them and then set the environment variables that will ultimately affect your build (i.e. those same ones without the `EXTRA_` prefix). Don't set the final ones directly yourself, as that is known to lead to potential failures in configure-time tests. +### CMake Arguments + +On Unix, the top-level `build.sh` accepts a shell-quoted command fragment with `--cmakeargs`. Quote values containing spaces inside that fragment. Multiple options, including repeated `--cmakeargs` fragments, reach CMake in their original order: + +```bash +./build.sh clr --cmakeargs "-DFIRST=1 -DSECOND=2" --cmakeargs "-DCMAKE_C_FLAGS='-O2 -g'" +``` + +When invoking `src/coreclr/build-runtime.sh`, `src/native/corehost/build.sh`, or `src/native/libs/build-native.sh` directly, each `-cmakeargs` accepts one literal argument. Alternatively, put `--` after all build-script options and follow it with CMake arguments using normal shell quoting. Arguments after `--` retain their order and override earlier definitions: + +```bash +./src/coreclr/build-runtime.sh -component jit -- -DFIRST=1 -DFIRST=2 "-DCMAKE_C_FLAGS=-O2 -g" +``` + ### Native ARM64 Building on Windows Currently, the runtime repo supports building CoreCLR directly on Windows ARM64 without the need to cross-compile, albeit it is still in an experimental phase. To do this, you need to install the ARM64 build tools and Windows SDK for Visual Studio, in addition to all the requirements outlined in the [Windows Requirements doc](/docs/workflow/requirements/windows-requirements.md). diff --git a/eng/build.sh b/eng/build.sh index a7735e6361a7f8..0a99e76d5dbcaa 100755 --- a/eng/build.sh +++ b/eng/build.sh @@ -622,8 +622,10 @@ initDistroRid "$os" "$arch" "$crossBuild" # The later changes are ignored when using the cache. export DOTNETSDK_ALLOW_TARGETING_PACK_CACHING=0 -# URL-encode space (%20) to avoid quoting issues until the msbuild call in /eng/common/tools.sh. -# In *proj files (XML docs), URL-encoded string are rendered in their decoded form. +# Preserve the command fragment through MSBuild's command-line property parsing. +cmakeargs="${cmakeargs//%/%25}" +cmakeargs="${cmakeargs//\"/%22}" +cmakeargs="${cmakeargs//;/%3B}" cmakeargs="${cmakeargs// /%20}" arguments+=("/p:TargetArchitecture=$arch" "/p:BuildArchitecture=$hostArch") arguments+=("/p:CMakeArgs=\"$cmakeargs\"" ${extraargs[@]+"${extraargs[@]}"}) diff --git a/eng/native/build-commons.sh b/eng/native/build-commons.sh index 6ae4db70da8caa..bcd417cd3d3b73 100755 --- a/eng/native/build-commons.sh +++ b/eng/native/build-commons.sh @@ -281,7 +281,8 @@ usage() echo "-ci: indicates if this is a CI build." echo "-clang: optional argument to build using clang in PATH (default)." echo "-clangx.y: optional argument to build using clang version x.y." - echo "-cmakeargs: user-settable additional arguments passed to CMake." + echo "-cmakeargs: one literal argument passed to CMake; may be repeated." + echo "--: pass all remaining arguments to CMake in the given order." echo "-configureonly: do not perform any builds; just configure the build." echo "-cross: optional argument to signify cross compilation," echo " will use ROOTFS_DIR environment variable if set." @@ -335,6 +336,12 @@ while :; do break fi + if [[ "$1" == "--" ]]; then + shift + __CMakeArgs=(${__CMakeArgs[@]+"${__CMakeArgs[@]}"} "$@") + break + fi + lowerI="$(echo "${1/--/-}" | tr "[:upper:]" "[:lower:]")" case "$lowerI" in -\?|-h|-help) diff --git a/src/coreclr/runtime.proj b/src/coreclr/runtime.proj index da62330489286e..eb8bdcfad7c973 100644 --- a/src/coreclr/runtime.proj +++ b/src/coreclr/runtime.proj @@ -22,8 +22,7 @@ DependsOnTargets="$(BuildRuntimeDependsOnTargets)" BeforeTargets="Build"> - <_CMakeArgs Include="$([MSBuild]::Unescape($(CMakeArgs.Trim().Replace(' ', ';'))))" /> - <_CoreClrBuildArg Include="@(_CMakeArgs->'-cmakeargs "%(Identity)"')" /> + <_CoreClrBuildArg Condition="$([MSBuild]::IsOsPlatform(Windows))" Include="-cmakeargs "$(CMakeArgs)"" /> <_CoreClrBuildArg Condition="'$(TargetArchitecture)' != ''" Include="-$(TargetArchitecture)" /> <_CoreClrBuildArg Include="-$(Configuration.ToLower())" /> <_CoreClrBuildArg Include="$(CppCompilerAndLinker)" /> @@ -53,7 +52,7 @@ <_CoreClrBuildArg Include="-targetrid $(TargetRid)" /> <_CoreClrBuildArg Include="-cmakeargs "-DCLR_DOTNET_RID=$(PortableTargetRid)"" /> <_CoreClrBuildArg Condition="'$(BuildSubdirectory)' != ''" Include="-subdir $(BuildSubdirectory)" /> - <_CoreClrBuildArg Include="-cmakeargs "-DCLR_DOTNET_HOST_PATH='$(DOTNET_HOST_PATH)'"" /> + <_CoreClrBuildArg Include="-cmakeargs "-DCLR_DOTNET_HOST_PATH=$(DOTNET_HOST_PATH)"" /> <_CoreClrBuildArg Condition="'$(HasCdacBuildTool)' == 'true'" Include="-cmakeargs "-DCDAC_BUILD_TOOL_BINARY_PATH=$(RuntimeBinDir)cdac-build-tool\cdac-build-tool.dll"" /> <_CoreClrBuildArg Condition="'$(FeatureXplatEventSource)' == 'false'" Include="-cmakeargs "-DFEATURE_EVENTSOURCE_XPLAT=0"" /> <_CoreClrBuildArg Condition="'$(FeatureInterpreter)' == 'true'" Include="-cmakeargs "-DFEATURE_INTERPRETER=1"" /> @@ -116,6 +115,7 @@ <_CoreClrBuildScript Condition="$([MSBuild]::IsOsPlatform(Windows))">build-runtime.cmd <_CoreClrBuildScript Condition="!$([MSBuild]::IsOsPlatform(Windows))">build-runtime.sh <_CoreClrBuildCommand>"$(MSBuildThisFileDirectory)$(_CoreClrBuildScript)" @(_CoreClrBuildArg, ' ') @(NativeCMakeArg, ' ') + <_CoreClrBuildCommand Condition="!$([MSBuild]::IsOsPlatform(Windows))">$(_CoreClrBuildCommand) -- $(CMakeArgs) diff --git a/src/native/corehost/corehost.proj b/src/native/corehost/corehost.proj index 9a3ebe2cfee87d..b6755148f3f3df 100644 --- a/src/native/corehost/corehost.proj +++ b/src/native/corehost/corehost.proj @@ -77,17 +77,12 @@ $(BuildArgs) -cmakeargs -DCLR_CMAKE_CXX_ABI_LIBRARY=$(CxxAbiLibrary) - - <_UserCMakeArgs Include="$([MSBuild]::Unescape($(CMakeArgs.Trim().Replace(' ', ';'))))" /> - - $(BuildArgs) -configureonly $(BuildArgs) -portablebuild=false $(BuildArgs) -keepnativesymbols $(BuildArgs) -cross $(BuildArgs) $(CppCompilerAndLinker) - $(BuildArgs) @(_UserCMakeArgs->'-cmakeargs "%(Identity)"', ' ') $(BuildArgs) -ninja $(BuildArgs) -ninja false $(BuildArgs) -runtimeflavor $(RuntimeFlavor) @@ -107,8 +102,8 @@ Use IgnoreStandardErrorWarningFormat because Arcade sets WarnAsError and we want to avoid upgrading compiler warnings to errors in release branches. --> - - + + $(ArtifactsObjDir)_version.h @@ -18,7 +14,7 @@ <_BuildNativeArgs Condition="'$(EnableNativeSanitizers)' != ''">$(_BuildNativeArgs) -fsanitize=$(EnableNativeSanitizers) <_BuildNativeArgs Condition="'$(OfficialBuildId)' != ''">$(_BuildNativeArgs) /p:OfficialBuildId="$(OfficialBuildId)" - <_CMakeArgs Condition="'$(CMakeArgs)' != ''"> @(_UserCMakeArgs->'-cmakeargs "%(Identity)"', ' ') + <_CMakeArgs Condition="'$(CMakeArgs)' != '' and $([MSBuild]::IsOsPlatform(Windows))"> -cmakeargs "$(CMakeArgs)" <_CMakeArgs Condition="'$(WasmEnableThreads)' == 'true'">$(_CMakeArgs) -cmakeargs "-DCLR_CMAKE_WASM_ENABLE_THREADS=1" <_BuildNativeArgs>$(_BuildNativeArgs)$(_CMakeArgs) @(NativeCMakeArg, ' ') @@ -60,7 +56,7 @@ --> <_BuildNativeCompilerArg Condition="'$(BuildNativeCompiler)' != ''"> $(BuildNativeCompiler) <_BuildNativeUnixArgs>$(_BuildNativeArgs)$(_ProcessorCountArg)$(_PortableBuildArg)$(_CrossBuildArg)$(_BuildNativeCompilerArg)$(_KeepNativeSymbolsBuildArg) $(CppCompilerAndLinker) - <_BuildNativeBuildCommand>"$(MSBuildThisFileDirectory)build-native.sh" $(_BuildNativeUnixArgs) + <_BuildNativeBuildCommand>"$(MSBuildThisFileDirectory)build-native.sh" $(_BuildNativeUnixArgs) -- $(CMakeArgs)