C++ 代码::Blocks and boost 1.55:存在动态库时不使用静态库
我使用以下命令构建了boost 1.55序列化库:C++ 代码::Blocks and boost 1.55:存在动态库时不使用静态库,c++,gcc,boost,linker,codeblocks,C++,Gcc,Boost,Linker,Codeblocks,我使用以下命令构建了boost 1.55序列化库: b2 --build-dir=build toolset=gcc --with-serialization --layout=tagged link=static threading=multi stage 并在我的stage/lib目录中获得了libboost_serialization-mt.a和libboost_wserialization-mt.a——很好。然后,我将boost_serialization添加到我的C::B项目的链接器
b2 --build-dir=build toolset=gcc --with-serialization --layout=tagged link=static threading=multi stage
并在我的stage/lib
目录中获得了libboost_serialization-mt.a
和libboost_wserialization-mt.a
——很好。然后,我将boost_serialization
添加到我的C::B项目的链接器库列表中,并编译了,它在命令行中运行良好。然后,我使用
b2 --build-dir=build toolset=gcc --with-serialization --layout=tagged link=static,shared threading=multi,single stage
并且在我的stage/lib
目录中获得了更多的库,正如预期的那样。让我困惑的是,每个库都有一个。因此
文件,即使是那些应该是静态的库。为什么在那里?需要它做什么
现在编译项目时,可执行文件会抱怨:
error while loading shared libraries: libboost_serialization.so.1.55.0: cannot open shared object file: No such file or directory
库肯定在那里,我可能只需要将路径添加到LD\u library\u path
,但我现在想静态链接。我该怎么做
我也不太了解库的命名:我在我的lib
文件夹中有一些libboost\u wserialization…
库,而w
前缀serialization
在当前文档的库命名部分没有描述
您的回答让我更好地了解了正在发生的事情——现在我知道了
boost\u wserialization
库的来源。我发现在进行第二次构建之后,所有现有库都被共享,静态库被覆盖。这就是为什么我被“额外的”搞糊涂了。所以,以前那些库的文件实际上是静态的
让我困惑的是,每个库都有一个.so文件,甚至
那些应该是静态的。为什么在那里?需要它做什么
你显然在使用别人的make文件。我自己写的。我的build命令不创建“.so”(共享对象库)。它只创建“.a”(存档库)。链接器知道如何使用其中一个
请参阅man ar。实用程序ar可建立档案。
见劳工处。实用程序ld可以构建共享对象
您可以在构建序列中查找这些实用程序调用,或者询问某人它们在哪里并注释掉ld的使用,因为您很可能不需要两者(并且构建两者都会不必要地延长构建时间)。或者,您可以暂时重命名ld命令,然后尝试构建。当它找不到ld命令时,您可能会得到一个有用的提示,说明在哪里调用ld
在我的make文件中,命令如下所示。注释字符在行的开头是一个#。(字符串扩展$(AR)和$(LD)允许使用非标准实用程序。)
存档(.a)在使用时直接链接到可执行文件并包含在可执行文件中。加载可执行文件时,.a的所有引用符号都已在其中。(未引用的符号和代码未链接到中)
共享对象(.so)不是直接链接的,而是您的可执行文件获得.so的句柄(或者文件名)。我相信,当加载可执行文件时,不会立即加载.so。直到可执行文件第一次引用.so中的符号时,.so才会加载。在加载时,您的应用程序将经历延迟,但对于大多数应用程序来说,延迟加载可能是合理的
在激活进程之前,.so也可能已加载到系统内存中。在这种情况下,当您的可执行文件第一次引用.so中的符号时,一些系统代码会将内存中现有的.so“映射”到您的应用程序--可能比加载它快,但我认为最大的好处是,许多进程使用/引用的.so只需加载一次,从而节省内存空间。即使你的应用程序不需要所有符号,也会加载.so的所有符号
在这两种情况下,.so的可执行文件都会变小,.a的可执行文件会变大,但是.so的每个文件都会有一些小的性能影响。因此,需要加载或映射这些文件。我的桌面有4GB,从来没有“拥挤”的感觉。它的交换从未使用过(afaik)。所以我一般用a
注意:当链接器可以访问存档(.a)和共享对象(.so)文件时,链接器将使用.so(并忽略.a)。也许你可以忽略这个偏好,但我没有尝试过。我发现简单地将归档(.a)移动到一个单独的目录(从.so的)中,并通过-L build选项通知链接器更容易 好的,第一个问题:
为什么会有boost\u序列化
和boost\u序列化
库
wserialization库是面向wchar\t的。放入一个单独的库中,因为实际上可能不需要它
为什么有多个共享/静态库
您之所以看到这些额外的共享库,是因为您正在使用link=static,shared
调用b2
,这指示boost构建共享库和静态库。此外,添加thread=multi
会导致构建mt
库,这些库是链接到多线程应用程序时应该使用的库
为什么我会收到关于libboost\u序列化的运行时链接错误。so.1.55.0
默认情况下,大多数unix/linux系统在链接时更喜欢使用共享库而不是静态库,因此当您尝试链接时,它更喜欢使用共享库而不是静态库。如果要强制链接静态库而不是共享库,请告诉编译时链接器使用:
-Wl,-Bstatic -lboost_serialization -Wl,-Bdynamic
这将导致链接器查找boost\u序列化
库的静态变量,而不是动态变量
现在,因为您使用的是code::blocks
-Wl,-Bstatic -lboost_serialization -Wl,-Bdynamic