How to specify source directory location in CMakeLists.txt? - c++

In my c++ cmake project I want my CMakeLists.txt and source files in different locations. How can you specify this to cmake? I want to know this because I believe it makes sense to separate build files from source files.
In my case, this is for a cross platform project. I know one usually uses a single top-level CMakeLists.txt + conditional constructs to handle different targets/platforms, but what I plan is to have different CMakeLists.txt files for each platform and have them AWAY from the sources. Like so:
-my_project
-sources
-module1
-common.hpp
-common.cpp
-windows
-win_functions.cpp
-win_functions.hpp
-linux
-linux_functions.cpp
-linux_functions.hpp
-module2 (...)
-module3 (...)
-build_projects
-windows
-CMakeLists.txt
-linux
-CMakeLists.txt
It seems to me it would be a matter of specifying a new cmake's working/source directory but so far the closet I get is to prepend the correct location when adding source files as in:
target_sources(my_target_windows PRIVATE ${win_source_dir}/win_functions.cpp)
But the problem is visual studio won't let me preview the source files when adding them in this way, and it seems I cannot solve this in visual studio's CMakeSettings.json either. So I am looking for a more built-in feature for this.

Ok, found a fix for my problem within Visual Studio:
In solution explorer set "solutions and folders" to "CMake Targets View" and it will now correctly display sources and headers added to the cmake project.
So, using relative paths to sources in cmake + this VS feature solves my problem.

Related

using cmake, build a visual studio project with dependencies, being able to debug also into the dependencies

I have a C++ project source code with several dependencies (C++ packages, compiled libs and source).
I need to create a CMake file which will generate the Visual Studio solution and projects files in such a way that if I put a break point in one of the dependencies source code, the execution of the main project in debug mode would break and debug at that break point in the dependency.
Any suggestion is highly appreciated.
[EDIT]
If I use the packages, with the provided ...config.cmake files, the source files are not included in the generated project.
If I generate the MS projects individually and use include_external_msproject to put them together in a solution, I have the source code, but it is executed from somewhere else (binaries), so my breakpoints are ignored.
On the other hand, there is overlap from duplicated targets, like DOCUMENTATION for example, which come from each dependency, if I want to use add_subdirectory to add the deps to the main project
I ended up modifying the dependencies so that they implement unique target names for documentation, but if built individually to create the original named target: DOCUMENTATION.
doxygen_add_docs(DOCUMENTATION_${PROJECT_NAME}
doc
src/component
)
if (NOT (TARGET DOCUMENTATION))
add_custom_target(DOCUMENTATION COMMENT "workaround for multi-dependencies project")
add_dependencies(DOCUMENTATION DOCUMENTATION_${PROJECT_NAME})
endif()
You need to write a CMakeLists.txt with the appropriate compile options. To do that, you can set the following CMake values in the CMakeLists.txt file :
set(CMAKE_CXX_FLAGS "your-msvc-debug-options") or set(CMAKE_CXX_DEBUG_FLAGS "your-msvc-debug-options"). You may also use add_compile_options() which will set values for all your project (dependencies included if you build them with CMake)

How to use Visual Studio with CMake AND preserve file structure

I use CMake to create C++ projects. Then I would like to use Visual Studio as my IDE. But the issue I face is that I can't get files to be structured properly.
Here is the problem:
Let's assume I have the following file structure on the disk.
And here is my CMakeLists.txt:
cmake_minimum_required(VERSION 3.20)
set(sourceDirectory src)
set(includeDirectory include)
set(targetName vulkan-tutorial)
set(targetVersion 1.0.0)
project(${targetName} VERSION ${targetVersion})
file(GLOB src
${sourceDirectory}/*.cpp
${sourceDirectory}/**/*.cpp
${sourceDirectory}/**/**/*.cpp
)
add_executable(${targetName} ${src})
target_include_directories(${targetName} PRIVATE ${includeDirectory})
Here is what this project looks like in Visual Studio with filters.
Or without using VS-filters.
I can create new files, but they're not going to land, where I want them to. The behavior I want to achieve is extremely simple: I want to see the root directory of my project and its "src" and "include" folders. I want to be able to right-click them and create new folders and files. Then I want Visual Studio to create them inside the selected folder. Like it would be in every normal file-explorer.
One solution I could imagine is to generate project files not inside a "build folder", but in the root directory of the project itself, which is obviously a terrible solution and leads to a pollution of the project structure.
Summarized - here is the result I want to end up with (now I can achieve it only by generating the project in the root). But all the build files should be located in the corresponding "build" folder in the root of the project.
I also would like to add that I tried to use different functions for CMake that kind of group my files together, but I just ended up with lots of filters that reflect my project structure on the disk. Of course, I still wasn't able to add new folders and files dynamically.
I appreciate any help. Thanks in advance.
Simply use the Open Folder option in visual studio.
This will open the directory and automatically configure the project using CMake. It will display the tree independently from the CMake configuration structure.
Microsoft has a page CMake projects in Visual Studio, that explains how to properly import CMake projects in visual studio

Display include-directory as separate part of project in Visual Studio using CMake

I am in the process of porting a big library project from Linux to Windows. Fortunately we were using CMake even before porting was even remotely on the table so not many adjustments were needed.
I figured it might be a good idea to develop the Windows parts natively on Windows for easier testing so i created a VS Studio using the CMake-gui
My project is organized like this:
lib/ # Library source code
include/
mylib/ # Public installable header files
In the top CMakeLists.txt i added
include_directories(${CMAKE_CURRENT_SOURCE_DIR}/include)
so my internal source files include the headers just like an external application would.
The problem is now the following: Visual Studio 2015 displays the public header files in the "External References"-directory among a lot of system headers. It is not obvious which header files belong to the project.
How can i make VS display the public headers separately from the system includes?
Turning my comment into an answer
All header files you want to be explicitly listed by CMake in Visual Studio projects have to be listed as a source file in your CMake target's list of sources.
Then you can group those sources/headers via the source_group(... FILES/REGULAR_EXPRESSION ...) command.
If you have more then one target and you don't want to add those steps manually every time, you could think about grouping them into a function():
function(my_add_library _target)
file(
GLOB_RECURSE _header_list
RELATIVE "${CMAKE_CURRENT_SOURCE_DIR}"
"${CMAKE_SOURCE_DIR}/include/*.h*"
)
add_library(${_target} ${ARGN} ${_header_list})
target_include_directories(${_target} PRIVATE "${CMAKE_SOURCE_DIR}/include")
source_group("Public Headers" FILES ${_header_list})
endfunction(my_add_library)
Note:
I'm using file(GLOB ...) only to collect the headers, not the sources (see Why is cmake file GLOB evil?)
You could keep the include_directories() command in the main CMakeLists.txt, I just prefer the target specific target_include_directories() variant
For more details on grouping source/header files in CMake see:
Keeping file hierarchy across subdirectories in CMake
How to keep source folders hierarchy on solution explorer?
And as a general reference:
What is the difference between "${CMAKE_CURRENT_SOURCE_DIR}" and "." in INCLUDE_DIRECTORIES?

Is it possible to add files to a CMake generated solution folder in Visual Studio?

This question is more or less a warmup of this question:
how to get cmake to add files to msvcs solution tree
It never got a valid answer so I want to repose it slightly different:
Is it possible to use the cmake solution folders that where introduced with cmake 2.8.3 to add files directly to the vs solution? I want to do the cmake equivalent of VS->Solution->Add->Existing Item. So my file will appear in a folder that belongs to the solution and not to a project.
I found examples how the solution folders can be used to group targets into folders with code like this:
set_property( GLOBAL PROPERTY USE_FOLDERS ON)
set_property(TARGET ${TARGET_NAME} PROPERTY FOLDER "Test")
So can I add a file instead of a target to the folder?
This is probably not possible.
CMake organizes its assets into projects and targets. The project is what corresponds to Visual Studio's solution file while each target will generate a Visual Studio project inside the respective solution.
The problem is now that CMake does not allow to add files to CMake projects. In fact, a CMake project is little more than a collection of targets and offers almost no customization options. Hence the USE_FOLDERS option you mentioned can only be used to group VS projects inside a solution, but not single files.
The closest to what you ask would probably be to add a custom target that holds your files. However, this will still generate a VS project (which also contains a bunch of other stuff besides your files) inside the solution and not a plain folder.
If I understand the question correctly, I think I know how to do it:
set(FILES_TO_ADD
file1
file2
file3)
source_group("Group Name" FILES ${FILES_TO_ADD})
The source_group command creates the folder inside the Visual Studio project.
This answer just adds an example for the "custom target" solution that was proposed by ComicSansMS in the accepted answer. This is what I currently use to add my global files.
set( SOLUTION_FILES
${CMAKE_SOURCE_DIR}/CMakeLists.txt # root CMakeLists file
${CMAKE_SOURCE_DIR}/cmake/macros.cmake # cmake functions
${CMAKE_SOURCE_DIR}/CMakeInCodeDefinitions.h.in # imported cmake variables
# etc...
)
add_custom_target( GlobalFiles SOURCES ${SOLUTION_FILES})

Source directories in Visual Studio 2010

I am using OF in my project and I want to use some add-ons but I have to add .cpp files to my project in order to compile them. I don't like it. Is there any option so I could specify a folder to scan for source files and compile every .cpp file it finds?
I thought it might be Source Directories in VC++ Directories section but it didn't work. Then I don't really get what it does.
If you want to compile sources using Visual Studio, you will have to add them to your project.
There is nothing wrong about adding external sources to your project in a nice filter.
You can also create a makefile to be used by Visual Studio which will list sources you need.
I'm not aware of an option that does what you ask for in VS. The Source directories configuration is used for locating source files that go along with libraries that you are using in your project. This way you can use the library in its binary format without the need to recompile it every time you rebuild your project, but you can also step into its code while debugging.