Reputation: 194
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:
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})
include_directories(include)
add_subdirectory(src)
add_subdirectory(include)
set(sources ${sources} PARENT_SCOPE)
set(headers ${headers} PARENT_SCOPE)
include_directories(helloworld)
add_subdirectory(helloworld)
set(headers ${headers} PARENT_SCOPE)
set(
headers
${headers}
${CMAKE_CURRENT_SOURCE_DIR}/MyClass.hpp
PARENT_SCOPE
)
add_subdirectory(helloworld)
set(
sources
${sources}
${CMAKE_CURRENT_SOURCE_DIR}/helloworld.cpp
PARENT_SCOPE
)
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
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
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