cmake undefined reference to function
The directory subdir1
doesn't generate a binary. Add this:
project(Example)
add_library(Example Example.cpp)
instead of your add_sources
. After this, you need to tell the project that uses it to link against it:
TARGET_LINK_LIBRARIES(subdir2 Example)
If your names differ, document yourself on the functionalities of these commands.
Comments
-
E-rich almost 2 years
The project structure below is a simplified example. I tried to boil it down to the minimal amount of files to reproduce my issue.
. ├── CMakeLists.txt ├── subdir1 │ ├── CMakeLists.txt │ └── subsubdir1 │ ├── CMakeLists.txt │ ├── Example.cpp │ └── Example.h └── subdir2 ├── CMakeLists.txt ├── main.cpp └── subsubdir1 ├── CMakeLists.txt ├── ExampleCreator.cpp └── ExampleCreator.h
./CMakeLists.txt
cmake_minimum_required(VERSION 2.8) project(test) macro(add_sources) file (RELATIVE_PATH _relPath "${CMAKE_SOURCE_DIR}" "${CMAKE_CURRENT_SOURCE_DIR}") foreach (_src ${ARGN}) if (_relPath) list (APPEND SRCS "${_relPath}/${_src}") else() list (APPEND SRCS "${_src}") endif() endforeach() if (_relPath) # propagate SRCS to parent directory set (SRCS ${SRCS} PARENT_SCOPE) endif() endmacro() add_subdirectory(subdir1) add_subdirectory(subdir2) add_executable(test ${SRCS})
subdir1/CMakeLists.txt
add_subdirectory(subsubdir1)
subdir1/subsubdir1/CMakeLists.txt
add_sources(Example.cpp)
subdir1/subsubdir1/Example.h
#ifndef EXAMPLE_H #define EXAMPLE_H class Example { public: Example(); virtual ~Example(); }; #endif
subdir1/subsubdir1/Example.cpp
#include <stdio.h> #include "Example.h" Example::Example() { printf("Inside Example constructor\n"); } Example::~Example() { }
subdir2/CMakeLists.txt
add_subdirectory(subsubdir1) add_sources(main.cpp)
subdir2/main.cpp
#include "subsubdir1/ExampleCreator.h" int main(int argc, char** argv) { ExampleCreator creator; return 0; }
subdir2/subsubdir1/CMakeLists.txt
add_sources(ExampleCreator.cpp)
subdir2/subsubdir1/ExampleCreator.h
#ifndef EXAMPLE_CREATOR_H #define EXAMPLE_CREATOR_H class ExampleCreator { public: ExampleCreator(); virtual ~ExampleCreator(); }; #endif
subdir2/subsubdir1/ExampleCreator.cpp
#include "ExampleCreator.h" #include "../../subdir1/subsubdir1/Example.h" ExampleCreator::ExampleCreator() { Example* ex1 = new Example(); } ExampleCreator::~ExampleCreator() { }
I'm hoping this is a really simple lack of understanding of how CMake handles dependencies. This compiles without error, but fails during linking. The
make
output below shows thatExample.cpp
isn't even compiling and I don't understand why.user>:~/src/test/build$ make Scanning dependencies of target test [ 50%] Building CXX object CMakeFiles/test.dir/subdir2/subsubdir1/ExampleCreator.cpp.o [100%] Building CXX object CMakeFiles/test.dir/subdir2/main.cpp.o Linking CXX executable test CMakeFiles/test.dir/subdir2/subsubdir1/ExampleCreator.cpp.o: In function `ExampleCreator::ExampleCreator()': ExampleCreator.cpp:(.text+0x2b): undefined reference to `Example::Example()' collect2: ld returned 1 exit status make[2]: *** [test] Error 1 make[1]: *** [CMakeFiles/test.dir/all] Error 2 make: *** [all] Error 2
All the sources are appended to the
SRCS
variable in the rootCMakeLists.txt
file from what I can tell. So, why isn'tExample.cpp
getting compiled? or linked? -
E-rich over 11 yearsThis worked, but I don't understand why I need to make a library and link against as opposed to just adding the source directly to the executable. I didn't need the
project(Example)
btw. -
Luchian Grigore over 11 years@E-rich you didn't add the sources in the project that actually needed the symbols.