CMake等同于Visual Studio的属性表(.vsprops)

时间:2015-02-02 17:57:37

标签: c++ visual-studio cmake clion vsprops

我试图从Visual Studio迁移到Jetbrains' (真棒)CLion IDE使用CMake来组织项目。

到目前为止,过渡一直很顺利:创建CMake项目并将它们导入CLion非常简单,我可以开始在一个平台上编码,然后在另一个平台上继续编码而没有问题。

然而,我无法在CMake中找到等效的Visual Studio的一个方面是property sheets:我主要使用它们来保存包含目录'库的路径和链接库(即每个库的一个.vsprops文件,例如OpenCV.vspropsBoost.vsprops等。

这样,在VS中,我可以在不同项目之间共享库的.vsprops文件,而无需每次都配置路径/库。

CMake与Visual Studio的属性表有类似的机制吗?如何将库的包含/库存储在 CMake-parsable 文件中,然后" import"它在CMakeLists.txt中以链接库?

基本上,我想做的是:

  1. 创建一个" cmake属性表" (对于一个给定的图书馆来说,没有更好的名字)。
  2. 然后,在CMakeLists.txt中,写下link_target_to_libs(myTarget "path/to/propertySheet1" "path/to/propertySheet2" ...)
  3. 之类的内容

3 个答案:

答案 0 :(得分:1)

在CMake中,库可以使用IMPORTED目标导出包,其他构建系统使用find_package导入:

http://www.cmake.org/cmake/help/v3.1/manual/cmake-packages.7.html

http://www.cmake.org/cmake/help/v3.0/manual/cmake-buildsystem.7.html

http://www.cmake.org/cmake/help/v3.0/manual/cmake-buildsystem.7.html#imported-targets

您可以链接到IMPORTED目标,而不是“链接到属性表”。

target_link_libraries(myTarget Dep1::Dep1 Dep2::Dep2)

并非所有库都创建IMPORTED目标,并非所有库都提供cmake配置文件包。在这些情况下(包括OpenCV和Boost),CMake提供了查找模块:

http://www.cmake.org/cmake/help/v3.0/manual/cmake-developer.7.html#find-modules

与find_package一起使用并链接到变量的内容。

答案 1 :(得分:1)

因为我真的想让库包含/链接到单行命令中,并且就我对CMake的基本知识而言,我认为应该做出一些妥协 - 主要是共享目标名称CMakeLists.txt与“属性表”之间的变量。所以这是我的解决方案......直到有人提出更简单/更清洁的方法:

  1. CMake属性表.cmake文本文件
  2. 众所周知的变量名称 - TARGET - 指定目标(即add_executable()的第一个参数),
  3. 除了特定于库的命令,.cmake文件包含对target_include_directories(${TARGET} PRIVATE ${PATH_TO_INCLUDE_DIR})target_link_libraries(${TARGET} ${LIST_OF_LIBS})的调用,
  4. 要使用/链接库,请在include("path/to/.cmake")中致电CMakeLists.txt
  5. 我已成功构建并执行了一个使用X11和OpenCV的简单程序,其中包含以下文件:

    <强> x11.cmake

    target_include_directories(${TARGET} PRIVATE "/usr/include/X11")
    target_link_libraries(${TARGET} "/usr/lib/x86_64-linux-gnu/libX11.so")
    

    <强> opencv.cmake

    # OpenCV-specific stuff
    set(OpenCV_DIR "/PATH/TO/OPENCV/INSTALL/DIR/share/OpenCV") # path to OpenCVConfig.cmake
    find_package(OpenCV REQUIRED)
    # include path
    target_include_directories(${TARGET} PRIVATE ${OpenCV_INCLUDE_DIRS})
    # linking libs
    target_link_libraries(${TARGET} opencv_world opencv_ts)
    

    <强>的CMakeLists.txt

    cmake_minimum_required(VERSION 2.8.4)
    project(hello_clion)
    
    set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -std=c++11")
    
    ## hello-clion ##############################
    # make a new target name
    set(TARGET hello-clion)
    
    # find sources
    file(GLOB_RECURSE SOURCE_FILES "src/*.cpp" "src/*.hpp")
    
    # declare a target
    add_executable(${TARGET} ${SOURCE_FILES})
    
    # link the libraries (to the last-declared ${TARGET}, which should be the last-added executable)
    include("x11.cmake")
    include("opencv.cmake")
    #############################################
    

    <强>的main.cpp

    #include <cstdio>
    #include <cstdlib>
    #include <cstring>
    #include <thread>
    
    #include <opencv2/opencv.hpp>
    
    #include <Xlib.h>
    
    int main_x11()
    {
        // adapted from: http://rosettacode.org/wiki/Window_creation/X11#Xlib
    }
    
    int main_ocv()
    {
        // adapted from: http://docs.opencv.org/doc/tutorials/introduction/display_image/display_image.html#source-code
    }
    
    int main()
    {
        using namespace std;
    
        thread tocv(main_ocv);
        thread tx11(main_x11);
    
        tocv.join();
        tx11.join();
    
        return 0;
    }
    

    现在,每次我想在项目/程序中使用OpenCV时,我只需将include("opencv.cmake")放在相应的CMakeLists.txt中。

答案 2 :(得分:1)

这似乎很有效,但肯定有一些我没有发现的问题。 (我担心多个宏添加相同的target_link_libraries会导致“已经定义”的链接错误,但至少g ++ 5.1.0会多次给出相同的库名称而没有错误。)

在根CMakeLists.txt中, BEFORE add_subdirectory()调用或整数,包括:

macro(USES_WX)
    include_directories(SYSTEM /usr/local/include/wx-3.0)
    include_directories(SYSTEM /usr/local/lib/wx/include/gtk3-unicode-3.0)
    link_directories(/usr/local/lib)
    add_definitions(-D_FILE_OFFSET_BITS=64 -DWXUSINGDLL -D__WXGTK__ -pthread)
    target_link_libraries(${TARGET} pthread wx_gtk3u_xrc-3.0 wx_gtk3u_html-3.0 wx_gtk3u_qa-3.0 wx_gtk3u_adv-3.0 wx_gtk3u_core-3.0 wx_baseu_xml-3.0 wx_baseu_net-3.0 wx_baseu-3.0)
endmacro()

(您可以使宏更加花哨,例如检查CMAKE_BUILD_TYPE是否为“Debug”或“Release”以链接到相应的库,改变预处理器定义等。请参阅http://www.cmake.org/cmake/help/v3.0/command/if.html

让你的项目的CMakeLists.txt如下:

set(TARGET myProgramName)
add_executable(${TARGET} myProgramName.cpp)
USES_WX()

^^宏调用必须在add_executable()之后

并且,如果您需要多个目标支持,请将上面显示的根CMakeLists.txt部分中的行修改为:

    ...
    target_link_libraries(${ARGV0} pthread wx_gtk3u_xrc-3.0 ...)
    ...

让你的项目的CMakeLists.txt像这样(行数减少,但出错的可能性更大):

add_executable(myProgramName myProgramName.cpp)
USES_WX(myProgramName)