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 :
#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_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 :
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:
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:
and here is the dll created using this cmake I posted above:
I must be doing something wrong, but I cant seem to figure it out! what am I missing here?