关于项目目录下的 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) |
它构建一个共享库,以及一个链接到该库的可执行文件:
|
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.
相关讨论
- 是的,我正在寻找有关如何最好地使用 SCons 执行此操作的建议,方法与 automake/libtool 处理它的方式类似。或者您是说我必须手动为项目中的每个潜在共享库设置 RPATH,并以某种方式确保在安装目标运行时未设置 RPATH?
- @user964970,RPATH 通常用于与应用程序捆绑在一起的共享库,wiki 解释了如何在 RPATH 内指定相对路径,以便构建的应用程序在开发环境和目标环境中都可以工作.
- @user964970,当然,这要求您的开发环境构建输出中的相对目录结构与部署的相对目录结构相匹配,但我认为这是一个合理的要求。
- 嗯,这对我来说是一个很不合理的要求。例如,我在 libA 和 libB 源文件夹下有 2 个共享库,这需要我将 RPATH 设置为 libA 和 libB,在安装项目时,库进入 /usr/lib(并且不需要 RPATH)。
- @user964970,我当然不是要求您更改源目录结构,只是要求您的二进制分发结构应该与部署的结构相匹配。构建 libA 和 libB 时,将输出放在名为 lib 的本地目录中。
- 除了手动复制文件之外,有关如何使用 scons 执行此操作的任何提示? variant_dir 不会有太大帮助,因为它还将中间文件放在变体目录中(这当然可能与文件名冲突)。