我有一个第三方库,主要包含大量的static(.a)库文件.我可以将它编译成单个.a库文件,但我真的需要它作为单个.so共享库文件.
有没有办法将静态.a文件转换为共享.so文件?或者更一般地说,有一种很好的方法可以将大量静态.a文件与一些.o目标文件合并到一个.so文件中?
我有一个与另一个(第三方)共享库链接的共享库.然后在我的应用程序中使用dlopen加载我的共享库.所有这一切都很好(假设文件在正确的路径等).
现在,问题是当我链接我的库时,我甚至不需要指定链接第三方共享库.GCC接受它而不报告有关未定义引用的错误.那么,问题; 我如何强制GCC通知我未定义的引用?
如果我将库更改为(临时)可执行文件,则会获得未定义的引用(当不向链接器提供库时).(如果我指定它,工作正常.)
即,完成以下操作:
g++ -fPIC -shared -o libb.so b.o
g++ -fPIC -shared -o liba.so a.o
g++ -o a.exe a.cpp
Run Code Online (Sandbox Code Playgroud)
第二行没有给出错误,第三行抱怨未定义的引用.
示例代码:
啊:
class a
{
public:
void foobar();
};
Run Code Online (Sandbox Code Playgroud)
a.cpp:
#include "a.h"
#include "b.h"
void a::foobar()
{
b myB;
myB.foobar();
}
int main()
{
a myA; myA.foobar();
}
Run Code Online (Sandbox Code Playgroud)
BH:
class b
{
public:
void foobar();
};
Run Code Online (Sandbox Code Playgroud)
b.cpp:
#include "b.h"
void b::foobar()
{
}
Run Code Online (Sandbox Code Playgroud) 所以每个人都可能知道glibc /lib/libc.so.6可以在shell中执行,就像普通的可执行文件一样,在这种情况下它可以打印出版本信息并退出.这是通过在.so中定义入口点来完成的.对于某些情况,将其用于其他项目可能会很有趣.不幸的是,您可以通过ld的-e选项设置的低级入口点有点太低级:动态加载器不可用,因此您无法调用任何正确的库函数.因此,glibc通过此入口点中的裸系统调用实现write()系统调用.
我现在的问题是,任何人都可以想到一个很好的方法,如何从该入口点引导一个完整的动态链接器,以便可以访问其他.so的函数?
我们在平原开发了一些项目C(C99).但是,我们有一个库作为源代码(数学库)C++.我们需要这个库,所以我想问一下,集成这些源代码的最优雅方式是什么?
大小之比C,并C++正在20:1使移动C++是不是选项.我们应该使用静态库吗?DLL?(这都是在Windows上).
我学会了" 程序库HOWTO ".它提到soname用于管理如下的版本.
gcc -shared -fPIC -Wl,-soname,libfoo.so.1 -o libfoo.so.1.0.0 foo.c
ln -s libfoo.so.1.0.0 libfoo.so.1
ln -s libfoo.so.1 libfoo.so
Run Code Online (Sandbox Code Playgroud)
我得到的信息是,如果soname没有设置.它将等于libfoo.so.1.0.0,请参阅此处的答案.
我发现它也可以在没有soname的情况下工作,就像下面一样
gcc -shared -fPIC -o libfoo.so.1.0.0 foo.c
ln -s libfoo.so.1.0.0 libfoo.so.1
ln -s libfoo.so.1 libfoo.so
Run Code Online (Sandbox Code Playgroud)
所以我认为唯一有用的一点是,soname当您使用readelf -d libfoo.so命令检查时,该选项可以告诉您共享库的版本.
它还能做什么?
我想控制在CMake中找到/链接我的二进制文件的库的类型.最终目标是,"尽可能静态地"生成二进制文件,以便静态链接每个具有可用静态版本的库.这很重要,因为在测试期间可以在不同系统中实现二进制文件的可移植性.
ATM这似乎很难实现,因为FindXXX.cmake软件包,或者更确切地说,只要静态和动态都可用,find_library命令总是会获取动态库.
有关如何实现此功能的提示 - 最好以优雅的方式 - 非常受欢迎!
linker cmake shared-libraries static-linking dynamic-library
有没有办法检查哪些库是正在运行的进程?
更具体地说,如果程序使用dlopen加载某些共享库,则readelf或ldd不会显示它.是否有可能从正在运行的进程中获取该信息?如果有,怎么样?
某些平台要求您向链接器提供共享库的外部符号列表.但是,在大多数不需要的unixish系统上:默认情况下,所有非静态符号都可用.
我的理解是,GNU工具链可以选择性地将可见性限制为显式声明的符号.如何使用GNU ld实现这一目标?
在Windows API和其他各种库中,我看到了方法的多个入口点,我注意到在MyApiCall和MyApiCallEx等场景中使用了Ex缩写.
我的假设是,这代表扩展或额外可以有人请确认吗?
任何关于为什么选择Ex而不是MyApiCall2或类似的历史也会受到赞赏.
我在index.html文件中有多个lib文件,它们按正确顺序加载到我正在运行的应用程序中.
<!-- example of some of them... -->
<script src="/./sys/lib/jquery.min.js"></script>
<script src="/./sys/lib/jquery.ui.min.js"></script>
<script src="/./sys/lib/jquery.easing.min.js"></script>
<script src="/./sys/lib/underscore.min.js"></script>
<script src="/./sys/lib/handlebars.min.js"></script>
<script src="/./sys/lib/backbone.min.js"></script>
<script src="/./sys/lib/moment.min.js"></script>
<script src="/./sys/lib/libs.extensions.js"></script>
Run Code Online (Sandbox Code Playgroud)
它们运行良好,它们已经全部缩小了.
现在,我想将这些全部组合到一个文件中以加载速度:
<script src="/./sys/lib/libs.all.js"></script>
Run Code Online (Sandbox Code Playgroud)
所以我打开新libs.all.js文件,逐个将缩小的.js文件粘贴到其中,零修改,按照与上面列出的完全相同的顺序.这有效,直到我到达moment.js.当我将其粘贴并运行它时,我得到一个JS错误.
TypeError: (intermediate value)(...) is not a function
Run Code Online (Sandbox Code Playgroud)
我没有得到我所缺少的东西 - 如果我在HTML文件中同步加载时按正确顺序粘贴它们,有什么区别?
shared-libraries ×10
c ×5
linux ×4
c++ ×3
linker ×2
api ×1
cmake ×1
compilation ×1
dlopen ×1
gcc ×1
glibc ×1
gnu ×1
html ×1
javascript ×1
synchronous ×1
windows ×1