Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/cplusplus/129.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C++ 代码::Blocks and boost 1.55:存在动态库时不使用静态库_C++_Gcc_Boost_Linker_Codeblocks - Fatal编程技术网

C++ 代码::Blocks and 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项目的链接器

我使用以下命令构建了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,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