diff --git a/foreign_cc/cmake.bzl b/foreign_cc/cmake.bzl index 3e390ece2..abbdaf363 100644 --- a/foreign_cc/cmake.bzl +++ b/foreign_cc/cmake.bzl @@ -148,6 +148,7 @@ load("//foreign_cc/private:transitions.bzl", "foreign_cc_rule_variant") load( "//foreign_cc/private/framework:platform.bzl", "os_name", + "target_os_name", ) load( "//toolchains/native_tools:tool_access.bzl", @@ -251,6 +252,7 @@ def _create_configure_script(configureParameters): configure_script = create_cmake_script( workspace_name = ctx.workspace_name, + target_os = target_os_name(ctx), generator = attrs.generator, cmake_path = attrs.cmake_path, tools = tools, diff --git a/foreign_cc/private/cmake_script.bzl b/foreign_cc/private/cmake_script.bzl index 1f2be40c4..e2d134660 100644 --- a/foreign_cc/private/cmake_script.bzl +++ b/foreign_cc/private/cmake_script.bzl @@ -19,6 +19,7 @@ def _escape_dquote_bash_crosstool(text): def create_cmake_script( workspace_name, + target_os, generator, cmake_path, tools, @@ -37,6 +38,7 @@ def create_cmake_script( Args: workspace_name: current workspace name + target_os: The target OS for the build generator: The generator target for cmake to use cmake_path: The path to the cmake executable tools: cc_toolchain tools (CxxToolsInfo) @@ -91,6 +93,14 @@ def create_cmake_script( if not params.cache.get("CMAKE_RANLIB"): params.cache.update({"CMAKE_RANLIB": ""}) + # Avoid cmake passing wrong linker flags when targeting android on macOS + # https://github.com/bazelbuild/rules_foreign_cc/issues/289 + if target_os == "android": + params.cache.update({ + "ANDROID": "YES", + "CMAKE_SYSTEM_NAME": "Linux", + }) + set_env_vars = [ "export {}=\"{}\"".format(key, _escape_dquote_bash(params.env[key])) for key in params.env diff --git a/foreign_cc/private/framework.bzl b/foreign_cc/private/framework.bzl index 3424518f6..8671bdb5d 100644 --- a/foreign_cc/private/framework.bzl +++ b/foreign_cc/private/framework.bzl @@ -209,6 +209,7 @@ CC_EXTERNAL_RULE_ATTRIBUTES = { cfg = "exec", default = [], ), + "_android_constraint": attr.label(default = Label("@platforms//os:android")), # we need to declare this attribute to access cc_toolchain "_cc_toolchain": attr.label( default = Label("@bazel_tools//tools/cpp:current_cc_toolchain"), diff --git a/foreign_cc/private/framework/platform.bzl b/foreign_cc/private/framework/platform.bzl index b3a211cf4..9cc196ebb 100644 --- a/foreign_cc/private/framework/platform.bzl +++ b/foreign_cc/private/framework/platform.bzl @@ -65,3 +65,20 @@ def os_name(ctx): return "unknown" return platform_info[ForeignCcPlatformInfo].os + +def target_os_name(ctx): + """A helper function for getting the target operating system name based on the constraints + + Args: + ctx (ctx): The current rule's context object + + Returns: + str: The string of the current platform + """ + operating_systems = ["android"] + for os in operating_systems: + constraint = getattr(ctx.attr, "_{}_constraint".format(os)) + if constraint and ctx.target_platform_has_constraint(constraint[platform_common.ConstraintValueInfo]): + return os + + return "unknown" diff --git a/test/cmake_text_tests.bzl b/test/cmake_text_tests.bzl index 2319fb5ee..eb6ed2638 100644 --- a/test/cmake_text_tests.bzl +++ b/test/cmake_text_tests.bzl @@ -242,6 +242,7 @@ def _merge_flag_values_no_toolchain_file_test(ctx): script = create_cmake_script( "ws", + "unknown", "Unix Makefiles", "cmake", tools, @@ -291,6 +292,7 @@ def _create_min_cmake_script_no_toolchain_file_test(ctx): script = create_cmake_script( "ws", + "unknown", "Ninja", "cmake", tools, @@ -344,6 +346,7 @@ def _create_min_cmake_script_wipe_toolchain_test(ctx): script = create_cmake_script( "ws", + "unknown", "Ninja", "cmake", tools, @@ -393,6 +396,7 @@ def _create_min_cmake_script_toolchain_file_test(ctx): script = create_cmake_script( "ws", + "unknown", "Ninja", "cmake", tools, @@ -470,6 +474,7 @@ def _create_cmake_script_no_toolchain_file_test(ctx): script = create_cmake_script( "ws", + "unknown", "Ninja", "cmake", tools, @@ -496,6 +501,71 @@ cmake -DCMAKE_AR="/cxx_linker_static" -DCMAKE_CXX_LINK_EXECUTABLE="became" -DCMA return unittest.end(env) +def _create_cmake_script_android_test(ctx): + env = unittest.begin(ctx) + + tools = CxxToolsInfo( + cc = "/some-cc-value", + cxx = "external/cxx-value", + cxx_linker_static = "/cxx_linker_static", + cxx_linker_executable = "ws/cxx_linker_executable", + ) + flags = CxxFlagsInfo( + cc = ["-cc-flag", "-gcc_toolchain", "cc-toolchain"], + cxx = [ + "--quoted=\"abc def\"", + "--sysroot=/abc/sysroot", + "--gcc_toolchain", + "cxx-toolchain", + ], + cxx_linker_shared = ["shared1", "shared2"], + cxx_linker_static = ["static"], + cxx_linker_executable = ["executable"], + assemble = ["assemble"], + ) + user_env = { + "CC": "sink-cc-value", + "CFLAGS": "--from-env", + "CUSTOM_ENV": "YES", + "CXX": "sink-cxx-value", + } + user_cache = { + "CMAKE_ASM_FLAGS": "assemble-user", + "CMAKE_BUILD_TYPE": "user_type", + "CMAKE_CXX_LINK_EXECUTABLE": "became", + "CMAKE_C_FLAGS": "--additional-flag", + "CUSTOM_CACHE": "YES", + } + + script = create_cmake_script( + "ws", + "android", + "Ninja", + "cmake", + tools, + flags, + "test_rule", + "external/test_rule", + True, + user_cache, + user_env, + ["--debug-output", "-Wdev"], + cmake_commands = [], + ) + expected = r"""export CC="sink-cc-value" +export CXX="sink-cxx-value" +export CFLAGS="-cc-flag -gcc_toolchain cc-toolchain --from-env --additional-flag" +export CXXFLAGS="--quoted=\\\"abc def\\\" --sysroot=/abc/sysroot --gcc_toolchain cxx-toolchain" +export ASMFLAGS="assemble assemble-user" +export CUSTOM_ENV="YES" +##enable_tracing## +cmake -DCMAKE_AR="/cxx_linker_static" -DCMAKE_CXX_LINK_EXECUTABLE="became" -DCMAKE_SHARED_LINKER_FLAGS="shared1 shared2" -DCMAKE_EXE_LINKER_FLAGS="executable" -DCMAKE_BUILD_TYPE="user_type" -DCUSTOM_CACHE="YES" -DCMAKE_INSTALL_PREFIX="test_rule" -DCMAKE_PREFIX_PATH="$$EXT_BUILD_DEPS$$" -DCMAKE_RANLIB="" -DANDROID="YES" -DCMAKE_SYSTEM_NAME="Linux" --debug-output -Wdev -G 'Ninja' $$EXT_BUILD_ROOT$$/external/test_rule +##disable_tracing## +""" + asserts.equals(env, expected.splitlines(), script) + + return unittest.end(env) + def _create_cmake_script_toolchain_file_test(ctx): env = unittest.begin(ctx) @@ -533,6 +603,7 @@ def _create_cmake_script_toolchain_file_test(ctx): script = create_cmake_script( "ws", + "unknown", "Ninja", "cmake", tools, @@ -592,6 +663,7 @@ create_min_cmake_script_no_toolchain_file_test = unittest.make(_create_min_cmake create_min_cmake_script_toolchain_file_test = unittest.make(_create_min_cmake_script_toolchain_file_test) create_cmake_script_no_toolchain_file_test = unittest.make(_create_cmake_script_no_toolchain_file_test) create_cmake_script_toolchain_file_test = unittest.make(_create_cmake_script_toolchain_file_test) +create_cmake_script_android_test = unittest.make(_create_cmake_script_android_test) merge_flag_values_no_toolchain_file_test = unittest.make(_merge_flag_values_no_toolchain_file_test) create_min_cmake_script_wipe_toolchain_test = unittest.make(_create_min_cmake_script_wipe_toolchain_test) @@ -609,6 +681,7 @@ def cmake_script_test_suite(): create_min_cmake_script_toolchain_file_test, create_cmake_script_no_toolchain_file_test, create_cmake_script_toolchain_file_test, + create_cmake_script_android_test, merge_flag_values_no_toolchain_file_test, create_min_cmake_script_wipe_toolchain_test, )