Issue
I'm trying to set up a simple c++ project with CMake. I am trying to include Logger.h
header residing under the utils
folder from a/A.cpp
file. Currently, I cannot configure my A.cpp
file access utils/Logger.h
header file. I have both A.cpp
and Logger.h
files in the executable in the CMakeLists.txt
file, and added utils
folder to be included directory for the executable
target_include_directories(${PROJECT_NAME} PRIVATE utils a)
but still I can't access Logger.h
file. I get a/A.cpp:1:10: fatal error: 'utils/Logger.cpp' file not found
- Do I need to add CMakeLists.txt to each subdirectory, one for each
a
andutils
? - Can't I have just one parent that manages what files I can include for each file?
- I want to have absolute path access from
a.cpp
#include "utils/Logger.h", how to obtain that?
Here is what my folder structure looks like
├── CMakeLists.txt
├── a
│ └── A.cpp
├── main.cpp
└── utils
└── Logger.h
a/A.cpp
#include "utils/Logger.cpp"
class A {
public:
void hello_a() {
Logger logger;
logger.print();
}
}
utils/Logger.h
#include "iostream"
class Logger {
public:
void print() { std::cout << "hello from Logger" << std::endl; }
}
CMakeLists.txt
project(MyProject)
cmake_minimum_required(VERSION 3.0)
add_executable(${PROJECT_NAME} main.cpp a/A.cpp utils/Logger.cppo)
target_include_directories(${PROJECT_NAME} PRIVATE utils a)
Solution
Includes in C++ use paths relative to the include directories (or the source file in case you use includes with ""
-quotes).
For
#include "utils/Logger.cpp"
to work in a/A.cpp
either there needs to be a file a/utils/Logger.cpp
or the top directory needs to be one of the include directories.
To achieve the latter, you can simply do
target_include_directories(${PROJECT_NAME} PRIVATE .)
in addition to including the header instead of the source file. Note that for public/interface headers of exported targets you need to replace .
, but in case of private headers it doesn't matter.
A note on #include ""
vs #include <>
though: When encountering the ""
version, usually compilers look for a file relative to the source file and if not found they do same lookup as for the <>
version. For this reason you'll never see
#include "iostream"
in any examples and I strongly recommend not making a habit of including standard library headers using the ""
version of #include
.
Furthermore including a .cpp
usually indicates an error; Avoid the necessity to do this, if you're tempted to create a program like this or at the very least document this clearly in the code. Include the header not the source.
Answered By - fabian Answer Checked By - David Goodson (WPSolving Volunteer)