CMake和#pragma评论(lib)

时间:2018-01-12 18:22:50

标签: c++ windows dll cmake .lib

对于我的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逻辑,但这感觉不对。添加所有文件也是不正确的,因为总是只需要一个。
  • 导入的目标允许我添加.dll和.lib文件,但同样,我要么必须复制逻辑或链接所有库。
  • link_directories()在全球范围内发挥作用。如果只有少数目标确实需要它,那就觉得没必要了。
  • 将给定目录添加到PATH似乎也是“全局”,即因为该库目前与代码一起分发。

所以我要找的是像target_link_directories()或类似的解决方案。 显然,在运行时实际加载.dll我将不得不采取进一步的步骤,所以如果你的解决方案包括这个,那将非常受欢迎。

4 个答案:

答案 0 :(得分:1)

  

target_link_libraries()强制我指定一个.lib / .dll文件

事实并非如此。您可以提供关键字来指示库所属的构建类型。

来自target_link_libraries

上的CMake文档
  

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接受generaloptimizeddebug关键字,这应该有助于获得您需要的任何库。

答案 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()