# CMake doesn't link the actual object to the resulting dll

**URL:** https://discourse.cmake.org/t/cmake-doesnt-link-the-actual-object-to-the-resulting-dll/1866
**Category:** Usage
**Created:** [September 20, 2020, 5:19am UTC](https://discourse.cmake.org/t/cmake-doesnt-link-the-actual-object-to-the-resulting-dll/1866 "2020-09-20T05:19:47Z")
**Posts on this page:** 3
**Page:** 1

<div class="post-metadata">

### Author: ![Coderx7](https://discourse.cmake.org/user_avatar/discourse.cmake.org/coderx7/32/837_2.png) [@Coderx7](https://discourse.cmake.org/u/Coderx7)
#### Post date: [September 20, 2020, 5:19am UTC](https://discourse.cmake.org/t/cmake-doesnt-link-the-actual-object-to-the-resulting-dll/1866/1 "2020-09-20T05:19:47Z")

</div>

I created a C++ library in visual studio and all is fine. However, I’m trying to convert the projects to CMake so I can build them on linux as well.  
The library in question is implemented as pimple (dont know if it makes any difference though just saying) and it looks like this :

```cpp
#ifndef BLINKER_H
#define BLINKER_H

/* If we are we on Windows, we want a single define for it.*/
#if !defined(_WIN32) && (defined( __WIN32__ ) || defined(WIN32) || defined( __MINGW32__ ))
#define _WIN32
#endif /* _WIN32 */

#if defined(_WIN32) && defined(_BLINKER_BUILD_DLL)
/* We are building DETECTOR as a Win32 DLL */
#define BLINKER_API __declspec(dllexport)
#elif defined(_WIN32) && defined(BLINKER_DLL)
/* We are calling DETECTOR as a Win32 DLL */
#define BLINKER_API __declspec(dllimport)
#elif defined( __GNUC__ ) && defined(_BLINKER_BUILD_DLL)
/* We are building DETECTOR as a shared / dynamic library */
#define BLINKER_API __attribute__ ((visibility("default")))
#else
/* We are building or calling DETECTOR as a static library */
#define BLINKER_API
#endif

#include <iostream>
#include <sstream>

#include <opencv2/core.hpp>
#include <opencv2/opencv.hpp>

using namespace std::chrono_literals;
typedef std::chrono::system_clock Time;

const int COUNT_VJ = 3;
const int ILS_DSM = 30;
const int ILS_DSM_EXT = 600;
const cv::Size ILF_SIZE = { 34, 26 };
const cv::Size ILF_SIZE_PROCESSED = { 41, 32 };
 
struct Info
{
	void CheckStatus()
	{
		//...
	}
    //...
};

class BlinkerImpl;

class BLINKER_API Blinker
{
public:
	Blinker(std::string path = "", std::string netPath = "");
	void main_op(cv::Mat& imgOrig, Info& inf, std::string sme = "IDLS_E5", bool show_debug_info = true);
	
	~Blinker();

private:
	BlinkerImpl* blinker;
};

#endif // !BLINKER_H

```

this is the cmake that I have written so far:

```cmake
cmake_minimum_required(VERSION 3.11)
project(Blinker)

set(CMAKE_CXX_STANDARD 17)

find_package(Torch REQUIRED)
find_package(OpenCV REQUIRED)

include_directories(D:/Codes/cpp/port/LibtorchPort/Dependencies/include ${TORCH_INCLUDE_DIRS} ${OpenCV_INCLUDE_DIRS})

# http://dlib.net/examples/CMakeLists.txt.html
add_subdirectory(C:/Users/User/Downloads/dlib-19.21_for_cmake/dlib-19.21 C:/Users/User/Downloads/dlib-19.21_for_cmake/dlib-19.21/build)     

set(BLINKER_SRC D:/Codes/cpp/port/LibtorchPort/Dependencies/include/Blinker/Blinker.cpp
)

add_library(
    Blinker_static
    ${BLINKER_SRC}
)
add_library(
    Blinker_dynamic
    SHARED
    ${BLINKER_SRC}
)

set(LIBS ${LIBS} ${TORCH_LIBRARIES} ${OpenCV_LIBS} dlib::dlib )
# Link
target_link_libraries(Blinker_static ${TORCH_LIBRARIES} ${OpenCV_LIBS} dlib::dlib)
target_link_libraries(Blinker_dynamic ${TORCH_LIBRARIES} ${OpenCV_LIBS} dlib::dlib)

```

When I run the cmake like this :

```auto
cmake -DCMAKE_PREFIX_PATH="$(python -c 'import torch.utils; print(torch.utils.cmake_prefix_path)');D:\External Libs\Opencv3.4.10_vc14_vc15\opencv3.4" ..

```

and then open the visual studio project and try to build everything, the build goes on smoothly and generates 4 files :  
Blinker\_dynamic.dll  
Blinker\_dynamic.exp  
Blinker\_dynamic.lib  
Blinker\_static.lib.

However, when I try to link a test application with the `Blinker_dynamic.dll` for example, I get linker errors as if the actual Blinker implementation is no where to be found:

```auto
Severity	Code	Description	Project	File	Line	Suppression State
Error	LNK2019	unresolved external symbol "public: void __cdecl Blinker::main_op(class cv::Mat &,struct Info &,class std::basic_string<char,struct std::char_traits<char>,class std::allocator<char> >,bool)" (?main_op@Blinker@@QEAAXAEAVMat@cv@@AEAUInfo@@V?$basic_string@DU?$char_traits@D@std@@V?$allocator@D@2@@std@@_N@Z) referenced in function "int__cdecl test1(void)" (?test1@@YAHXZ)	Blinker_dynamic_test	D:\Codes\cpp\port\LibtorchPort\Blinker_Test\build\Blinker_Test.obj	1	
Error	LNK2019	unresolved external symbol "public: __cdecl Blinker::Blinker(class std::basic_string<char,struct std::char_traits<char>,class std::allocator<char> >,class std::basic_string<char,struct std::char_traits<char>,class std::allocator<char> >)" (??0Blinker@@QEAA@V?$basic_string@DU?$char_traits@D@std@@V?$allocator@D@2@@std@@0@Z) referenced in function "int__cdecl test1(void)" (?test1@@YAHXZ)	Blinker_dynamic_test	D:\Codes\cpp\port\LibtorchPort\Blinker_Test\build\Blinker_Test.obj	1	
Error	LNK2019	unresolved external symbol "public: __cdecl Blinker::~Blinker(void)" (??1Blinker@@QEAA@XZ) referenced in function "int__cdecl test1(void)" (?test1@@YAHXZ)	Blinker_dynamic_test	D:\Codes\cpp\port\LibtorchPort\Blinker_Test\build\Blinker_Test.obj	1	
Error	LNK1120	3 unresolved externals	Blinker_dynamic_test	D:\Codes\cpp\port\LibtorchPort\Blinker_Test\build\Release\Blinker_dynamic_test.exe	1	

```

And when inspecting the dll itself, you can indeed see, there is no trace of the actual `Blinker.cpp` in it.

For the reference here is the `Blinker.dll` created inside visual studio:  
[![enter image description here](https://i.stack.imgur.com/KNRFl.png)](https://i.stack.imgur.com/KNRFl.png)

and here is the dll created using this cmake I posted above:

 ![](https://discourse.cmake.org/uploads/default/original/1X/4fb28e2eacdfc8d2fc4e3cf71443a3b0635523d1.png)

I must be doing something wrong, but I cant seem to figure it out! what am I missing here?

---

<div class="post-metadata">

### Author: ![craig.scott](https://discourse.cmake.org/user_avatar/discourse.cmake.org/craig.scott/32/20_2.png) [@craig.scott](https://discourse.cmake.org/u/craig.scott)
#### Post date: [September 20, 2020, 6:37am UTC](https://discourse.cmake.org/t/cmake-doesnt-link-the-actual-object-to-the-resulting-dll/1866/2 "2020-09-20T06:37:09Z")

</div>

Rather than manually implementing all that logic for working out whether you need to export the class symbols or not, I recommend you consider using the `GenerateExportHeader` module instead. It makes handling these things very straightforward and has the added benefit of broad platform/compiler support too. You can get a good introduction to this from the first part of my CppCon talk from last year:

> **[CppCon 2019: Deep CMake For Library Authors - Crascit](https://crascit.com/2019/10/16/cppcon-2019-deep-cmake-for-library-authors/)**
>
> This talk highlights key CMake features relevant to C++ cross-platform library authors, digging deeper into platform-specific quirks and conventions.

In your case, I think you’ll find that `BLINKER_API` is not being defined to what you expect when building your library. The logic for the preprocessor paths that would define it all rely on either `_BLINKER_BUILD_DLL` or `BLINKER_DLL` being defined, but I don’t see either of those being defined in your CMake source. Again, the `GenerateExportHeader` module takes care of that aspect for you too, so take a look at that and it should simplify this for you considerably.

---

<div class="post-metadata">

### Author: ![Coderx7](https://discourse.cmake.org/user_avatar/discourse.cmake.org/coderx7/32/837_2.png) [@Coderx7](https://discourse.cmake.org/u/Coderx7)
#### Post date: [September 20, 2020, 6:38am UTC](https://discourse.cmake.org/t/cmake-doesnt-link-the-actual-object-to-the-resulting-dll/1866/3 "2020-09-20T06:38:33Z")

</div>

Thanks a lot greatly appreciate your kind help.  
God bless you
