关于项目目录下的 c:scons 可执行共享库

scons executable + shared library in project directory

这是一个示例 SConscript 文件:

1
2
3
4
5
6
7
8
env = Environment()
hello_lib = env.SharedLibrary('hello', ['libhello.c'])
exe = env.Program('main', ['main.c'], LIBS=hello_lib)

env.Install('/usr/lib', hello_lib)
env.Install('/usr/bin', exe)
env.Alias('install', '/usr/bin')
env.Alias('install', '/usr/lib')

它构建一个共享库,以及一个链接到该库的可执行文件:

1
2
3
4
5
6
7
8
9
$ scons
scons: Reading SConscript files ...
scons: done reading SConscript files.
scons: Building targets ...
gcc -o libhello.os -c -fPIC libhello.c
gcc -o libhello.so -shared libhello.os
gcc -o main.o -c main.c
gcc -o main main.o libhello.so
scons: done building targets.

现在,问题是创建的可执行文件在从项目目录运行时找不到共享库,
这是很自然的,因为没有设置 LD_LIBRARY_PATH 环境变量,或者
在可执行文件中设置了任何 RPATH:

1
2
[fedora 00:07:10 2 ~] $ ./main
./main: error while loading shared libraries: libhello.so: cannot open shared object file: No such file or directory

我总是可以在开发时设置 LD_LIBRARY_PATH 变量,但是如果项目的目录层次结构在 sub_directories 中有多个共享库,这将变得很麻烦。

GNU autotools/libtool 通过自动将可执行文件的 RPATH 设置到项目目录中构建共享库的任何位置来解决这个问题,这样可以在开发时轻松运行/测试可执行文件。并且它在安装时重新链接可执行文件以省略那些不再需要的 RPATH。

是否有任何类似于 autotools 的功能可以使用 scons 来简化开发时的可执行文件测试?

有没有推荐的方法来使用共享库和 scons 构建应用程序,这样可以很容易地从构建目录运行可执行文件?


您可以修改每个生成库的 SConscript 文件,如下所示:

1
hello_lib = env.SharedLibrary('#/lib/hello', ['libhello.c'])

您的所有共享库现在都位于一个目录中。

生成可执行文件的 SConscript 变为:

1
exe = env.Program('main', ['main.c'], LIBPATH='#/lib', LIBS=hello_lib)

然后您就可以将 LD_LIBRARY_PATH 设置为 $PWD/lib


看起来您正在寻找 scons 中的 RPATH 选项。

在 wiki 页面中,RPATH 被描述为 scons,如下所示。

A list of paths to search for shared libraries when running programs.
Currently only used in the GNU linker (gnulink) and IRIX linker
(sgilink). Ignored on platforms and toolchains that don't support it.
Note that the paths added to RPATH are not transformed by scons in any
way: if you want an absolute path, you must make it absolute yourself.