Skip to content

Commit 2b47375

Browse files
committed
Bazel/CMake: use -iquote
1 parent 81628f5 commit 2b47375

File tree

2 files changed

+40
-14
lines changed

2 files changed

+40
-14
lines changed

misc/bazel/cmake/cmake.bzl

Lines changed: 32 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,9 @@ CmakeInfo = provider(
77
"hdrs": "",
88
"srcs": "",
99
"deps": "",
10+
"system_includes": "",
1011
"includes": "",
12+
"quote_includes": "",
1113
"stripped_includes": "",
1214
"imported_static_libs": "",
1315
"imported_dynamic_libs": "",
@@ -45,6 +47,10 @@ def _file_kind(file):
4547
return "dynamic_lib"
4648
return None
4749

50+
def _get_includes(includes):
51+
# see strip prefix comment below to understand why we are skipping virtual includes here
52+
return [_cmake_path(i) for i in includes.to_list() if "/_virtual_includes/" not in i]
53+
4854
def _cmake_aspect_impl(target, ctx):
4955
if not ctx.rule.kind.startswith("cc_"):
5056
return [CmakeInfo(name = None, transitive_deps = depset())]
@@ -82,18 +88,17 @@ def _cmake_aspect_impl(target, ctx):
8288
linkopts += [ctx.expand_make_variables("linkopts", o, {}) for o in ctx.rule.attr.linkopts]
8389

8490
compilation_ctx = target[CcInfo].compilation_context
85-
includes = compilation_ctx.system_includes.to_list()
86-
includes += compilation_ctx.includes.to_list()
87-
includes += compilation_ctx.quote_includes.to_list()
88-
includes += [opt[2:] for opt in copts if opt.startswith("-I")]
91+
system_includes = _get_includes(compilation_ctx.system_includes)
92+
93+
# move -I copts to includes
94+
includes = _get_includes(compilation_ctx.includes) + [_cmake_path(opt[2:]) for opt in copts if opt.startswith("-I")]
95+
copts = [opt for opt in copts if not opt.startswith("-I")]
96+
quote_includes = _get_includes(compilation_ctx.quote_includes)
8997

9098
# strip prefix is special, as in bazel it creates a _virtual_includes directory with symlinks
9199
# as we want to avoid relying on bazel having done that, we must undo that mechanism
92100
# also for some reason cmake fails to propagate these with target_include_directories,
93101
# so we propagate them ourselvels by using the stripped_includes field
94-
# also, including '.' on macOS creates a conflict between a `version` file at the root of the
95-
# workspace and a standard library, so we skip that (and hardcode an `-iquote .` in setup.cmake)
96-
includes = [_cmake_path(i) for i in includes if not ("/_virtual_includes/" in i or (is_macos and i == "."))]
97102
stripped_includes = []
98103
if getattr(ctx.rule.attr, "strip_include_prefix", ""):
99104
prefix = ctx.rule.attr.strip_include_prefix.strip("/")
@@ -108,7 +113,6 @@ def _cmake_aspect_impl(target, ctx):
108113
"${BAZEL_EXEC_ROOT}/%s/%s" % (ctx.var["BINDIR"], prefix), # generated
109114
]
110115

111-
copts = [opt for opt in copts if not opt.startswith("-I")]
112116
deps = [dep[CmakeInfo] for dep in deps if CmakeInfo in dep]
113117

114118
# by the book this should be done with depsets, but so far the performance implication is negligible
@@ -127,6 +131,8 @@ def _cmake_aspect_impl(target, ctx):
127131
srcs = srcs,
128132
deps = [dep for dep in deps if dep.name != None],
129133
includes = includes,
134+
system_includes = system_includes,
135+
quote_includes = quote_includes,
130136
stripped_includes = stripped_includes,
131137
imported_static_libs = static_libs,
132138
imported_dynamic_libs = dynamic_libs,
@@ -145,7 +151,7 @@ cmake_aspect = aspect(
145151
fragments = ["cpp"],
146152
)
147153

148-
def _map_cmake_info(info):
154+
def _map_cmake_info(info, is_windows):
149155
args = " ".join([info.name, info.modifier] + info.hdrs + info.srcs).strip()
150156
commands = [
151157
"add_%s(%s)" % (info.kind, args),
@@ -180,6 +186,19 @@ def _map_cmake_info(info):
180186
commands += [
181187
"target_include_directories(%s %s %s)" % (info.name, info.modifier or "PUBLIC", " ".join(info.includes)),
182188
]
189+
if info.system_includes:
190+
commands += [
191+
"target_include_directories(%s SYSTEM %s %s)" % (info.name, info.modifier or "PUBLIC", " ".join(info.system_includes)),
192+
]
193+
if info.quote_includes:
194+
if is_windows:
195+
commands += [
196+
"target_include_directories(%s %s %s)" % (info.name, info.modifier or "PUBLIC", " ".join(info.quote_includes)),
197+
]
198+
else:
199+
commands += [
200+
"target_compile_options(%s %s %s)" % (info.name, info.modifier or "PUBLIC", " ".join(["-iquote%s" % i for i in info.quote_includes])),
201+
]
183202
if info.copts and info.modifier != "INTERFACE":
184203
commands += [
185204
"target_compile_options(%s PRIVATE %s)" % (info.name, " ".join(info.copts)),
@@ -219,8 +238,10 @@ def _generate_cmake_impl(ctx):
219238
inputs += info.inputs
220239
infos[info.name] = info
221240

241+
is_windows = ctx.target_platform_has_constraint(ctx.attr._windows[platform_common.ConstraintValueInfo])
242+
222243
for info in infos.values():
223-
commands += _map_cmake_info(info)
244+
commands += _map_cmake_info(info, is_windows)
224245
commands.append("")
225246

226247
for include in ctx.attr.includes:
@@ -246,5 +267,6 @@ generate_cmake = rule(
246267
attrs = {
247268
"targets": attr.label_list(aspects = [cmake_aspect]),
248269
"includes": attr.label_list(providers = [GeneratedCmakeFiles]),
270+
"_windows": attr.label(default = "@platforms//os:windows"),
249271
},
250272
)

misc/bazel/cmake/setup.cmake

Lines changed: 8 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,13 +1,17 @@
11
option(BUILD_SHARED_LIBS "" 0)
22

3-
execute_process(COMMAND bazel info workspace OUTPUT_VARIABLE BAZEL_WORKSPACE COMMAND_ERROR_IS_FATAL ANY OUTPUT_STRIP_TRAILING_WHITESPACE)
3+
macro(bazel)
4+
execute_process(COMMAND bazel ${ARGN} COMMAND_ERROR_IS_FATAL ANY OUTPUT_STRIP_TRAILING_WHITESPACE)
5+
endmacro()
46

5-
execute_process(COMMAND bazel info output_base OUTPUT_VARIABLE BAZEL_OUTPUT_BASE COMMAND_ERROR_IS_FATAL ANY OUTPUT_STRIP_TRAILING_WHITESPACE)
7+
bazel(info workspace OUTPUT_VARIABLE BAZEL_WORKSPACE)
8+
9+
bazel(info output_base OUTPUT_VARIABLE BAZEL_OUTPUT_BASE)
610
string(REPLACE "-" "_" BAZEL_EXEC_ROOT ${PROJECT_NAME})
711
set(BAZEL_EXEC_ROOT ${BAZEL_OUTPUT_BASE}/execroot/${BAZEL_EXEC_ROOT})
812

9-
execute_process(COMMAND bazel query "kind(generate_cmake, //...)" OUTPUT_VARIABLE BAZEL_GENERATE_CMAKE_TARGETS COMMAND_ERROR_IS_FATAL ANY OUTPUT_STRIP_TRAILING_WHITESPACE)
10-
execute_process(COMMAND bazel build ${BAZEL_GENERATE_CMAKE_TARGETS} COMMAND_ERROR_IS_FATAL ANY)
13+
bazel(query "kind(generate_cmake, //...)" OUTPUT_VARIABLE BAZEL_GENERATE_CMAKE_TARGETS)
14+
bazel(build ${BAZEL_GENERATE_CMAKE_TARGETS})
1115

1216
string(REPLACE "//" "" BAZEL_GENERATE_CMAKE_TARGETS "${BAZEL_GENERATE_CMAKE_TARGETS}")
1317
string(REPLACE ":" "/" BAZEL_GENERATE_CMAKE_TARGETS "${BAZEL_GENERATE_CMAKE_TARGETS}")

0 commit comments

Comments
 (0)