# Linking a prebuilt static library

**URL:** <https://discourse.cmake.org/t/linking-a-prebuilt-static-library/11199>\
**Category:** Code\
**Tags:** os:windows\
**Created:** [July 9, 2024, 2:36am UTC](https://discourse.cmake.org/t/linking-a-prebuilt-static-library/11199 "2024-07-09T02:36:43Z")\
**Posts on this page:** 6\
**Page:** 1

<div class="post-metadata">

**Author:** ![Shackster](https://discourse.cmake.org/letter_avatar_proxy/v4/letter/s/ecc23a/32.png) [@Shackster](https://discourse.cmake.org/u/Shackster)\
**Post date:** [July 9, 2024, 2:36am UTC](https://discourse.cmake.org/t/linking-a-prebuilt-static-library/11199/1 "2024-07-09T02:36:43Z")

</div>

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
> 
> clean:  
> rm StaticHello.lib  
> rm Hello.o

_ **Hello.h:** _

> void HelloWorld();

_ **Hello.cpp:** _

> #include `<iostream>`  
> #include “Hello.h”
> 
> using namespace std;
> 
> void HelloWorld()  
> {  
> cout \<\< “Hello World!!!” \<\< endl;  
> }

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.

---

<div class="post-metadata">

**Author:** ![fenrir](https://discourse.cmake.org/user_avatar/discourse.cmake.org/fenrir/32/734_2.png) [@fenrir](https://discourse.cmake.org/u/fenrir)\
**Post date:** [July 9, 2024, 6:18am UTC](https://discourse.cmake.org/t/linking-a-prebuilt-static-library/11199/2 "2024-07-09T06:18:11Z")

</div>

It may be because you’re using two different compilers, and they may have different rules for name mangling.

You either should use the same compiler for both parts, or export a C interface, which does not suffer from C++ mangling issues.

---

<div class="post-metadata">

**Author:** ![Shackster](https://discourse.cmake.org/letter_avatar_proxy/v4/letter/s/ecc23a/32.png) [@Shackster](https://discourse.cmake.org/u/Shackster)\
**Post date:** [July 9, 2024, 10:50am UTC](https://discourse.cmake.org/t/linking-a-prebuilt-static-library/11199/3 "2024-07-09T10:50:55Z")

</div>

Thank you for taking the time to have a look at this!

Based on what you have said, I thought to perhaps add an _extern “C”_ to the declaration in the header. I tried that and now get the following:

> StaticHello.lib(Hello.o) : error LNK2019: unresolved external symbol _ZStlsISt11char\_traitsIcEERSt1  
> 3basic\_ostreamIcT\_ES5\_PKc referenced in function HelloWorld [C:\Users\Shack\Desktop\Git\Projects\C_  
> C++\Linking-static-libraries\build\Main.vcxproj]  
> StaticHello.lib(Hello.o) : error LNK2019: unresolved external symbol \_ZNSolsEPFRSoS\_E referenced in  
> function HelloWorld [C:\Users\Shack\Desktop\Git\Projects\C\_C++\Linking-static-libraries\build\Main  
> .vcxproj]  
> StaticHello.lib(Hello.o) : error LNK2001: unresolved external symbol _ZSt4endlIcSt11char\_traitsIcEE  
> RSt13basic\_ostreamIT\_T0\_ES6_ [C:\Users\Shack\Desktop\Git\Projects\C\_C++\Linking-static-libraries\bu  
> ild\Main.vcxproj]  
> StaticHello.lib(Hello.o) : error LNK2001: unresolved external symbol \_ZSt4cout [C:\Users\Shack\Desk  
> top\Git\Projects\C\_C++\Linking-static-libraries\build\Main.vcxproj]  
> C:\Users\Shack\Desktop\Git\Projects\C\_C++\Linking-static-libraries\build\Debug\Main.exe : fatal err  
> or LNK1120: 4 unresolved externals [C:\Users\Shack\Desktop\Git\Projects\C\_C++\Linking-static-librar  
> ies\build\Main.vcxproj]

_ **Hello.h:** _ _edited_

> extern “C” {  
> void HelloWorld();  
> }

---

<div class="post-metadata">

**Author:** ![fenrir](https://discourse.cmake.org/user_avatar/discourse.cmake.org/fenrir/32/734_2.png) [@fenrir](https://discourse.cmake.org/u/fenrir)\
**Post date:** [July 9, 2024, 11:33am UTC](https://discourse.cmake.org/t/linking-a-prebuilt-static-library/11199/4 "2024-07-09T11:33:49Z")

</div>

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.

---

<div class="post-metadata">

**Author:** ![Shackster](https://discourse.cmake.org/letter_avatar_proxy/v4/letter/s/ecc23a/32.png) [@Shackster](https://discourse.cmake.org/u/Shackster)\
**Post date:** [July 9, 2024, 4:30pm UTC](https://discourse.cmake.org/t/linking-a-prebuilt-static-library/11199/5 "2024-07-09T16:30:30Z")

</div>

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.

---

<div class="post-metadata">

**Author:** ![Gulasch](https://discourse.cmake.org/letter_avatar_proxy/v4/letter/g/b3f665/32.png) [@Gulasch](https://discourse.cmake.org/u/Gulasch)\
**Post date:** [July 10, 2024, 11:59am UTC](https://discourse.cmake.org/t/linking-a-prebuilt-static-library/11199/6 "2024-07-10T11:59:14Z")

</div>

> [@Shackster](#):
>

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](https://cmake.org/cmake/help/latest/variable/CMAKE_LANG_COMPILER.html)  
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`](https://cmake.org/cmake/help/latest/manual/cmake.1.html#cmdoption-cmake-D) 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
