Search code examples
c++visual-studiocmakeclionvsprops

CMake's equivalent to Visual Studio's Property Sheets (.vsprops)


I'm trying to migrate from Visual Studio towards Jetbrains' (awesome) CLion IDE which uses CMake to organize the projects.

Until now, the transition has been smooth: creating CMake projects and importing them into CLion is easy, and I can begin coding on one plateform then continue on another one without problems.

However, one aspect of Visual Studio that I couldn't find an equivalent to in CMake is property sheets: I use them mainly for holding the include directories' paths and the linking libs for libraries (i.e. one .vsprops file for each library, e.g. OpenCV.vsprops, Boost.vsprops, etc.).

This way, in VS, I could share a library's .vsprops file between different projects without having to configure the paths/libs each time.

Does CMake have a similar mechanism to Visual Studio's property sheets ? How is it possible to store a library's includes/libs in a CMake-parsable file then "import" it in CMakeLists.txt in order to link against the library ?

Basically, what I want to do is:

  1. Create a "cmake property sheet" (for lack of a better name) for a given library.
  2. Then, in CMakeLists.txt, write something like link_target_to_libs(myTarget "path/to/propertySheet1" "path/to/propertySheet2" ...) .

Solution

  • Since I really want to make the libraries' inclusion/linking into a one-line command, and as far as my (basic) knowledge of CMake goes, I think that some compromise should be made -- mainly sharing the target name's variable between CMakeLists.txt and the "property sheets". So this is my solution... until someone proposes a simpler/cleaner one:

    1. A CMake property sheet is a .cmake text file,
    2. A well-known variable name --TARGET-- designates the target (i.e. the first argument of add_executable()),
    3. Aside from library-specific commands, a .cmake file contains a call to target_include_directories(${TARGET} PRIVATE ${PATH_TO_INCLUDE_DIR}) and target_link_libraries(${TARGET} ${LIST_OF_LIBS}),
    4. In order to use/link against a library, call include("path/to/.cmake") in CMakeLists.txt.

    I have successfully built and executed a simple program that uses X11 and OpenCV with the following files:

    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;
    }
    

    Now, each time I want to use OpenCV in a project/program, I just have to put include("opencv.cmake") in the corresponding CMakeLists.txt.