make vpath and header files - g++

I was learning about make's vpath recently and I stumbled upon this question:
Makefile vpath not working for header files
Is there any point of using make's vpath for header (.h) files when the header files/directory still need to be included for g++ by using -I?

One reason I can think to add the "include" directory (for .h files) to the vpath would be for dependency checking.
Your .c files should depend on all of the .h files they include - so if you change a header file, all compilation units that include that might be affected are re-built.
Lets say you have a src/ directory for all of your .c files, and an include/ directory for all of your .h files. By using vpath for include/, and adding a -I include path for g++, you can simply refer to all the header files by name (in the Makefile), and not have to be concerned with their paths.

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.

Add include header generated in configure_file

I have a cmake project with an application and a library. The library has one header file generated with configure_file. The problem is that the application code cannot find the generated header file.
What is the proper way to include the generated header file path to the application -I options? target_link_libraries adds the path, but to the source but not to the binary directory?
Is it possible to add a property to the library when add_library is used so that this property can be used when target_link_libraries is used?
If you have generated your header file with
configure_file(config.h.in config.h #ONLY)
and have your library target already created with
add_library(libtarget ${SOURCE_FILES})
it's simply a call to
target_include_directories(libtarget PUBLIC ${CMAKE_CURRENT_BINARY_DIR})
under the assumption that all commands are given in this order and are located in the same CMakeLists.txt file.

cmake: generated header in subdir A needed transitively by target in subdir B

So I'm transitioning from make to cmake and I'm stuck at a point which is trivial in make because of in-source-dir building.
The following scenario:
Directory A/ generates some header, A.h.
In order for other cpp/h, non-generated files to find the generated header, I've added the ${CMAKE_CURRENT_BINARY_DIR} as an include (<--assumption 1 here for being best approach)
However now in directory B/ (a sibling directory of A/) there is a particular source file which transitively through a file.h, which is also in A/, needs the generated A.h file.
The problem I face now is that file.h has the reference to A.h as #include "A.h" but at this point in the cmake execution the only include directories are:
B/
Now.. what is the best way to include A.h in directory B, should I hardcode something like: ${CMAKE_BINARY_DIR}/path/to/include/for/A/A.h that feels bad though
Another way is to generate the A.h file to the source dir, however I often see advise to not generate anything to the source directory.
You can use PROJECT_BINARY_DIR variable to set up location of generated file from different directories. Note that PROJECT_BINARY_DIR change every time you use project command. In this case you can use <PROJECT>_BINARY_DIR variable:
# CMakeLists.txt
project(Foo)
add_subdirectory(Boo)
# Boo/CMakeLists.txt
project(Boo)
message("Boo_BINARY_DIR: ${Boo_BINARY_DIR}") # == PROJECT_BINARY_DIR
message("Foo_BINARY_DIR: ${Foo_BINARY_DIR}") # != PROJECT_BINARY_DIR

Avoid repeating the directory name for multiple file inclusions

I have a CMakeLists.txt file for a library. It's pretty basic:
set(LIB_FILES source/first.cpp)
add_library(first ${LIB_FILES})
I put the files in a list because I will eventually be adding more source files to the library. The problem is that all of the files will be in the source directory. And I don't want to constantly have to repeat that.
I also don't want to use the GLOB pattern matching solution, because I want to have to edit the CMakeLists.txt file when I add a new file. That way, my build will re-build the build solution, and new files will correctly appear (as I understand it. I'm still new with CMake).
I tried adding a CMakeLists.txt file into the source directory itself, just to build the LIB_FILES list. That didn't work out very well. Variables in CMake are file scoped. And even when I broke scoping (with PARENT_SCOPE), I still had to prefix each file with the directory. So that gained nothing.
I don't want to put the actual library definition in the source directory, as that will generate all the build files in the source directory. And I don't want that. Also, I will need to include headers that aren't in or under the source directory.
My directory structure looks like this:
libroot (where the project build files should go)
\-source (where the source code is)
\-include (where the headers that the user of the library includes go)
So how do I tell CMake that all of the source files come from the source directory, so that I don't have to constantly spell it out?
You could move the add_library call to your source/CMakeLists.txt also:
set(LIB_FILES first.cpp)
add_library(first ${LIB_FILES})
Then just use add_subdirectory in your top-level CMakeLists.txt:
add_subdirectory(source)
you could use a simple macro for that
macro(AddSrc dst_var basepath_var)
foreach(file ${ARGN})
list(APPEND ${dst_var} ${basepath_var}/${file})
endforeach()
endmacro()
set(MY_SRCFILES "")
AddSrc(MY_SRCFILES path/to/source
foo.cpp
bar.cpp
whatever.cpp
)

How do I merge subdirectories into a single executable?

I understand that every subdirectory has to have a CMakeLists.txt, but I don't want to create a library or an executable for each directory.
My folder structure:
/src
/exportedHeaders
/server
main.cpp
Each subfolder has a mix of .h and .cpp files. I don't understand how I can mix all of it up into a single executable, there doesn't seem to be a command for that.
I haven't really used CMake, so there is probably a better way, but as far as I know you can just specify the path to all the source files.
eg:
add_executable (myProgram main.cpp subdir1/foo.cpp subdir2/bla.cpp)
I imagine you could use file globbing to get *.cpp in each subdir, to reduce typing.
See this mailing list message for info about file globbing in CMake.