Say I have a project that looks like:
Project (dir)
-- CMakeLists.txt
-- MyLib (dir)
|-- CMakeLists.txt
|-- MyLib.h
|-- MyLib.cpp
-- MyOtherLib (dir)
|-- CMakeLists.txt
|-- MyLib.h (note that this is exactly the same name as in MyLib above)
|-- MyLib.cpp
If in MyLib/CMakeLists.txt I do this:
target_include_directories(MyLib PUBLIC
$<BUILD_INTERFACE:${CMAKE_CURRENT_SOURCE_DIR}>
Then anything that target_link_libraries
to MyLib
will have the "correct" include path to do #include "MyLib.h"
. However, if another executable MyExecutable
depends on both libraries using target_link_libraries(MyExecutable MyLib MyOtherLib)
you'd like to be able to instead specify which one is intended with #include "MyLib/MyLib.h"
or #include "MyOtherLib/MyLib.h"
. The only way I see to do that is to instead use:
target_include_directories(MyLib PUBLIC
$<BUILD_INTERFACE:${CMAKE_CURRENT_SOURCE_DIR}/..>
which kind of defeats one of the nice things about target_include_directories
in that it really strongly enforces avoiding accidental header dependencies, because you literally can't include things that you aren't explicitly claiming to use.
Is there another way to get this #include "MyLib/MyLib.h"
behavior?
You should reconsider your directory tree as follows:
Project (dir)
-- CMakeLists.txt
-- MyLib (dir)
|-- CMakeLists.txt
|-- src (dir)
MyLib.cpp
|-- include/MyLib (two dirs)
MyLib.h
-- MyOtherLib (dir)
|-- CMakeLists.txt
|-- src (dir)
MyLib.cpp
|-- include/MyOtherLib (two dirs)
MyLib.h
In this way you avoid including the ../
, i.e. Project
, folder and everything therein, which is not a clean approach and may lead to other problem should you add other files/folders in the future.
Then, you can write in MyLib/CMakeLists.txt
target_include_directories(MyLib PUBLIC
$<BUILD_INTERFACE:${CMAKE_CURRENT_SOURCE_DIR}>/include)
and in MyOtherLib/CMakeLists.txt
target_include_directories(MyOtherLib PUBLIC
$<BUILD_INTERFACE:${CMAKE_CURRENT_SOURCE_DIR}>/include)
As a result, you will be able to write #include "MyLib/MyLib.h"
and #include "MyOtherLib/MyLib.h"
in any program linking against the libraries in the build-tree.
If you also want to differentiate the include directories between the build-tree and the install-tree have a look at target_include_directories documentation and the useful cmake-generator-expressions.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With