Undefined refence ?????

Hello ! I have an issue with cmake (I’m a beginner) I don’t really know how to express my problem since I don’t know the terms and since english is not my mother language… but basically I can’t get my project to compile because of what I think is a linking problem but I can’t seem to fix it.

Here’s the structure of the project
| build -
| code - src - main.cpp
CMakeLists.txt
| LibRationnel - include - ratio.hpp
- src - ratio.cpp
| CMakelists.txt

Here’s the CMakeLists :
./

cmake_minimum_required(VERSION 3.13)
set(CMAKE_EXE_LINKER_FLAGS "-lrt")


# give a name to the project
project(LibRationnel)

# display VERBOSE messages : cmake --log-level=VERBOSE ..

# specify the system
message(VERBOSE "CMAKE_VERSION           : " ${CMAKE_VERSION})
message(VERBOSE "CMAKE_SYSTEM_NAME       : " ${CMAKE_SYSTEM_NAME})
message(VERBOSE "CMAKE_SYSTEM            : " ${CMAKE_SYSTEM})
message(VERBOSE "CMAKE_SYSTEM_PROCESSOR  : " ${CMAKE_SYSTEM_PROCESSOR} "\n")

# specify the directories
message(VERBOSE "CMAKE_BINARY_DIR        : " ${CMAKE_BINARY_DIR})
message(VERBOSE "CMAKE_SOURCE_DIR        : " ${CMAKE_SOURCE_DIR})
message(VERBOSE "CMAKE_HOME_DIRECTORY    : " ${CMAKE_HOME_DIRECTORY})
message(VERBOSE "PROJECT_BINARY_DIR      : " ${PROJECT_BINARY_DIR})
message(VERBOSE "PROJECT_SOURCE_DIR      : " ${PROJECT_SOURCE_DIR} "\n")

# compile flags
message(VERBOSE "CMAKE_CXX_FLAGS         : " ${CMAKE_CXX_FLAG})
message(VERBOSE "CMAKE_CXX_FLAGS_DEBUG   : " ${CMAKE_CXX_FLAGS_DEBUG})
message(VERBOSE "CMAKE_CXX_FLAGS_RELEASE : " ${CMAKE_CXX_FLAGS_RELEASE})
message(VERBOSE "CMAKE_CXX_COMPILER      : " ${CMAKE_CXX_COMPILER} "\n")


# not clear to me, but vscode can't work fine without
set(CMAKE_EXPORT_COMPILE_COMMANDS ON)

# Prevents compiler-specific extensions to C++ because they might allow code to compile on your machine but not on other people's machine
#set_target_properties(${PROJECT_NAME} PROPERTIES CXX_EXTENSIONS OFF)

# (optional) add a "output" directory in the project binary directory
file(MAKE_DIRECTORY ${PROJECT_BINARY_DIR}/output)

# (optaional) put the binary files in this directory
set(EXECUTABLE_OUTPUT_PATH ${PROJECT_BINARY_DIR}/bin)

# add LibRationnel
message(STATUS "LibRationnel cmake part ..." )
add_subdirectory(LibRationnel INTERFACE)
include_directories(${CMAKE_SOURCE_DIR}/LibRationnel/include) # important : other projects called by this cmake will know this include directory

# add test code
message(STATUS "code cmake part ..." )
add_subdirectory(code)

./code

cmake_minimum_required(VERSION 3.13)
set(CMAKE_EXE_LINKER_FLAGS "-lrt")

# give a name to the project
project(RatioTest)

# file to compile and name of the executable
# add_executable(simpleProject src/main.cpp src/plop.cpp include/plop.hpp)
add_executable(RatioTest src/main.cpp)

# include directory
target_include_directories(RatioTest PRIVATE "include")
target_include_directories(RatioTest PRIVATE "include")

# compilation options
# target_compile_features(simpleProject PRIVATE cxx_std_11) # use at least c++ 11
target_compile_features(RatioTest PRIVATE cxx_std_17) # use at least c++ 17

# for each sample file, make an exe
foreach(src_file ${src_files_list})

    get_filename_component(file_exe ${src_file} NAME_WE)    # define te name of the app (filename Without Extension)
    add_executable(${file_exe} ${src_file})                 # file to compile and name of the app
    target_link_libraries(${file_exe} PRIVATE Ratio)      # lib dependency
    target_compile_features(${file_exe} PRIVATE cxx_std_17) # use at least c++ 17
    if (MSVC)
        target_compile_options(${file_exe} PRIVATE /W3)
    else()
        target_compile_options(${file_exe} PRIVATE -Wall -02 -Wextra -Wpedantic -pedantic-errors)
    endif()

    message(STATUS "src file  " ${src_file})
    message(STATUS "exe file  " ${file_exe})

endforeach()


if (MSVC)
    # target_compile_options(simpleProject PRIVATE /W3)
    target_compile_options(RatioTest PRIVATE /W3)
else()
    # target_compile_options(simpleProject PRIVATE -Wall -Wextra -Wpedantic -pedantic-errors)
    target_compile_options(RatioTest PRIVATE -Wall -O2 -Wextra -Wpedantic -pedantic-errors)
endif()

./LibRationnel

cmake_minimum_required(VERSION 3.13)

# give a name to the project
project(Ratio LANGUAGES C CXX)

# automatic get all files in a directory
file(GLOB_RECURSE source_files src/*.cpp)
file(GLOB_RECURSE header_files include/*.hpp)

# call the CMakeLists.txt to make the documentation (Doxygen) - - - -  - - - - D O X Y G E N - - - - - - - 
# find_package(Doxygen OPTIONAL_COMPONENTS QUIET)
# if(DOXYGEN_FOUND)
# 	add_subdirectory(doc)
# else()
# 	message(WARNING "Doxygen not found, skip dococumentation")
# endif()

# Instructions to compile a library (no main() inside)
# default STATIC ??
# SHARED to make a .so instead of a .a
# add_library(ganQ SHARED ${source_files} ${header_files})
add_library(Ratio STATIC ${source_files} ${header_files})

# compilation flags
target_compile_features(Ratio PRIVATE cxx_std_17) # use at least c++ 11
if (MSVC)
    target_compile_options(Ratio PRIVATE /W3)
else()
    target_compile_options(Ratio PRIVATE -Wall -O2 -Wextra -Wpedantic -pedantic-errors)
endif()

# include directory
target_include_directories(Ratio PRIVATE "include")

# install (optional, install a lib is not mandatory)
install(FILES ${header_files} DESTINATION /usr/local/include/Ratio)
install(TARGETS Ratio
        RUNTIME DESTINATION /usr/local/lib
        LIBRARY DESTINATION /usr/local/lib
        ARCHIVE DESTINATION /usr/local/lib)

And I can’t compile because the compiler finds an Undefined reference with a function which prototype is in ratio.hpp and it is defined in ratio.cpp.

output

eric@ERIC-PC:~/Ratio/build$ make
[ 60%] Built target Ratio
Scanning dependencies of target RatioTest
[ 80%] Building CXX object code/CMakeFiles/RatioTest.dir/src/main.cpp.o
[100%] Linking CXX executable ../bin/RatioTest
/usr/bin/ld : CMakeFiles/RatioTest.dir/src/main.cpp.o : dans la fonction « Ratio<int>::operator*(int const&) const [clone .isra.0] [clone .constprop.0] » :
main.cpp:(.text+0x36a) : référence indéfinie vers « convert_float_to_ratio(double const&, unsigned int const&) »
/usr/bin/ld : CMakeFiles/RatioTest.dir/src/main.cpp.o : dans la fonction « Ratio<int>::sqrt() » :
main.cpp:(.text._ZN5RatioIiE4sqrtEv[_ZN5RatioIiE4sqrtEv]+0x5e) : référence indéfinie vers « convert_float_to_ratio(double const&, unsigned int const&) »
/usr/bin/ld : main.cpp:(.text._ZN5RatioIiE4sqrtEv[_ZN5RatioIiE4sqrtEv]+0x95) : référence indéfinie vers « convert_float_to_ratio(double const&, unsigned int const&) »
/usr/bin/ld : CMakeFiles/RatioTest.dir/src/main.cpp.o : dans la fonction « Ratio<int>::operator+(int const&) const » :
main.cpp:(.text._ZNK5RatioIiEplERKi[_ZNK5RatioIiEplERKi]+0x4c) : référence indéfinie vers « convert_float_to_ratio(double const&, unsigned int const&) »
/usr/bin/ld : CMakeFiles/RatioTest.dir/src/main.cpp.o : dans la fonction « Ratio<int>::operator-(int const&) const » :
main.cpp:(.text._ZNK5RatioIiEmiERKi[_ZNK5RatioIiEmiERKi]+0x4c) : référence indéfinie vers « convert_float_to_ratio(double const&, unsigned int const&) »
/usr/bin/ld : CMakeFiles/RatioTest.dir/src/main.cpp.o:main.cpp:(.text._ZNK5RatioIiEdvERKi[_ZNK5RatioIiEdvERKi]+0x4c) : encore plus de références indéfinies suivent vers « convert_float_to_ratio(double const&, unsigned int const&) »
collect2: error: ld returned 1 exit status
make[2]: *** [code/CMakeFiles/RatioTest.dir/build.make:84 : bin/RatioTest] Erreur 1
make[1]: *** [CMakeFiles/Makefile2:142 : code/CMakeFiles/RatioTest.dir/all] Erreur 2
make: *** [Makefile:130 : all] Erreur 2

What can I do about it ?

Thank you in advance for your help !

What source file contains the implementation of convert_float_to_ratio?

Just guessing, but I see for the main executable you have

add_executable(RatioTest src/main.cpp)

but there is no corresponding call to

target_link_libraries(RatioTest PRIVATE Ratio)

which should link in the library that presumably contains the function implementation.

Oh, yeah, that’s probably it. I saw the loop doing links to Ratio, but the top-level RatioTest is missing one.