Jan Hanson
Jan Hanson

Reputation: 194

CMake with multiple subdirectories not compiling

My Problem is that CMake is refusing to compile giving the following error:

 [orpheus@Poseidon build]$ make 
 sources : /home/orpheus/Projects/Personal/C++/test/testProj/src/helloworld/MyClass.cpp/home/orpheus/Projects/Personal/C++/test/testProj/src/helloworld.cpp
 headers : /home/orpheus/Projects/Personal/C++/test/testProj/include/helloworld/MyClass.hpp
 -- Configuring done
 -- Generating done
 -- Build files have been written to: /home/orpheus/Projects/Personal/C++/test/build
 [ 33%] Building CXX object CMakeFiles/TEST.dir/testProj/src/helloworld/MyClass.cpp.o
 /home/orpheus/Projects/Personal/C++/test/testProj/src/helloworld/MyClass.cpp:1:51: fatal error: testProj/include/helloworld/MyClass.hpp: No such file or directory
  #include "testProj/include/helloworld/MyClass.hpp"
                                                    ^
 compilation terminated.
 make[2]: *** [CMakeFiles/TEST.dir/build.make:63:      CMakeFiles/TEST.dir/testProj/src/helloworld/MyClass.cpp.o] Error 1
 make[1]: *** [CMakeFiles/Makefile2:68: CMakeFiles/TEST.dir/all] Error 2
 make: *** [Makefile:84: all] Error 2

I am relatively new to CMake and have gone through most of the tutorials I can find as well as all the relevant stack overflow questions I could find, however nothing quite seems to cover my particular needs, I did (in my tweaking) stumble across a way where this didnt happen(unfortunately I cant replicate this now), however that gave me a linking error claiming:

 c++; fatal error: no input files

should I use the include_directory() command rather than set() to add the header files?

I decided on not using the glob() method of adding sources as per the CMake documentation and have based my solution off of this thread and a variety of tutorials.

I have the following project structure:

test/
 |
 +--CMakeLists.txt
 +--build/
 |     |----CMakeFiles/
 |     |----etc
 |
 +--testProj/
 |     +----CMakeLists.txt
 |     +----include
 |     |       +----CMakeLists.txt
 |     |       +----helloworld/
 |     |       |        +----CMakeLists.txt
 |     |       |        +----MyClass.hpp  
 |     |
 |     |----src
 |     |     +----helloworld.cpp
 |     |     +----CMakeLists.txt
 |     |     +----helloworld/
 |     |     |       +----CMakeLists.txt
 |     |     |       +----MyClass.cpp

files are as follows:

test/CMakeFiles.txt

 cmake_minimum_required(VERSION 3.6.1)
 project(TEST)
 add_subdirectory(testProj)
 add_executable(${CMAKE_PROJECT_NAME} ${sources} ${headers})
 set_target_properties(${CMAKE_PROJECT_NAME} PROPERTIES LINKER_LANGUAGE CXX)
 set(extraFlags "-Wall -Wextra -Weffc++ -pedantic -pedantic-errors -std=c++14")
 set(CMAKE_CXX_FLAGS ${CMAKE_CXX_FLAGS} ${extraFlags})

test/testProj/CMakeLists.txt

 include_directories(include)
 add_subdirectory(src)
 add_subdirectory(include)
 set(sources ${sources} PARENT_SCOPE)
 set(headers ${headers} PARENT_SCOPE)

test/testProj/include/CMakeLists.txt

 include_directories(helloworld)
 add_subdirectory(helloworld)
 set(headers ${headers} PARENT_SCOPE)

test/testProj/include/helloworld/CMakeLists.txt

 set(
    headers
    ${headers}
    ${CMAKE_CURRENT_SOURCE_DIR}/MyClass.hpp
    PARENT_SCOPE
)

test/testProj/src/CMakeLists.txt

 add_subdirectory(helloworld)
 set(
        sources 
        ${sources} 
        ${CMAKE_CURRENT_SOURCE_DIR}/helloworld.cpp 
        PARENT_SCOPE
 )

test/testProj/src/helloworld/CMakeLists.txt

 set(
    sources
    ${sources}
    ${CMAKE_CURRENT_SOURCE_DIR}/MyClass.cpp
    PARENT_SCOPE
    )

please can someone point me in the right direction as i'm about to put my head through the monitor.

Upvotes: 0

Views: 1958

Answers (2)

Jan Hanson
Jan Hanson

Reputation: 194

It Was indeed my 'include_directories()' that was the issue, I didnt realise that it is a recursive command making the work in the include subdirs redundant, I fixed this by adding the following line to my root CMakeLists.txt

 target_include_directories(${CMAKE_PROJECT_NAME} PRIVATE ${PROJECT_SOURCE_DIR}/testProj/include/)

and then modifying my #include statements to reflect that the testProj/include directory is now on my include path.

as well as removing the now redundant code the other CMakeList files in nested subdirectories

thanks to Jacob Panikulum for pointing me in the right direction.

Upvotes: 1

Jacob Panikulam
Jacob Panikulam

Reputation: 1218

Try

#include <MyClass.hpp>

The quotes tell the compiler to look for a relative path. The header genuinely doesn't exist at that path relative to MyClass.cpp

The angle-brackets tell the compiler to start looking in your CMake include_directories folders. Since you did include_directories(hello_world), the compiler will start looking in include/hello_world when you do include <*>.

Upvotes: 0

Related Questions