我使用conan作为依赖管理器,使用cmake作为构建工具。我有一些预先构建的第三方库,它们在lib文件夹(.a和.so文件)中都有共享库和静态库。我的计划是从那些预先构建的库中创建conan包,并使用它们来构建应用程序
当我在构建应用程序时尝试链接库时,它默认链接共享库。但我想将静态库用于特定的应用程序。
解决问题的一种方法是为静态和共享库创建两个单独的conan包,并在conanfile中包含所需的静态包,但这将导致Artifact管理的冗余(相同的头文件将出现在多个包中)。
有没有更好的方法对conanfile.py或CMakeLists.txt进行任何更改,这样我就可以链接静态库而不是共享库,即使同一个lib文件中存在类似的共享库(例如libX) .a和libX.so都在同一个lib文件夹中)?
答案 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的标题,否则我肯定会采用第一种方法。