I am trying to build a library in both Windows and Linux using the following CMakeLists.txt
cmake_minimum_required(VERSION 3.26)
if (WIN32)
set(CMAKE_WINDOWS_EXPORT_ALL_SYMBOLS ON)
endif()
add_library(mylib)
set_property(TARGET mylib PROPERTY CXX_STANDARD 17)
target_sources(mylib PRIVATE "src/mylib.cpp" "src/mylib.h")
target_include_directories(mylib PUBLIC src)
target_include_directories(mylib PUBLIC ${R_INCLUDE_DIR})
target_link_directories(mylib PUBLIC ${R_LIB_DIR})
target_link_libraries(mylib PUBLIC ${R_LIB_FILES})
target_link_libraries(mylib PUBLIC other-imported-libs::other-imported-libs)
target_compile_definitions(mylib PUBLIC ${R_PREPROC_DEFS})
target_compile_options(mylib PUBLIC ${MY_COMPILE_OPTIMIZATION_LEVEL})
if(LINUX)
target_compile_options(mylib PUBLIC ${R_COMPILE_OPTIONS})
endif ()
if (MSVC)
set_property(TARGET mylib PROPERTY MSVC_RUNTIME_LIBRARY ${MY_MSVC_RT_LB})
target_link_options(mylib PUBLIC "/NODEFAULTLIB")
endif()
I am using the following toolchains for Windows and Linux:
"DCMAKE_TOOLCHAIN_FILE=/root/programs/vcpkg/scripts/buildsystems/vcpkg.cmake"
"-DCMAKE_TOOLCHAIN_FILE=C:\Dev\vcpkg\scripts\buildsystems\vcpkg.cmake"
My library is built successfully as a static library in both Windows and Linux using Visual Studio 20222 and GCC 11. other-imported-libs::other-imported-libs is also built as a SHARED library.
However, as soon as I change the library from static to shared by add_library(mylib SHARED), (I want the library to be a shared library), it fails in the linking stage with many errors.
Using MSVC, I get more than 10 errors of the following type:
error LNK2019: unresolved external symbol "__declspec(dllimport)
For example:
mylib.cpp.obj : error LNK2019: unresolved external symbol "__declspec(dllimport) public: class std::basic_ostream<char,struct std::char_traits<char> > * __cdecl std::basic_ios<char,struct std::char_traits<char> >::tie(void)const " (__imp_?tie@?$basic_ios@DU?$char_traits@D@std@@@std@@QEBAPEAV?$basic_ostream@DU?$char_traits@D@std@@@2@XZ) referenced in function "public: __cdecl std::basic_ostream<char,struct std::char_traits<char> >::sentry::sentry(class std::basic_ostream<char,struct std::char_traits<char> > &)" (??0sentry@?$basic_ostream@DU?$char_traits@D@std@@@std@@QEAA@AEAV12@@Z)
Using g++, I get the following warnings and errors:
/opt/rh/devtoolset-11/root/usr/libexec/gcc/x86_64-redhat-linux/11/ld: warning: alignment 8 of symbol `bio_lookup_lock' in /root/programs/vcpkg/installed/x64-linux/debug/lib/libcrypto.a(libcrypto-lib-bio_addr.o) is smaller than 32 in /mnt/c/Dev/myapp/external/packages/r/12.4.0.0/linux-gnu-3.10.0-x86_64/lib/libcrypto.a(b_addr.o)
/root/programs/vcpkg/buildtrees/openssl/x64-linux-dbg/../src/nssl-3.2.0-06d693f20a.clean/crypto/bio/bio_addr.c:53: multiple definition of `BIO_ADDR_new'; /mnt/c/Dev/myapp/external/packages/rithmic/12.4.0.0/linux-gnu-3.10.0-x86_64/lib/libcrypto.a(b_addr.o):b_addr.c:(.text+0x0): first defined here
...
Many more
...
collect2: error: ld returned 1 exit status
make[3]: *** [CMakeFiles/mylib.dir/build.make:119: lib/libmylib.so] Error 1
make[2]: *** [CMakeFiles/Makefile2:520: CMakeFiles/mylib.dir/all] Error 2
make[1]: *** [CMakeFiles/Makefile2:527: CMakeFiles/mylib.dir/rule] Error 2
make: *** [Makefile:283: mylib] Error 2
My C++ header file has the following defined and I export several classes in mylib.h.
#if defined(_MSC_VER)
// Microsoft
#define DllExport __declspec(dllexport)
#define DllImport __declspec(dllimport)
#elif defined(__GNUC__)
// GCC
#define DllExport __attribute__((visibility("default")))
#define DllImport
#else
#define DllExport
#define DllImport
#pragma warning Unknown dynamic link import/export semantics.
#endif
What could be wrong that is preventing a successful building of the shared library?