I am new to managed c++, cmake and need some help to get this going.
I am developing two managed/c++ libraries; A, and B, and want the second library
to use the first.
Whatever I try I get:
MyClassB.cpp.obj : error LNK2020: unresolved token (06000001) MyClassA::.ctor
Example managed code:
public ref class MyClassA
{
public:
MyClassA();
~MyClassA();
};
Example cmake file, library A
string(REPLACE "/RTC1" " " CMAKE_CXX_FLAGS_DEBUG "${CMAKE_CXX_FLAGS_DEBUG}")
string(REPLACE "/EHsc" "" CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS}")
SET(CMAKE_CXX_FLAGS_DEBUG "${CMAKE_CXX_FLAGS_DEBUG} /clr /EHa /MDd /GS")
SET(CMAKE_CXX_FLAGS_RELEASE "${CMAKE_CXX_FLAGS_RELEASE} /clr /EHa /MD /GS")
add_library(MyClassA MODULE MyClassA.cpp)
Example cmake file, library B
Similar to the one for library A, with this addition:
add_library(MyClassA MODULE IMPORTED)
If I uncomment the next line:
#target_link_libraries(MyClassB MyClassA)
I get this error:
Target "KM.Library.Types.Managedd" of type MODULE_LIBRARY may not be linked
into another target. One may link only to STATIC or SHARED libraries, ...
The code above is not the real code, I could not find a way to attach files :-(
Anyway, the task is simple enough I have two managed/c++ libraries and
want to link one to the other. The link step fails.
One other thing if I try dumpbin on library A, the EXPORTS/SYMBOLS section
is empty, is this correct ?
Regards,
Even
It seems using the /FU flag to the compiler solved the problem
Related
I'm using CMake to build a project that includes the spdlog library. At present, I'm doing so with Visual Studio, but I'm more used to Linux/GCC for what it's worth. Anyway, I'm having a heck of a time getting MSVC to treat spdlog as the external dependency that it is. Here's what I've got:
CMakeLists.txt from the root:
cmake_minimum_required(VERSION 3.16)
project(spdlogtest)
list(APPEND CMAKE_MODULE_PATH "${CMAKE_CURRENT_LIST_DIR}")
find_package(spdlog REQUIRED)
add_executable(
spdlogtest
main.cpp
)
target_include_directories(
spdlogtest SYSTEM PUBLIC
${spdlog_SOURCE_DIR}/include/
)
target_compile_options(
spdlogtest PUBLIC
/Od /EHsc /nologo /MP /sdl /Wall
/external:W0
)
target_compile_definitions(
spdlogtest PUBLIC
DEBUG
)
set_target_properties(
spdlogtest PROPERTIES
CXX_STANDARD 20
CXX_STANDARD_REQUIRED ON
BINARY_OUTPUT_DIRECTORY_DEBUG ${CMAKE_SOURCE_DIR}/debug/bin
BINARY_OUTPUT_DIRECTORY_DEBUG ${CMAKE_SOURCE_DIR}/release/bin
)
Findspdlog.cmake:
message(STATUS "Pulling in external spdlog")
include(FetchContent)
FetchContent_Declare(
spdlog
GIT_REPOSITORY https://github.com/gabime/spdlog.git
GIT_TAG eb3220622e73a4889eee355ffa37972b3cac3df5 # v1.9.2
)
FetchContent_MakeAvailable(spdlog)
And finally main.cpp is just the quickstart example from the GitHub page.
#include "spdlog/spdlog.h"
int main()
{
spdlog::info("Welcome to spdlog!");
spdlog::error("Some error message with arg: {}", 1);
spdlog::warn("Easy padding in numbers like {:08d}", 12);
spdlog::critical("Support for int: {0:d}; hex: {0:x}; oct: {0:o}; bin: {0:b}", 42);
spdlog::info("Support for floats {:03.2f}", 1.23456);
spdlog::info("Positional args are {1} {0}..", "too", "supported");
spdlog::info("{:<30}", "left aligned");
spdlog::set_level(spdlog::level::debug); // Set global log level to debug
spdlog::debug("This message should be displayed..");
// change log pattern
spdlog::set_pattern("[%H:%M:%S %z] [%n] [%^---%L---%$] [thread %t] %v");
// Compile time log levels
// define SPDLOG_ACTIVE_LEVEL to desired level
SPDLOG_TRACE("Some trace message with param {}", 42);
SPDLOG_DEBUG("Some debug message");
}
Basically, if I've got the compiler set to /W4, everything compiles without a hitch. If I set it to /Wall though, I get 100+ warnings that mostly seem to come from the libfmt included in spdlog. I've tried using an external libfmt, but achieve much the same result.
I prefer /Wall (and -pedantic) while I'm writing my own code. Holding other people to that standard is ridiculous though, so mark the fetched project as a system include and you're good, right? I certainly thought so.
The CMakeLists.txt from the root produces the massive warnings, as do the variations I've attempted. On the plus side, I think I'm better at CMake than I was when I started.
This suggestion worked for me some time in the past, but doesn't seem to affect behavior here. Adding the flag /external:I${spdlog_SOURCE_DIR}/include directly to target_compile_options() also doesn't affect anything. I also tried brute forcing it and using GLOB_RECURSE to mark all of the files in ${spdlog_SOURCE_DIR} as explicitly /W0 after fetching them, but no luck there either.
If anyone can point me in the right direction and explain why what I'm trying to do is failing, I'd be very grateful.
I have been working with WebRtc Development for the Windows Platform. I want to develop webrtc based desktop application. I am doing it from scratch for learning and better understanding.
The normal process of WebRtc Library Compilation:
I have initially started with (Getting Started with WinRTC). I followed the normal compilation process. After that, I have tried multiple ways to generate project files for webrtc such as;
1.Default
gn gen --ide=vs2019 out/Default
2.Custom Flags
gn gen --ide=vs2019 out/Default --args="use_rtti=true is_clang=false rtc_build_tools=false rtc_include_tests=false rtc_build_examples=false"
3.Custom Flags
gn gen --ide=vs2019 out\Default --filters=//:webrtc "--args=is_debug=true use_lld=false is_clang=false rtc_include_tests=true rtc_build_tools=true rtc_win_video_capture_winrt=true target_cpu=\"x86\" target_os=\"win\" rtc_build_examples=true rtc_win_use_mf_h264=true enable_libaom=true rtc_enable_protobuf=true"
For the building process, I have Followed these methods:
With command line:
Run the following command to build the patched WebRTC from the command line.
ninja -C out\Default\x64
With Visual Studio 2019:
Open the generated Visual Studio solution with the following command:
devenv out\Default\x64\all.sln
I have tried almost all available combinations to generate build files and to build webrtc.lib static library. I have successfully managed to compile the static webrtc library webrtc.lib for both architectures;
x64 (Default Arch) (For Debug as well as release)
x86 (Custom Arch) (For Debug as well as release)
IMPORTANT:
I have successfully managed to run peerconnection_server.exe and
peerconnection_client.exe on windows. These examples are
successfully running on localhost.
Using VS2019:
After that, I created a new Console based project using VS2019 to consume generated binaries and followed these steps;
Add include folders
Configuration Properties → C/C++ → General → Additional Include Directories and add the following paths:
c:\webrtc\src
c:\webrtc\src\out\Default\$(Configuration)\$(PlatformTarget)\gen
c:\webrtc\src\third_party\abseil-cpp
c:\webrtc\src\third_party\libyuv\include
Preprocessor macros:
Click on Preprocessor → Preprocessor Definitions and add the following definitions:
USE_AURA=1;_HAS_EXCEPTIONS=0;__STD_C;_CRT_RAND_S;_CRT_SECURE_NO_DEPRECATE;_SCL_SECURE_NO_DEPRECATE;_ATL_NO_OPENGL;_WINDOWS;CERT_CHAIN_PARA_HAS_EXTRA_FIELDS;PSAPI_VERSION=2;WIN32;_SECURE_ATL;WINUWP;__WRL_NO_DEFAULT_LIB__;WINAPI_FAMILY=WINAPI_FAMILY_PC_APP;WIN10=_WIN32_WINNT_WIN10;WIN32_LEAN_AND_MEAN;NOMINMAX;_UNICODE;UNICODE;NTDDI_VERSION=NTDDI_WIN10_RS2;_WIN32_WINNT=0x0A00;WINVER=0x0A00;NDEBUG;NVALGRIND;DYNAMIC_ANNOTATIONS_ENABLED=0;WEBRTC_ENABLE_PROTOBUF=0;WEBRTC_INCLUDE_INTERNAL_AUDIO_DEVICE;RTC_ENABLE_VP9;HAVE_SCTP;WEBRTC_LIBRARY_IMPL;WEBRTC_NON_STATIC_TRACE_EVENT_HANDLERS=0;WEBRTC_WIN;ABSL_ALLOCATOR_NOTHROW=1;HAVE_SCTP;WEBRTC_VIDEO_CAPTURE_WINRT
Linker additional library path:
Click on Linker → General → Additional Library Directories and add the following path:
c:\webrtc\src\out\Default\$(Configuration)\$(PlatformTarget)\obj
WebRTC library name:
Click on Input → Additional Dependencies and add the following filename:
webrtc.lib
Now, when I simply use this basic implementation such as;
#include <iostream>
#include "rtc_base/thread.h"
#include "rtc_base/logging.h"
#include "rtc_base/ssl_adapter.h"
#include "rtc_base/arraysize.h"
#include "rtc_base/net_helpers.h"
#include "rtc_base/string_utils.h"
#include "rtc_base/signal_thread.h"
int main(int argc, char** argv) {
rtc::InitializeSSL();
return 0;
}
The program is flooded with two types of errors:
1. LNK2038 mismatch detected for 'RuntimeLibrary': value 'MTd_StaticDebug' doesn't match value 'MDd_DynamicDebug'
and another one is
2. LNK2038 mismatch detected for '_ITERATOR_DEBUG_LEVEL': value '0' doesn't match value '2'
You can also see as given; Here I have used webrtc.lib with Configuration (Release) & Platform (x64).
Using Clion-2021.2.1 and CMAKE:
Here I have used webrtc.lib with Configuration (Release) & Platform (x86).
CMakeLists.txt is given as;
cmake_minimum_required(VERSION 3.20)
project(NewRtc)
set(CMAKE_CXX_STANDARD 14)
#set(CMAKE_CXX_FLAGS_RELEASE "${CMAKE_CXX_FLAGS_RELEASE} /MT")
#set(CMAKE_CXX_FLAGS_DEBUG "${CMAKE_CXX_FLAGS_DEBUG} /MTd")
include_directories(
"c:/webrtc/src"
"C:/webrtc/src/out/Default/x86/obj"
"c:/webrtc/src/third_party/abseil-cpp"
"c:/webrtc/src/third_party/libyuv/include"
)
# error LNK2038: mismatch detected for '_ITERATOR_DEBUG_LEVEL': value '0' doesn't match value '2' in main.obj
# Solution:
#1. _ITERATOR_DEBUG_LEVEL = 0 // disabled (for release builds)
#2. _ITERATOR_DEBUG_LEVEL = 1 // enabled (if _SECURE_SCL is defined)
#3. _ITERATOR_DEBUG_LEVEL = 2 // enabled (for debug builds)
add_definitions(
-D_ITERATOR_DEBUG_LEVEL=0
-DUSE_AURA=1
-D_HAS_EXCEPTIONS=0
-D__STD_C
-D_CRT_RAND_S
-D_CRT_SECURE_NO_DEPRECATE
-D_SCL_SECURE_NO_DEPRECATE
-D_ATL_NO_OPENGL
-D_WINDOWS
-DCERT_CHAIN_PARA_HAS_EXTRA_FIELDS
-DPSAPI_VERSION=2
-DWIN32
-D_SECURE_ATL
-DWINUWP
-D__WRL_NO_DEFAULT_LIB__
-DWINAPI_FAMILY=WINAPI_FAMILY_PC_APP
-DWIN10=_WIN32_WINNT_WIN10
-DWIN32_LEAN_AND_MEAN
-DNOMINMAX
-D_UNICODE
-DUNICODE
-DNTDDI_VERSION=NTDDI_WIN10_RS2
-D_WIN32_WINNT=0x0A00
-DWINVER=0x0A00
-DNDEBUG
-DNVALGRIND
-DDYNAMIC_ANNOTATIONS_ENABLED=0
-DWEBRTC_ENABLE_PROTOBUF=0
-DWEBRTC_INCLUDE_INTERNAL_AUDIO_DEVICE
-DRTC_ENABLE_VP9
-DHAVE_SCTP
-DWEBRTC_LIBRARY_IMPL
-DWEBRTC_NON_STATIC_TRACE_EVENT_HANDLERS=0
-DWEBRTC_WIN
-DABSL_ALLOCATOR_NOTHROW=1
-DHAVE_SCTP
-DWEBRTC_VIDEO_CAPTURE_WINRT)
#set(CMAKE_CXX_FLAGS_RELEASE "/MT")
#set(CMAKE_CXX_FLAGS_DEBUG "/MTd")
set(-Dwebrtc.lib)
add_executable(NewRtc main.cpp)
set_property(TARGET NewRtc PROPERTY
MSVC_RUNTIME_LIBRARY "MultiThreaded$<$<CONFIG:Debug>:Debug>")
target_link_libraries(NewRtc
PRIVATE "C:/webrtc/src/out/Default/x86/obj/webrtc.lib"
)
But when I simply build the project, this error comes up for every implementation of WebRtc. Here you can see:
Please assist me that how can I simply use webrtc library in any project on windows suing VS2019 or Clion. I am trying to solve these problems, I have tried multiple solutions over stack overflow and other communities using cmake or adding flags inside project properties such as;
Linker Tool Errors
/MD, /MT, /LD (Use Run-Time Library)
LNK2038 mismatch detected for '_ITERATOR_DEBUG_LEVEL': value '0' doesn't match value '2'
Mismatch Detected for 'RuntimeLibrary'
I have tried my best to explain the complete solution and associated problem so that someone might help me accordingly.
Well Guys, After spending almost 12 hours of research, I have made my day. I have exactly figured out what was wrong with my development setup in (VS2019/Clion) of using static webrtc.lib in executable projects.
I must thank Mr.#drescherjm for his support on my question. It's
really appreciated it.
All things were in a positive direction from library compilation to its usage in VS2019/Clion projects. Actually, webrtc development in .netCore projects required some useful libraries for the normal use of webrtc.lib in your projects.
Here is the list of libraries that you must use during development such as;
For Windows:
Required Modules for building WebRtc projects for Windows as follows;
WS2_32 secur32.lib winmm.lib dmoguids.lib wmcodecdspuuid.lib msdmo.lib Strmiids.lib
For Linux:
Required Modules for building WebRtc projects for Linux as follows;
Secur32 Msdmo Winmm Dmoguids wmcodecdspuuid
These are the important libraries as webrtc peer-to-peer communication mostly comes up with the extensive implementation of socket programming in C/C++ for both Linux as well as Windows Operating Systems.
How to use these libraries in projects:
using CmakeLists.txt
using #pragma keyword
For CMakeLists.txt:
You can simply include these modules in target_link_libraries() in which you are also linking webrtc.lib such as;
add_executable(NewRtc main.cpp)
set_property(TARGET NewRtc PROPERTY
MSVC_RUNTIME_LIBRARY "MultiThreaded$<$<CONFIG:Debug>:Debug>")
target_link_libraries(NewRtc
PRIVATE "{$LIB_PATH}/webrtc.lib"
# Required Modules for building projects
WS2_32 secur32.lib winmm.lib dmoguids.lib wmcodecdspuuid.lib msdmo.lib Strmiids.lib
)
For #Pragma Keyword:
You can directly include all the required libraries using the #pragma keyword inside your executable files (in my case main.cpp) such as;
# pragma comment(lib, "webrtc.lib")
# pragma comment(lib,"WS2_32")
# pragma comment(lib, "secur32.lib")
# pragma comment(lib, "winmm.lib")
# pragma comment(lib, "dmoguids.lib")
# pragma comment(lib, "wmcodecdspuuid.lib")
# pragma comment(lib, "msdmo.lib")
# pragma comment(lib, "Strmiids.lib")
Both procedures will 100% serve the same purpose. I hope it would help someone.
First of all I am complete new to C++, so if you know the answer please be patient with me ;). Here my problem:
I wanna solve an IP with Gurobi in a C++ Code. The Code itself seems fine since there are no expression marked as errors. However when I run the Code I get the following error report:
Undefined symbols for architecture x86_64:
and many lines like that:
"GRBLinExpr::GRBLinExpr(GRBVar, double)", referenced from:
bridge_problem::max_flow_lp(time_expanded_network&, lemon::ListDigraph&, lemon::DigraphExtender<lemon::ListDigraphBase>::ArcMap<int>&, lemon::DigraphExtender<lemon::ListDigraphBase>::ArcMap<int>&, lemon::DigraphExtender<lemon::ListDigraphBase>::NodeMap<int>&) in bridge_problem.cpp.o
I suppose that the mistake is in my CMakeList.txt file. This file was automatically created since I am using Clion and for including gurobi I entered those additional lines:
include_directories(/Library/gurobi604/mac64/include)
link_directories(/Library/gurobi604/mac64/lib/libgurobi_c++.a)
link_directories(/Library/gurobi604/mac64/lib/libgurobi60.so)
Any help is greatly appreciated and if you need any more information just let me know. (In case it is important I using a mac).
EDIT: I changed my make code since I found this one:
https://github.com/joschu/trajopt/blob/master/cmake/modules/FindGUROBI.cmake
I changed the version since I have gurobi604 but it still does not work. My new error message is:
fatal error: 'gurobi_c++.h' file not found #include "gurobi_c++.h"
I don't get it since I thought by
find_path(GUROBI_INCLUDE_DIR
NAMES gurobi_c++.h
PATHS "$ENV{GUROBI_HOME}/include"
"/Library/gurobi604/mac64/include"
"C:\\libs\\gurobi604\\include"
)
that should be easy to find. Any suggestion?
From the small excerpt of your CMakeLists.txt, I expect you should be using target_link_libraries rather than link_directories.
I'd normally recommend linking to the static version of any library rather than the shared if possible (i.e. in this case prefer "libgurobi_c++.a" over "libgurobi60.so" assuming they're the same library, just compiled differently).
So, if your exe is called MyExe, you could do:
target_link_libraries(MyExe /Library/gurobi604/mac64/lib/libgurobi_c++.a)
Also, it's almost always best to avoid specifying hard-coded paths in your CMakeLists.txt. Although your copy of "libgurobi_c++.a" lives in "/Library/gurobi604/mac64/lib/", that won't be the case for other users, or on different platforms.
You can avoid this by having CMake "find" the library, for example by calling find_library:
find_library(Gurobi NAMES gurobi_c++)
if(NOT Gurobi)
message(FATAL_ERROR "Failed to find Gurobi lib. Try setting CMAKE_PREFIX_PATH")
endif()
target_link_libraries(MyExe ${Gurobi})
Then, when you run CMake, you just need to tell it where the Gurobi library is. I'm not sure how you do that in CLion, but for example if you were running CMake from the command line, you'd do:
cmake . -DCMAKE_PREFIX_PATH=/Library/gurobi604/mac64
I am trying to migrate my Qt project from QMake to CMake but I am getting some errors when trying to build my library on Windows 7 with MSVC10. My CMakeLists.txt files is as follows:
cmake_minimum_required( VERSION 2.8.11 )
project( MyLibrary )
find_package(Qt4 REQUIRED)
set( CMAKE_AUTOMOC ON )
set( QT_USE_QTSCRIPT TRUE )
include( ${QT_USE_FILE} )
include_directories( ${CMAKE_CURRENT_BINARY_DIR}/include ${QT_INCLUDES} )
set( MyLibrary_SOURCES
src/connection.cpp
src/mylibrary.cpp
src/node.cpp
src/socket.cpp
include/connection.h
include/mylibrary.h
include/node.h
include/socket.h
include/MyLibrary_global.h
)
add_library(MyLibrary SHARED ${MyLibrary_SOURCES})
target_link_libraries(MyLibrary ${QT_LIBRARIES} )
When I run I try to build with the generated nmake Makefile I get the following errors:
C2491:'Connection::staticMetaObjectExtraData' : definition of dllimport static data member not allowed
C2491: 'Connection::staticMetaObject' : definition of dllimport static data member not allowed
I'm new to CMake so I'm not sure if I'm missing something in the CMakeLists.txt file or if there are more tricks to using it with Qt. I should mention that the files that are getting the errors are the MOC generated ones.
Edit:
So the output of
message(${QT_INCLUDES})
is as follows (formatting is for readability):
C:/Qt/4.8.3/include/QtDesigner
C:/Qt/4.8.3/include/QtDeclarative
C:/Qt/4.8.3/include/QtScriptTools
C:/Qt/4.8.3/include/QtDBus
C:/Qt/4.8.3/include/QtDesigner
C:/Qt/4.8.3/include/QtXml
C:/Qt/4.8.3/include/QtSql
C:/Qt/4.8.3/include/QtOpenGL
C:/Qt/4.8.3/include/QtMultimedia
C:/Qt/4.8.3/include/QtNetwork
C:/Qt/4.8.3/include/phonon
C:/Qt/4.8.3/include/QtXmlPatterns
C:/Qt/4.8.3/include/QtWebKit
C:/Qt/4.8.3/include/QtHelp
C:/Qt/4.8.3/include/QtUiTools
C:/Qt/4.8.3/include/QtTest
C:/Qt/4.8.3/include/QtScript
C:/Qt/4.8.3/include/QtSvg
C:/Qt/4.8.3/include/Qt3Support
C:/Qt/4.8.3/include/QtGui
C:/Qt/4.8.3/include/QtCore
C:/Qt/4.8.3/mkspecs/default
C:/Qt/4.8.3/include
C:/Qt/4.8.3/include/QtCore
I made tried not using auto-moc but I still get the same result and errors.
Reading this: Export QObject-based class to DLL I found what's wrong:
In .pro file I had the following:
DEFINES +=APPLETTUTORIAL1_LIBRARY
Then in applet-tutorial1_global.h I have:
#if defined(APPLETTUTORIAL1_LIBRARY)
# define APPLETTUTORIAL1SHARED_EXPORT Q_DECL_EXPORT
#else
# define APPLETTUTORIAL1SHARED_EXPORT Q_DECL_IMPORT
#endif
#endif // APPLETTUTORIAL1_GLOBAL_H
Since I didn't have the equivalent in CMakeLists.txt the compiler goes to the
# define APPLETTUTORIAL1SHARED_EXPORT Q_DECL_IMPORT
line rather than the expected one:
# define APPLETTUTORIAL1SHARED_EXPORT Q_DECL_EXPORT
So my solution was to leave only this line and my shared library built well!
# define APPLETTUTORIAL1SHARED_EXPORT Q_DECL_EXPORT
I tried the folllowing in CMakeLists.txt after reading this:http://www.cmake.org/Wiki/CMake:ConvertFromQmake but I did it wrong I think, thus the solution above.
SET(DEFINES "APPLETTUTORIAL1_LIBRARY")
Most of
http://www.cmake.org/cmake/help/v3.0/manual/cmake-qt.7.html
applies to CMake 2.8.11 too. Use imported targets, not the Use file.
Ok, I have 3 Ideas, not sure if they lead to a solution, but it could work.
First of all, what is in ${QT_INCLUDES}? Add some message(${QT_INCLUDES}) please and share the output.
The second Idea would be to mock manually, as the error orrurs in the mock. For this try to remove the set( CMAKE_AUTOMOC ON ) and add:
set(QT_USE_QTUITOOLS true)
QT4_WRAP_UI(UI UiFiles.ui)
QT4_WRAP_CPP(MOC3 QObjectFiles.h)
add_library(..........
${UI}
${MOC3})
My third idea is to remove the SHARED, maybe this causes the error, but I am not sure on that one.
Please share what you get and I'll try to help :)
I don't have enough reputation to add a comment so I have to write an answer...
Same problem but Qt4.8.5 here.
Keep using CMAKE_AUTOMOC because QT4_WRAP_CPP is the old way of doing... I found this : http://plagatux.es/2012/12/qt-automoc-with-cmake/
When I used old way, I got the same linkage error you had. With AUTOMOC I get other linkage /compilation errors but think I can go further:
applettutorial1.cpp.obj : error LNK2019: unresolved external symbol "__declspec(dllimport) const tutorial1::AppletTutorial1::`vftable'{for `XAppletPlugin'}" (__imp_??_7AppletTutorial1#tutorial1##6BXAppletPlugin###) referenced in function "public: __cdecl tutorial1::AppletTutorial1::AppletTutorial1(void)" (??0AppletTutorial1#tutorial1##QEAA#XZ)
You might add this to your includes:
${QT_QTCORE_INCLUDE_DIR}
${QT_INCLUDE_DIR}
Hoping you solved and could give us feedback so this helps other people.
EDIT : in my case I solved the following errors to get a successful build:
correctly check CMAKE_BUILD_TYPE against "Debug" string, not "DEBUG" as I read here and there. RTFM.
build my lib as STATIC, not SHARED.
I am trying to port a big project from gcc (Linux) to msvc (windows), using cmake and boost libraries.
The project compile and runs fine for gcc but on msvc it returns the following error:
Dyna.obj : error LNK2019: unresolved external symbol "void __cdecl boost::throw_exception(class std::exception const &)" (?throw_exception#boost##YAXABVexception#std###Z) referenced in function "void __cdecl boost::asio::detail::do_throw_error(class boost::system::error_code const &,char const *)" (?do_throw_error#detail#asio#boost##YAXABVerror_code#system#3#PBD#Z)
I tried running a simple project using boost asio and it worked, which teorethically excludes boost build problems.
The CMakeLists.txt is as follows: (separated the parts of interest)
.
.
.
IF(WIN32)
# Flags para garantir a compilação em windows
SET(CMAKE_CXX_COMPILER icpl)
SET(TPN_WIN32 "/D WIN32")
SET(TPN_WIN32_LIB ws2_32.lib odbc32.lib odbccp32.lib)
SET(CMAKE_EXE_LINKER_FLAGS /NODEFAULTLIB:LIBC;LIBCMT)
ENDIF(WIN32)
# Comando para se livrar de warning sobre o caminho da library pthread
IF(COMMAND cmake_policy)
cmake_policy(SET CMP0003 NEW)
ENDIF(COMMAND cmake_policy)
# Configuracao do TPN REALTIME
# === inicio ===
IF (REALTIME_YES)
MESSAGE ("[TPN] REALTIME ENABLED")
set(Boost_ADDITIONAL_VERSIONS "1.45.0")
set(Boost_USE_MULTITHREAD ON)
set(Boost_USE_STATIC_LIBS ON)
FIND_PACKAGE( Boost "1.45.0" COMPONENTS system filesystem serialization program_options regex thread date_time REQUIRED)
FIND_PACKAGE( Threads REQUIRED )
set(HYDRO_CXX_FLAGS "-DREALTIME -DJOYSTICK")
set(HYDRO_CXX_LFLAGS ${Boost_LIBRARIES})
INCLUDE_DIRECTORIES(hydro)
INCLUDE_DIRECTORIES(${Boost_INCLUDE_DIR})
ENDIF (REALTIME_YES)
# === final ===
.
.
.
TARGET_LINK_LIBRARIES(Dyna
tpn
preadyn
${WHERE_PREA3D}
${WHERE_WAMIT_IO}
${WHERE_WAMIT_CONVERTER}
${WHERE_TECLINE}
${HYDRO_CXX_LFLAGS}
${TPN_WIN32_LIB}
)
Thanks in advance
Try to add the flag "/EHsc" into your TPN_WIN32 variable in cmake.
It seems that MSVC is not throwing exceptions and you need to enable it in your vcproj.
In my case, the /EHsc flag did not work. Turned out that BOOST_NO_EXCEPTIONS was defined so the compiler was searching for the "user defined" (as in boost/throw_exception.hpp) function.
Therefore, a quick fix is to write your favorite boost::throw_exception() function:
namespace boost
{
#ifdef BOOST_NO_EXCEPTIONS
void throw_exception( std::exception const & e ){
throw 11; // or whatever
};
#endif
}// namespace boost
Looks like, to be linking compatible, binary must have same structure exception handling enablement option. MSVC standard library implementation use structured exception handling option on. Looks like this is why boost::system also uses this on. You might see corresponding warnings telling you to add structure exception handling.
IF(MSVC)
ADD_DEFINITIONS("/EHsc")
ENDIF(MSVC)
When running on windows you need (by default) to link to boost.system and boost.regex
As it says here:
Note With MSVC or Borland C++ you may want to add
-DBOOST_DATE_TIME_NO_LIB and -DBOOST_REGEX_NO_LIB to your project
settings to disable autolinking of the Boost.Date_Time and Boost.Regex
libraries respectively. Alternatively, you may choose to build these
libraries and link to them.
If you don't want to link to other boost libraries then you can use the identical (non-boost) asio library from here.
In terms of your CMakeLists.txt file, you want a line such as
target_link_libraries (your_application ${Boost_LIBRARIES})
to actually link the library.
EDIT: also, have a look at How to link against boost.system with cmake, it could be that you have to specify the individual boost libraries specifically rather than ${Boost_LIBRARIES}