我正在Linux上构建C++可执行文件.可执行文件链接到一些boost库.
这是我尝试运行二进制文件时的输出:
root@yourbox:~/work/dev/c++/projects/testfgci/dist/Debug/GNU-Linux-x86$ ./testfgci
./testfgci: error while loading shared libraries: libboost_system.so.1.45.0: cannot open shared object file: No such file or directory
Run Code Online (Sandbox Code Playgroud)
然后我在二进制文件上运行ldd来检查依赖项:
root@yourbox:~/work/dev/c++/projects/testfgci/dist/Debug/GNU-Linux-x86$ ldd testfgci
linux-gate.so.1 => (0x00380000)
libboost_system.so.1.45.0 => not found
libstdc++.so.6 => /usr/lib/libstdc++.so.6 (0x00b50000)
libm.so.6 => /lib/tls/i686/cmov/libm.so.6 (0x005f6000)
libgcc_s.so.1 => /lib/libgcc_s.so.1 (0x0099a000)
libc.so.6 => /lib/tls/i686/cmov/libc.so.6 (0x001b3000)
libpthread.so.0 => /lib/tls/i686/cmov/libpthread.so.0 (0x00110000)
/lib/ld-linux.so.2 (0x00ea2000)
Run Code Online (Sandbox Code Playgroud)
我不确定为什么找不到liboos_system.sl.1.45.0 SO.我今天早些时候成功地建造了它.谁能解释一下?
这通常不是我喜欢的两件事,因为这些事情让我非常恼火(除了我的孩子).我在工作中编写了一个Haskell程序,它使用文本,xml-enumerator,attoparsec-text等库.我在工作的Windows机器上正常工作,我的Ubuntu虚拟机在工作(32位),我的Ubuntu桌面(再次32位)和运行Ubuntu(64位)的EC2实例.
我们的客户端运行的是CentOS 5.3,64位.我不能为我的生活让这个可执行文件正常运行.我尝试使用以下方法创建静态可执
ghc --make myprog.hs -optl-static -optl-pthread
Run Code Online (Sandbox Code Playgroud)
但是当我尝试在CentOS服务器上运行该可执行文件时,我收到一条错误消息:
openFile: invalid argument (Invalid argument)
Run Code Online (Sandbox Code Playgroud)
我假设这与此处描述的错误有关.我尝试从32位和64位Ubuntu编译,尝试静态和共享版本,没有任何作用(虽然我偶尔会得到段错误而不是上面的错误消息).我可以尝试下载CentOS 5.3并为它创建一个虚拟机,但下载需要一段时间,而且我不确定哪个版本的GHC可以使用它(我尝试在他们的服务器上安装GHC 7,但我跑了进入libc问题).
在这一点上,我想出了一些可能的方法,但我想尽可能避免这些:
总而言之,这些是我真的希望我们有GHC的JVM后端的情况.我想我也可以试用LambdaVM.但我很想听听社区对这里做什么的建议.
我们正在构建一个主要使用Obj-C/Cocoa编写的Mac OSX应用程序.然后,应用程序静态链接一些第三方库,用C/C++编写并由我们编译(在命令行上,使用MacPorts或通常的"./configure && make";所有都是通用二进制文件).
该应用程序运行正常,但广告编译时我们总是得到这些奇怪的链接器警告:
ld: warning: direct access in ___cxx_global_var_init17 to global weak symbol __ZGVN4i18n12phonenumbers9SingletonINS0_15PhoneNumberUtilEE8instanceE means the weak symbol cannot be overridden at runtime. This was likely caused by different translation units being compiled with different visibility settings.
ld: warning: direct access in ___cxx_global_var_init17 to global weak symbol __ZGVN4i18n12phonenumbers9SingletonINS0_15PhoneNumberUtilEE8instanceE means the weak symbol cannot be overridden at runtime. This was likely caused by different translation units being compiled with different visibility settings.
ld: warning: direct access in ___cxx_global_var_init17 to …
Run Code Online (Sandbox Code Playgroud) 我的问题可归纳如下:
bar.c:
#include <stdio.h>
void bar() {
printf("bar\n");
}
Run Code Online (Sandbox Code Playgroud)
main.c:
#include <stdio.h>
void __attribute__((weak)) bar() {
printf("foo\n");
}
int main() {
bar();
return 0;
}
Run Code Online (Sandbox Code Playgroud)
Makefile:
all:
gcc -c bar.c
ar -rc libbar.a bar.o
gcc main.c -L. -lbar
Run Code Online (Sandbox Code Playgroud)
输出:
$ ./a.out
foo
Run Code Online (Sandbox Code Playgroud)
所以main.c中的弱符号栏不会被bar.c中的强符号覆盖,因为bar.c被链接到静态库libbar.a中的main.c.
我如何告诉gcc在libbar.a中使用强符号来覆盖main.c中的弱符号?
我已经构建了glibc 2.14并将其安装在目录中~/GLIBC/glibc_install
.现在我想使用这个C库而不是系统的默认C库来构建和运行程序.
为了确保我使用的是自定义glibc,我添加了一个put glibc/stdio-common/printf.c:__printf
来打印消息的调用.
然后我重建并重新安装了glibc.
然后我写了一个"Hello,World"程序并尝试编译并链接如下:
gcc -nodefaultlibs -static -lgcc -L~/GLIBC/glibc_install/lib -o myprog myprog.c
Run Code Online (Sandbox Code Playgroud)但是我得到以下链接器错误报告:
/usr/lib/gcc/x86_64-linux-gnu/4.4.3/../../../../lib/crt1.o: In function `_start':
(.text+0x19): undefined reference to `__libc_csu_init'
/usr/lib/gcc/x86_64-linux-gnu/4.4.3/../../../../lib/crt1.o: In function `_start':
(.text+0x25): undefined reference to `__libc_start_main'
/tmp/ccACTQEp.o: In function `main':
c1.c:(.text+0xa): undefined reference to `puts'
collect2: ld returned 1 exit status
Run Code Online (Sandbox Code Playgroud)
我究竟做错了什么?
我正在试图弄清楚如何设置一些环境变量,这将使g ++链接到正确版本的库.
我在/ usr/lib64中有一些旧的boost库(链接这些将失败)和/ v/users/regel/lib中的新库.因此链接器应链接新库.
命令:
$ g++ test.cpp -lboost_system -L/v/users/regel/lib
Run Code Online (Sandbox Code Playgroud)
正确链接程序.但是,我希望将其设置为链接器的第1个搜索目录,这样我每次链接时都不必指定"-L".
以下环境变量似乎不起作用:
$ LIBRARY_PATH=/v/users/regel/lib g++ test.cpp -lboost_system
/tmp/regel/cc4SmBtI.o: In function `main':
test.cpp:(.text+0x5): undefined reference to `boost::system::system_category()'
collect2: error: ld returned 1 exit status
Run Code Online (Sandbox Code Playgroud)
和
$ LD_LIBRARY_PATH=/v/users/regel/lib:$LD_LIBRARY_PATH g++ test.cpp -lboost_system
/tmp/regel/ccUreBZy.o: In function `main':
test.cpp:(.text+0x5): undefined reference to `boost::system::system_category()'
collect2: error: ld returned 1 exit status
Run Code Online (Sandbox Code Playgroud)
尽管阅读了大量关于类似主题的文章和帖子,但我还没有找到解决方案.
我正在用C++编写Excel文件构建器.
我有我需要的一切工作,但我仍然依赖一个外部空的.xlsx文件,我解压缩,迭代,并根据需要添加数据来创建最终文件.
我想通过将.xlsx文件转换为可执行文件的.rodata部分中的二进制blob来删除此依赖项,方法是将其首先转换为对象文件,如下所示:
$ ld -r -b binary -o template.o template.xlsx
$ objcopy --rename-section .data=.rodata,alloc,load,readonly,data,contents template.o template.o
Run Code Online (Sandbox Code Playgroud)
我从博客文章http://www.burtonini.com/blog/computers/ld-blobs-2007-07-13-15-50获得了这些信息.
第二步是将它链接到二进制文件,我可以使用它ld
.
如何使用CMake自动执行这两个步骤?
我目前不知道如何ld
在第一步中运行如上所述的特定命令,并且我已尝试在第二步中添加files/template.o
到我的target_link_libraries,但ld
只是说:
/usr/bin/ld: cannot find -lfiles/template.o
Run Code Online (Sandbox Code Playgroud)
我将以下自定义命令添加到我的CMakeLists.txt:
add_custom_command(OUTPUT files/template.o
COMMAND ld -r -b binary -o files/template.o files/template.xlsx
COMMAND objcopy --rename-section .data=.rodata,alloc,load,readonly,data,contents files/template.o files/template.o)
Run Code Online (Sandbox Code Playgroud)
并将文件/ template.o添加到add_executable调用.
不幸的是,CMake说:
ld:无法打开输出文件files/template.o:没有这样的文件或目录
据我所知,OUTPUT命令add_custom_command
允许我们告诉CMake COMMAND命令正在创建什么文件.所以我现在有点困惑.
我更新了CMakeLists.txt文件并添加了一个目标,以确保模板文件已构建:
add_custom_target(run ALL
DEPENDS template.o)
Run Code Online (Sandbox Code Playgroud)
并且依赖于确保它在excelbuilder
目标之前构建:
add_dependencies(excelbuilder run)
Run Code Online (Sandbox Code Playgroud)
我还更新了自定义命令,如下所示:
add_custom_command(OUTPUT template.o
COMMAND ld -r -b binary -o template.o …
Run Code Online (Sandbox Code Playgroud) -l选项告诉链接器搜索标准目录中的库.使用-L,我们可以指定自己的库目录进行搜索.
问题:顺序顺序是否也与-L选项有关,就像-l wrt链接器一样?
这个链接:http://gcc.gnu.org/onlinedocs/gcc/Link-Options.html没有多说-L的序列.
编辑 另外,
在默认目录之前搜索命令行中指定的目录
是来自手册页(正如Dmitry指出的那样),这是否意味着即使我指定的顺序如下:
gcc -lm hello.c -Lx
Run Code Online (Sandbox Code Playgroud)
仍然首先给出用-L指定的目录?
我正在使用Xcode构建旧代码并指定 SDKROOT=/Developer/SDKs/MacOSX"${HOST_VERSION}".sdk/
我想为系统上预安装的最新SDK指定SDKROOT(?).例如我已经在10.8
,我想SDKROOT
用-syslibroot 指定,但是没有这样的SDK /Developer/SDKs/
.我应该完全忽略syslibroot SDK_VERSION == HOST_VERSION
吗?
我正在阅读:http: //gcc.gnu.org/onlinedocs/gcc/Optimize-Options.html
它首先表明:与-flto结合使用此选项(-fwhole-program)不应该使用.相反,依赖链接器插件应该提供更安全和更精确的信息.
然后,它表明:如果程序不需要导出任何符号,则可以将-flto和-fwhole-program结合使用,以允许过程间优化器使用更积极的假设,这可能会改善优化机会.当链接器插件处于活动状态时,不需要使用-fwhole-program(请参阅-fuse-linker-plugin).
这是否意味着在理论上,使用-fuse-linker-plugin和-flto总是得到比使用-fwhole-program with -flto更好的可执行文件?
我尝试使用ld 分别与-fuse -linker-plugin和-fwhole-program 链接,并且可执行文件的大小至少是不同的.
提前致谢.
PS我在CentOS 6上使用gcc 4.6.2和ld 2.21.53.0.1.