From cc21998c299b4d1f97df37b961552ff8168da17f Mon Sep 17 00:00:00 2001 From: cparsons Date: Wed, 3 May 2017 22:13:44 +0200 Subject: [PATCH] Rollforward #2 of: Basic open-source crosstool to support targeting apple platform types. RELNOTES: None. PiperOrigin-RevId: 154993630 --- .../shell/bazel/apple/bazel_apple_test.sh | 136 +- .../shell/bazel/external_correctness_test.sh | 2 +- src/test/shell/bazel/remote_execution_test.sh | 7 + tools/cpp/cc_configure.bzl | 193 +- tools/objc/libtool.sh | 10 +- tools/osx/crosstool/BUILD.tpl | 71 + tools/osx/crosstool/CROSSTOOL.tpl | 10384 ++++++++-------- tools/osx/crosstool/osx_archs.bzl | 28 + tools/osx/crosstool/wrapped_clang.tpl | 10 + tools/osx/crosstool/wrapped_clang_pp.tpl | 10 + tools/osx/xcode_configure.bzl | 101 +- 11 files changed, 5643 insertions(+), 5309 deletions(-) create mode 100644 tools/osx/crosstool/BUILD.tpl create mode 100644 tools/osx/crosstool/osx_archs.bzl create mode 100644 tools/osx/crosstool/wrapped_clang.tpl create mode 100644 tools/osx/crosstool/wrapped_clang_pp.tpl diff --git a/src/test/shell/bazel/apple/bazel_apple_test.sh b/src/test/shell/bazel/apple/bazel_apple_test.sh index ac6b17cb15dbcf..b34063819a4530 100755 --- a/src/test/shell/bazel/apple/bazel_apple_test.sh +++ b/src/test/shell/bazel/apple/bazel_apple_test.sh @@ -212,7 +212,7 @@ EOF bazel build --verbose_failures --objccopt=-DCOPTS_FOO=1 -s \ --xcode_version=$XCODE_VERSION \ //ios:swift_lib >$TEST_log 2>&1 || fail "should build" - expect_log "-module-cache-path bazel-out/local-fastbuild/genfiles/_objc_module_cache" + expect_log "-module-cache-path bazel-out/darwin_x86_64-fastbuild/genfiles/_objc_module_cache" } function test_swift_import_objc_framework() { @@ -766,8 +766,8 @@ EOF bazel build --verbose_failures --xcode_version=$XCODE_VERSION -s \ //ios:bin >$TEST_log 2>&1 || fail "should build" - expect_log "-Xlinker -add_ast_path -Xlinker bazel-out/local-fastbuild/genfiles/ios/dep/_objs/ios_dep.swiftmodule" - expect_log "-Xlinker -add_ast_path -Xlinker bazel-out/local-fastbuild/genfiles/ios/swift_lib/_objs/ios_swift_lib.swiftmodule" + expect_log "-Xlinker -add_ast_path -Xlinker bazel-out/darwin_x86_64-fastbuild/genfiles/ios/dep/_objs/ios_dep.swiftmodule" + expect_log "-Xlinker -add_ast_path -Xlinker bazel-out/darwin_x86_64-fastbuild/genfiles/ios/swift_lib/_objs/ios_swift_lib.swiftmodule" } function test_swiftc_script_mode() { @@ -914,4 +914,134 @@ EOF || fail "should contain DWARF data" } +function test_apple_binary_crosstool_ios() { + rm -rf package + mkdir -p package + cat > package/BUILD < \$(@)", + tags = ["requires-darwin"], +) +EOF + touch package/a.m + touch package/b.m + cat > package/main.m < package/cc_lib.cc << EOF +#include + +std::string GetString() { return "h3ll0"; } +EOF + + bazel build --verbose_failures //package:lipo_out \ + --experimental_enable_objc_cc_deps \ + --experimental_objc_crosstool=all \ + --apple_crosstool_transition \ + --ios_multi_cpus=i386,x86_64 \ + --xcode_version=$XCODE_VERSION \ + || fail "should build apple_binary and obtain info via lipo" + + cat bazel-genfiles/package/lipo_out | grep "i386 x86_64" \ + || fail "expected output binary to be for x86_64 architecture" +} + +function test_apple_binary_crosstool_watchos() { + rm -rf package + mkdir -p package + cat > package/BUILD < \$(@)", + tags = ["requires-darwin"], +) + +apple_binary( + name = "main_binary", + srcs = ["main.m"], + deps = [":lib_a"], + platform_type = "watchos", +) +cc_library( + name = "cc_lib", + srcs = ["cc_lib.cc"], +) +# By depending on a library which requires it is built for watchos, +# this test verifies that dependencies of apple_binary are compiled +# for the specified platform_type. +objc_library( + name = "lib_a", + srcs = ["a.m"], + deps = [":cc_lib"], +) +EOF + cat > package/main.m < + +// Note that WKExtensionDelegate is only available in Watch SDK. +@interface TestInterfaceMain : NSObject +@end + +int main() { + return 0; +} +EOF + cat > package/a.m < + +// Note that WKExtensionDelegate is only available in Watch SDK. +@interface TestInterfaceA : NSObject +@end + +int aFunction() { + return 0; +} +EOF + cat > package/cc_lib.cc << EOF +#include + +std::string GetString() { return "h3ll0"; } +EOF + + bazel build --verbose_failures //package:lipo_out \ + --experimental_enable_objc_cc_deps \ + --experimental_objc_crosstool=library \ + --apple_crosstool_transition \ + --watchos_cpus=armv7k \ + --xcode_version=$XCODE_VERSION \ + || fail "should build watch binary" + + cat bazel-genfiles/package/lipo_out | grep "armv7k" \ + || fail "expected output binary to be for armv7k architecture" +} + run_suite "apple_tests" diff --git a/src/test/shell/bazel/external_correctness_test.sh b/src/test/shell/bazel/external_correctness_test.sh index 07bffba9dd2f29..183ee2aa0d24fb 100755 --- a/src/test/shell/bazel/external_correctness_test.sh +++ b/src/test/shell/bazel/external_correctness_test.sh @@ -142,7 +142,7 @@ genrule( ) EOF bazel build @a//b/c:echo-d &> $TEST_log || fail "Build failed" - assert_contains "bazel-out/local.*-fastbuild/genfiles/external/a/b/c" \ + assert_contains "bazel-out/.*-fastbuild/genfiles/external/a/b/c" \ "bazel-genfiles/external/a/b/c/d" } diff --git a/src/test/shell/bazel/remote_execution_test.sh b/src/test/shell/bazel/remote_execution_test.sh index 66a99a6654c896..051fbe331f6667 100755 --- a/src/test/shell/bazel/remote_execution_test.sh +++ b/src/test/shell/bazel/remote_execution_test.sh @@ -53,6 +53,13 @@ function tear_down() { } function test_cc_binary() { + if [[ "$PLATFORM" == "darwin" ]]; then + # TODO(b/37355380): This test is disabled due to RemoteWorker not supporting + # setting SDKROOT and DEVELOPER_DIR appropriately, as is required of + # action executors in order to select the appropriate Xcode toolchain. + return 0 + fi + mkdir -p a cat > a/BUILD <-version-min=%{version_min}" } } } feature { - name: "strip_debug_symbols" + name: "dead_strip" flag_set { action: "c++-link-executable" action: "c++-link-dynamic-library" - action: "c++-link-interface-dynamic-library" action: "objc-executable" action: "objc++-executable" flag_group { - flag: "-Wl,-S" - expand_if_all_available: "strip_debug_symbols" + flag: "--dead_strip" + flag: "--no_dead_strip_inits_and_terms" } } + requires { + feature: "opt" + } } feature { - name: "symbol_counts" - flag_set { - action: "c++-link-executable" - action: "c++-link-dynamic-library" - flag_group { - flag: "-Wl,--print-symbol-counts=%{symbol_counts_output}" - } - expand_if_all_available: "symbol_counts_output" - } + name: "run_coverage" } feature { - name: "use_objc_modules" + name: "llvm_coverage_map_format" flag_set { + action: "c-compile" + action: "c++-compile" action: "objc-compile" action: "objc++-compile" flag_group { - flag: "-fmodule-name=%{module_name}" - flag: "-iquote" - flag: "%{module_maps_dir}" - flag: "-fmodules-cache-path=%{modules_cache_path}" + flag: "-fprofile-instr-generate" + flag: "-fcoverage-mapping" } } + requires { + feature: "run_coverage" + } } feature { - name: "version_min" + name: "gcc_coverage_map_format" flag_set { - action: "objc-executable" - action: "objc++-executable" - action: "c++-link-executable" - action: "c++-link-dynamic-library" - action: "preprocess-assemble" action: "c-compile" action: "c++-compile" - action: "c++-header-parsing" - action: "c++-header-preprocessing" - action: "c++-module-compile" action: "objc-compile" action: "objc++-compile" flag_group { - flag: "-m-version-min=%{version_min}" + flag: "-fprofile-arcs" + flag: "-ftest-coverage" } } + requires { + feature: "run_coverage" + } } - action_config { - config_name: "assemble" - action_name: "assemble" - tool { - tool_path: "wrapped_clang" - execution_requirement: "requires-darwin" + feature { + name: "apply_implicit_frameworks" + flag_set { + action: "objc-executable" + action: "objc++-executable" + flag_group { + flag: "-framework Foundation" + flag: "-framework UIKit" + } } - implies: "objc_arc" - implies: "no_objc_arc" - implies: "include_system_dirs" - implies: "apple_env" } action_config { - config_name: "c++-compile" - action_name: "c++-compile" + config_name: "c-compile" + action_name: "c-compile" tool { tool_path: "wrapped_clang" execution_requirement: "requires-darwin" @@ -12288,8 +12266,8 @@ toolchain { implies: "apple_env" } action_config { - config_name: "c++-header-parsing" - action_name: "c++-header-parsing" + config_name: "c++-compile" + action_name: "c++-compile" tool { tool_path: "wrapped_clang" execution_requirement: "requires-darwin" @@ -12302,8 +12280,8 @@ toolchain { implies: "apple_env" } action_config { - config_name: "c++-header-preprocessing" - action_name: "c++-header-preprocessing" + config_name: "c++-module-compile" + action_name: "c++-module-compile" tool { tool_path: "wrapped_clang" execution_requirement: "requires-darwin" @@ -12312,112 +12290,26 @@ toolchain { implies: "include_system_dirs" implies: "version_min" implies: "objc_arc" - implies: "no_objc_arc" - implies: "apple_env" - } - action_config { - config_name: "c++-link-alwayslink-pic-static-library" - action_name: "c++-link-alwayslink-pic-static-library" - tool { - tool_path: "/usr/bin/ar" - } - implies: "global_whole_archive_open" - implies: "runtime_root_flags" - implies: "cc_archiver_flags" - implies: "input_param_flags" - implies: "linker_param_file" - implies: "apple_env" - } - action_config { - config_name: "c++-link-alwayslink-static-library" - action_name: "c++-link-alwayslink-static-library" - tool { - tool_path: "/usr/bin/ar" - } - implies: "global_whole_archive_open" - implies: "runtime_root_flags" - implies: "cc_archiver_flags" - implies: "input_param_flags" - implies: "linker_param_file" - implies: "apple_env" - } - action_config { - config_name: "c++-link-dynamic-library" - action_name: "c++-link-dynamic-library" - tool { - tool_path: "wrapped_clang" - } - implies: "has_configured_linker_path" - implies: "symbol_counts" - implies: "shared_flag" - implies: "linkstamps" - implies: "output_execpath_flags" - implies: "global_whole_archive_open" - implies: "runtime_root_flags" - implies: "input_param_flags" - implies: "legacy_link_flags" - implies: "strip_debug_symbols" - implies: "linker_param_file" - implies: "version_min" - implies: "apple_env" - } - action_config { - config_name: "c++-link-executable" - action_name: "c++-link-executable" - tool { - tool_path: "DUMMY_TOOL" - } - implies: "symbol_counts" - implies: "linkstamps" - implies: "output_execpath_flags_executable" - implies: "global_whole_archive_open" - implies: "runtime_root_flags" - implies: "input_param_flags" - implies: "force_pic_flags" - implies: "legacy_link_flags" - implies: "strip_debug_symbols" - implies: "linker_param_file" - implies: "version_min" - implies: "apple_env" - } - action_config { - config_name: "c++-link-interface-dynamic-library" - action_name: "c++-link-interface-dynamic-library" - tool { - tool_path: "DUMMY_TOOL" - } - implies: "strip_debug_symbols" - implies: "apple_env" - } - action_config { - config_name: "c++-link-pic-static-library" - action_name: "c++-link-pic-static-library" - tool { - tool_path: "/usr/bin/ar" - } - implies: "global_whole_archive_open" - implies: "runtime_root_flags" - implies: "cc_archiver_flags" - implies: "input_param_flags" - implies: "linker_param_file" + implies: "no_objc_arc" implies: "apple_env" } action_config { - config_name: "c++-link-static-library" - action_name: "c++-link-static-library" + config_name: "c++-header-parsing" + action_name: "c++-header-parsing" tool { - tool_path: "/usr/bin/ar" + tool_path: "wrapped_clang" + execution_requirement: "requires-darwin" } - implies: "global_whole_archive_open" - implies: "runtime_root_flags" - implies: "cc_archiver_flags" - implies: "input_param_flags" - implies: "linker_param_file" + implies: "preprocessor_defines" + implies: "include_system_dirs" + implies: "version_min" + implies: "objc_arc" + implies: "no_objc_arc" implies: "apple_env" } action_config { - config_name: "c++-module-compile" - action_name: "c++-module-compile" + config_name: "c++-header-preprocessing" + action_name: "c++-header-preprocessing" tool { tool_path: "wrapped_clang" execution_requirement: "requires-darwin" @@ -12430,12 +12322,22 @@ toolchain { implies: "apple_env" } action_config { - config_name: "c-compile" - action_name: "c-compile" + config_name: "objc-compile" + action_name: "objc-compile" tool { tool_path: "wrapped_clang" execution_requirement: "requires-darwin" } + flag_set { + flag_group { + flag: "-arch" + flag: "" + } + } + implies: "objc_actions" + implies: "apply_default_compiler_flags" + implies: "apply_default_warnings" + implies: "framework_paths" implies: "preprocessor_defines" implies: "include_system_dirs" implies: "version_min" @@ -12469,17 +12371,61 @@ toolchain { implies: "apple_env" } action_config { - config_name: "objc++-executable" - action_name: "objc++-executable" + config_name: "assemble" + action_name: "assemble" tool { - tool_path: "wrapped_clang_pp" + tool_path: "wrapped_clang" + execution_requirement: "requires-darwin" + } + implies: "objc_arc" + implies: "no_objc_arc" + implies: "include_system_dirs" + implies: "apple_env" + } + action_config { + config_name: "preprocess-assemble" + action_name: "preprocess-assemble" + tool { + tool_path: "wrapped_clang" + execution_requirement: "requires-darwin" + } + implies: "preprocessor_defines" + implies: "include_system_dirs" + implies: "version_min" + implies: "objc_arc" + implies: "no_objc_arc" + implies: "apple_env" + } + action_config { + config_name: "objc-archive" + action_name: "objc-archive" + tool { + tool_path: "libtool" execution_requirement: "requires-darwin" } flag_set { flag_group { - flag: "-stdlib=libc++" - flag: "-std=gnu++11" + flag: "-static" + flag: "-filelist" + flag: "%{obj_list_path}" + flag: "-arch_only" + flag: "" + flag: "-syslibroot" + flag: "%{sdk_dir}" + flag: "-o" + flag: "%{archive_path}" } + } + implies: "apple_env" + } + action_config { + config_name: "objc-executable" + action_name: "objc-executable" + tool { + tool_path: "wrapped_clang" + execution_requirement: "requires-darwin" + } + flag_set { flag_group { flag: "-arch" flag: "" @@ -12530,59 +12476,17 @@ toolchain { implies: "apply_implicit_frameworks" } action_config { - config_name: "objc-archive" - action_name: "objc-archive" - tool { - tool_path: "libtool" - execution_requirement: "requires-darwin" - } - flag_set { - flag_group { - flag: "-static" - flag: "-filelist" - flag: "%{obj_list_path}" - flag: "-arch_only" - flag: "" - flag: "-syslibroot" - flag: "%{sdk_dir}" - flag: "-o" - flag: "%{archive_path}" - } - } - implies: "apple_env" - } - action_config { - config_name: "objc-compile" - action_name: "objc-compile" + config_name: "objc++-executable" + action_name: "objc++-executable" tool { - tool_path: "wrapped_clang" + tool_path: "wrapped_clang_pp" execution_requirement: "requires-darwin" } flag_set { flag_group { - flag: "-arch" - flag: "" + flag: "-stdlib=libc++" + flag: "-std=gnu++11" } - } - implies: "objc_actions" - implies: "apply_default_compiler_flags" - implies: "apply_default_warnings" - implies: "framework_paths" - implies: "preprocessor_defines" - implies: "include_system_dirs" - implies: "version_min" - implies: "objc_arc" - implies: "no_objc_arc" - implies: "apple_env" - } - action_config { - config_name: "objc-executable" - action_name: "objc-executable" - tool { - tool_path: "wrapped_clang" - execution_requirement: "requires-darwin" - } - flag_set { flag_group { flag: "-arch" flag: "" @@ -12632,6 +12536,106 @@ toolchain { implies: "apple_env" implies: "apply_implicit_frameworks" } + action_config { + config_name: "c++-link-executable" + action_name: "c++-link-executable" + tool { + tool_path: "DUMMY_TOOL" + } + implies: "symbol_counts" + implies: "linkstamps" + implies: "output_execpath_flags_executable" + implies: "global_whole_archive_open" + implies: "runtime_root_flags" + implies: "input_param_flags" + implies: "force_pic_flags" + implies: "legacy_link_flags" + implies: "strip_debug_symbols" + implies: "linker_param_file" + implies: "version_min" + implies: "apple_env" + } + action_config { + config_name: "c++-link-dynamic-library" + action_name: "c++-link-dynamic-library" + tool { + tool_path: "wrapped_clang" + } + implies: "has_configured_linker_path" + implies: "symbol_counts" + implies: "shared_flag" + implies: "linkstamps" + implies: "output_execpath_flags" + implies: "global_whole_archive_open" + implies: "runtime_root_flags" + implies: "input_param_flags" + implies: "legacy_link_flags" + implies: "strip_debug_symbols" + implies: "linker_param_file" + implies: "version_min" + implies: "apple_env" + } + action_config { + config_name: "c++-link-static-library" + action_name: "c++-link-static-library" + tool { + tool_path: "/usr/bin/ar" + } + implies: "global_whole_archive_open" + implies: "runtime_root_flags" + implies: "cc_archiver_flags" + implies: "input_param_flags" + implies: "linker_param_file" + implies: "apple_env" + } + action_config { + config_name: "c++-link-alwayslink-static-library" + action_name: "c++-link-alwayslink-static-library" + tool { + tool_path: "/usr/bin/ar" + } + implies: "global_whole_archive_open" + implies: "runtime_root_flags" + implies: "cc_archiver_flags" + implies: "input_param_flags" + implies: "linker_param_file" + implies: "apple_env" + } + action_config { + config_name: "c++-link-pic-static-library" + action_name: "c++-link-pic-static-library" + tool { + tool_path: "/usr/bin/ar" + } + implies: "global_whole_archive_open" + implies: "runtime_root_flags" + implies: "cc_archiver_flags" + implies: "input_param_flags" + implies: "linker_param_file" + implies: "apple_env" + } + action_config { + config_name: "c++-link-alwayslink-pic-static-library" + action_name: "c++-link-alwayslink-pic-static-library" + tool { + tool_path: "/usr/bin/ar" + } + implies: "global_whole_archive_open" + implies: "runtime_root_flags" + implies: "cc_archiver_flags" + implies: "input_param_flags" + implies: "linker_param_file" + implies: "apple_env" + } + action_config { + config_name: "c++-link-interface-dynamic-library" + action_name: "c++-link-interface-dynamic-library" + tool { + tool_path: "DUMMY_TOOL" + } + implies: "strip_debug_symbols" + implies: "apple_env" + } action_config { config_name: "objc-fully-link" action_name: "objc-fully-link" @@ -12661,19 +12665,5 @@ toolchain { } implies: "apple_env" } - action_config { - config_name: "preprocess-assemble" - action_name: "preprocess-assemble" - tool { - tool_path: "wrapped_clang" - execution_requirement: "requires-darwin" - } - implies: "preprocessor_defines" - implies: "include_system_dirs" - implies: "version_min" - implies: "objc_arc" - implies: "no_objc_arc" - implies: "apple_env" - } cc_target_os: "apple" } diff --git a/tools/osx/crosstool/osx_archs.bzl b/tools/osx/crosstool/osx_archs.bzl new file mode 100644 index 00000000000000..5ee87c6173ca3b --- /dev/null +++ b/tools/osx/crosstool/osx_archs.bzl @@ -0,0 +1,28 @@ +"""Information regarding crosstool-supported architectures.""" +# Copyright 2017 The Bazel Authors. All rights reserved. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +# List of architectures supported by osx crosstool. +OSX_TOOLS_ARCHS = [ + "armeabi-v7a", + "darwin_x86_64", + "ios_x86_64", + "ios_i386", + "ios_armv7", + "ios_arm64", + "watchos_i386", + "watchos_armv7k", + "tvos_x86_64", + "tvos_arm64", +] diff --git a/tools/osx/crosstool/wrapped_clang.tpl b/tools/osx/crosstool/wrapped_clang.tpl new file mode 100644 index 00000000000000..3a523d22802c5c --- /dev/null +++ b/tools/osx/crosstool/wrapped_clang.tpl @@ -0,0 +1,10 @@ +# A trick to allow invoking this script in multiple contexts. +if [ -z ${MY_LOCATION+x} ]; then + if [ -d "$0.runfiles/" ]; then + MY_LOCATION="$0.runfiles/bazel_tools/tools/objc" + else + MY_LOCATION="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)" + fi +fi + +"${MY_LOCATION}"/xcrunwrapper.sh clang $@ diff --git a/tools/osx/crosstool/wrapped_clang_pp.tpl b/tools/osx/crosstool/wrapped_clang_pp.tpl new file mode 100644 index 00000000000000..4afc7b056ec9e2 --- /dev/null +++ b/tools/osx/crosstool/wrapped_clang_pp.tpl @@ -0,0 +1,10 @@ +# A trick to allow invoking this script in multiple contexts. +if [ -z ${MY_LOCATION+x} ]; then + if [ -d "$0.runfiles/" ]; then + MY_LOCATION="$0.runfiles/bazel_tools/tools/objc" + else + MY_LOCATION="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)" + fi +fi + +"${MY_LOCATION}"/xcrunwrapper.sh clang++ $@ diff --git a/tools/osx/xcode_configure.bzl b/tools/osx/xcode_configure.bzl index 82833c07bf1b77..7326e602a4d4f1 100644 --- a/tools/osx/xcode_configure.bzl +++ b/tools/osx/xcode_configure.bzl @@ -89,22 +89,30 @@ def _xcode_version_output(repository_ctx, name, version, aliases, developer_dir) VERSION_CONFIG_STUB = "xcode_config(name = 'host_xcodes')" -def _darwin_build_file(repository_ctx): - """Evaluates local system state to create xcode_config and xcode_version targets.""" - xcodebuild_result = repository_ctx.execute(["env", "-i", "xcrun", "xcodebuild", "-version"], 30) - # "xcodebuild -version" failing may be indicative of no versions of xcode - # installed, which is an acceptable machine configuration to have for using - # bazel. Thus no print warning should be emitted here. - if (xcodebuild_result.return_code != 0): - error_msg = ( - "Running xcodebuild -version failed, " + - "return code {code}, stderr: {err}, stdout: {out}").format( - code=xcodebuild_result.return_code, - err=xcodebuild_result.stderr, - out=xcodebuild_result.stdout) - return VERSION_CONFIG_STUB + "\n# Error: " + error_msg.replace("\n", " ") + "\n" +def run_xcode_locator(repository_ctx, xcode_locator_src_label): + """Generates xcode-locator from source and runs it. + + Builds xcode-locator in the current repository directory. + Returns the standard output of running xcode-locator with -v, which will + return information about locally installed Xcode toolchains and the versions + they are associated with. - xcodeloc_src_path = str(repository_ctx.path(Label(repository_ctx.attr.xcode_locator))) + This should only be invoked on a darwin OS, as xcode-locator cannot be built + otherwise. + + Args: + repository_ctx: The repository context. + xcode_locator_src_label: The label of the source file for xcode-locator. + Returns: + A 2-tuple containing: + output: A list representing installed xcode toolchain information. Each + element of the list is a struct containing information for one installed + toolchain. This is instead None if there was an error building or + running xcode-locator. + err: An error string describing the error that occurred when attempting + to build and run xcode-locator, or None if the run was successful. + """ + xcodeloc_src_path = str(repository_ctx.path(xcode_locator_src_label)) xcrun_result = repository_ctx.execute(["env", "-i", "xcrun", "clang", "-fobjc-arc", "-framework", "CoreServices", "-framework", "Foundation", "-o", "xcode-locator-bin", xcodeloc_src_path], 30) @@ -116,8 +124,7 @@ def _darwin_build_file(repository_ctx): code=xcrun_result.return_code, err=xcrun_result.stderr, out=xcrun_result.stdout) - print(error_msg) - return VERSION_CONFIG_STUB + "\n# Error: " + error_msg.replace("\n", " ") + "\n" + return (None, error_msg.replace("\n", " ")) xcode_locator_result = repository_ctx.execute(["./xcode-locator-bin", "-v"], 30) if (xcode_locator_result.return_code != 0): @@ -127,28 +134,58 @@ def _darwin_build_file(repository_ctx): code=xcode_locator_result.return_code, err=xcode_locator_result.stderr, out=xcode_locator_result.stdout) - print(error_msg) + return (None, error_msg.replace("\n", " ")) + xcode_toolchains = [] + # xcode_dump is comprised of newlines with different installed xcode versions, + # each line of the form ::. + xcode_dump = xcode_locator_result.stdout + for xcodeversion in xcode_dump.split("\n"): + if ":" in xcodeversion: + infosplit = xcodeversion.split(":") + toolchain = struct( + version = infosplit[0], + aliases = infosplit[1].split(","), + developer_dir = infosplit[2] + ) + xcode_toolchains.append(toolchain) + return (xcode_toolchains, None) + + +def _darwin_build_file(repository_ctx): + """Evaluates local system state to create xcode_config and xcode_version targets.""" + xcodebuild_result = repository_ctx.execute(["env", "-i", "xcrun", "xcodebuild", "-version"], 30) + # "xcodebuild -version" failing may be indicative of no versions of xcode + # installed, which is an acceptable machine configuration to have for using + # bazel. Thus no print warning should be emitted here. + if (xcodebuild_result.return_code != 0): + error_msg = ( + "Running xcodebuild -version failed, " + + "return code {code}, stderr: {err}, stdout: {out}").format( + code=xcodebuild_result.return_code, + err=xcodebuild_result.stderr, + out=xcodebuild_result.stdout) return VERSION_CONFIG_STUB + "\n# Error: " + error_msg.replace("\n", " ") + "\n" + (toolchains, xcodeloc_err) = run_xcode_locator(repository_ctx, + Label(repository_ctx.attr.xcode_locator)) + + if xcodeloc_err: + return VERSION_CONFIG_STUB + "\n# Error: " + xcodeloc_err + "\n" + default_xcode_version = _search_string(xcodebuild_result.stdout, "Xcode ", "\n") default_xcode_target = "" target_names = [] buildcontents = "" - # xcode_dump is comprised of newlines with different installed xcode versions, - # each line of the form ::. - xcode_dump = xcode_locator_result.stdout - for xcodeversion in xcode_dump.split("\n"): - if ":" in xcodeversion: - infosplit = xcodeversion.split(":") - version = infosplit[0] - aliases = infosplit[1].split(",") - developer_dir = infosplit[2] - target_name = "version%s" % version.replace(".", "_") - buildcontents += _xcode_version_output(repository_ctx, target_name, version, aliases, developer_dir) - target_names.append("':%s'" % target_name) - if (version == default_xcode_version or default_xcode_version in aliases): - default_xcode_target = target_name + for toolchain in toolchains: + version = toolchain.version + aliases = toolchain.aliases + developer_dir = toolchain.developer_dir + target_name = "version%s" % version.replace(".", "_") + buildcontents += _xcode_version_output(repository_ctx, target_name, version, aliases, developer_dir) + target_names.append("':%s'" % target_name) + if (version == default_xcode_version or default_xcode_version in aliases): + default_xcode_target = target_name buildcontents += "xcode_config(name = 'host_xcodes'," if target_names: buildcontents += "\n versions = [%s]," % ", ".join(target_names)