CLion / CMake Multiple include directories issue - cmake

I'm trying to build multiple executable with some source in common.
My source tree looks like this :
root
- CMakeLists.txt
- 00 - common
- CMakeLists.txt
- include
- Window.h
- sources
- Window.cpp
- 01 - sample
- CMakeLists.txt
- include
- sources
... and so on
In my root CMakeLists.txt I do add_subdirectory to include common and all the samples, the common part is built as a static library.
The compilation works fine in command line and also on CLion. The problem is that CLion don't understand the structure, when I include Window.h inside Window.cpp of the "common" folder, CLion don't know it, but it offer to use "../include/Window.h" using the auto-completion.
In the CMakeLists.txt of "common" folder I do:
add_library(common STATIC ${sources})
target_include_directories(common PUBLIC "include")
I also tried to use the standard method with include_directories() without success.
What I did wrong ?

Ok after trying to reproduce the problem, I figured out that the folder name accept space but not dashes
Removed the dashes from folder names fixed the problem

Related

How to include headers in CMake?

I am having trouble in linking header files to .c files. It will tell me "Cannot open include file: headerfile1.h : No such file directory"
My file structure looks like this
library
- folder1
-- include
--- headerfile1.h
--- headerfile2.h
--- CMakeLists.txt
-- CMakeLists.txt
- CMakeLists.txt
src
- file.c
- file.h
- CMakeLists.txt
CMakeLists.txt
I have read many posts about this and tried a lot. Originally, I tried to create a header-only library or using ${CMAKE_SOURCE_DIR} referencing from a few posts, but was unsuccessful. I would get the same error
Currently, I have this
Under the root CMakeLists.txt, I've added the subdirectories
add_subdirectory(src)
add_subdirectory(library/folder1/include)
Under the src CMakeLists.txt, I've included the directory
include_directories(library/folder1/include)
In file.h, I have
#include "include/headerfile2.h"
The CMakeLists.txt files I have under the library folder are empty. They were made so that add_subdirectory(library/folder1/include) could work
You need to add an interface library [1][2] in the library/folder1/include/CMakeLists.txt (or the parent one... I dunno what do you have in it and why you need another one in the include/).
This library gonna export include path via build interface (and probably install interface if you plan other projects gonna have this one as an external dependency to be found via find_package()).
So, your executable (or whatever) just needs target_link_library(my_exe PRIVATE my_header_lib) to get the proper #include path.
PS Please, forget about include_directories() and use only target_xxx() calls.

How to circumvent "This file does not belong to any project target"?

I'm using CLion (2022.2 EAP).
I have some source files in my CMake C/C++ project directory structure which - for now - are not mentioned in the CMakeLists.txt ; they probably never will. But - I want them to be parsed with certain include directories to search includes in. Can I do this without adding them as proper targets?

Zephyr / PlatformIO / CMake / external code

I'm pretty new to Zephyr and am having trouble adding and compiling code in a sibling folder. This may be further complicated by using PlatformIO, which has a slightly different build structure than the stock Zephyr structure.
The IDE is Visual Studio Code under Windows
The structure of the code is:
Parent Folder
|-ext_library (contains CMakeList.txt)
|--source
|--include
|-zephyr_project (structure generated by PlatformIO)
|--zephyr (contains the master CMakeList.txt and prj.conf)
|--source
|--include
|--lib
What I want to do is add either source files or a static library from ext_library to the zephyr_project with out manually copying source / include files or manually building the library and copying it over.
What I've tried so far:
Adding a path to ext_library in the FILE(GLOB ...) command in the zephyr_project/zephyr/CMakeList.txt. This command pulls the
source files from zephyr_project/source, but doesn't seem to like
either relative or static paths to ext_library.
Adding a CMakeList.txt in the ext_library that compiles a static library. This also requires using add_subdirectory to the
zephyr CMakeLists.txt file. This didn't seem to compile the library,
however, it appears to have found the ext_library/CMakeLists.txt.
The evidence of this is in zephyr_project/lib folder which has some CMake folders that are empty but named the same as
the ext_library/CMakeLists.txt. Other evidence is that the
message(...) commands in both CMakeLists.txt are being printed.
Using both static and relative paths to the ext_library folder.
Using cmake FILE(COPY ...), the files weren't copied. No apparent error.
What has worked:
Manually copying code from the ext_library/source and ext_library/include into the appropriate folders in zephyr_project.
Additional info:
zephyr_project/zephyr/CMakeLists.txt (original + attempt at adding the ext_library as a subdirectory)
cmake_minimum_required(VERSION 3.13.1)
include($ENV{ZEPHYR_BASE}/cmake/app/boilerplate.cmake NO_POLICY_SCOPE)
project(firmware)
set(EXT_LIB "C:/Users/mcelr/Desktop/project/ext_library")
add_subdirectory(${EXT_LIB} ${PROJECT_SOURCE_DIR})
FILE(GLOB app_sources
"../src/*.c*"
)
ext_library/CMakeLists.txt (CMAKE_CURRENT_SOURCE_DIR does point to the correct directory at runtime, as confirmed via removed message(...) logging)
cmake_minimum_required(VERSION 3.13.1)
project(ext_lib)
include_directories(${CMAKE_CURRENT_SOURCE_DIR}/include)
set(LIBRARY_OUTPUT_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR}/build)
add_library(ext_lib_zephyr STATIC
${CMAKE_CURRENT_SOURCE_DIR}/source/packet.c
${CMAKE_CURRENT_SOURCE_DIR}/source/checksum.c
)
Thank you so much for any advice or hints to solve this,
Austin
I found workaround for it:
cmake_minimum_required(VERSION 3.13.1)
include($ENV{ZEPHYR_BASE}/cmake/app/boilerplate.cmake NO_POLICY_SCOPE)
project(Project_work_queue)
SET(LIB_PATH ../../libs/)
FILE(GLOB lib_sources ${LIB_PATH}*.*)
FILE(COPY ${lib_sources} DESTINATION ../../../src/libs_tmp)
FILE(GLOB app_sources ../src/*.c*)
include_directories(${LIB_PATH})
target_sources(app PRIVATE
${app_sources}
)
And add src/libs_tmp to .gitignore. I know it is ugly way but it works :-P

CMake have a target depend on a generated file in a subdirectory

I have a scenario that I think is very similar to this one: CMake add_custom_command/_target in different directories for cross-compilation, however the solution for that issue isn't working for me.
In subdir/CMakeLists.txt I have:
add_custom_command(OUTPUT foo.h foo.cpp COMMAND ... DEPENDS foo.xml)
add_custom_target(generate_foo DEPENDS foo.h foo.cpp)
and then CMakeLists.txt:
add_executable(MyTarget
subdir/foo.h
subdir/foo.cpp
${OTHER_SOURCES})
add_dependencies(MyTarget generate_foo)
add_subdirectory(subdir)
This fails with "Cannot find source file: subdir/foo.h". The documentation for add_dependencies suggests that it will ensure that generate_foo builds before MyTarget, but if that's the case it looks like it's at least trying to access all source files before either target builds. Am I doing something wrong here? How can I compile source files that are generated by a custom target/command in a subdirectory?
The problem is that the GENERATED file property (that CMake uses to determine if it needs to check that a file exists at configure time) is not visible outside the directory in which the file is generated. The problem goes away in CMake 3.20. This is explained here.
I usually solve this problem by compiling generated source files into a static or object library in the subdirectory, then linking to that, since targets are globally visible. You can also explicitly set the GENERATED property on the generated files in the scope you wish to use them, but this hack breaks the encapsulation gained by using a subdirectory.
It's also worth noting that you can do away with the custom target and the call to add_dependencies because the generated files are already dependencies of the executable (this has always has been the case AFAIK).

Changing cmake directories

I'm writing a cmake file for a project which has the following structure
project/ (root)
libraries/ (contains (precompiled) libraries
src/
code/ (contains a set of fortran files)
My CMakeLists.txt file is currently in project/ and effectively is just
cmake_minimum_required(VERSION 2.6)
enable_language(Fortran)
project(project1)
set(projsrc src/code)
set(libdir lib/)
find_library(PROJ_LIBRARY pr10 PATHS ${libdir})
add_executable (sc1 sc1.f90)
target_link_libraries(sc1 ${PROJ_LIBRARY})
This creates my binary in the same folder as the source code, when I actually want it in the level above (i.e. in the src folder - this structure will be changed so we have a bin folder eventually), but haven't worked out how to do it.
Some answers on SO say you have to have a CMakeLists.txt file in every folder - is this correct? Is it possible to set an environment variable or use a CMake variable (e.g. http://cmake.org/cmake/help/v2.8.8/cmake.html#command:set). It's also not very clear from some answers whether the solutions they have posted are C++ specific (as that is what language CMake most often seems to be used for).
Edit
I found out that I can change it to the behaviour I want by modifying it slightly:
cmake_minimum_required(VERSION 2.6)
enable_language(Fortran)
project(project1)
set(projsrc src/code)
set(libdir lib/)
find_library(PROJ_LIBRARY pr10 PATHS ${libdir})
add_executable (src/sc1 ${projsrc}/sc1.f90)
target_link_libraries(src/sc1 ${PROJ_LIBRARY})
However, this doesn't explain why my behaviour is different to how it should be, according to arrowdodger below. I'm also still trying to work out how to display the values of environment variables; I've tried the following with no luck:
message(${RUNTIME_OUTPUT_DIRECTORY})
message($ENV{RUNTIME_OUTPUT_DIRECTORY})
message(${CMAKE_RUNTIME_OUTPUT_DIRECTORY})
message($ENV{CMAKE_RUNTIME_OUTPUT_DIRECTORY})
By default, binaries will appear in respective subdirectory of your build dir. By respective i mean the directory that contains CMakeLists.txt with add_executable() call.
For example, if you have following CMakeLists.txt
add_executable(tgt1 src1.f90)
add_executable(tgt2 subdir/src2.f90)
in the root folder, you will get both binaries in ${CMAKE_BINARY_DIR}. So if you wish tgt2 to be in ${CMAKE_BINARY_DIR}/subdir, you need to add CMakeLists.txt there and call add_executable(tgt2 src2.f90) from there.
You can change this behavior:
CMAKE_LIBRARY_OUTPUT_DIRECTORY, CMAKE_RUNTIME_OUTPUT_DIRECTORY and others.
You can also set respective target properties.