# CMake automatically reads `CFLAGS`, `CXXFLAGS`, `LDFLAGS`, etc. from the # environment and uses them to populate its default flag variables -- but the # Swift build system blows away `CMAKE_C{XX}_FLAGS` without picking up the # environment. These need to be picked up again to not be ignored. --- a/swift/utils/build-script-impl +++ b/swift/utils/build-script-impl @@ -1819,10 +1819,10 @@ for host in "${ALL_HOSTS[@]}"; do cmake_options=( "${cmake_options[@]}" - -DCMAKE_C_FLAGS="$(swift_c_flags ${host})" - -DCMAKE_CXX_FLAGS="$(swift_c_flags ${host})" - -DCMAKE_C_FLAGS_RELWITHDEBINFO="-O2 -DNDEBUG" - -DCMAKE_CXX_FLAGS_RELWITHDEBINFO="-O2 -DNDEBUG" + -DCMAKE_C_FLAGS="${CFLAGS} $(swift_c_flags ${host})" + -DCMAKE_CXX_FLAGS="${CXXFLAGS} $(swift_c_flags ${host})" + -DCMAKE_C_FLAGS_RELWITHDEBINFO="${CFLAGS} -O2 -DNDEBUG" + -DCMAKE_CXX_FLAGS_RELWITHDEBINFO="${CXXFLAGS} -O2 -DNDEBUG" -DCMAKE_BUILD_TYPE:STRING="${SWIFT_BUILD_TYPE}" -DLLVM_ENABLE_ASSERTIONS:BOOL=$(true_false "${SWIFT_ENABLE_ASSERTIONS}") -DSWIFT_ANALYZE_CODE_COVERAGE:STRING=$(toupper "${SWIFT_ANALYZE_CODE_COVERAGE}") @@ -2229,8 +2229,8 @@ for host in "${ALL_HOSTS[@]}"; do cmake_options=( "${cmake_options[@]}" -C${LLDB_SOURCE_DIR}/cmake/caches/${cmake_cache} - -DCMAKE_C_FLAGS="$(llvm_c_flags ${host})" - -DCMAKE_CXX_FLAGS="$(llvm_c_flags ${host})" + -DCMAKE_C_FLAGS="${CFLAGS} $(llvm_c_flags ${host})" + -DCMAKE_CXX_FLAGS="${CXXFLAGS} $(llvm_c_flags ${host})" -DCMAKE_BUILD_TYPE:STRING="${LLDB_BUILD_TYPE}" -DLLDB_SWIFTC:PATH=${SWIFTC_BIN} -DLLDB_SWIFT_LIBS:PATH="$(build_directory ${LOCAL_HOST} swift)/lib/swift" --- a/swift/utils/swift_build_support/swift_build_support/products/llvm.py +++ b/swift/utils/swift_build_support/swift_build_support/products/llvm.py @@ -284,10 +284,10 @@ class LLVM(cmake_product.CMakeProduct): # llvm/tools, e.g. to build LLDB. llvm_c_flags = ' '.join(self.llvm_c_flags(platform, arch)) - llvm_cmake_options.define('CMAKE_C_FLAGS', llvm_c_flags) - llvm_cmake_options.define('CMAKE_CXX_FLAGS', llvm_c_flags) - llvm_cmake_options.define('CMAKE_C_FLAGS_RELWITHDEBINFO', '-O2 -DNDEBUG') - llvm_cmake_options.define('CMAKE_CXX_FLAGS_RELWITHDEBINFO', '-O2 -DNDEBUG') + llvm_cmake_options.define('CMAKE_C_FLAGS', ' '.join([os.environ.get('CFLAGS', ''), llvm_c_flags])) + llvm_cmake_options.define('CMAKE_CXX_FLAGS', ' '.join([os.environ.get('CXXFLAGS', ''), llvm_c_flags])) + llvm_cmake_options.define('CMAKE_C_FLAGS_RELWITHDEBINFO', ' '.join([os.environ.get('CFLAGS', ''), '-O2 -DNDEBUG'])) + llvm_cmake_options.define('CMAKE_CXX_FLAGS_RELWITHDEBINFO', ' '.join([os.environ.get('CXXFLAGS', ''), '-O2 -DNDEBUG'])) llvm_cmake_options.define('CMAKE_BUILD_TYPE:STRING', self.args.llvm_build_variant) llvm_cmake_options.define('LLVM_TOOL_SWIFT_BUILD:BOOL', 'FALSE') --- a/swift/utils/swift_build_support/swift_build_support/products/product.py +++ b/swift/utils/swift_build_support/swift_build_support/products/product.py @@ -450,8 +450,8 @@ class Product(object): (platform, arch) = host_target.split('-') common_c_flags = ' '.join(self.common_cross_c_flags(platform, arch)) - self.cmake_options.define('CMAKE_C_FLAGS', common_c_flags) - self.cmake_options.define('CMAKE_CXX_FLAGS', common_c_flags) + self.cmake_options.define('CMAKE_C_FLAGS', ' '.join([os.environ.get('CFLAGS', ''), common_c_flags])) + self.cmake_options.define('CMAKE_CXX_FLAGS', ' '.join([os.environ.get('CXXFLAGS', ''), common_c_flags])) toolchain_file = None if self.is_darwin_host(host_target): --- a/swift/SwiftCompilerSources/CMakeLists.txt +++ b/swift/SwiftCompilerSources/CMakeLists.txt @@ -222,6 +222,11 @@ function(add_swift_compiler_modules_library name) list(APPEND sdk_option "-I" "${swift_exec_bin_dir}/../lib" "-I" "${sdk_path}/usr/lib") endif() + separate_arguments(cxxflags NATIVE_COMMAND "${CMAKE_CXX_FLAGS}") + foreach(flag IN LISTS cxxflags) + list(APPEND swift_compile_options "-Xcc" "${flag}") + endforeach() + set(all_obj_files) set(all_module_targets) set(all_module_files) --- a/swift/cmake/modules/AddPureSwift.cmake +++ b/swift/cmake/modules/AddPureSwift.cmake @@ -110,6 +110,11 @@ function(_set_swift_cxx_interop_options name) "-cxx-interoperability-mode=default" ) endif() + + separate_arguments(cxxflags NATIVE_COMMAND "${CMAKE_CXX_FLAGS}") + foreach(flag IN LISTS cxxflags) + target_compile_options(${name} PRIVATE "SHELL: -Xcc ${flag}") + endforeach() endfunction() function(_set_pure_swift_link_flags name relpath_to_lib_dir) --- a/swift/stdlib/cmake/modules/SwiftSource.cmake +++ b/swift/stdlib/cmake/modules/SwiftSource.cmake @@ -138,6 +138,12 @@ function(handle_swift_sources endif() endif() list(APPEND swift_compile_flags "-color-diagnostics") + + separate_arguments(cxxflags NATIVE_COMMAND "${CMAKE_CXX_FLAGS}") + foreach(flag IN LISTS cxxflags) + list(APPEND swift_compile_flags "-Xcc" "${flag}") + endforeach() + _compile_swift_files( dependency_target module_dependency_target --- a/swift-driver/Utilities/build-script-helper.py +++ b/swift-driver/Utilities/build-script-helper.py @@ -4,6 +4,7 @@ import argparse import os import json import platform +import shlex import shutil import subprocess import sys @@ -117,6 +118,10 @@ def get_swiftpm_options(args): if args.action == 'install': swiftpm_args += ['-Xswiftc', '-no-toolchain-stdlib-rpath'] + cxxflags = shlex.split(os.getenv('CXXFLAGS', '')) + for flag in cxxflags: + swiftpm_args.extend(['-Xcc', flag]) + return swiftpm_args def install_binary(file, source_dir, install_dir, verbose): @@ -460,9 +465,7 @@ def build_llbuild_using_cmake(args, target, swiftc_exec, build_dir, base_cmake_f mkdir_p(llbuild_api_dir) subprocess.check_call(['touch', os.path.join(llbuild_api_dir, 'codemodel-v2')]) flags = [ - '-DCMAKE_C_COMPILER:=clang', - '-DCMAKE_CXX_COMPILER:=clang++', - '-DCMAKE_CXX_FLAGS=-target %s' % target, + '-DCMAKE_CXX_FLAGS=%s -target %s' % (os.getenv('CXXFLAGS', ''), target), '-DLLBUILD_SUPPORT_BINDINGS:=Swift' ] llbuild_cmake_flags = base_cmake_flags + flags @@ -544,6 +547,9 @@ def cmake_build(args, swiftc_exec, cmake_args, swift_flags, source_path, args.cmake_bin, '-G', 'Ninja', '-DCMAKE_MAKE_PROGRAM=%s' % args.ninja_bin, '-DCMAKE_BUILD_TYPE:=Release', + '-DCMAKE_C_COMPILER:=clang', + '-DCMAKE_CXX_COMPILER:=clang++', + '-DCMAKE_CXX_FLAGS=' + os.getenv('CXXFLAGS', ''), '-DCMAKE_Swift_FLAGS=' + ' '.join(swift_flags), '-DCMAKE_Swift_COMPILER:=%s' % (swiftc_exec), ] + cmake_args + [source_path] --- a/swiftpm/Sources/Build/BuildDescription/ClangModuleBuildDescription.swift +++ b/swiftpm/Sources/Build/BuildDescription/ClangModuleBuildDescription.swift @@ -19,6 +19,7 @@ import struct PackageGraph.ResolvedModule import struct SPMBuildCore.BuildParameters import struct SPMBuildCore.BuildToolPluginInvocationResult import struct SPMBuildCore.CommandPluginResult +import enum TSCBasic.ProcessEnv @available(*, deprecated, renamed: "ClangModuleBuildDescription") public typealias ClangTargetBuildDescription = ClangModuleBuildDescription @@ -365,6 +366,9 @@ public final class ClangModuleBuildDescription { args += self.buildParameters.toolchain.extraFlags.cxxCompilerFlags // User arguments (from -Xcxx) should follow generated arguments to allow user overrides args += self.buildParameters.flags.cxxCompilerFlags + if let cxxflags = ProcessEnv.vars["CXXFLAGS"] { + args += cxxflags.split(separator: " ").map(String.init) + } } // Enable the correct lto mode if requested. --- a/swiftpm/Utilities/bootstrap +++ b/swiftpm/Utilities/bootstrap @@ -22,6 +22,7 @@ import os import pathlib import platform import re +import shlex import shutil import subprocess import sys @@ -554,6 +555,7 @@ def build_with_cmake(args, cmake_args, ninja_args, source_path, build_dir, cmake cmd = [ "env"] + cmake_env + ["MACOSX_DEPLOYMENT_TARGET=%s" % (g_macos_deployment_target), + 'CXXFLAGS=%s' % os.getenv('CXXFLAGS', ''), args.cmake_path, "-G", "Ninja", "-DCMAKE_MAKE_PROGRAM=%s" % args.ninja_path, "-DCMAKE_BUILD_TYPE:=Debug", @@ -881,6 +883,10 @@ def get_swiftpm_flags(args): # Enforce explicit target dependencies # build_flags.extend(["--explicit-target-dependency-import-check", "error"]) + cxxflags = shlex.split(os.getenv('CXXFLAGS', '')) + for flag in cxxflags: + build_flags.extend(['-Xcc', flag]) + return build_flags if __name__ == '__main__':