Add target_include_directories
ghuser404 opened this issue ยท 6 comments
CMake 3.12 allows normal libraries and executables to link to object libraries to get their usage requirements, i.e. include directories, etc.
https://cmake.org/cmake/help/v3.12/command/target_link_libraries.html#linking-object-libraries
To propagate the include directory to cppcodec's users, add this line into CMakeLists.txt
target_include_directories(cppcodec INTERFACE "${PROJECT_SOURCE_DIR}")
Maybe this isn't as clear as it should be in the docs, but the CMakeLists.txt files in the repository aren't meant to be used by users of the library. There are no particular usage requirements other than C++11 (or higher) support, which the library user must already have specified for their own files (in order to include cppcodec's C++11 headers) and I believe it's better to make them specify this explicitly. Given that there's no object library to be linked in and no particular compile flags required, I don't really see the need for having usage requirements in the first place.
For CMake users, including cppcodec is a one-liner anyway:
include_directories(${CPPCODEC_ROOT})
# alternatively, the user could set this only a particular target - that's their choice
and that's it. This ignores the project's CMakeLists.txt, is no more involved or complicated than add_subdirectory()
, and importantly, doesn't convey an impression that CMake would be necessary or preferred over other build systems.
For these reasons, I'll close the issue as not applicable. Feel free to reopen if you feel that there's a particular need that's not covered by this simpler include. I reserve the right to make a judgment call of convenience vs. added/perceived complexity even if there is a valid use case.
@jpetso Thanks for your answer.
However, this is not how modern CMake works. Modern CMake is all about targets and not directories. If you want to use a library, you call target_link_libraries
on it. Unless you have a very good reason, you should never call include_directories
. In case of your library, there is no choice.
I suggest you see how some popular header-only libraries work with CMake. One of the examples would be https://github.com/nlohmann/json
The library looks relatively clean, and I hope you reconsider this.
I'm with ghuser404 on this. Creating the targets is the proper way of doing this. It also allows you to install the library and then use find_package.
Mocking about with include dirs is not why I'm using CMake.
Reopening as I'm starting to reconsider doing this. Ideally I'd like to keep CMakeLists for including the headers (useful to a user) separate from the larger CMakeLists.txt that builds tests, tools, etc. (useful to a contributor to this repository). I wonder whether putting a CMakeLists.txt inside the cppcodec
subdirectory would be the proper solution for that, although it would still have to define its parent directory as include directory, so that's not the cleanest either.
Open for suggestions on how to best make that split.
You can have the same CmakeLists.txt with options to build tests, etc.
Yes, using options is a good way to do this - and it seems you are already doing this. You only run add_subdirectory when BUILD_TESTING evaluates to true.
Another option you could try is to unconditionally do the add_subdirectory, but add EXCLUDE_FROM_ALL. This way, the targets that are defined in this directory are always there, they are just not build when the target 'all' (the default) is built. This has the advantage that you don't have to rerun CMake if you suddenly decide you want to build tests - you could just do a 'make test_cppcodec' (assuming a UNIX-like make-system, but they all have their equivalents of course).