frans
frans

Reputation: 9788

How to influence value for RPATH in a given gcc/configure environment?

I'm currently facing the following fuzzy problem: I'm wrapping the configure/make based build process for a library my project depends on in a Bazel environment using foreign_cc and I need to set the value for RPATH to a fixed value.

I managed to inject "-Wl,--rpath,SOME_VALUE" using the copts argument which results in ASFLAGS CFLAGS and CXXFLAGS being set inside the resulting build-script, which kind of seems to work, but the binaries created by Bazel contain a strange combination of paths prefixed to the one I've set:

$ objdump -x bazel-bin/external/path/to/binary | grep PATH
  RPATH                /opt/gcc-12.2.0/lib/../lib64:/long/path/inside/bazel/cache:SOME_VALUE

Trying to reproduce this behavior outside Bazel, i.e. fetching/extracting the source, running .configure with the exact same environment variables and running make install similar to the build script used by Bazel results in exactly the value for RPATH I need it to have

$ objdump -x dest/usr/local/lib/binary  |grep 'R.*PATH'
  RUNPATH              SOME_VALUE

So what's going on? What does the Bazel-Buildscript do differently to get to those concatenated value for RPATH?

Well, I guess there are some differences I just don't think about, but I have no clue where to start. Is there a hidden environment variable I can set which says "prefix the intended value for RPATH with some values extracted from the toolchain"?

Here is the part of build_script.sh which actually builds the binaries, which I ran externally, too, but with different results:

ARFLAGS="rcsD" \
AR_FLAGS="rcsD" \
ASFLAGS="-U_FORTIFY_SOURCE -fstack-protector -Wall -Wunused-but-set-parameter -Wno-free-nonheap-object -fno-omit-frame-pointer -fno-canonical-system-headers -Wno-builtin-macro-redefined -D__DATE__="redacted" -D__TIMESTAMP__="redacted" -D__TIME__="redacted" -Wl,--rpath,SOME_VALUE" \
CFLAGS="-U_FORTIFY_SOURCE -fstack-protector -Wall -Wunused-but-set-parameter -Wno-free-nonheap-object -fno-omit-frame-pointer -fno-canonical-system-headers -Wno-builtin-macro-redefined -D__DATE__="redacted" -D__TIMESTAMP__="redacted" -D__TIME__="redacted" -Wl,--rpath,SOME_VALUE" \
CXXFLAGS="-U_FORTIFY_SOURCE -fstack-protector -Wall -Wunused-but-set-parameter -Wno-free-nonheap-object -fno-omit-frame-pointer -std=c++0x -fno-canonical-system-headers -Wno-builtin-macro-redefined -D__DATE__="redacted" -D__TIMESTAMP__="redacted" -D__TIME__="redacted" -Wl,--rpath,SOME_VALUE" \
LDFLAGS="-fuse-ld=gold -Wl,-no-as-needed -Wl,-z,relro,-z,now -B/usr/bin -pass-exit-codes -lstdc++ -lm -L$EXT_BUILD_DEPS/openssl/lib" \
AR="/usr/bin/ar" \
CC="/usr/bin/gcc" \
CXX="/usr/bin/gcc" \
RANLIB=":" \
CPPFLAGS="-I$EXT_BUILD_DEPS/openssl/include" \
./configure
$EXT_BUILD_ROOT/bazel-out/k8-opt-exec-2B5CBBC6/bin/external/rules_foreign_cc/toolchains/make/bin/make install

Upvotes: 1

Views: 346

Answers (1)

Ondrej K.
Ondrej K.

Reputation: 9664

I'm gonna go ahead and assume you're using the auto-resolved toolchain (specifically on Linux by the looks of it).. the RPATH bits you're looking at would come from the runtime_library_search_directories feature which inserts -rpath dynamically linking binaries... so that they work with bazel run or bazel test.

Generally speaking, for cc_* rules the tool configuration is a function of toolchain configuration (your own or auto-resolved and configured). It processes different pieces of information (user passed config) as well build derived (such as where to expect solibs in the resulting tree) to get the complete call. The flags added through copts attribute are processed by user_compile_flags feature (like this). The "other" -rpath arguments are as mentioned added by runtime_library_search_directories feature based on runtime_library_search_directories variable which will be populated by bazel as it adds solibs to link against. The TL;DR there are multiple sources of information (beyond just copts) the command line for compiler/linker invocation will be assembled from.

This description would pertain to auto-resolved toolchain or custom toolchain defining these features / having them patched in with Legacy features patching logic. A fully (from scratch) custom toolchain could handle constructing the command line and tool calling differently.

Beyond that, I don't really have much insight into cc_foreign rules and while I understand the reason for their existence, I generally try to avoid their use (but your mileage may vary by your dependencies and control you have over the tree)... What struck me a little odd on the surface of it, while you say it works, I would not expect copts and passing via CXXFLAGS &Co. Since RPATH is very much a link time configuration, I would actually expect linkopts and "foreign" passing it through LDFLAGS to make more sense?

Upvotes: 0

Related Questions