# Cmake Project not linking correctly

**URL:** <https://discourse.cmake.org/t/cmake-project-not-linking-correctly/8806>\
**Category:** Code\
**Tags:** os:windows\
**Created:** [August 22, 2023, 8:53pm UTC](https://discourse.cmake.org/t/cmake-project-not-linking-correctly/8806 "2023-08-22T20:53:41Z")\
**Posts on this page:** 9\
**Page:** 1

<div class="post-metadata">

**Author:** ![Tmurdoch](https://discourse.cmake.org/user_avatar/discourse.cmake.org/tmurdoch/32/3746_2.png) [@Tmurdoch](https://discourse.cmake.org/u/Tmurdoch)\
**Post date:** [August 22, 2023, 8:53pm UTC](https://discourse.cmake.org/t/cmake-project-not-linking-correctly/8806/1 "2023-08-22T20:53:41Z")

</div>

I have been trying to link a test file (TestIntstantiator.cpp) to a library for a while, i’ve tried using add\_subdirectories and multiple libraries but this just confused me (and the compiler). I am now trying to do it in the simplest way possible, but still coming across problems.

This is my CmakeLists file:

```auto
cmake_minimum_required(VERSION 3.9.1)

project(Icicle)

set(CMAKE_CXX_FLAGS "-Wall")

# check OS
# UNIX, WIN32, WINRT, CYGWIN, APPLE are environment variables as flags set by default system
if(UNIX)
    message("This is a ${CMAKE_SYSTEM_NAME} system")
elseif(WIN32)
    message("This is a Windows System")
endif()

if (NOT CMAKE_BUILD_TYPE)
  # CMake defaults to leaving CMAKE_BUILD_TYPE empty. This screws up
  # differentiation between debug and release builds.
  set(CMAKE_BUILD_TYPE "None" CACHE STRING "Choose the type of build, options are: None (CMAKE_CXX_FLAGS or CMAKE_C_FLAGS used) Debug Release" FORCE)
endif ()

# Specify build paths
set(CMAKE_ARCHIVE_OUTPUT_DIRECTORY "${PROJECT_BINARY_DIR}/lib")
set(CMAKE_LIBRARY_OUTPUT_DIRECTORY "${PROJECT_BINARY_DIR}/lib")
set(CMAKE_RUNTIME_OUTPUT_DIRECTORY "${PROJECT_BINARY_DIR}/bin")

#cmake_policy(SET CMP0079 NEW)

add_executable(TestInstantiator Tests/Main/TestInstantiator.cpp )

file(GLOB HEADER_FILES $(CMAKE_SOURCE_DIR)/Main/src/*.h)
list(APPEND HEADER_FILES 
    "${CMAKE_SOURCE_DIR}/Main/Math/IcicleMath.h"
    "${CMAKE_SOURCE_DIR}/Main/Memory/Allocator.h"
    "${CMAKE_SOURCE_DIR}/Main/Memory/StackAllocator.h"
    "${CMAKE_SOURCE_DIR}/Main/Memory/MemoryManager.h"
    "${CMAKE_SOURCE_DIR}/Main/Resources/Resource.h"
)

file(GLOB SOURCE_FILES $(CMAKE_SOURCE_DIR)/Main/src/*.cpp)
list(APPEND SOURCE_FILES
"${CMAKE_SOURCE_DIR}/Main/Math/IcicleMath.cpp"
"${CMAKE_SOURCE_DIR}/Main/Memory/Allocator.cpp"
"${CMAKE_SOURCE_DIR}/Main/Memory/StackAllocator.cpp"
"${CMAKE_SOURCE_DIR}/Main/Memory/MemoryManager.cpp"
)

add_library(IcicleMain SHARED ${HEADER_FILES} ${SOURCE_FILES})

install(FILES ${HEADER_FILES} DESTINATION include/Icicle)

add_executable(Test "Tests/Main/TestInstantiator.cpp")
target_include_directories(Test PRIVATE 
"${CMAKE_SOURCE_DIR}/Main/src" 
"${CMAKE_SOURCE_DIR}/Main/Math" 
"${CMAKE_SOURCE_DIR}/Main/Memory" 
"${CMAKE_SOURCE_DIR}/Main/Resources")

link_directories(Test)

target_link_libraries(Test IcicleMain)
# target_link_libraries(TestInstantiator vtkCommon)

add_test(NAME TestInstantiator
         COMMAND TestInstantiator)

```

And the project structure looks like this:

```auto
├── Main
│ ├── Src
│ │ ├── **/*.cpp/.h
│ ├── Math
│ │ ├── **/*.cpp/.h
│ ├── Memory
│ │ ├── **/*.cpp/.h
│ ├── Resources
│ │ ├── **/*.cpp/.h
├── Tests
│ ├── Main
│ │ ├── TestInstantiator.cpp
├──CmakeLists.txt

```

The errors I’m getting:  
Icicle/Tests/Main/TestInstantiator.cpp:34: undefined reference to S  
tackAllocator::StackAllocator(unsigned long long, void\*)’  
undefined reference to `Math::ptr_add(void*, unsigned long long)' /Icicle/Main/Memory/MemoryManager.h:53: undefined reference to `Icicle::MemoryManager::~MemoryManager()’  
Icicle/Main/Memory/MemoryManager.h:53: undefined reference to `Icicle::MemoryManager::MemoryManager()’  
collect2.exe: error: ld returned 1 exit status  
make[2]: \*\*\* [bin/TestInstantiator.exe] Error 1  
make[1]: \*\*\* [CMakeFiles/TestInstantiator.dir/all] Error 2  
make: \*\*\* [all] Error 2

---

<div class="post-metadata">

**Author:** ![bill.hoffman](https://discourse.cmake.org/user_avatar/discourse.cmake.org/bill.hoffman/32/13_2.png) [@bill.hoffman](https://discourse.cmake.org/u/bill.hoffman)\
**Post date:** [August 22, 2023, 9:39pm UTC](https://discourse.cmake.org/t/cmake-project-not-linking-correctly/8806/2 "2023-08-22T21:39:12Z")

</div>

There is not enough information in this to help you. You need to figure out where StackAllocator::StackAllocator and Icicle::MemoryManager::~MemoryManager are defined in the source code. This could be a C++ issue and not a build system issue.

---

<div class="post-metadata">

**Author:** ![Tmurdoch](https://discourse.cmake.org/user_avatar/discourse.cmake.org/tmurdoch/32/3746_2.png) [@Tmurdoch](https://discourse.cmake.org/u/Tmurdoch)\
**Post date:** [August 22, 2023, 11:10pm UTC](https://discourse.cmake.org/t/cmake-project-not-linking-correctly/8806/3 "2023-08-22T23:10:36Z")

</div>

My includes in TestInstantiator.cpp look like this:

```auto
#include "../doctest.h"
#include "../../Main/src/IceRoot.h" 
#include "../../Main/Memory/StackAllocator.h"
#include "../../Main/Memory/Allocator.h"
#include "../../Main/Math/IcicleMath.h"

```

Is this what you mean?

---

<div class="post-metadata">

**Author:** ![Tmurdoch](https://discourse.cmake.org/user_avatar/discourse.cmake.org/tmurdoch/32/3746_2.png) [@Tmurdoch](https://discourse.cmake.org/u/Tmurdoch)\
**Post date:** [August 22, 2023, 11:13pm UTC](https://discourse.cmake.org/t/cmake-project-not-linking-correctly/8806/4 "2023-08-22T23:13:11Z")

</div>

Also what doesn’t make sense to me is this error:  
/Main/Memory/MemoryManager.h:53: undefined reference to `Icicle::MemoryManager::~MemoryManager()’

Where line 53 is this:  
`MemoryManager IceMemoryManager;`

---

<div class="post-metadata">

**Author:** ![ben.boeckel](https://discourse.cmake.org/letter_avatar_proxy/v4/letter/b/ea5d25/32.png) [@ben.boeckel](https://discourse.cmake.org/u/ben.boeckel)\
**Post date:** [August 22, 2023, 11:31pm UTC](https://discourse.cmake.org/t/cmake-project-not-linking-correctly/8806/5 "2023-08-22T23:31:12Z")

</div>

> [@Tmurdoch](#):
>
> /Main/Memory/MemoryManager.h:53: undefined reference to `Icicle::MemoryManager::~MemoryManager()’
> 
> Where line 53 is this:  
> `MemoryManager IceMemoryManager;`

A static instance will need the destructor; it seems that it is not defined anywhere (it is probably in the library).

> [@Tmurdoch](#):
>
> `link_directories(Test)`

This should not be needed at all for intra-project target usages.

> [@Tmurdoch](#):
>
> `# target_link_libraries(TestInstantiator vtkCommon)`

The `TestInstantiator` target needs to link to `IcicleMain` at least.

---

<div class="post-metadata">

**Author:** ![Tmurdoch](https://discourse.cmake.org/user_avatar/discourse.cmake.org/tmurdoch/32/3746_2.png) [@Tmurdoch](https://discourse.cmake.org/u/Tmurdoch)\
**Post date:** [August 23, 2023, 5:55pm UTC](https://discourse.cmake.org/t/cmake-project-not-linking-correctly/8806/6 "2023-08-23T17:55:54Z")

</div>

Okay I added both recomended, but cmake is generating makefiles that don’t compile anything (i searched for g++, gcc). All i see are rules like this:

```auto
# target to build an object file

Tests/Main/TestInstantiator.cpp.o:

$(MAKE) $(MAKESILENT) -f CMakeFiles/TestInstantiator.dir/build.make CMakeFiles/TestInstantiator.dir/Tests/Main/TestInstantiator.cpp.o

.PHONY : Tests/Main/TestInstantiator.cpp.o

```

---

<div class="post-metadata">

**Author:** ![ben.boeckel](https://discourse.cmake.org/letter_avatar_proxy/v4/letter/b/ea5d25/32.png) [@ben.boeckel](https://discourse.cmake.org/u/ben.boeckel)\
**Post date:** [August 23, 2023, 7:02pm UTC](https://discourse.cmake.org/t/cmake-project-not-linking-correctly/8806/7 "2023-08-23T19:02:08Z")

</div>

The structure of the makefiles is not obvious (see the `build.make` file referenced there for the “real” commands). Does it build if you run `make`?

---

<div class="post-metadata">

**Author:** ![Tmurdoch](https://discourse.cmake.org/user_avatar/discourse.cmake.org/tmurdoch/32/3746_2.png) [@Tmurdoch](https://discourse.cmake.org/u/Tmurdoch)\
**Post date:** [August 23, 2023, 8:58pm UTC](https://discourse.cmake.org/t/cmake-project-not-linking-correctly/8806/8 "2023-08-23T20:58:06Z")

</div>

It builds the library but I don’t know if the individual files in the library are being linked to eachother, i get this error message now:

```auto
[27%] Linking CXX shared library lib/libIcicleMain.so
[81%] Built target IcicleMain
[90%] Linking CXX executable bin/TestInstantiator
/usr/bin/ld: CMakeFiles/TestInstantiator.dir/Tests/Main/TestInstantiator.cpp.o: in function `DOCTEST_ANON_FUNC_21()':
/home/work/Projects/Icicle/Tests/Main/TestInstantiator.cpp:63: undefined reference to `Icicle::ptr_add(void*, unsigned long)'
/usr/bin/ld: lib/libIcicleMain.so: undefined reference to `Icicle::ptr_subtract(void*, unsigned long)'
/usr/bin/ld: lib/libIcicleMain.so: undefined reference to `Icicle::alignForwardAdjustmentWithHeader(void*, unsigned char)'
/usr/bin/ld: lib/libIcicleMain.so: undefined reference to `Icicle::MemoryManager::instancePtr'
collect2: error: ld returned 1 exit status
make[2]: *** [CMakeFiles/TestInstantiator.dir/build.make:98: bin/TestInstantiator] Error 1
make[1]: *** [CMakeFiles/Makefile2:111: CMakeFiles/TestInstantiator.dir/all] Error 2
make: *** [Makefile:136: all] Error 2

```

I noticed a couple brackets meant to be squiggly brackets but otherwise my cmakelists is similar to before:

```auto
file(GLOB HEADER_FILES "${CMAKE_SOURCE_DIR}/Main/src/*.h")
list(APPEND HEADER_FILES 
    "${CMAKE_SOURCE_DIR}/Main/Math/IcicleMath.h"
    "${CMAKE_SOURCE_DIR}/Main/Memory/Allocator.h"
    "${CMAKE_SOURCE_DIR}/Main/Memory/StackAllocator.h"
    "${CMAKE_SOURCE_DIR}/Main/Memory/MemoryManager.h"
    "${CMAKE_SOURCE_DIR}/Main/Resources/Resource.h"
)

file(GLOB SOURCE_FILES "${CMAKE_SOURCE_DIR}/Main/src/*.cpp")
list(APPEND SOURCE_FILES
"${CMAKE_SOURCE_DIR}/Main/Math/IcicleMath.cpp"
"${CMAKE_SOURCE_DIR}/Main/Memory/Allocator.cpp"
"${CMAKE_SOURCE_DIR}/Main/Memory/StackAllocator.cpp"
"${CMAKE_SOURCE_DIR}/Main/Memory/MemoryManager.cpp"
)

add_library(IcicleMain SHARED ${HEADER_FILES} ${SOURCE_FILES})

target_include_directories(IcicleMain PUBLIC
"${CMAKE_CURRENT_SOURCE_DIR}/Main/src" 
"${CMAKE_CURRENT_SOURCE_DIR}/Main/Math" 
"${CMAKE_CURRENT_SOURCE_DIR}/Main/Memory" 
"${CMAKE_CURRENT_SOURCE_DIR}/Main/Resources")

install(FILES ${HEADER_FILES} DESTINATION include/Icicle)

add_executable(TestInstantiator Tests/Main/TestInstantiator.cpp )

target_link_libraries(TestInstantiator IcicleMain)
# target_link_libraries(TestInstantiator vtkCommon)

add_test(NAME TestInstantiator
         COMMAND TestInstantiator)

```

---

<div class="post-metadata">

**Author:** ![ben.boeckel](https://discourse.cmake.org/letter_avatar_proxy/v4/letter/b/ea5d25/32.png) [@ben.boeckel](https://discourse.cmake.org/u/ben.boeckel)\
**Post date:** [August 24, 2023, 12:10am UTC](https://discourse.cmake.org/t/cmake-project-not-linking-correctly/8806/9 "2023-08-24T00:10:08Z")

</div>

> [@Tmurdoch](#):
>
> ```auto
> /home/work/Projects/Icicle/Tests/Main/TestInstantiator.cpp:63: undefined reference to `Icicle::ptr_add(void*, unsigned long)'
> /usr/bin/ld: lib/libIcicleMain.so: undefined reference to `Icicle::ptr_subtract(void*, unsigned long)'
> /usr/bin/ld: lib/libIcicleMain.so: undefined reference to `Icicle::alignForwardAdjustmentWithHeader(void*, unsigned char)'
> /usr/bin/ld: lib/libIcicleMain.so: undefined reference to `Icicle::MemoryManager::instancePtr'
> 
> ```

These seem to just be unimplemented functions. Do you really have implementations of these in the sources? If so, are they added to the library?
