Issue
Enviroment:
- Windows 11 x64
- Msys2 with the mingw64 compiler
- VSCode
- CMAKE
I want to compile an executable so that I can give it to another device without having to deal with installing dependencies on that system.
I currently use cmake together with msys2, vscode and the mingw64 compiler. The Problem I am having is that when I currently compile, it seems like cmake only uses the .dll.a files, I installed with pacman, for linking. Thus it will not run on another system. When I try to change the CMakeLists.txt to link with a static library, it give me a linker error for every library I try it on.
The two questions I am having are:
- How do I get cmake to use the static variant of system libraries like libstdc++.dll
- How can I use the static library varient of a package I installed with pacman in msys2
CMakeLists.txt:
cmake_minimum_required(VERSION 3.26.4)
project(Project LANGUAGES C CXX)
set(CMAKE_CXX_STANDARD 17)
add_executable(Project main.cpp)
#set(CMAKE_FIND_DEBUG_MODE 1)
target_include_directories(Project PUBLIC C:/msys64/usr/include/curl)
target_include_directories(Project PUBLIC ${CMAKE_CURRENT_SOURCE_DIR}/include)
find_package(CURL REQUIRED)
#target_link_libraries(Project C:/msys64/mingw64/lib/libcurl.a) <-- Does not work, when building it gives me a linker error for every curl function in my project
target_link_libraries(Project ${CURL_LIBRARIES})
target_link_libraries(Project ${OpenSSL_LIBRARIES})
I have tried linking only with the commented out link_libraries command and removing the find packaged, however when I try to build it afterwards I get this linker error:
[main] Building folder: Proto
[build] Starting build
[proc] Executing command: C:\msys64\mingw64\bin\cmake.EXE --build c:/Users/user/Documents/project/Proto/build --config Debug --target all --verbose -j 10 --
[build] C:\msys64\mingw64\bin\cmake.exe -SC:\Users\user\Documents\project\Proto -BC:\Users\user\Documents\project\Proto\build --check-build-system CMakeFiles\Makefile.cmake 0
[build] C:\msys64\mingw64\bin\cmake.exe -E cmake_progress_start C:\Users\user\Documents\project\Proto\build\CMakeFiles C:\Users\user\Documents\project\Proto\build\\CMakeFiles\progress.marks
[build] C:/msys64/mingw64/bin/mingw32-make.exe -f CMakeFiles\Makefile2 all
[build] mingw32-make[1]: Entering directory 'C:/Users/user/Documents/project/Proto/build'
[build] C:/msys64/mingw64/bin/mingw32-make.exe -f CMakeFiles\Project.dir\build.make CMakeFiles/Project.dir/depend
[build] mingw32-make[2]: Entering directory 'C:/Users/user/Documents/project/Proto/build'
[build] C:\msys64\mingw64\bin\cmake.exe -E cmake_depends "MinGW Makefiles" C:\Users\user\Documents\project\Proto C:\Users\user\Documents\project\Proto C:\Users\user\Documents\project\Proto\build C:\Users\user\Documents\project\Proto\build C:\Users\user\Documents\project\Proto\build\CMakeFiles\Project.dir\DependInfo.cmake --color=
[build] mingw32-make[2]: Leaving directory 'C:/Users/user/Documents/project/Proto/build'
[build] C:/msys64/mingw64/bin/mingw32-make.exe -f CMakeFiles\Project.dir\build.make CMakeFiles/Project.dir/build
[build] mingw32-make[2]: Entering directory 'C:/Users/user/Documents/project/Proto/build'
[build] [ 50%] Building CXX object CMakeFiles/Project.dir/main.cpp.obj
[build] C:\msys64\mingw64\bin\g++.exe @CMakeFiles/Project.dir/includes_CXX.rsp -g -MD -MT CMakeFiles/Project.dir/main.cpp.obj -MF CMakeFiles\Project.dir\main.cpp.obj.d -o CMakeFiles\Project.dir\main.cpp.obj -c C:\Users\user\Documents\project\Proto\main.cpp
[build] [100%] Linking CXX executable Project.exe
[build] C:\msys64\mingw64\bin\cmake.exe -E cmake_link_script CMakeFiles\Project.dir\link.txt --verbose=1
[build] C:\msys64\mingw64\bin\cmake.exe -E rm -f CMakeFiles\Project.dir/objects.a
[build] C:\msys64\mingw64\bin\ar.exe qc CMakeFiles\Project.dir/objects.a @CMakeFiles\Project.dir\objects1.rsp
[build] C:\msys64\mingw64\bin\g++.exe -g -Wl,--whole-archive CMakeFiles\Project.dir/objects.a -Wl,--no-whole-archive -o Project.exe -Wl,--out-implib,libProject.dll.a -Wl,--major-image-version,0,--minor-image-version,0 @CMakeFiles\Project.dir\linkLibs.rsp
[build] C:/msys64/mingw64/bin/../lib/gcc/x86_64-w64-mingw32/13.1.0/../../../../x86_64-w64-mingw32/bin/ld.exe: CMakeFiles\Project.dir/objects.a(main.cpp.obj): in function `tokenRequests(char const*, std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> >*)':
[build] C:/Users/user/Documents/project/Proto/main.cpp:37: undefined reference to `__imp_curl_global_init'
[build] C:/msys64/mingw64/bin/../lib/gcc/x86_64-w64-mingw32/13.1.0/../../../../x86_64-w64-mingw32/bin/ld.exe: C:/Users/user/Documents/project/Proto/main.cpp:38: undefined reference to `__imp_curl_easy_init'
[build] C:/msys64/mingw64/bin/../lib/gcc/x86_64-w64-mingw32/13.1.0/../../../../x86_64-w64-mingw32/bin/ld.exe: C:/Users/user/Documents/project/Proto/main.cpp:48: undefined reference to `__imp_curl_easy_setopt'
[build] C:/msys64/mingw64/bin/../lib/gcc/x86_64-w64-mingw32/13.1.0/../../../../x86_64-w64-mingw32/bin/ld.exe: C:/Users/user/Documents/project/Proto/main.cpp:49: undefined reference to `__imp_curl_easy_setopt'
[build] C:/msys64/mingw64/bin/../lib/gcc/x86_64-w64-mingw32/13.1.0/../../../../x86_64-w64-mingw32/bin/ld.exe: C:/Users/user/Documents/project/Proto/main.cpp:50: undefined reference to `__imp_curl_easy_setopt'
[build] C:/msys64/mingw64/bin/../lib/gcc/x86_64-w64-mingw32/13.1.0/../../../../x86_64-w64-mingw32/bin/ld.exe: C:/Users/user/Documents/project/Proto/main.cpp:51: undefined reference to `__imp_curl_easy_setopt'
[build] C:/msys64/mingw64/bin/../lib/gcc/x86_64-w64-mingw32/13.1.0/../../../../x86_64-w64-mingw32/bin/ld.exe: C:/Users/user/Documents/project/Proto/main.cpp:53: undefined reference to `__imp_curl_easy_perform'
[build] C:/msys64/mingw64/bin/../lib/gcc/x86_64-w64-mingw32/13.1.0/../../../../x86_64-w64-mingw32/bin/ld.exe: C:/Users/user/Documents/project/Proto/main.cpp:55: undefined reference to `__imp_curl_easy_strerror'
[build] C:/msys64/mingw64/bin/../lib/gcc/x86_64-w64-mingw32/13.1.0/../../../../x86_64-w64-mingw32/bin/ld.exe: C:/Users/user/Documents/project/Proto/main.cpp:60: undefined reference to `__imp_curl_easy_cleanup'
[build] C:/msys64/mingw64/bin/../lib/gcc/x86_64-w64-mingw32/13.1.0/../../../../x86_64-w64-mingw32/bin/ld.exe: C:/Users/user/Documents/project/Proto/main.cpp:63: undefined reference to `__imp_curl_easy_cleanup'
[build] C:/msys64/mingw64/bin/../lib/gcc/x86_64-w64-mingw32/13.1.0/../../../../x86_64-w64-mingw32/bin/ld.exe: CMakeFiles\Project.dir/objects.a(main.cpp.obj): in function `main':
[build] C:/Users/user/Documents/project/Proto/main.cpp:268: undefined reference to `__imp_curl_global_cleanup'
[build] C:/msys64/mingw64/bin/../lib/gcc/x86_64-w64-mingw32/13.1.0/../../../../x86_64-w64-mingw32/bin/ld.exe: C:/Users/user/Documents/project/Proto/main.cpp:275: undefined reference to `__imp_curl_global_cleanup'
[build] C:/msys64/mingw64/bin/../lib/gcc/x86_64-w64-mingw32/13.1.0/../../../../x86_64-w64-mingw32/bin/ld.exe: C:/Users/user/Documents/project/Proto/main.cpp:297: undefined reference to `__imp_curl_global_cleanup'
[build] C:/msys64/mingw64/bin/../lib/gcc/x86_64-w64-mingw32/13.1.0/../../../../x86_64-w64-mingw32/bin/ld.exe: C:/Users/user/Documents/project/Proto/main.cpp:311: undefined reference to `__imp_curl_global_cleanup'
[build] collect2.exe: error: ld returned 1 exit status
[build] mingw32-make[2]: *** [CMakeFiles\Project.dir\build.make:100: Project.exe] Error 1
[build] mingw32-make[2]: Leaving directory 'C:/Users/user/Documents/project/Proto/build'
[build] mingw32-make[1]: Leaving directory 'C:/Users/user/Documents/project/Proto/build'
[build] mingw32-make[1]: *** [CMakeFiles\Makefile2:82: CMakeFiles/Project.dir/all] Error 2
[build] mingw32-make: *** [Makefile:90: all] Error 2
[proc] The command: C:\msys64\mingw64\bin\cmake.EXE --build c:/Users/user/Documents/project/Proto/build --config Debug --target all --verbose -j 10 -- exited with code: 2
[driver] Build completed: 00:00:04.819
[build] Build finished with exit code 2
Solution
To make sure that CMake uses libraries with MSYS2 here are a few things you can do;
- Linking Static System Libraries; You can force linkage by adding the flag;
set(CMAKE_EXE_LINKER_FLAGS " static libgcc static libstdc++")
Static Libraries, with Pacman; When installing libraries using
pacman
make sure you're getting the versions than just the import libraries (.dll.a
files). The static versions usually have the extension.a
without the.dll
prefix. In case you can't find the version throughpacman
consider building the library from source with linkage enabled.CMakeLists.txt Updates; check that you are linking against the libraries in your CMakeLists.txt file. The
find_package
command should automatically find the libraries if they are available. If not you might need to specify the path to the `file.
Also keep in mind that some libraries have dependencies on libraries. If you're linking statically ensure that all dependencies are also available, as libraries.
I hope these suggestions help!
Answered By - santranti Answer Checked By - Willingham (WPSolving Volunteer)