当lib文件夹中存在静态和共享C ++库时,仅链接静态库

时间:2018-04-11 02:38:00

标签: c++ build cmake conan

我使用conan作为依赖管理器,使用cmake作为构建工具。我有一些预先构建的第三方库,它们在lib文件夹(.a和.so文件)中都有共享库和静态库。我的计划是从那些预先构建的库中创建conan包,并使用它们来构建应用程序

当我在构建应用程序时尝试链接库时,它默认链接共享库。但我想将静态库用于特定的应用程序。

解决问题的一种方法是为静态和共享库创建两个单独的conan包,并在conanfile中包含所需的静态包,但这将导致Artifact管理的冗余(相同的头文件将出现在多个包中)。

有没有更好的方法对conanfile.py或CMakeLists.txt进行任何更改,这样我就可以链接静态库而不是共享库,即使同一个lib文件中存在类似的共享库(例如libX) .a和libX.so都在同一个lib文件夹中)?

1 个答案:

答案 0 :(得分:1)

  

解决问题的一种方法是为静态和共享库创建两个单独的conan包,并在conanfile中包含所需的静态包,但这将导致Artifact管理的冗余(相同的头文件将出现在多个包中)。

这是我的第一个建议。但不是作为两个单独的包,而是使用与options={"shared": [True, False]}相同的包配方,并使其生成2个不同的包二进制文件(但对于相同的包。除非你有一个包含数千个头文件的巨大库(即使) ,下载时间和磁盘空间的影响非常小。如果必须手动创建或安装软件包,可能会出现问题,但由于一切都是自动的,您不会注意到。 如果生成一些config.h(针对不同平台或静态/共享使用不同的配置),或者针对不同平台具有不同的头,典型的“header_win.h”,这种方法具有以后更容易维护的优点。和“header_linux.h ”,可以使用conan完全自动化,以便有一个对消费者透明的“header.h”

如果您仍然希望没有这种重复,可以有不同的方法:

首先,您可以创建“PkgHeaders”包,其中只包含“Pkg”包中的required标题,其中包含只有二​​进制文件(共享或静态)

另一种方法:您可以使“Pkg”包包含静态和共享版本。它类似于解释here in the docs的发布/调试多配置包。我们的想法是该软件包没有shared选项。它将创建和打包两者。 package_info()方法将为每个变量声明不同的变量,例如

 def package_info(self):
     self.cpp_info.shared.libs = ["libX.so"]
     self.cpp_info.static.libs = ["libX.a"]

这将在生成的 conanbuildinfo.cmake

中生成不同的CMake变量
set(CONAN_LIBS_SHARED libX.so ${CONAN_LIBS_SHARED})
set(CONAN_LIBS_STATIC libX.a ${CONAN_LIBS_STATIC})

但请注意,这些变量不会在消费者中自动使用,但您必须明确决定使用哪一个。

因此增加的复杂性是不值得的。除非你的库有数百MB的标题,否则我肯定会采用第一种方法。