使用 CMake 在 Windows(MSVC) 中查找库

jjc*_*mar 4 c++ windows cmake visual-studio

我在尝试链接 MSVC 中的库时遇到问题。我为发布和调试编译了一些外部依赖项,并将它们设置在不同的文件夹中(${PROJECT_SOURCE_DIR}/External/Debug/lib 和 ${PROJECT_SOURCE_DIR}/External/Release/lib)。我已经编写了一些 FindFoo.cmake 模块,它们作为 find_library 命令的提示 ${EXTERNAL_LIB_DIR},它根据 ${CMAKE_BUILD_TYPE} 设置。

这项工作在 Linux 上很完美,但在 Windows 中失败(它总是将 EXTERNAL_LIB_DIR 路径设置为调试路径)并且由于 _ITERATOR_DEBUG_LEVEL 而无法链接。

这是我正在使用的 FindFoo.cmake 的示例。

FIND_PATH(SOIL_INCLUDE_DIR                                                                                    
NAMES SOIL/SOIL.h                                                                                         
PATHS                                                                                                     
${EXTERNAL_DIR}/soil/inc                                                                                  
NO_DEFAULT_PATH                                                                                           
)                                                                                                         


find_library(                                                                                                 
SOIL_LIBRARY                                                                                              
    NAMES SOIL soil soil_debug                                                                            
PATHS                                                                                                     
    ${EXTERNAL_LIB_DIR}                                                                                   
    NO_DEFAULT_PATH                                                                                       
)                                                                                                         


INCLUDE(FindPackageHandleStandardArgs)                                                                        

FIND_PACKAGE_HANDLE_STANDARD_ARGS(SOIL DEFAULT_MSG SOIL_LIBRARY S 
SOIL_INCLUDE_DIR)                             


if (${SOIL_FOUND})                                                                                            
SET(SOIL_INCLUDE_DIRS ${SOIL_INCLUDE_DIR})                                                                
SET(SOIL_LIBRARIES    ${SOIL_LIBRARY})                                                                    
endif()                                                                                                       


MARK_AS_ADVANCED( SOIL_LIBRARY SOIL_INCLUDE_DIR ) 
Run Code Online (Sandbox Code Playgroud)

而这里创建EXTERNAL_LIB_DIR #设置外部库

set(EXTERNAL_DIR ${PROJECT_SOURCE_DIR}/External)                                                              

if (${CMAKE_BUILD_TYPE} MATCHES Debug)                                                                        
set(EXTERNAL_LIB_DIR ${PROJECT_SOURCE_DIR}/External/lib/Debug)                                            
else()                                                                                                        
set(EXTERNAL_LIB_DIR ${PROJECT_SOURCE_DIR}/External/lib/Release)                                          

endif()                                                                                                       
message(STATUS "Using libraries in ${EXTERNAL_LIB_DIR}") 
Run Code Online (Sandbox Code Playgroud)

我应该如何修改创建 EXTERNAL_LIB_DIR 变量的 FindFoo.cmake 以使其与 MSVC 一起使用?

谢谢

Com*_*sMS 5

您将需要两种不同的find_library调用,一种用于调试,一种用于发布。

find_library(SOIL_LIBRARY_DEBUG NAMES soil_debug
    PATHS ${PROJECT_SOURCE_DIR}/External/lib/Debug
    NO_DEFAULT_PATH)
find_library(SOIL_LIBRARY_RELEASE NAMES SOIL soil 
    PATHS ${PROJECT_SOURCE_DIR}/External/lib/Release
    NO_DEFAULT_PATH)
set(SOIL_LIBRARIES debug ${SOIL_LIBRARY_DEBUG} optimized ${SOIL_LIBRARY_RELEASE})

target_link_libraries(foo ${SOIL_LIBRARIES})
Run Code Online (Sandbox Code Playgroud)

请注意,这仍然不完全正确,因为它没有正确区分所有四种默认配置(Debug、Release、MinSizeRel 和 RelWithDebInfo),但对于大多数用例来说已经足够了。

在现代 CMake 中,查找脚本通常创建导入的目标,而不是通过变量公开查找结果,理论上,如果需要,它提供与config-file packages相同的灵活性。查看新 CMake 版本附带的脚本,以了解它的外观(这FindZlib.cmake是一个很好的例子,因为它相当小)。

永远不要依赖CMAKE_BUILD_TYPE于 find 脚本,因为它只被单配置生成器(如 Makefiles)支持!