cc_library produces empty .so library if srcs input is a tree artifact (dynamic linking/gcc gold linker/Linux)
- Dominant language
- Java
- Stars
- 25.8k
- Forks
- 4.6k
- Avg merge
- 2d 20h
- Merged PRs (30d)
- 72
Description
### Description of the problem / feature request:
Using Linux gcc gold linker as default of running bazel in Ubuntu 20.04.
If the srcs input of cc_library is a tree artifact, like a declare_directory of a rule, the generated actions for building will pass the directory of the corresponding object .o files to the linker command. This works fine for the ar command producing a correct .a, however for the .so linker command it will produce an empty .so dynamic library.
### Bugs: what's the simplest, easiest way to reproduce this bug? Please provide a minimal example if possible.
#### 1. Have any rule generating .c/cpp/h source files but return the object from declare_directory (for example the specific names of files are not previously known).
```
out_dir = ctx.actions.declare_directory(ctx.attr.name)
(...)
compilation_context = cc_common.create_compilation_context(
headers = depset([out_h]),
includes = depset([out_dir.path])
)
return [
DefaultInfo(files = depset([out_dir])),
CcInfo(compilation_context = compilation_context)
]
```
#### 2. Have a cc_library using the output of the previous rule in the srcs to compile them
```
# this rules generates .cpp and .h in a tree artifact
my_best_generator(
name = "vasco",
)
# this library uses the generated files
cc_library(
name = "vasco_lib",
srcs = [":vasco"],
deps = [":vasco"],
)
```
#### 3. Build the cc_library and Verify the symbols exported in the resulting .a and .so (for example nm command)
#### 4. The .so will not have symbols from the generated sources
#### 6. Verify the actions with aquery
For linking the .a file:
```
Command Line: (exec /usr/bin/ar \
rcsD \
bazel-out/k8-fastbuild/bin/app/libvasco_lib.a \
bazel-out/k8-fastbuild/bin/app/_pic_objs/vasco_lib/vasco \
@bazel-out/k8-fastbuild/bin/app/libvasco_lib.a-2.params)
```
This works fine for ar.
However for linking the .so file:
```
Command Line: (exec /usr/bin/gcc \
-shared \
-o \
bazel-out/k8-fastbuild/bin/app/libvasco_lib.so \
-Wl,-S \
'-fuse-ld=gold' \
-Wl,-no-as-needed \
-Wl,-z,relro,-z,now \
-B/usr/bin \
-pass-exit-codes \
-Wl,--start-lib \
bazel-out/k8-fastbuild/bin/app/_pic_objs/vasco_lib/vasco \
-Wl,--end-lib \
-lstdc++ \
-lm \
@bazel-out/k8-fastbuild/bin/app/libvasco_lib.so-2.params)
```
This will produce an empty dynamic library, since --start-lib --end-lib doesn't expect a directory
#### 7. tested in several versions of bazel including 4.x, 5.x and 6.x
### What operating system are you running Bazel on?
Linux Ubuntu 20.04
### What's the output of `bazel info release`?
release 5.0.0
### Have you found anything relevant by searching the web?
Places to look:
- Man page of gcc gold linker: http://manpages.ubuntu.com/manpages/trusty/man1/ld.gold.1.html
- Introduction of --start-lib end --end-lib options in binutils: https://sourceware.org/pipermail/binutils/2010-March/066146.html
### Any other information, logs, or outputs that you want to share?
My test scenario:
[test.txt](https://github.com/bazelbuild/bazel/files/8082243/test.txt)
Contributor guide
Research direction
Start with the minimal generator and cc_library scenario in the issue and inspect the link actions with aquery. Compare the archive action with the shared-library action using --start-lib and --end-lib, then consult the linked gold linker documentation. Done means generated symbols appear in the resulting .so as well as the .a.
Written by the indexing model from the issue text.
Assessment
- Tech stack
- cpp, linux
- Domain
- build-system, compilers
- Issue type
- Bug
- Difficulty
- 4/5
- Estimated time
- 3-5 days
- Activity status
- Stale
- Clarity
- Mostly clear
- Newbie friendliness
- 42/100