Is it bad that CLion adds header files to cmake source files? - c++

When I create a new pair of .h and .cpp file with clion using the following dialog
if I check "add to targets" and "create an associated header", it modifies the line set(SOURCE_FILES ...) which it later passes to add_executable so that it containes both new_source_file.h and new_source_file.cpp. If I understand C++ and cmake correctly, it is bad, because header files should not be compiled by themselves. Am I right? Is this a problem with CLion?

It's correct to add headers to CMakeLists.txt.
CMake is smart enough and doesn't invoke the compiler on headers, but adding them to the CMakeLists.txt makes sure that they are referenced in the projects generated by cmake (for example, Visual Studio projects and Code Block projects). This in turn makes it possible to show the headers (and not only the .cpp files) in the "project" pane of most IDEs which support cmake.
If you don't add them, the compilation itself should work fine, but the IDE probably won't know that such headers are part of your project, thus they won't be included in the project pane, in the "search in project" function and so on.

From CLion's FAQ:
using set(SOURCE_FILES main.cpp) is how CLion now knows that main.cpp is included in your project.
As for now, header files (in case their names differ from the
appropriate .cpp files already added to the SOURCE_FILES variable)
should also be included in the project in that way.
In your case, you don't need to specify lcm.h when setting SOURCE_FILES, but it also doesn't hurt.

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 specify source directory location in CMakeLists.txt?

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.

add_executable (or adding source to project) vs including it?

I have been curious about the difference between including a file in another source file with #include filename.h and "adding" a source to a C++ project.
In Visual Studio, adding a source file to a project is done by right clicking and choosing "add existing source to project".
We don't need to do that to a file that is in the "additional directories" path and included using #include.
However, sometimes .cpp files which are not #included need to be added to the project.
So:
When is it that a .cpp file needs to be added to my project?
Also, W/R/T to CMAKE:
When I specify include_directories and point it to the path where I my files to be included are, and those files are referenced in the source, why do I also have to add every header with add_exectuable?
In other words, those files are included with #include and CMAKE knows where to look for them, so what does setting add_executable do?

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?

Add some header dependencies of source files to solution explorer for cmake target

Suppose I have a.cpp as a source and I add it to a cmake target:
add_executable(MY_TARG a.cpp)
If a.cpp includes a.h it will be added as a dependency for the target and when I change the header, everything will get rebuilt properly, but a.h won't show up in the list of sources for my project (in visual studio for instance).
Is there a way to add it there?
And can I distinguish between system headers (like <vector>) and headers from a folder from the same directory structure? I might wish to add only headers included with quotes and not with brackets ("header.h" and not <header.h>)
I am looking for something automatic - I already have a lot of CMakeLists.txt files with only .cpp files listed there and going through all of them seems impractical.
It's fairly simple - if you want a file to be listed as part of a project in an IDE, list it as part of the target in CMake:
add_executable(MY_TARG a.cpp a.h)
CMake knows enough to recognize it as a header (and thus not attempt to compile it), but it will list it in the generated IDE project.
EDIT
Based on the added information of looking for an automatic change to an existing system, I don't think that's easy. But it should still be doable. Compilers usually have a way of listing headers included by a file they compile (e.g. gcc has -MM). You should be able to build a one-time conversion script based using this output and your favourite text-processing language.