Describing header file locations in makefile - c++

In a new project I am working on I have the following dir structure:
Project_base
|---- src
|---- bin
|---- h
| Makefile
And in my source files I have includes that look like so:
#include "../h/SomeHeaderFile.h"
instead of the more correct form:
#include "SomeHeaderFile.h"
What do I need to add to my makefile so that I can removed the relative path includes so they will look normal?
ADDITION: also, where do I set this in CDT (C++ for eclipse) so that in design time this is reflected as well?

You need to add -I../h in the list of parameters you pass to gcc.

Add a flag to your CFLAGS so that the root of the headers is part of the headers search path:
-IProject_base/h
That way gcc/g++ will also look here in addition to the default headers directories.

Related

CMake target_include_directories does not affect header files

My project is roughly structured like this:
├CMakeLists.txt
|
├───ExampleApp
| ├───CMakeLists.txt
| ├───header.hpp
| └───main.cpp
|
└───ExampleLibrary
├───CMakeLists.txt
├───mylib.hpp
└───mylib.cpp
In the root CMakeLists.txt I call
add_subdirectory(ExampleLibrary)
add_subdirectory(ExampleApp)
To build the library I call:
add_library(ExampleLibrary
mylib.hpp mylib.cpp
)
And finally, in the executable, I try to do:
add_executable(ExampleApp
header.hpp main.cpp
)
target_include_directories(ExampleApp
PRIVATE ${PROJECT_SOURCE_DIR}/ExampleLibrary
)
target_link_libraries(ExampleApp
Path/To/The/Binary/Directory
)
Now the build files generate just fine, and the project also builds with no errors. However, when I now try to include mylib.hpp in header.hpp, I get build errors because it can't find the file mylib.hpp. But I actually can include mylib.hpp in main.cpp and the project builds and compiles.
Am I missing something? I thought target_include_directories() works for both .cpp and .hpp files.
It seems like you may not have added the correct directory as an include directory for the ExampleApp. The PROJECT_SOURCE_DIR variable evaluates to the directory in which the last project() call was made in your CMake project. You have not shown where this is, but you could use the root directory of the CMake project to be sure it is correct; try using ${CMAKE_SOURCE_DIR}/ExampleLibrary in the target_include_directories call instead:
target_include_directories(ExampleApp
PRIVATE ${CMAKE_SOURCE_DIR}/ExampleLibrary
)
A couple more notes:
If you aren't using an IDE such as Visual Studio for compilation, there is no need to add header files to calls like add_library() and add_executable(). Doing this only ensures they are shown in an IDE.
Instead, specify directories within which the headers can be found, using target_include_directories(). In your case, it sounds like you should have both directories listed here.
To link the ExampleLibrary target to the executable, you can simply use the target name in target_link_libraries(). There is no need to list out the binary directory (unless you are linking other libraries from there).
So with this in mind, the ExampleApp CMake file could look something like this:
add_executable(ExampleApp
main.cpp
)
target_include_directories(ExampleApp PRIVATE
${PROJECT_SOURCE_DIR}/ExampleLibrary
${CMAKE_CURRENT_LIST_DIR}
)
target_link_libraries(ExampleApp PRIVATE
ExampleLibrary
)

add root directory as include directory

During compilation certain header files aren't found, although I added the respective include directories in CMake. Unfortunately this is the code and directory structure I am stuck with and I can't change anything on the include statements.
I have the following directory structure:
projectfolder
+--source1
| |--prog.cpp
| |--anotherHeader.h
| |--CMakeLists
|
+--includefolder
| +--source1_include
| | |--header.h
|
|--CMakeLists
CMakeLists in projectfolder looks like this:
project (project)
include_directories(includefolder)
add_subdirectory(source1)
prog.cpp has:
#include "source1_include/header.h"
and header.h has:
#include "anotherHeader.h"
(don't ask me why, I don't know myself, maybe it has something to do with the fact that originally this is a Visual Studio project)
I thought I could fix this, by adding
include_directories(.)
to the CMakeLists in the source1 directory but unfortunately it wont work that way. anotherHeader.h isn't found.
I'm assuming that "." is "projectfolder"
If I understand correctly, you added -I "projectfolder", so now "source1_include/header.h" correctly finds "projectfolder/source1_include/header.h"
Now, "header.h" tries to include "anotherHeader.h", which is not in its folder and not in any of the included folders. It is actually in "source1". So cmake is correct to error out.
You need to either move "anotherHeader.h" into your includes folder (my recommendation), or edit "header.h" to find it by the correct relative path "../source1/anotherHeader.h" (not recommended), or add include_directories("source1"), which is where it actually is.

CMake inlucde project file without folder prefix

My project structure is the following:
-Engine
|-Shaders
| '-shader.glsl
|-source
| |-Math
| |'- matrix.hpp
| | - vector.hpp
| '-Lua
| |'-lua_state.hpp
'-CMakeLists.txt
I am using CMake as build system and my question is :
How can I include for example matrix.hpp into lua_state.hpp without using the prefix for folder path ? i mean instead to use in lua_state.hpp #include "../Math/matrix.hpp" , just included like this -> #include "matrix.hpp" , there is any way to do this with CMake ?
You can specify the include path for compiler (-I option)
To include it for all targets (docs)
include_directories(source/Math)
or use target properties (docs)
target_include_directories(yourAppOrLibTargetName PRIVATE source/Math)
Add the directory to the include path by calling the include_directories command.
You'll also need to make sure the header files are declared as dependencies of the library or executable you're creating, either using add_library or add_executable. I can't quite tell what you'll need based on the files you listed.

Including directories in Clion

Whenever I wanted to include a directory that was located outside of my project with Clion I would use the -I somedir flag. This time however, what I want to do is to have a hierarchy like this:
/project
CMakeLists.txt
/src
/Graph
Graph.h
Graph.cpp
/Dijkstra
Dijkstra.h
Dijstra.cpp
I want my code in a /src directory. And not only that, but also, for example, inside the file Dijkstra.h I want to include the Graph.h like this: #include "Graph/Graph.h and not like this: #include "../Graph/Graph.h.
If I only add an -I src flag, then if I am inside the Dijkstra.h file and I wanted to include Graph.h, I would have to write #include "../Graph/Graph.h, which is not what I want.
So I tried to also add INCLUDE_DIRECTORIES(src). That fixed the problem above, however when tried to compiled, I got a linker error undefined reference to....
So I tried adding the files one by one like this:
set(SOURCE_FILES
src/Dijkstra/Dijkstra.h
src/Dijkstra/Dijkstra.cpp
src/Graph/Graph.h
src/Graph/Graph.cpp)
add_executable(someprojectname ${SOURCE_FILES})
and that brought back the previous problem, where I had to include the files like this: #include "../Graph/Graph.h".
How can I do this properly to get the behavior I want ?
Command INCLUDE_DIRECTORIES doesn't add any source file for compile!
Instead, this command defines directories for search header files.
You need to list all source files in add_executable() call in any case:
include_directories(src)
set(SOURCE_FILES
src/Dijkstra/Dijkstra.cpp
src/Graph/Graph.cpp)
add_executable(someprojectname ${SOURCE_FILES})
UPDATE: #Tsyvarev's answer is correct. I've edited this answer to remove the incorrect part and keep the comments relating to target_include_directories(), but it should be viewed as additional to Tsyvarev's answer.
INCLUDE_DIRECTORIES(src) will make the src directory get added as a search path to all targets defined from that point on. It does not add sources to any targets. The search path will be relative to the current source directory and CMake will adjust it as appropriate when descending into subdirectories via add_subdirectory(). While this is fine if that's what you want, as the project gets bigger and more complicated, you may find you would prefer to apply the include path settings to just some targets. For that, use target_include_directories() instead:
target_include_directories(someprojectname "${CMAKE_CURRENT_SOURCE_DIR}/src")
This will have the same effect, but it restricts the use of the added include path to just the someprojectname target. If you later define some other target which doesn't need the include path, it won't be added. This can help prevent situations like unexpected files being picked up if you have deep directory hierarchies and you re-use directory names in different places, for example).
The target_include_directories() command has additional benefits when applied to library targets because CMake has the ability to carry the include path through to anything you link against that library too. Doesn't sound like much, but for large projects which define and link many libraries, it can be a huge help. There are other target-specific commands which have similar benefits too. This article may give you a bit of a feel for what is possible (disclaimer: I wrote the article). It is more focused on target_sources(), but the discussion around carrying dependencies through to other targets may be useful.

Non recursive (non-recursive) Automake

I am trying to convert a project to use non-recursive automake. Based on a search on SO I could see that the topic has been covered to some extend. But there are not really any questions on how to convert a recursive automake project to a non recursive one. I have already read Karel Zak's blog and of course the autotools-mythbuster. There is a question with experiences regarding non-recursive automake but it does not explain how to convert a project. The only question that explains a bit seems to be regarding the subdir-objects option. But I could not get my project converted with these resources. Hence this question.
Lets start with a simple project setup:
project/
\-- configure.ac
|-- Makefile.am
\-- src/
\-- Makefile.am
|-- foo.c
|-- foo.h
\-- main.c
In configure.ac I just add the subdir-objects option:
AM_INIT_AUTOMAKE([subdir-objects])
In Makefile.am I removed the src directory from the root Makefiles.am's SUBDIRS variable. Then I removed the src/Makefile entry from the AC_CONFIG_FILES macro in `configure.ac.
Karel Zak's blog suggests to name the included Makefiles of the subdirectories Makemodule.am but Makefile.am seem to work too, if the sub folder is removed for the SUBDIRS variable and if the Makefile entry is removed from the AC_CONFIG_FILES config files macro.
Next I defined a global variable for the programs in the root Makefile.am and included the src/Makefile.am
bin_PROGRAMS=
include src/Makefile.am
In src/Makefile.am I changed:
bin_PROGRAMS=foo
to:
bin_PROGRAMS+=src/foo
and I also changed all occurences of foo_XXX to src_foo_XXX. And I added the prefix src/ to all .c and .h file names in src_foo_SOURCES.
But the program was not building and gave errors about include files not being found, for example:
fatal error: debug.h: No such file or directory
#include <debug.h>
Originally my src directories Makefile.am only hat the content variables src_foo_SOURCES, src_foo_CFLAGS, src_foo_LDFLAGS and src_foo_LDADD. My solution to this problem was to add src_foo_CPPFLAGS like this:
src_foo_CPPFLAGS = \
$(AM_CPPFLAGS) \
-I$(top_builddir)/src \
-DDATADIR='"$(datadir)"' \
-DMODULEDIR='"$(moduledir)"' \
-DLIBEXECDIR='"$(libexecdir)"'
But I dont' really understand why this was necessary and why it built fine when I was using recursive automake?
I have another question regarding the answer of Brett Hale in this question. He writes:
You could use "$(srcdir)/sourceA.cpp", but this directory is implicit anyway. All you need is:
libadapter_la_SOURCES = sourceA.cpp sourceB.cpp
But I could not get it to work without prefixing the path, so that seems wrong to me, can someone confirm my experience?
Update: I am also having problems with the po/ subdir, how can I make that non-recursive? There is no Makefile.am in po/ just a Makevars file. There is a post on autotools-mythbuster, that indicates non-recursive make with gettext is not supported, but that post is from 2011. I'm not sure if anything might have changed in the mean time.
I'll start from the bottom up: nothing changed with respect to gettext since 2011, and po/ directories should still be handled recursively, unfortunately. The same is true for gtk-doc. The reason is that they build somewhat-automake-compatible Makefile.in files, but they are not really automake-based.
As for the header file not found, the reason why it now fails is because you're using the wrong #include statement format: you should use #include "debug.h" and then it would work without having to add the -Isrc to the command line. The preprocessor will look for "" enclosed headers in the same directory as the source file, and for <> enclosed header in the include path; automake by default adds the current directory to the include path with -I. and that meant that it was satisfied when using recursive Makefile.am, but now the "current directory" no longer matches your source file's directory.
I would also suggest both against re-using the name Makefile.am if you're using Karel's suggested approach (automake, or at least some versions of it, will then generate a Makefile.in file for the subdirectory that will not work properly), and to consider not using Karel's approach at all if your software is self-contained enough, for instance if it only has one binary target. Karel's use case was linux-utils which is a fairly sparse project with a few dozen targets each with its own set of source files.
I'll try to comment on the Brett Hale answer you noted, as I think there's a misunderstanding there altogether.