对于我的CMake项目,我有一个外部库,包含一个头文件和几个.lib / .dll对。
头文件有选择地链接到.lib / .dll对中的一个,举个例子:
#ifdef DEBUG
#pragma comment(lib "exampled.lib")
#elif
#pragma comment(lib "example.lib")
#endif
完整的,有一个.lib和匹配的.dll用于32/64位和Debug / Release,所以共有4对。头文件内部是正确的#ifdef
- 用于链接正确库的逻辑。正如我所说它是一个外部库,所以我不想改变那个标题。
将此课程教授给CMake的正确方法是什么?
对于编译时(即包含目录),我可以使用target_include_directories()
,它可以正常工作。我也可以创建一个带有接口包含目录的导入目标,这也可以正常工作。
问题始于链接时间:
target_link_libraries()
强制我指定一个.lib / .dll文件。我可以复制#ifdef
逻辑,但这感觉不对。添加所有文件也是不正确的,因为总是只需要一个。link_directories()
在全球范围内发挥作用。如果只有少数目标确实需要它,那就觉得没必要了。PATH
似乎也是“全局”,即因为该库目前与代码一起分发。所以我要找的是像target_link_directories()
或类似的解决方案。
显然,在运行时实际加载.dll我将不得不采取进一步的步骤,所以如果你的解决方案包括这个,那将非常受欢迎。
答案 0 :(得分:1)
target_link_libraries()强制我指定一个.lib / .dll文件
事实并非如此。您可以提供关键字来指示库所属的构建类型。
来自target_link_libraries
debug,optimized或general关键字表示库 紧随其后只能用于相应的 构建配置。 debug关键字对应于Debug 配置(或DEBUG_CONFIGURATIONS中指定的配置 如果设置了全局属性)
示例:target_link_libraries( my_target optimized example.lib debug exampled.lib
然后由CMAKE_BUILD_TYPE
变量控制。有关此变量的更多信息,请参阅the cmake documentation
对于32位与64位,你需要添加if-blocks来检查架构,我承认这是一个限制。
答案 1 :(得分:1)
要检查32对64位变体,可以使用CMAKE_SIZEOF_VOID_P EQUAL 8
if(CMAKE_SIZEOF_VOID_P EQUAL 8)
// Set 64 bit stuff
else()
// Set 32 bit stuff
endif(CMAKE_SIZEOF_VOID_P EQUAL 8)
由于mascoj已经指出我要去做什么,target_link_libraries接受general
,optimized
和debug
关键字,这应该有助于获得您需要的任何库。
答案 2 :(得分:0)
保持#pragma
s是在寻找麻烦。如果可能,您应该停用它们。
有很多库可以做到这一点(例如Windows上的Boost),但是当与CMake一起使用时,这确实没有意义。这些编译指示是非标准的,不适用于大多数编译器。虽然CMake构建的全部要点是可移植到所有平台,因此如果您想要移植,则需要移动用于链接到CMake的逻辑。即使你不关心可移植性,CMake构建通常也不能很好地处理这些文件(就像你自己经历过的那样)。 CMake负责构建,因此您应该将所有关联的问题转移到CMake。
首先要找到一种方法来停用pragma。通常,这可以通过预处理器定义或类似来完成(对于Boost,您可以target_link_libraries(... Boost::disable_autolinking )
,这将设置所需的预处理器定义。)
你将需要复制你现在在头文件中的逻辑,是的。这就是它的工作原理,构建系统需要知道链接的内容。使用generator expressions,你仍然可以在一个导入的目标中隐藏所有这些内容,所以至少使用它会很方便。
.dll
问题没有很好的解决方案。如果要在构建目录中使用dll,则需要在那里手动复制它们。 CMake在此处不提供任何特殊支持,但如果您已找到.lib
进行链接,则查找.dll
通常很简单。
答案 3 :(得分:0)
link_directories()对#pragma注释(lib)根本不起作用
我使用搜索pragma的lib
if (MSVC)
set(CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS}"
"/LIBPATH:<path to my libs>")
endif()
例如
if (MSVC)
set(CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS}"
"/LIBPATH:${CMAKE_CURRENT_BINARY_DIR}/../src_lib/")
endif()