我正在尝试制作尽可能便携的可执行文件.删除一些依赖项后,我在另一个系统上运行二进制文件时遇到以下情况:
/lib/x86_64-linux-gnu/libm.so.6: version `GLIBC_2.15' not found (required by foob)
/lib/x86_64-linux-gnu/libc.so.6: version `GLIBC_2.15' not found (required by foob)
/lib/x86_64-linux-gnu/libc.so.6: version `GLIBC_2.14' not found (required by foob)
Run Code Online (Sandbox Code Playgroud)
我更喜欢我的二进制文件不要求用户升级他们的libc版本,所以我也想删除这个依赖项.
生成上述二进制文件的链接器标志已包含在内-static-libgcc -static-libstdc++
.为什么二进制文件仍然需要共享的libc.so.6?
我也尝试添加-static
标志,但是当我尝试运行该二进制文件时,结果非常奇怪:
$ ls -l foob
-rwxr-xr-x 1 claudiu claudiu 13278191 Oct 10 13:03 foob
$ ./foob
bash: ./foob: No such file or directory
Run Code Online (Sandbox Code Playgroud)
该怎么办?
编辑:
$ file foob
foob: ELF 64-bit LSB executable, x86-64, version 1 (GNU/Linux), dynamically linked (uses shared libs), …
Run Code Online (Sandbox Code Playgroud) 我有一个我在gcc中使用的c库.该库具有扩展名.lib,但始终链接为静态库.如果我编写一个使用该库作为c代码的程序,那么一切都可以.但是,如果我将文件重命名为.cpp(在c/c ++中执行简单的操作),我会得到未定义的引用.这些是我为测试目的编写的简单小程序,因此没有花哨的东西.我编译使用:
gcc -g -Wall -I <path to custom headers> -o program main.c customlibrary.lib -lm -lpthread
Run Code Online (Sandbox Code Playgroud)
上面的作品就像一个魅力.然而:
g++ -g -Wall -I <path to custom headers> -o program main.cpp customlibrary.lib -lm -lpthread
Run Code Online (Sandbox Code Playgroud)
要么
gcc -g -Wall -I <path to custom headers> -o program main.cpp customlibrary.lib -lm -lpthread -lstdc++
Run Code Online (Sandbox Code Playgroud)
导致对customlibrary.lib中任何函数的未定义引用.我尝试创建一个名为customlibrary.a的符号链接,但没有运气.
为什么g ++不能识别我的库.不幸的是我无法访问库的源代码,但是将c-lib链接到c ++应该不是问题吧?
当对使用库链接-l
选项(比方说-lfoo
),GCC会喜欢一个共享对象静态库,如果两者都发现了(会喜欢libfoo.so
到libfoo.a
).有没有办法让gcc更喜欢静态库,如果两者都找到了?
我正在尝试解决的问题如下:我正在为应用程序(飞行模拟器称为X-Plane)创建一个插件,具有以下约束:
/usr/lib
或/usr/lib32
:
LD_PRELOAD
或LD_LIBRARY_PATH
查找我的插件附带的共享对象为了解决上述约束,一种可能的解决方案是将生成的共享对象链接到所使用的所有非平凡库的静态32位版本.但是,在安装这些库时,通常会安装静态和动态版本,因此gcc将始终链接到共享对象而不是静态库.
当然,移动/删除/删除有问题的共享对象,只是将静态库放在中/usr/lib32
,这是一种解决方法,但它不是一个好的
注意:
-Wl,-static -lfoo -Wl,-Bdynamic,
但没有带来预期的结果-l:libfoo.a
过,但这也没有带来预期的结果为什么某些静态库(lib*.a)可以以与共享库(lib*.so)链接(ld -l switch)相同的方式链接,但有些不可以?
我一直被教导所有库,无论是否静态,都可以与-l ...链接,但是我到目前为止遇到了一个库(GLFW),如果我发出"未定义的引用"链接错误,它什么都不做试图以这种方式链接它.
根据对这个问题的回答,链接静态库的"正确"方法是将它们与我自己的目标文件一起直接包含在内,而不是使用-l.而且,就GLFW库而言,这肯定解决了这个问题.但是我正在使用的每个其他静态库在与-l链接时工作得很好.
所以:
考虑以下代码:
one.c:
#include <stdio.h>
int one() {
printf("one!\n");
return 1;
}
Run Code Online (Sandbox Code Playgroud)
two.c:
#include <stdio.h>
int two() {
printf("two!\n");
return 2;
}
Run Code Online (Sandbox Code Playgroud)
prog.c中
#include <stdio.h>
int one();
int two();
int main(int argc, char *argv[])
{
one();
two();
return 0;
}
Run Code Online (Sandbox Code Playgroud)
我想将这些程序链接在一起.所以我这样做:
gcc -c -o one.o one.c
gcc -c -o two.o two.c
gcc -o a.out prog.c one.o two.o
Run Code Online (Sandbox Code Playgroud)
这很好用.
或者我可以创建一个静态库:
ar rcs libone.a one.o
ar rcs libtwo.a two.o
gcc prog.c libone.a libtwo.a
gcc -L. prog.c -lone -ltwo
Run Code Online (Sandbox Code Playgroud)
所以我的问题是:为什么我会使用第二个版本 - 我创建了一个".a"文件 - 而不是链接我的".o"文件?它们似乎都是静态链接,所以它们之间是否有优势或架构差异?
我创建了一个系统,它根据全局实例的构造函数自动将函数对象(仿函数)注册到映射中.
在定义仿函数的每个cpp文件中,有一个注册器类实例的全局实例,用于将仿函数注册到单个std::map<int, std::function<...> >
对象.
这是注册商类的定义:
template
<
typename map_type,
typename handler_type
>
struct registrar
{
registrar
(
map_type& map_object,
boost::uint16_t cmd_code,
const handler_type& handler
)
{
map_object.insert(std::pair<boost::uint16_t, handler_type>(cmd_code, handler));
}
};
Run Code Online (Sandbox Code Playgroud)
在每个.cpp文件中.全局实例定义如下:
namespace one_way
{
static registrar <in_out_map_type, handler>
post_receiver(in_out_map_type::instance(), command, handlers());
}
Run Code Online (Sandbox Code Playgroud)
如果我将所有cpp与main.cpp一起编译,那么一切正常.但是如果我将cpp文件编译成静态库并将其链接到main.cpp
,则注册不起作用.
我在Windows和Ubuntu 11.10上使用VC10和GCC4.61进行了测试.两者都失败了
我发现一个线程有同样的问题,但OP没有说是否解决了.
我错过了什么吗?
编辑
感谢所有回复,包括评论.
每一个回复确实帮助我更多地思考并深入研究这种方法.经过所有的研究和试验,我终于放弃了依赖全局/静态变量进行二元边界自注册的想法,因为没有可靠的方法来保证它能够正常工作.
我最后的方法是将注册保持在一个二进制文件中.
c++ initialization global-variables static-libraries static-linking
我已经构建了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)
我究竟做错了什么?
我正在试验Linux上纯静态链接的PIE可执行文件的概念,但是遇到了GNU binutils链接器在使用时坚持在输出二进制文件中添加PT_INTERP头的问题-pie
,即使在给出时也是如此-static
.有没有办法抑制这种行为?也就是说,有没有办法告诉GNU ld具体不要将某些标题写入输出文件?也许使用链接器脚本?
(请不要回答声称它不起作用;我很清楚该程序仍然需要重定位处理 - 仅由于我的使用而导致的加载地址相对重定位-Bsymbolic
- 并且我有特殊的启动代码代替Scrt1.o
处理这个问题的标准.但是,如果没有动态链接器已经开始并且正在进行工作,除非PT_INTERP
将二进制文件中的标题变为十六进制,否则我无法调用它.)
我正在尝试使用我在iOS应用程序中编译自己的库.该库是Tesseract OCR库.似乎编译(及其依赖)已经好了.
但是,当我尝试在我的应用程序项目中链接此lib时,该应用程序无法链接.链接错误让我感到惊讶; 好像Tesseract找到相当标准的C++东西有问题.
关于我可能做错的任何建议都会有所帮助.
这是我看到的那种链接错误的片段.
Undefined symbols for architecture armv7:
"std::string::find_last_of(char const*, unsigned long) const", referenced from:
tesseract::WordSizeModel::Init(std::string const&, std::string const&) in libtesseract.a(word_size_model.o)
"std::string::find_first_of(std::string const&, unsigned long) const", referenced from:
tesseract::CubeUtils::SplitStringUsing(std::string const&, std::string const&, std::vector<std::string, std::allocator<std::string> >*) in libtesseract.a(cube_utils.o)
"std::string::find_first_not_of(std::string const&, unsigned long) const", referenced from:
tesseract::CubeUtils::SplitStringUsing(std::string const&, std::string const&, std::vector<std::string, std::allocator<std::string> >*) in libtesseract.a(cube_utils.o)
"std::string::data() const", referenced from:
tesseract::CubeUtils::SplitStringUsing(std::string const&, std::string const&, std::vector<std::string, std::allocator<std::string> >*) in libtesseract.a(cube_utils.o)
"std::string::find(char, unsigned long) const", referenced from:
tesseract::TessLangModel::IsLeadingPunc(int) in libtesseract.a(tess_lang_model.o)
Run Code Online (Sandbox Code Playgroud) 我相当熟悉Windows和Linux库的编译但今天当我看到MinGW
我的Windows机器上抛出了dll.a
和.a
文件的OpenCV编译后我开始认真地开始思考.
这些是我\lib
从OpenCV编译的输出:
2012-12-21 23:35 1 338 420 libopencv_core243.dll.a
2012-12-21 23:33 224 994 libopencv_core_pch_dephelp.a
2012-12-21 23:38 830 820 libopencv_features2d243.dll.a
Run Code Online (Sandbox Code Playgroud)
我的\bin
输出:
2012-12-21 23:40 356 178 libopencv_perf_core.dll.a
2012-12-21 23:45 362 702 libopencv_perf_features2d.dll.a
2012-12-21 23:35 4 086 052 libopencv_core243.dll
2012-12-21 23:38 2 102 896 libopencv_features2d243.dll
Run Code Online (Sandbox Code Playgroud)
(我显然有更多的二进制文件,但在这里列出它是没有意义的)
有人能告诉我这些是否是我可以链接的普通静态库?我应该如何与他们联系?