Visual Studio as an editor for CMake friendly proj

2020-03-23 11:23发布

问题:

I'm trying to use Visual Studio as an editor for browsing a large open source project on GitHub. The directory structure looks like

/module1/include/
/module1/src/
/module2/include/
/module2/src/
...

and build is maintained by CMakeLists.txt.

If I insist to use Visual Studio as an editor for some reason (for example, good IntelliSense support), what would be the best practice?

  1. I tried "New - Project from Existing Code". It produces ugly project structure where all *.cpp files are under Source Files filter while I still need to manually specify a bunch of /*/include/ directories.

  2. I tried to actually use CMake to produce a visual studio solution. It immediately failed with many critical errors because of a lot of Linux dependencies.

Is there any way to create a visual studio solution with a proper directory structure and include paths?

回答1:

I see four possible approaches:

  1. Using a commercial product like Visual GDB or WinGDB you could e.g. import remote Linux projects to Visual Studio.

  2. You create a new empty C++ project at the root of your sources and use the trick described in Importing an existing source file in Visual Studio 2012 (but this seems to require a newer version of Visual Studio > 2012).

    With "Show All Files" and "Include in Project" I was able to get all sources/headers with their directory structure (tested with Visual Studio 2013/2015).

  3. You could mock all functions beside the most basic ones (like add_library() or message()) and try to get the original CMake project to generate a Visual Studio solution. E.g. you make your own VSToolchain.cmake or PreLoad.cmake with empty implementations:

    macro(add_custom_command)
    endmacro()
    
    macro(add_custom_target)
    endmacro()
    
    macro(set_property)
    endmacro()
    
    ...
    

    I admit this approach has it's limits.

  4. You're writing a special main CMakeLists.txt to collect all sources/headers into a new solution like:

    cmake_minimum_required(VERSION 2.8)
    
    project(MyProject C CXX)
    
    set(_src_root_path "${CMAKE_CURRENT_SOURCE_DIR}")
    file(
        GLOB_RECURSE _source_list 
        LIST_DIRECTORIES false
        RELATIVE "${CMAKE_CURRENT_SOURCE_DIR}"
        "${_src_root_path}/*.c*"
        "${_src_root_path}/*.h*"
    )
    
    add_library(MySources ${_source_list})
    
    foreach(_source IN ITEMS ${_source_list})
        get_filename_component(_source_path "${_source}" PATH)
        string(REPLACE "/" "\\" _source_path_msvc "${_source_path}")
        source_group("${_source_path_msvc}" FILES "${_source}")
    endforeach()
    

    Just put it somewhere (in my example the root of the sources; but you could just change _src_root_path) and generate a Visual Studio project containing your sources/headers structured by directories (see How to set Visual Studio Filters for nested sub directory using cmake).