1

My project has the following structure:

-project
|- main.cpp
|- CMakeLists.txt
|- Headers
    |- animal.cpp
    |- animal.hpp
    |- lives.cpp
    |- lives.hpp
    |- CMakeLists.txt

We further have:

#/project/CMakeLists.txt
cmake_minimum_required(VERSION 3.1)

set(CMAKE_CXX_STANDARD 11)

project(main)

include_directories(Headers/)
link_directories(Headers/)
add_subdirectory(Headers)

add_executable(main main.cpp Headers/animal.cpp Headers/lives.cpp)
target_link_libraries(main animal_lib)
target_link_libraries(main genome_lib)

as well as

#/project/Headers/CMakeLists.txt
add_library(lives_lib STATIC lives.cpp lives.hpp)
add_library(animal_lib STATIC animal.cpp animal.hpp)

target_include_directories(lives_lib PUBLIC ./)
target_include_directories(animal_lib PUBLIC ./)

Note also that animal.cpp includes lives.hpp. When I try to run cmake I get an linking error (undefined reference). If I a remove animal.cpp and animal.hpp (and all the functions that depend on it, so only things from lives.cpp are used) everything runs fine. Is the problem that I'm using function from lives.hpp in animal.cpp and if so, how do I fix this.


Note: I tried a couple of thins, mostly the suggestions from here. But it still doesn't link correctly.


Error message:

$ make
[ 33%] Built target animal_lib
Scanning dependencies of target genome_lib
[ 55%] Built target lives_lib
[ 66%] Linking CXX executable main
/usr/bin/ld: CMakeFiles/main.dir/Headers/animal.cpp.o: in function `Animal::set_something(double)':
animal.cpp:(.text+0x53): undefined reference to `Animal::something_else_'
collect2: error: ld returned 1 exit status
make[2]: *** [CMakeFiles/main.dir/build.make:118: main] Error 1
make[1]: *** [CMakeFiles/Makefile2:77: CMakeFiles/main.dir/all] Error 2
make: *** [Makefile:84: all] Error 2
Jonathan Hall
  • 75,165
  • 16
  • 143
  • 189
Sito
  • 494
  • 10
  • 29
  • 1
    Do I understand you correct that `animal_lib` makes use of `lives.cpp` and `lives.hpp`? In that case you need to include them for `animal_lib` or make it link against `lives_lib`. – super Oct 19 '19 at 18:25
  • @super yes, you understand correctly. What exactly do you mean with "include them" or link? – Sito Oct 19 '19 at 18:26
  • I've never tried building one static lib from other static libs, but [this post](https://stackoverflow.com/questions/50022318/using-cmake-to-build-a-static-library-of-static-libraries) suggests it can be done. However, my thought is why is it not `add_library(animal_lib STATIC animal.cpp animal.hpp lives.cpp lives.hpp)` since they are part of `animal_lib`. – super Oct 19 '19 at 18:31
  • @super I just tried your suggestion, but I still have the same problem. – Sito Oct 19 '19 at 18:35
  • "When I try to run cmake I get an linking error (`undefined reference`)." - Please, show that **exact error message** (add it to the question post). Currently I see that source file `animal.cpp` is **compiled both** to the `animal_lib` and to the `main`. Because you link one with another, you should get "double definition" error instead. – Tsyvarev Oct 19 '19 at 18:49
  • @Tsyvarev added the error message. – Sito Oct 19 '19 at 18:54
  • @JesperJuhl How exactly does the Question you linked to answer my question? – Sito Oct 19 '19 at 19:01
  • Which source file defines `something_else_` method? Note to the **terminating undescrore** (`_`); normally such names are not used in the code. – Tsyvarev Oct 19 '19 at 19:03
  • @Tsyvarev its defines in `animal.hpp`. I've put the underscore there when defining the variable `something_else_` since it is a private member of a class.. – Sito Oct 19 '19 at 19:06
  • @Sito It tells you what an "undefined reference" *is* and how to fix it by actually linking in the (object file or library) bits that *define* the missing function. – Jesper Juhl Oct 19 '19 at 19:07
  • @JesperJuhl I understood that, my main issue is how I'm supposed to do this in the above example with cmake. – Sito Oct 19 '19 at 19:08
  • @Sito fair enough. I re-opened the question. – Jesper Juhl Oct 19 '19 at 19:12
  • 1
    @Sito Please show the definition and the declaration for `something_else_`. Tsyvarev is right, it should yield a different error if you had two definitions of a method. But right now it sounds as you have managed to have only a declaration but no definition for `something_else_` in any of your compilation units. – Ext3h Oct 19 '19 at 19:28
  • 1
    "its defines in `animal.hpp`" - The **header** file only **declares** the methods of the class (that is, it contains the signature of the method, but doesn't contain the body of the method inside `{}`). But it is a **source** file (`.cpp`) which should **define** the method: it repeats the function signature and provides its body inside `{}`. Please, show the code which **defines** `something_else_` method. For more information about what declaration and definition are see .e.g [this answer](https://stackoverflow.com/a/12574407/3440745). – Tsyvarev Oct 19 '19 at 19:37

0 Answers0