bazel-contrib / bazel-contrib/rules_foreign_cc
cmake: file installed from the source directory are only symlinked
- Dominant language
- Starlark
- Stars
- 737
- Forks
- 270
- PR merge metrics
- No merged PRs in 30d
Description
When using `cmake()` together with Bazel 7.0 with exported headers the build fails.
```sh
$ cd rules_foreign_cc/examples
$ USE_BAZEL_VERSION=7.0.0rc7 bazelisk build //cmake_hello_world_lib/shared/...
INFO: Analyzed 3 targets (0 packages loaded, 0 targets configured).
ERROR: /home/me/src/rules_foreign_cc/examples/cmake_hello_world_lib/shared/BUILD.bazel:13:6: Error while validating output TreeArtifact File:[[]bazel-out/k8-fastbuild/bin]cmake_hello_world_lib/shared/libhello/include : Failed to resolve relative path hello.h inside TreeArtifact /home/tweisssc/.cache/bazel/_bazel_tweisssc/691c198c0f7498b76c679347f393fea9/execroot/_main/bazel-out/k8-fastbuild/bin/cmake_hello_world_lib/shared/libhello/include. The associated file is either missing or is an invalid symlink.
ERROR: /home/me/src/rules_foreign_cc/examples/cmake_hello_world_lib/shared/BUILD.bazel:13:6: Foreign Cc - CMake: Building libhello failed: not all outputs were created or valid
Use --verbose_failures to see the command lines of failed build steps.
INFO: Elapsed time: 0.428s, Critical Path: 0.36s
INFO: 2 processes: 1 internal, 1 linux-sandbox.
ERROR: Build did NOT complete successfully
```
And indeed the installed header file is a symlink:
```sh
$ ls -l /home/me/.cache/bazel/_bazel_me/691c198c0f7498b76c679347f393fea9/execroot/_main/bazel-out/k8-fastbuild/bin/cmake_hello_world_
lib/shared/libhello/include/hello.h
lrwxrwxrwx 1 me me 66 Dec 11 16:57 /home/me/.cache/bazel/_bazel_tweisssc/691c198c0f7498b76c679347f393fea9/execroot/_main/bazel-out/k8-fastbuild/bin/cmake_hello_world_lib/shared/libhello/include/hello.h -> /tmp/bazel-source-roots/0/cmake_hello_world_lib/shared/src/hello.h
```
The problem is that cmake will preserve symlinks when installing them instead of resolving them to the contents (see `cmFileCopier::Install()`).
cmake() with filegroup() symlinks all the sources into the internal build tree, leading for example headers from the source tree to be also installed as (broken) symlink.
Contributor guide
Research direction
Start by reproducing the Bazel 7.0.0rc7 command in the issue under rules_foreign_cc/examples, then inspect CMake's cmFileCopier::Install() behavior for files linked into the internal build tree. Done means installed headers are regular files containing the source contents rather than symlinks, so the exported-header TreeArtifact validates successfully.
Written by the indexing model from the issue text.
Assessment
- Tech stack
- cmake
- Domain
- build-system
- Issue type
- Bug
- Difficulty
- 4/5
- Estimated time
- 3-5 days
- Activity status
- Stale
- Clarity
- Mostly clear
- Newbie friendliness
- 35/100