Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
47 changes: 23 additions & 24 deletions CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -288,26 +288,29 @@ if(NOT PYTHON_VERSION_MAJOR_MINOR VERSION_EQUAL SUPPORTED_PYTHON_VERSION)
)
endif()

# We need to run Bazel in a dedicated temporary directory. The particular
# name `drake_build_cwd` isn't important, it just needs to be unique. Note,
# however, that the macOS wheel builds also need to know this path, so if it
# ever changes, tools/wheel/macos/build-wheel.sh will also need to be updated.
set(DRAKE_BAZEL_BUILD_DIR "${CMAKE_BINARY_DIR}/drake_build_cwd")
file(MAKE_DIRECTORY "${DRAKE_BAZEL_BUILD_DIR}")

set(BAZEL_REPO_ENV)

# Put this patch where `cmake/MODULE.bazel.in` expects it during its call to
# `single_version_override`.
file(CREATE_LINK
"${PROJECT_SOURCE_DIR}/tools/workspace/rules_cc/patches/upstream/cc-as-gcc.patch"
"${DRAKE_BAZEL_BUILD_DIR}/cc-as-gcc.patch"
SYMBOLIC
)
if(NOT APPLE)
# N.B. Bazel does its own compiler-chasing with Xcode, which we shouldn't
# interfere with here.
string(APPEND BAZEL_REPO_ENV
" --repo_env=CC=${CMAKE_C_COMPILER}"
" --repo_env=CXX=${CMAKE_CXX_COMPILER}"
)
# Pass a Bazel flag which enforces the underlying compiler so that
# compiler- and version-specific logic (e.g., warnings) is enforced in the
# build, since rules_cc's support for compiler identification is not as
# robust as using CMake's CMAKE_<LANG>_COMPILER_ID.
if(CMAKE_C_COMPILER_ID STREQUAL Clang)
string(APPEND BAZEL_REPO_ENV
" --@drake//tools/cc_toolchain:compiler=clang"
)
elseif(CMAKE_C_COMPILER_ID STREQUAL GNU)
string(APPEND BAZEL_REPO_ENV
" --@drake//tools/cc_toolchain:compiler=gcc"
)
endif()
endif()

get_filename_component(PROJECT_BINARY_DIR_REALPATH
Expand Down Expand Up @@ -815,15 +818,11 @@ foreach(import IN LISTS BAZELRC_IMPORTS)
string(APPEND BAZELRC_IMPORT "import ${PROJECT_SOURCE_DIR}/${import}\n")
endforeach()

# We need to run Bazel in a dedicated temporary directory. The particular
# name `drake_build_cwd` isn't important, it just needs to be unique. Note,
# however, that the macOS wheel builds also need to know this path, so if it
# ever changes, tools/wheel/macos/build-wheel.sh will also need to be updated.
configure_file(cmake/bazel.rc.in drake_build_cwd/.bazelrc @ONLY)
configure_file(cmake/MODULE.bazel.in drake_build_cwd/MODULE.bazel @ONLY)
configure_file(cmake/BUILD.bazel.in drake_build_cwd/BUILD.bazel @ONLY)
file(CREATE_LINK "${PROJECT_SOURCE_DIR}/.bazeliskrc" drake_build_cwd/.bazeliskrc SYMBOLIC)
file(CREATE_LINK "${PROJECT_SOURCE_DIR}/.bazelversion" drake_build_cwd/.bazelversion SYMBOLIC)
configure_file(cmake/bazel.rc.in "${DRAKE_BAZEL_BUILD_DIR}/.bazelrc" @ONLY)
configure_file(cmake/MODULE.bazel.in "${DRAKE_BAZEL_BUILD_DIR}/MODULE.bazel" @ONLY)
configure_file(cmake/BUILD.bazel.in "${DRAKE_BAZEL_BUILD_DIR}/BUILD.bazel" @ONLY)
file(CREATE_LINK "${PROJECT_SOURCE_DIR}/.bazeliskrc" "${DRAKE_BAZEL_BUILD_DIR}/.bazeliskrc" SYMBOLIC)
file(CREATE_LINK "${PROJECT_SOURCE_DIR}/.bazelversion" "${DRAKE_BAZEL_BUILD_DIR}/.bazelversion" SYMBOLIC)

find_package(Git)

Expand Down Expand Up @@ -851,7 +850,7 @@ add_custom_target(drake_version ALL

add_custom_target(drake_install ALL
COMMAND "${Bazel_EXECUTABLE}" build ${BAZEL_INSTALL_TARGET}
WORKING_DIRECTORY "${CMAKE_CURRENT_BINARY_DIR}/drake_build_cwd"
WORKING_DIRECTORY "${DRAKE_BAZEL_BUILD_DIR}"
USES_TERMINAL
)
add_dependencies(drake_install drake_version)
Expand All @@ -861,7 +860,7 @@ install(CODE
COMMAND
\"${Bazel_EXECUTABLE}\" run ${BAZEL_INSTALL_TARGET}
-- ${BAZEL_INSTALL_ARGS}
WORKING_DIRECTORY \"${CMAKE_CURRENT_BINARY_DIR}/drake_build_cwd\"
WORKING_DIRECTORY \"${DRAKE_BAZEL_BUILD_DIR}\"
)"
ALL_COMPONENTS
)
Expand Down
7 changes: 7 additions & 0 deletions MODULE.bazel
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,13 @@ bazel_dep(name = "rules_python", version = "1.6.3") # Keep this in sync with cm
bazel_dep(name = "rules_rust", version = "0.67.0")
bazel_dep(name = "rules_shell", version = "0.6.1")

single_version_override(
module_name = "rules_cc",
patches = [
"@drake//tools/workspace/rules_cc:patches/upstream/cc-as-gcc.patch",
],
)

# Customize our toolchains.

cc_configure = use_extension(
Expand Down
5 changes: 5 additions & 0 deletions cmake/MODULE.bazel.in
Original file line number Diff line number Diff line change
Expand Up @@ -24,3 +24,8 @@ python_repository(
)

register_toolchains("@python//:all")

single_version_override(
module_name = "rules_cc",
patches = ["//:cc-as-gcc.patch"],
)
70 changes: 16 additions & 54 deletions tools/cc_toolchain/BUILD.bazel
Original file line number Diff line number Diff line change
Expand Up @@ -26,28 +26,16 @@ string_flag(
],
)

# In our developer builds and CMake installs, we use the following two flags
# as optional hints for configuring compiler warnings. It's not strictly
# necessary to set these, but doing so will tweak the compiler flags and
# reduce warning spam during the build.
# In our developer builds and CMake installs, we use the following flag as
# an optional hint for configuring compiler warnings. It's not strictly
# necessary to set, but doing so will tweak the compiler flags and reduce
# warning spam during the build.
#
# These are intended for internal use only, not for users to configure.
# This is intended for internal use only, not for users to configure.
#
# TODO(jwnimmer-tri) Ideally, rules_cc would provide,
# * for 'compiler', a check for the real underlying compiler by invoking it
# (akin to CMake) instead of just parsing the filename; and
# * for 'compiler_major', some toolchain attribute that we could query.
# Neither of these seem to exist yet.
string_flag(
name = "compiler",
build_setting_default = "",
values = [
"",
"gcc",
"clang",
],
)

# TODO(jwnimmer-tri) Ideally, rules_cc would provide some toolchain attribute
# that we could query for the version of the compiler, but that doesn't seem to
# exist yet.
int_flag(
name = "compiler_major",
build_setting_default = 0,
Expand All @@ -73,37 +61,11 @@ config_setting(
flag_values = {":error_severity": "error"},
)

config_setting(
name = "compiler_clang",
flag_values = {":compiler": "clang"},
)

config_setting(
name = "compiler_gcc",
flag_values = {":compiler": "gcc"},
)

selects.config_setting_group(
name = "clang",
match_any = [
"@rules_cc//cc/compiler:clang",
":compiler_clang",
],
)

selects.config_setting_group(
name = "gcc",
match_any = [
"@rules_cc//cc/compiler:gcc",
":compiler_gcc",
],
)

selects.config_setting_group(
name = "apple_clang_with_warnings",
match_all = [
":apple",
":clang",
"@rules_cc//cc/compiler:clang",
":error_severity_warning",
],
)
Expand All @@ -112,23 +74,23 @@ selects.config_setting_group(
name = "apple_clang_with_errors",
match_all = [
":apple",
":clang",
"@rules_cc//cc/compiler:clang",
":error_severity_error",
],
)

selects.config_setting_group(
name = "gcc_with_warnings",
match_all = [
":gcc",
"@rules_cc//cc/compiler:gcc",
":error_severity_warning",
],
)

selects.config_setting_group(
name = "gcc_with_errors",
match_all = [
":gcc",
"@rules_cc//cc/compiler:gcc",
":error_severity_error",
],
)
Expand All @@ -137,7 +99,7 @@ selects.config_setting_group(
name = "linux_clang_with_warnings",
match_all = [
":linux",
":clang",
"@rules_cc//cc/compiler:clang",
":error_severity_warning",
],
)
Expand All @@ -146,7 +108,7 @@ selects.config_setting_group(
name = "linux_clang_with_errors",
match_all = [
":linux",
":clang",
"@rules_cc//cc/compiler:clang",
":error_severity_error",
],
)
Expand Down Expand Up @@ -191,7 +153,7 @@ config_setting(
selects.config_setting_group(
name = "gcc_13_with_warnings",
match_all = [
":gcc",
"@rules_cc//cc/compiler:gcc",
":compiler_major_13",
":error_severity_warning",
],
Expand All @@ -200,7 +162,7 @@ selects.config_setting_group(
selects.config_setting_group(
name = "gcc_13_with_errors",
match_all = [
":gcc",
"@rules_cc//cc/compiler:gcc",
":compiler_major_13",
":error_severity_error",
],
Expand Down
4 changes: 2 additions & 2 deletions tools/skylark/drake_cc.bzl
Original file line number Diff line number Diff line change
Expand Up @@ -141,8 +141,8 @@ def _platform_copts(rule_copts, rule_gcc_copts, rule_clang_copts, cc_test = 0):
test_gcc_copts = (CC_TEST_FLAGS + GCC_CC_TEST_FLAGS) if cc_test else []
test_clang_copts = CC_TEST_FLAGS if cc_test else []
return BASE_COPTS + rule_copts + select({
"//tools/cc_toolchain:gcc": rule_gcc_copts + test_gcc_copts,
"//tools/cc_toolchain:clang": rule_clang_copts + test_clang_copts,
"@rules_cc//cc/compiler:gcc": rule_gcc_copts + test_gcc_copts,
"@rules_cc//cc/compiler:clang": rule_clang_copts + test_clang_copts,
"//conditions:default": [],
})

Expand Down
2 changes: 1 addition & 1 deletion tools/skylark/pybind.bzl
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ load("//tools/skylark:drake_py.bzl", "drake_py_library", "drake_py_test")
load("//tools/skylark:py.bzl", "py_library")

EXTRA_PYBIND_COPTS = select({
"@drake//tools/cc_toolchain:clang": [
"@rules_cc//cc/compiler:clang": [
# GCC and Clang don't always agree / succeed when inferring storage
# duration (#9600). Workaround it for now.
"-Wno-unused-lambda-capture",
Expand Down
3 changes: 3 additions & 0 deletions tools/workspace/rules_cc/BUILD.bazel
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
load("//tools/lint:lint.bzl", "add_lint_tests")

add_lint_tests()
19 changes: 19 additions & 0 deletions tools/workspace/rules_cc/patches/upstream/cc-as-gcc.patch
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
[rules_cc] Recognize CC as GCC when applicable

Running `cc -v` when CC is really GCC under the hood will still print GCC
information, similar to the logic with Clang immediately above.

--- cc/private/toolchain/unix_cc_configure.bzl
+++ cc/private/toolchain/unix_cc_configure.bzl
@@ -273,10 +273,7 @@ def _is_clang(repository_ctx, cc):
return "clang" in repository_ctx.execute([cc, "-v"]).stderr

def _is_gcc(repository_ctx, cc):
- # GCC's version output uses the basename of argv[0] as the program name:
- # https://gcc.gnu.org/git/?p=gcc.git;a=blob;f=gcc/gcc.cc;h=158461167951c1b9540322fb19be6a89d6da07fc;hb=HEAD#l8728
- cc_stdout = repository_ctx.execute([cc, "--version"]).stdout
- return cc_stdout.startswith("gcc ") or cc_stdout.startswith("gcc-")
+ return "gcc version " in repository_ctx.execute([cc, "-v"]).stderr.split('\n')[-2]

def _get_compiler_name(repository_ctx, cc):
if _is_clang(repository_ctx, cc):