0

Here is an MWE that isolates a problem I have in a larger project. (I am still wrapping my head around CMake.) Here is the layout of the project: enter image description here

Inside tests/CMakeLists.txt we have

cmake_minimum_required(VERSION 3.13)

add_executable(test_class_a test_class_a.cpp)
target_include_directories(test_class_a PUBLIC ${CMAKE_SOURCE_DIR}/modules/class_a/)

Now, when I try to compile test_class_a, it complains with something like enter image description here Essentially, although inside test_class_a.cpp file I have included #include "class_a.hpp" and it looks fine there, somehow class_a.cpp does not get invited into the party, it seems. How I make sure it does, without having to add #include "class_a.cpp", which would be ugly?

Inside the top-most CMakeLists.txt I have of course add_subdirectory(modules/tests/).

EDIT: the comment below says I need to add it inside add_executables, and it does fix the problem. However, this can be my misconception, but shouldn't it be the case that class_a.hpp and class_a.cpp are somehow semantically "linked" together, without me having to include the *.cpp inside the sources explicitly? Sorry for a long question, you are certainly free to delete it.

EDIT: Based on the accepted answer below, I've settled on the following CMakeLists.txt, which from now on will likely be my modus operandi in CMake:

cmake_minimum_required(VERSION 3.13)

add_library(class_a ${CMAKE_SOURCE_DIR}/modules/class_a/class_a.cpp)
add_executable(test_class_a test_class_a.cpp)
target_include_directories(test_class_a PUBLIC ${CMAKE_SOURCE_DIR}/modules/class_a/)
target_link_libraries(test_class_a PUBLIC class_a)
Ilonpilaaja
  • 1,169
  • 2
  • 15
  • 26
  • *"but shouldn't it be the case that class_a.hpp and class_a.cpp are somehow semantically "linked" together"* - no, from the perspective of compiler or linker they are unrelated. Also note that `include_directories` has no impact on linker. – user7860670 Nov 16 '19 at 09:55
  • *"you are certainly free to delete it"* - questions should not be deleted, they should be improved and answered. – Evg Nov 16 '19 at 09:57

1 Answers1

1

First solution: add class_a.cpp into add_executable:

add_executable(test_class_a test_class_a.cpp modules/class_a/class_a.cpp)

Second solution: create a library:

add_library(class_a modules/class_a/class_a.cpp)
target_include_directories(class_a PUBLIC modules/class_a/)
target_link_libraries(test_class_a PUBLIC class_a)

Probably, you already have a library: modules/class_a/CMakeLists.txt is there. Then you can do:

add_subdirectory(modules/class_a)
target_link_libraries(test_class_a PUBLIC <library name>)

(Paths should be fixed appropriately.)

However, this can be my misconception, but shouldn't it be the case that class_a.hpp and class_a.cpp are somehow semantically "linked" together, without me having to include the *.cpp inside the sources explicitly?

How should CMake know that? These files are completely unrelated from the point of view of CMake. It's your job to tell it they actually are related.

Evg
  • 25,259
  • 5
  • 41
  • 83