Using wxWidgets with CMAKE and visual studio - c++

Every time I try to build my project with CMAKE having the wxWidgets as library I get a lot of linker errors LNK I even get two errors for just compiling my main.cpp that only includes this :
#include "wx/wx.h"
int main(){
return 0;
}
I just downloaded the source code of wxwidgets, put it in a lib folder and linked it with cmake
This is my CMakeLists.txt :
cmake_minimum_required(VERSION 3.10)
# set the project name
project(wxtest VERSION 1.0)
add_subdirectory(libs/wxWidgets)
add_executable(wx_test WIN32 src/main.cpp)
target_link_libraries(wx_test wx::net wx::core wx::base)
Here are the errors:
Error LNK1120 1 unresolved externals
Error LNK2019 unresolved external symbol WinMain referenced in function "int __cdecl invoke_main(void)" (?invoke_main##YAHXZ)
Is there anything wrong with linking the wxWidgets lib to my project ?

wxWidgets programs are compiled as GUI Win32 applications and so use WinMain() entry point by default, which you don't define.
The usual way to define it is by using wxIMPLEMENT_APP() macro, but you may also do it manually if you really need to -- but you must define it, one way or the other.

Related

CMake project cannot link with Boost.Test statically or dynamically

I am trying to setup a simple C++ project with CMake and Boost libraries (Boost.Test in this case). I am following this guide except trying to link statically: https://www.jetbrains.com/help/clion/boost-test-support.html. I have installed Boost using this guide: https://www.boost.org/doc/libs/1_73_0/more/getting_started/windows.html and successfully followed step 5 to generate the library binaries.
Using the below CMake configuration, I get this error when trying to build with cmake --build .:
test1.obj : error LNK2001: unresolved external symbol "public: virtual void __cdecl boost::unit_test::unit_test_log_t::test_start(unsigned long)" (?test_start#unit_test_log_t#unit_test#boost##UEAAXK#Z)
tests2.obj : error LNK2001: unresolved external symbol "public: virtual void __cdecl boost::unit_test::unit_test_log_t::test_start(unsigned long)" (?test_start#unit_test_log_t#unit_test#boost##UEAAXK#Z)
MSVCRTD.lib(exe_main.obj) : error LNK2019: unresolved external symbol main referenced in function "int __cdecl invoke_main(void)" (?invoke_main##YAHXZ)
CMakeLists.txt
cmake_minimum_required(VERSION 3.13)
project(cmake_boost_test)
set(CMAKE_CXX_STANDARD 14)
add_executable(cmake_boost_test main.cpp)
add_subdirectory(Boost_tests)
Boost_tests/CMakeLists.txt
set(Boost_DEBUG ON)
set(Boost_USE_STATIC_LIBS ON)
find_package(Boost REQUIRED COMPONENTS unit_test_framework)
include_directories(${Boost_INCLUDE_DIRS})
add_executable(Boost_Tests_run test1.cpp tests2.cpp)
target_link_libraries(Boost_Tests_run ${Boost_LIBRARIES})
Boost_tests/test1.cpp
#define BOOST_TEST_MAIN
#include <boost/test/unit_test.hpp>
Boost_tests/tests2.cpp
#include <boost/test/unit_test.hpp>
There are basically 3 steps:
building boost and the relevant libraries and their variant (see here for Boost.Test)
configure the project with CMake (an example here)
build the project
It seems like you have all the steps, but what makes things difficult is that those 3 steps are related and should be done in a coherent manner:
Step 1+2: if you are building specific variants of Boost (or Boost.Test) in step 1, you have to instruct CMake with that variant
Step 3: when you build your project, your code program should in some cases be build with defines that instruct what is the variant being built. For instance if you want to link with the shared library version of Boost.Test, you have to define BOOST_TEST_DYN_LINK (in the code before any include of Boost.Test or with target_compile_definitions(test_executable PRIVATE "BOOST_TEST_DYN_LINK=1"))
In the case of Boost.Test, there is another gotcha: on Windows there is the autolink feature that will instruct the linker to link automatically with one version of a .lib: this is something I usually disable by passing a define BOOST_ALL_NO_LIB.
If you are able to make CMake detect for Boost.Test, I would not bother at the beginning with all those linking issues and use the header variant for which no linking issue is involved.
Coming back to what you have currently:
the error Could NOT find Boost (missing: unit_test_framework) (found version 1.60.0") is related to step 1+2: CMake is unable to find the libraries with the configuration you are indicating. Sometimes you need to give more variables to CMake such that it finds the right libraries, but my guess is that you just did not build the shared variant (see here). For instance I use Boost_COMPILER and Boost_ARCHITECTURE sometimes.
Boost_USE_STATIC_LIBS is an instruction for CMake only: it will not enforce the compilation of your with the right defines.
If you post the error that you get with CMake by passing -DBoost_DEBUG=ON, we will be able to support you with more precision.

Unresolved external symbol with Catch library

I'm migrating some projects to use CMake build system. Now I'm adding project with some unit tests using the Catch library. It is header only library. The old Visual Studio project builds fine, but the new CMake project gives unresolved external symbol linker error. I have defined CATCH_CONFIG_MAIN in one of my source files. There are added all cpp files from other projects which are needed for the tests and all libraries on which other tested projects depend are linked. Despite this I have unresolved external symbol error only with generated from CMake project:
ChipCountTests.obj : error LNK2019: unresolved external symbol "public: __thiscall Catch::SourceLineInfo::SourceLineInfo(char const *,unsigned int)" (??0SourceLineInfo#Catch##QAE#PBDI#Z) referenced in function "void __cdecl `anonymous namespace'::`dynamic initializer for 'autoRegistrar1''(void)" (??__EautoRegistrar1#?A0xb4291ec5##YAXXZ)
1>FlyingChipRewardCalculatorUT.obj : error LNK2001: unresolved external symbol "public: __thiscall Catch::SourceLineInfo::SourceLineInfo(char const *,unsigned int)" (??0SourceLineInfo#Catch##QAE#PBDI#Z)
Obviously I'm missing to add some configuration from vcxproj to CMakeLists.txt but I'm currently can't figure it out.
In one of my files I have:
#define CATCH_CONFIG_MAIN
#include <catch.hpp>
but I also using CMake macro for adding precompiled header to the project:
add_precompiled_header (${TARGET_NAME}
${CMAKE_CURRENT_SOURCE_DIR}/StdAfx.h
${CMAKE_CURRENT_SOURCE_DIR}/StdAfx.cpp)
This macro forcefully includes precompiled header in all files, but in it I have #include <catch.hpp> without #define CATCH_CONFIG_MAIN which is needed by all files except one.
I added option to the macro to pass list of files in which not to be included precompiled header and this resolves the issue.
It's a little bit hard to deduce a concrete problem from the context you provided, but here is an official Catch instruction for CMake integration.
In my experience using it with Visual Studio - integration went smoothly.
When I try to use Catch with the Precompiled Header option enabled in my test project, I end up with linker errors LNK2019.
I still use stdafx.h in my project and disable the Precompiled header option in order for the project to build.
Right-click project -> Configuration Properties -> C/C++->Precompiled Headers -> Precompiled Header -> Not Using Precompiled Headers.
I have the same error and I solved it by linking the target to Catch2WithMain
target_link_libraries( ${PROJECT_TEST} Catch2 Catch2WithMain)
set_property(TARGET ${PROJECT_TEST} PROPERTY CXX_STANDARD 14)
set_property(TARGET ${PROJECT_TEST} PROPERTY CXX_EXTENSIONS OFF)

Link against a 3rd-party library with Visual Studio

I'm trying to create a .dll with Visual Studios 2013. The project includes libpq functionality.
Per other stackoverflow posts, and other sources I've found on the internet, I've (as far as I'm aware) correctly added the postgres lib and include directories to the project. However, when I go to build the project, it returns a number of "unresolved external symbol" errors.
My paths are C:\Program Files\PostresSQL\9.3\... so I have them surrounded by quotation marks in the Additional Library/Include Directory fields. I've included the libpq-fe.h header file in the project... I'm just not sure what I'm doing wrong.
Another note, I can compile a test program from the command line using g++ with the -I, -L, and -lpq flags, but I'm not sure how to compile to a .dll from the command line (plus it adds complexity that I just don't want to deal with).
These are the specific errors I'm getting:
1>sql_arma.obj : error LNK2001: unresolved external symbol _PQconnectdb
1>sql_arma.obj : error LNK2001: unresolved external symbol _PQstatus
1>sql_arma.obj : error LNK2001: unresolved external symbol _PQerrorMessage
1>sql_arma.obj : error LNK2001: unresolved external symbol _PQfinish
1>C:\Users\tills13\documents\visual studio 2013\Projects\sql_arma\Release\sql_arma.dll : fatal error LNK1120: 4 unresolved externals
I have, as suggested below, included #pragma comment(lib, "libpq.lib") in the source file for my project, I still receive these errors.
I've successfully compiled the sample program by setting these project properties:
Add <pgsql install path>\include and \lib to VC++ Directories->Include and ->Library, correspondingly
Add libpq.lib to Linker->Input->Additional dependencies
This is the standard way to reference 3rd-party libs. It's just that they recommend using environment variables for their "base dirs" to avoid patching the project when it's under a VCS.
To be able to run the app from VS (both with and without debugging), I also specified PATH=%PATH%;<pgsql install path>\bin in Debugging->Environment since this dir isn't in PATH on my system.
It's not sufficient add the postgres lib directory to the project, you must also add
reference to libpq.lib. Just add this line to one of your source .cpp files:
#pragma comment(lib, "libpq.lib")
As noted by Marco A. the library must match a program bitness (32 or 64 bit): if you build 32-bit DLL (referred as Win32) you must use 32 bit library; if 64-bit (x64) - 64-bit library.
I have also faced same issue. Then I realized that I was building my application as a 32bit. I changed the target of my application to x64 and it compiled successfully

boost LNK2019 error

I read through the boost documentation using the '5.3.4 Invoke b2' and followed up with forum threads that explained details of linking the boost library to the header and linker directories, in the boost help '4.1 Build From the Visual Studio IDE', and found this cool boost related wiki that explained the bjam.exe controls.
placed #include <boost/thread/thread.hpp> in the main.cpp
And, I get this linker error, and the existing help threads have identified the problem is with x64:
Directory path and x32/x64
unrelated to Visual studio
unresolved
The error:
error LNK2019: unresolved external symbol "class boost::system::error_category const & __cdecl boost::system::generic_category(void)" (?generic_category#system#boost##YAAEBVerror_category#12#XZ) referenced in function "void __cdecl boost::system::`dynamic initializer for 'posix_category''(void)" (??__Eposix_category#system#boost##YAXXZ) main.obj
error LNK2019: unresolved external symbol "class boost::system::error_category const & __cdecl boost::system::system_category(void)" (?system_category#system#boost##YAAEBVerror_category#12#XZ) referenced in function "void __cdecl boost::system::`dynamic initializer for 'native_ecat''(void)" (??__Enative_ecat#system#boost##YAXXZ) main.obj
they are similar, something about 'posix_category' and something about 'native_ecat'
So, I tried to build the x64 boost library, and found conflicting instructions on where to put these:
did not say "Note for x64 users: Add the address-model=64 option to bjam (after the threading argument) in order to build static libs with the 64-bit compiler."
cant find the link but one said to place x64 lib in the vs2008 bin?
Also, I tried changing the vs2008 configuration back to x32 -> solutionExplorer/solution_properties/configuration_manager/active_solution_platform - Win32, closed and reopened visual studio - relinked the additional directories C/C++/general and Linker/general to Boost/root and Boost/stage/lib - and it compiled without error.
My best guess at the b2 commands is --toolset=msvc-9.0 address-model=64 --build-type=complete --stagedir=lib\x64 stage
Please give concise instructions for how to build and install x64 version of boost on VS2008. Also, what was the wiki talking about for release and debug - they are not in Boost invocation?
use c++ 11
It more or less includes all the features of boost I wanted to use, also compiles in g++ without figuring out how to build the boost library on my university server and then reference into a remote g++ build - pretty much solved everything with that

OpenGL in Visual studio - Issues with GLEW

I'm currently following the openglbook.com tutorials (set up) (Tutorial) and have run into an issue fairly early on. I'm getting the following two errors:
1>main.obj : error LNK2019: unresolved external symbol __imp__glewGetErrorString#4 referenced in function _Initialize
1>main.obj : error LNK2019: unresolved external symbol __imp__glewInit#0 referenced in function _Initialize
I have downloaded and compiled freeglut 2.8.0 as well as the glew 1.9.0 binaries. I have copied the libs and includes to C:\Program Files (x86)\Microsoft SDKs\Windows\v6.0A\Lib and Include respectively.
The Lib and Include paths have also been added to my project properties under Additional Library/Include directories.
I have also defined glew32.lib and freeglut.lib in my linker->Input->Additional dependencies.
I have included GL/glew.h and GL/freeglut.h at the top of my main file.
What am I missing? Every other thread I've found has been solved by adding the directories to the project properties. Does anyone have any ideas?
This means that you try to use GLEW as a DLL (because your application looks for a name that begins with __imp, like "import" ), but you didn't built GLEW as a DLL (because otherwise it would work).
3 possible options :
Rebuild GLEW with the GLEW_BUILD preprocessor definition (Project->Properties->C++->Preprocessor->Additional definitions). Then rebuild your application.
Don't build GLEW at all. Simply put glew.c in your application's project. This is the easiest way.
(my favourite) Define GLEW_STATIC in your application's preprocessor definitions, and rebuild.