Skip to content

Commit

Permalink
Fix cross compiling for android on macOS (#997)
Browse files Browse the repository at this point in the history
  • Loading branch information
keith authored Feb 22, 2023
1 parent 7914d08 commit b7074f1
Show file tree
Hide file tree
Showing 5 changed files with 103 additions and 0 deletions.
2 changes: 2 additions & 0 deletions foreign_cc/cmake.bzl
Original file line number Diff line number Diff line change
Expand Up @@ -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",
Expand Down Expand Up @@ -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,
Expand Down
10 changes: 10 additions & 0 deletions foreign_cc/private/cmake_script.bzl
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@ def _escape_dquote_bash_crosstool(text):

def create_cmake_script(
workspace_name,
target_os,
generator,
cmake_path,
tools,
Expand All @@ -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)
Expand Down Expand Up @@ -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
Expand Down
1 change: 1 addition & 0 deletions foreign_cc/private/framework.bzl
Original file line number Diff line number Diff line change
Expand Up @@ -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"),
Expand Down
17 changes: 17 additions & 0 deletions foreign_cc/private/framework/platform.bzl
Original file line number Diff line number Diff line change
Expand Up @@ -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"
73 changes: 73 additions & 0 deletions test/cmake_text_tests.bzl
Original file line number Diff line number Diff line change
Expand Up @@ -242,6 +242,7 @@ def _merge_flag_values_no_toolchain_file_test(ctx):

script = create_cmake_script(
"ws",
"unknown",
"Unix Makefiles",
"cmake",
tools,
Expand Down Expand Up @@ -291,6 +292,7 @@ def _create_min_cmake_script_no_toolchain_file_test(ctx):

script = create_cmake_script(
"ws",
"unknown",
"Ninja",
"cmake",
tools,
Expand Down Expand Up @@ -344,6 +346,7 @@ def _create_min_cmake_script_wipe_toolchain_test(ctx):

script = create_cmake_script(
"ws",
"unknown",
"Ninja",
"cmake",
tools,
Expand Down Expand Up @@ -393,6 +396,7 @@ def _create_min_cmake_script_toolchain_file_test(ctx):

script = create_cmake_script(
"ws",
"unknown",
"Ninja",
"cmake",
tools,
Expand Down Expand Up @@ -470,6 +474,7 @@ def _create_cmake_script_no_toolchain_file_test(ctx):

script = create_cmake_script(
"ws",
"unknown",
"Ninja",
"cmake",
tools,
Expand All @@ -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)

Expand Down Expand Up @@ -533,6 +603,7 @@ def _create_cmake_script_toolchain_file_test(ctx):

script = create_cmake_script(
"ws",
"unknown",
"Ninja",
"cmake",
tools,
Expand Down Expand Up @@ -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)

Expand All @@ -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,
)

0 comments on commit b7074f1

Please sign in to comment.