linking `bison_cc_library` is broken.
Reproducible by running bazel build //tests:hello_c on the following platforms:
Windows
(18:14:52) ERROR: C:/b/bk-windows-0n2b/bazel/github-dot-com-jmillikin-rules-bison/tests/BUILD:27:17: Linking tests/hello_c.dll failed: (Exit 1120): link.exe failed: error executing CppLink command (from target //tests:hello_c)
cd /d C:/b/j3tx7vr2/execroot/_main
SET LIB=C:\Program Files (x86)\Microsoft Visual Studio\2022\BuildTools\VC\Tools\MSVC\14.39.33519\lib\x64;C:\Program Files (x86)\Windows Kits\NETFXSDK\4.8\lib\um\x64;C:\Program Files (x86)\Windows Kits\10\lib\10.0.22621.0\ucrt\x64;C:\Program Files (x86)\Windows Kits\10\\lib\10.0.22621.0\\um\x64
SET PATH=C:\Program Files (x86)\Microsoft Visual Studio\2022\BuildTools\VC\Tools\MSVC\14.39.33519\bin\HostX64\x64;C:\Program Files (x86)\Microsoft Visual Studio\2022\BuildTools\Common7\IDE\VC\VCPackages;C:\Program Files (x86)\Microsoft Visual Studio\2022\BuildTools\Common7\IDE\CommonExtensions\Microsoft\TestWindow;C:\Program Files (x86)\Microsoft Visual Studio\2022\BuildTools\MSBuild\Current\bin\Roslyn;C:\Program Files (x86)\Microsoft SDKs\Windows\v10.0A\bin\NETFX 4.8 Tools\x64\;C:\Program Files (x86)\Microsoft Visual Studio\2022\BuildTools\Common7\IDE\Extensions\Microsoft\CodeCoverage.Console;C:\Program Files (x86)\Windows Kits\10\bin\10.0.22621.0\\x64;C:\Program Files (x86)\Windows Kits\10\bin\\x64;C:\Program Files (x86)\Microsoft Visual Studio\2022\BuildTools\\MSBuild\Current\Bin\amd64;C:\Windows\Microsoft.NET\Framework64\v4.0.30319;C:\Program Files (x86)\Microsoft Visual Studio\2022\BuildTools\Common7\IDE\;C:\Program Files (x86)\Microsoft Visual Studio\2022\BuildTools\Common7\Tools\;;C:\Windows\system32;C:\Program Files (x86)\Microsoft Visual Studio\2022\BuildTools\Common7\IDE\CommonExtensions\Microsoft\CMake\CMake\bin;C:\Program Files (x86)\Microsoft Visual Studio\2022\BuildTools\Common7\IDE\CommonExtensions\Microsoft\CMake\Ninja;C:\Program Files (x86)\Microsoft Visual Studio\2022\BuildTools\Common7\IDE\VC\Linux\bin\ConnectionManagerExe
SET PWD=/proc/self/cwd
SET TEMP=C:\temp
SET TMP=C:\temp
C:\Program Files (x86)\Microsoft Visual Studio\2022\BuildTools\VC\Tools\MSVC\14.39.33519\bin\HostX64\x64\link.exe @bazel-out/x64_windows-fastbuild/bin/tests/hello_c.dll-2.params
# Configuration: eb7728ac105a8ebc0b6d7ce4ede9f5d5ffd138b47e90f4c048860530bb450ddb
# Execution platform: @@platforms//host:host
hello_c.obj : error LNK2019: unresolved external symbol hello_common referenced in function yyparse
bazel-out\x64_windows-fastbuild\bin\tests\hello_c.dll : fatal error LNK1120: 1 unresolved externals
MacOS
(20:21:48) ERROR: /Users/buildkite/builds/bk-macos-pln3-07zz/bazel/github-dot-com-jmillikin-rules-bison/tests/BUILD:27:17: Linking tests/libhello_c.dylib failed: (Exit 1): cc_wrapper.sh failed: error executing CppLink command (from target //tests:hello_c)
(cd /private/var/tmp/_bazel_buildkite/2d370554060627d4441068531d803fb9/sandbox/darwin-sandbox/171/execroot/_main && \
exec env - \
PATH=/Users/buildkite/Library/Caches/bazelisk/downloads/sha256/2c29176d6ce9ccdd16d5a15e348c756abd6e0005c77d4695b61871219295fa96/bin:/usr/local/bin:/usr/bin:/bin:/usr/sbin:/sbin:/usr/bin:/bin:/usr/sbin:/sbin:/usr/local/bin \
PWD=/proc/self/cwd \
ZERO_AR_DATE=1 \
external/bazel_tools~cc_configure_extension~local_config_cc/cc_wrapper.sh @bazel-out/darwin_x86_64-fastbuild/bin/tests/libhello_c.dylib-2.params)
# Configuration: 99e3f04cc72c05e150c67c4cf777d8003787724af895ca16db228bfeab5b2c77
# Execution platform: @@platforms//host:host
Use --sandbox_debug to see verbose messages from the sandbox and retain the sandbox build root for debugging
ld: Undefined symbols:
_hello_common, referenced from:
_yyparse in hello_c.o
clang: error: linker command failed with exit code 1 (use -v to see invocation)
I tried the following diff but ran into more issues downstream
diff --git a/bison/rules/bison_cc_library.bzl b/bison/rules/bison_cc_library.bzl
index bc662af..4038ce5 100644
--- a/bison/rules/bison_cc_library.bzl
+++ b/bison/rules/bison_cc_library.bzl
@@ -54,13 +54,14 @@ def _cc_library(ctx, bison_result):
**compile_kwargs
)
- (cc_linking_context, cc_linking_outputs) = cc_common.create_linking_context_from_compilation_outputs(
- name = ctx.attr.name,
+ cc_linking_outputs = cc_common.link(
actions = ctx.actions,
feature_configuration = cc_feature_configuration,
cc_toolchain = cc_toolchain,
- compilation_outputs = cc_compilation_outputs,
linking_contexts = [cc_deps.linking_context],
+ compilation_outputs = cc_compilation_outputs,
+ name = ctx.label.name,
+ output_type = "dynamic_library",
)
outs = []
@@ -69,6 +70,13 @@ def _cc_library(ctx, bison_result):
if cc_linking_outputs.library_to_link.dynamic_library:
outs.append(cc_linking_outputs.library_to_link.dynamic_library)
+ cc_linking_context = cc_common.create_linking_context(
+ linker_inputs = depset([cc_common.create_linker_input(
+ owner = ctx.label,
+ libraries = depset([cc_linking_outputs.library_to_link]),
+ )]),
+ )
+
return struct(
outs = depset(direct = outs),
cc_info = CcInfo(
Curious why this works on linux but no other platforms.
I think I figured out why it's working on Linux, but the root cause is buried somewhere deep within Bazel. A mitigation / workaround within bison_cc_library() is probably the most practical approach.
On Linux, bazel build //tests:hello_common (the cc_library rule) produces both a static .a and shared .so output. When //tests:hello_c (the bison_cc_library) is built, the only output file is a .so. So it's possible to link the output given the available linker inputs from hello_common:
$ bazel build //tests:hello_common
[...]
Target //tests:hello_common up-to-date:
bazel-bin/tests/libhello_common.a
bazel-bin/tests/libhello_common.so
$ bazel build //tests:hello_c
[...]
Target //tests:hello_c up-to-date:
bazel-bin/_solib_k8/libtests_Slibhello_Uc.so
However, on macOS, it seems to be ... different? Reversed? The cc_library is producing only a static library, and the bison_cc_library is trying to produce both.
% bazel build //tests:hello_common
[...]
Target //tests:hello_common up-to-date:
bazel-bin/tests/libhello_common.a
% bazel build //tests:hello_c
Target //tests:hello_c up-to-date:
bazel-bin/tests/libhello_c.a
bazel-bin/_solib_darwin_arm64/libtests_Slibhello_Uc.dylib
It wants to link a .dylib, can't find a dylib from hello_common, and the link fails. Fair enough, but I'm confused about the outputs of the cc_common.* helpers here.
Digging around in the recent-ish builtins_bzl/common/cc/cc_library.bzl, I found that there's now a supports_dynamic_linker feature that needs to be tested for, and its result must be passed to create_linking_context_from_compilation_outputs().
Lots of mood about this.
macOS fixed in https://github.com/jmillikin/rules_bison/commit/f2cb421ce79013b21f99f3ecfd6cb84444f0f246, but CI tests indicate that the Windows build is still broken on current Bazel.
Windows linking fixed by https://github.com/jmillikin/rules_bison/commit/9c0a729486b29c8f1f6b9c3e37850d89e50ba449, and execution of bison.exe by https://github.com/jmillikin/rules_bison/commit/ce9ddfd9138cd29641bde2ba36ff21d148ee68e0