I am trying to link a static library to my main executable but I keep receiving the following error:
main.obj : error LNK2019: unresolved external symbol “void __cdecl HelloWorld(void)” (?HelloWorld@@
YAXXZ) referenced in function main [C:\Users\Shack\Desktop\Git\Projects\C_C++\Linking-static-librar
ies\build\Main.vcxproj]
C:\Users\Shack\Desktop\Git\Projects\C_C++\Linking-static-libraries\build\Debug\Main.exe : fatal err
or LNK1120: 1 unresolved externals [C:\Users\Shack\Desktop\Git\Projects\C_C++\Linking-static-librar
ies\build\Main.vcxproj]
Here is the configuration details:
– Building for: Visual Studio 16 2019
– Selecting Windows SDK version 10.0.19041.0 to target Windows 10.0.19045.
– The CXX compiler identification is MSVC 19.29.30147.0
– Detecting CXX compiler ABI info
– Detecting CXX compiler ABI info - done
– Check for working CXX compiler: C:/Program Files (x86)/Microsoft Visual Studio/2019/Community/VC/
Tools/MSVC/14.29.30133/bin/Hostx64/x64/cl.exe - skipped
– Detecting CXX compile features
– Detecting CXX compile features - done
– Configuring done
– Generating done
– Build files have been written to: C:/Users/Shack/Desktop/Git/Projects/C_C++/Linking-static-librar
ies/build
I am building on windows 10 with a cmake version of 3.25.0. The project has cmake build the main project and make build the static library.
My code is as follows:
--------->Cmake project:
CMakeLists.txt:
cmake_minimum_required (VERSION 3.8)
project (“Linking-static-libraries” LANGUAGES CXX)
add_executable (Main main.cpp)
target_link_libraries (Main C:/Users/Shack/Desktop/Git/Projects/C_C++/Linking-static-libraries-StaticHello.lib)
target_include_directories (Main PUBLIC C:/Users/Shack/Desktop/Git/Projects/C_C++/Linking-static-libraries)
main.cpp:
#include<iostream> #include “Hello.h”
using namespace std;
int main()
{
HelloWorld();
return 0;
}
--------->Makefile Project:
Makefile:
rebuild: clean all
all: Hello
Hello: Hello.cpp Hello.h
g++ -c Hello.cpp
ar rcs StaticHello.lib Hello.o
All files are in the same directory. With “make all”, and then “cmake -S . -B build” and then of course “cmake --build build”, The errors mentioned above are produced. Any ideas on the cause? and perhaps a solution? Thanks.
This is the same problem, but more convoluted.
Your static library make calls into the the C++ standard library. When building the library, the toolchain finds the appropriate symbols in the standard library provided by the compiler (libstdc++ for GCC).
However, when your main executable, the msvc toolchain brings its own standard library implementation, with differently named and differently mangled symbols.
It seems basically impossible (at least not without a lot of hacks) to use static libraries between different toolchains. Especially, when msvc is involved.
I have a compiler installed through msys that I use. Is there a simple way to switch from msvc to it and have cmake use it? Or perhaps just a resource to start.
Cmake detected MSVC 19 as your default C++ compiler. You can tell cmake to use a different C++ compiler by setting the CMAKE_CXX_COMPILER value to a different compiler, see CMAKE_CXX_COMPILER
There are three common ways to achieve this, either set the CXX environment variable before calling cmake, create a toolchain file containing CMAKE_CXX_COMPILER and pass it with -DCMAKE_TOOLCHAIN_FILE=path/to/file or simply pass -DCMAKE_CXX_COMPILER=path/to/compiler to your initial cmake call.
Take note that each of these approaches requires you to delete your current cmake cache beforehand