4

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

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

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

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

4

1 回答 1

1

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

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

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

首先,您可以制作一个仅包含标头的“PkgHeaders”包,它将required来自“Pkg”包,仅包含二进制文件(共享或静态)

另一种方法:您可以使“Pkg”包同时包含静态和共享版本。它类似于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 的标头,否则我肯定会采用第一种方法。

于 2018-04-11T09:03:03.363 回答