diff --git a/utils/swift_build_support/swift_build_support/products/cmark.py b/utils/swift_build_support/swift_build_support/products/cmark.py index 832126c204c6c..2a212b94ad29c 100644 --- a/utils/swift_build_support/swift_build_support/products/cmark.py +++ b/utils/swift_build_support/swift_build_support/products/cmark.py @@ -10,8 +10,6 @@ # # ---------------------------------------------------------------------------- -from build_swift.build_swift.wrappers import xcrun - from . import cmake_product from . import earlyswiftdriver @@ -61,20 +59,12 @@ def build(self, host_target): host_target.startswith("appletv") or \ host_target.startswith("watch"): - cmake_os_sysroot = xcrun.sdk_path(platform) - - cmake_osx_deployment_target = '' - if platform == "macosx": - cmake_osx_deployment_target = self.args.darwin_deployment_version_osx - 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_OSX_SYSROOT:PATH', cmake_os_sysroot) - self.cmake_options.define('CMAKE_OSX_DEPLOYMENT_TARGET', - cmake_osx_deployment_target) - self.cmake_options.define('CMAKE_OSX_ARCHITECTURES', arch) + toolchain_file = self.generate_darwin_toolchain_file(platform, arch) + self.cmake_options.define('CMAKE_TOOLCHAIN_FILE:PATH', toolchain_file) self.build_with_cmake(["all"], self.args.cmark_build_variant, []) diff --git a/utils/swift_build_support/swift_build_support/products/product.py b/utils/swift_build_support/swift_build_support/products/product.py index 74acc9fc92e4b..fd202b8cf1738 100644 --- a/utils/swift_build_support/swift_build_support/products/product.py +++ b/utils/swift_build_support/swift_build_support/products/product.py @@ -13,7 +13,10 @@ import abc import os +from build_swift.build_swift.wrappers import xcrun + from .. import cmake +from .. import shell from .. import targets @@ -204,14 +207,15 @@ def install_toolchain_path(self, host_target): return targets.toolchain_path(install_destdir, self.args.install_prefix) + def is_darwin_host(self, host_target): + return host_target.startswith("macosx") or \ + host_target.startswith("iphone") or \ + host_target.startswith("appletv") or \ + host_target.startswith("watch") + def should_include_host_in_lipo(self, host_target): - if self.args.cross_compile_hosts: - if host_target.startswith("macosx") or \ - host_target.startswith("iphone") or \ - host_target.startswith("appletv") or \ - host_target.startswith("watch"): - return True - return False + return self.args.cross_compile_hosts and \ + self.is_darwin_host(host_target) def host_install_destdir(self, host_target): if self.args.cross_compile_hosts: @@ -233,38 +237,62 @@ def is_cross_compile_target(self, host_target): return self.args.cross_compile_hosts and \ host_target in self.args.cross_compile_hosts - # TODO: Remove once we've moved over to cmake toolchains - def common_cross_c_flags(self, platform, arch): - cross_flags = [] + def generate_darwin_toolchain_file(self, platform, arch): + shell.makedirs(self.build_dir) + toolchain_file = os.path.join(self.build_dir, 'BuildScriptToolchain.cmake') + cmake_osx_sysroot = xcrun.sdk_path(platform) + + target = None if platform == 'macosx': target = '{}-apple-macosx{}'.format( arch, self.args.darwin_deployment_version_osx) - cross_flags.extend(['-arch', arch, '-target', target]) elif platform == 'iphonesimulator': target = '{}-apple-ios{}'.format( arch, self.args.darwin_deployment_version_ios) - cross_flags.extend(['-arch', arch, '-target', target]) elif platform == 'iphoneos': target = '{}-apple-ios{}'.format( arch, self.args.darwin_deployment_version_ios) - cross_flags.extend(['-arch', arch, '-target', target]) elif platform == 'appletvsimulator': target = '{}-apple-tvos{}'.format( arch, self.args.darwin_deployment_version_tvos) - cross_flags.extend(['-arch', arch, '-target', target]) elif platform == 'appletvos': target = '{}-apple-tvos{}'.format( arch, self.args.darwin_deployment_version_tvos) - cross_flags.extend(['-arch', arch, '-target', target]) elif platform == 'watchsimulator': target = '{}-apple-watchos{}'.format( arch, self.args.darwin_deployment_version_watchos) - cross_flags.extend(['-arch', arch, '-target', target]) elif platform == 'watchos': target = '{}-apple-watchos{}'.format( arch, self.args.darwin_deployment_version_watchos) - cross_flags.extend(['-arch', arch, '-target', target]) + else: + raise RuntimeError("Unhandled platform?!") + + toolchain_args = {} + + toolchain_args['CMAKE_SYSTEM_NAME'] = 'Darwin' + toolchain_args['CMAKE_OSX_SYSROOT'] = cmake_osx_sysroot + toolchain_args['CMAKE_OSX_ARCHITECTURES'] = arch + + if self.toolchain.cc.endswith('clang'): + toolchain_args['CMAKE_C_COMPILER_TARGET'] = target + if self.toolchain.cxx.endswith('clang++'): + toolchain_args['CMAKE_CXX_COMPILER_TARGET'] = target + # Swift always supports cross compiling. + toolchain_args['CMAKE_Swift_COMPILER_TARGET'] = target + + # Sort by the key so that we always produce the same toolchain file + data = sorted(toolchain_args.items(), key=lambda x: x[0]) + if not self.args.dry_run: + with open(toolchain_file, 'w') as f: + f.writelines("set({} {})\n".format(k, v) for k, v in data) + else: + print("DRY_RUN! Writing Toolchain file to path: {}".format(toolchain_file)) + + return toolchain_file + + def common_cross_c_flags(self, platform, arch): + cross_flags = [] if self.is_release(): cross_flags.append('-fno-stack-protector') diff --git a/validation-test/BuildSystem/cmark_crosscompile_using_toolchain_always.test b/validation-test/BuildSystem/cmark_crosscompile_using_toolchain_always.test new file mode 100644 index 0000000000000..25dbee7709ea1 --- /dev/null +++ b/validation-test/BuildSystem/cmark_crosscompile_using_toolchain_always.test @@ -0,0 +1,9 @@ +# REQUIRES: standalone_build +# REQUIRES: OS=macosx + +# RUN: %empty-directory(%t) +# RUN: mkdir -p %t +# RUN: SKIP_XCODE_VERSION_CHECK=1 SWIFT_BUILD_ROOT=%t %swift_src_root/utils/build-script --dry-run --install-all --cmake %cmake --skip-build-llvm --skip-build-swift 2>&1 | %FileCheck %s + +# CHECK: DRY_RUN! Writing Toolchain file to path:{{.*}}BuildScriptToolchain.cmake +# CHECK: cmake {{.*}}-DCMAKE_TOOLCHAIN_FILE:PATH={{.*}}BuildScriptToolchain.cmake {{.*}}cmark