Windows上的Cmake和dll/lib链接
我正在使用mingw和cmake在窗户上工作。
有人提供一个带有lib,dll和标头文件的库。我可以在Visual Studio项目中很容易使用它。但是我无法将其集成到CMAKE项目中。关于此主题已经有很多问题,但仅用于Linux,或使用CMAKE构建图书馆或可用来源的图书馆,或者与我相同的用例,但是在评论中有很多勘误表明答案是答案是永远不要完全正确...
我想在我的 foo 库中使用 foo_function 在我的 bar 项目中。我没有这个 foo 项目的来源。只有DLL,LIB和标题文件。
BarProject
├───
├─── CMakeLists.txt
├─── Foo
├─── include
└─── foo.h
├─── x64
|─── foo.dll
└─── foo.lib
└─── main_bar.c
这是我的 cmakelists.txt文件的内容:
cmake_minimum_required(VERSION 3.10)
# set the project name and version
project(bar VERSION 1.0)
# add the executable
add_executable(bar main_bar.c)
target_include_directories(bar PUBLIC "${PROJECT_BINARY_DIR}" "foo/include")
add_library(foo SHARED IMPORTED)
set_property(TARGET foo PROPERTY
IMPORTED_LOCATION "${CMAKE_SOURCE_DIR}/Foo/x64/foo.dll")
set_property(TARGET foo PROPERTY
IMPORTED_IMPLIB "${CMAKE_SOURCE_DIR}/Foo/x64/foo.lib")
target_link_libraries(bar PRIVATE foo)
set(CMAKE_VERBOSE_MAKEFILE ON)
set(CMAKE_SUPPRESS_REGENERATION true)
set_property(DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR} PROPERTY VS_STARTUP_PROJECT bar)
$ ls
main_bar.c CMakeLists.txt Foo
$ mkdir tutu
$ cd tutu
$ cmake .. && cmake --build . -v
-- Building for: Visual Studio 16 2019
-- Selecting Windows SDK version 10.0.19041.0 to target Windows 10.0.19044.
-- The C compiler identification is MSVC 19.29.30145.0
-- The CXX compiler identification is MSVC 19.29.30145.0
-- Detecting C compiler ABI info
-- Detecting C compiler ABI info - done
-- Check for working C compiler: C:/Program Files (x86)/Microsoft Visual Studio/2019/Community/VC/Tools/MSVC/14.29.30133/bin/Hostx64/x64/cl.exe - skipped
(...)
cl /c /IC:\Users\lambe\work\repository\bar\tutu /IC:\Users\lambe\work\repository\bar\. /IC:\Users\lambe\work\repository\bar\Foo\include/Wall /WX /diagnostics:column /Od /D _MBCS /D WIN32 /D _WINDOWS /D STAND_ALONE /D "CMAKE_INTDIR=\"Debug\"" /Gm- /MD /GS /fp:precise /Zc:wchar_t /Zc:forScope /Zc:inline /Fo"bar.dir\Debug\\" /Fd"bar.dir\Debug\vc142.pdb" /external:W4 /Gd /TC /wd4996 /wd4820 /wd5045 /wd4668 /errorReport:queue C:\Users\lambe\work\repository\bar\main_bar.c
main_bar.c
Generating Code...
Link:
C:\Program Files (x86)\Microsoft Visual Studio\2019\Community\VC\Tools\MSVC\14.29.30133\bin\HostX64\x64\link.exe /ERRORREPORT:QUEUE /OUT:"C:\Users\lambe\work\repository\bar\tutu\Debug\bar.exe" /INCREMENTAL /ILK:"bar.dir\Debug\bar.ilk" /NOLOGO ..\Foo\x64\foo.lib kernel32.lib user32.lib gdi32.lib winspool.lib shell32.lib ole32.lib oleaut32.lib uuid.lib comdlg32.lib advapi32.lib /MANIFEST /MANIFESTUAC:"level='asInvoker' uiAccess='false'" /manifest:embed /DEBUG /PDB:"C:/Users/lambe/work/repository/bar/tutu/Debug/bar.pdb" /SUBSYSTEM:CONSOLE /TLBID:1 /DYNAMICBASE /NXCOMPAT /IMPLIB:"C:/Users/lambe/work/repository/bar/tutu/Debug/bar.lib" /MACHINE:X64 /machine:x64 bar.dir\Debug\main_bar.obj
bar.dir\Debug\main_bar.obj
main_bar.obj : error LNK2019: unresolved external symbol foo_function referenced in function main [C:\Users\lambe\work\repository\bar\tutu\bar.vcxproj]
C:\Users\lambe\work\repository\bar\tutu\Debug\bar.exe : fatal error LNK1120: 1 unresolved externals [C:\Users\lambe\work\repository\bar\tutu\bar.vcxproj]
汇编步骤运行良好,问题在链接步骤中。
编辑:
确定在Ben Voigt的评论后,我选择探索使用Mingw中使用GCC/G ++编译器的解决方案,而不是使用CL/Visual Studio Thing。
新的测试过程:
$ cmake .. -G "MinGW Makefiles" && cmake --build . -v
(...)
C:\MinGW\bin\gcc.exe -DSTAND_ALONE @CMakeFiles/bar.dir/includes_C.rsp -MD -MT CMakeFiles/bar.dir/main_bar.c.obj -MF
CMakeFiles\bar.dir\main_bar.c.obj.d -o CMakeFiles\bar.dir\main_bar.c.obj -c C:\Users\lambe\work\repository\bar\main_bar.c
[100%] Linking C executable bar.exe
"C:\Program Files\CMake\bin\cmake.exe" -E cmake_link_script CMakeFiles\bar.dir\link.txt --verbose=1
"C:\Program Files\CMake\bin\cmake.exe" -E rm -f CMakeFiles\bar.dir/objects.a
C:\MinGW\bin\ar.exe qc CMakeFiles\bar.dir/objects.a @CMakeFiles\bar.dir\objects1.rsp
C:\MinGW\bin\gcc.exe -Wl,--whole-archive CMakeFiles\bar.dir/objects.a -Wl,--no-whole-archive -o bar.exe -Wl,--out-implib,libbar.dll.a -Wl,--major-image-version,0,--minor-image-version,0 @CMakeFiles\bar.dir\linklibs.rsp
CMakeFiles\bar.dir/objects.a(main_bar.c.obj):main_bar.c:(.text+0x4f4e): undefined reference to `foo_function'
collect2.exe: error: ld returned 1 exit status
CMakeFiles\bar.dir\build.make:830: recipe for target 'bar.exe' failed
mingw32-make.exe[2]: *** [bar.exe] Error 1
mingw32-make.exe[2]: Leaving directory 'C:/Users/lambe/work/repository/bar/test'
CMakeFiles\Makefile2:81: recipe for target 'CMakeFiles/bar.dir/all' failed
mingw32-make.exe[1]: *** [CMakeFiles/bar.dir/all] Error 2
mingw32-make.exe[1]: Leaving directory 'C:/Users/lambe/work/repository/bar/test'
Makefile:89: recipe for target 'all' failed
mingw32-make.exe: *** [all] Error 2
好的结果是相同的,但至少,命令行和工具对我来说更熟悉。 我在命令行中找不到对FOO库的任何引用。然后我检查文件linklibs.rsp,我们在这里:
$ cat CMakeFiles/bar.dir/linklibs.rsp
-lm *Foo/x64/foo.lib* -lkernel32 -luser32 -lgdi32 -lwinspool -lshell32 -lole32 -loleaut32 -luuid -lcomdlg32 -ladvapi32
这是预期的结果吗?
I am working on windows with mingw and CMake.
Someone provide a library with lib, dll and header files. I am able to use it quite easily in Visual Studio projects. But I was not able to integrate it into a CMake project. There are already a lot of questions about this topic but only working for Linux, or with library build with CMake, or library where sources are available, or the same use case as me but with a lot of erratum in comments saying that the answer is never completely correct...
I would like to use the foo_function from the foo library in my bar project. I don't have the source of this foo project. Only a dll, lib and header file.
BarProject
├───
├─── CMakeLists.txt
├─── Foo
├─── include
└─── foo.h
├─── x64
|─── foo.dll
└─── foo.lib
└─── main_bar.c
This is the content of my CmakeLists.txt file :
cmake_minimum_required(VERSION 3.10)
# set the project name and version
project(bar VERSION 1.0)
# add the executable
add_executable(bar main_bar.c)
target_include_directories(bar PUBLIC "${PROJECT_BINARY_DIR}" "foo/include")
add_library(foo SHARED IMPORTED)
set_property(TARGET foo PROPERTY
IMPORTED_LOCATION "${CMAKE_SOURCE_DIR}/Foo/x64/foo.dll")
set_property(TARGET foo PROPERTY
IMPORTED_IMPLIB "${CMAKE_SOURCE_DIR}/Foo/x64/foo.lib")
target_link_libraries(bar PRIVATE foo)
set(CMAKE_VERBOSE_MAKEFILE ON)
set(CMAKE_SUPPRESS_REGENERATION true)
set_property(DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR} PROPERTY VS_STARTUP_PROJECT bar)
Finally to test my work :
$ ls
main_bar.c CMakeLists.txt Foo
$ mkdir tutu
$ cd tutu
$ cmake .. && cmake --build . -v
-- Building for: Visual Studio 16 2019
-- Selecting Windows SDK version 10.0.19041.0 to target Windows 10.0.19044.
-- The C compiler identification is MSVC 19.29.30145.0
-- The CXX compiler identification is MSVC 19.29.30145.0
-- Detecting C compiler ABI info
-- Detecting C compiler ABI info - done
-- Check for working C compiler: C:/Program Files (x86)/Microsoft Visual Studio/2019/Community/VC/Tools/MSVC/14.29.30133/bin/Hostx64/x64/cl.exe - skipped
(...)
cl /c /IC:\Users\lambe\work\repository\bar\tutu /IC:\Users\lambe\work\repository\bar\. /IC:\Users\lambe\work\repository\bar\Foo\include/Wall /WX /diagnostics:column /Od /D _MBCS /D WIN32 /D _WINDOWS /D STAND_ALONE /D "CMAKE_INTDIR=\"Debug\"" /Gm- /MD /GS /fp:precise /Zc:wchar_t /Zc:forScope /Zc:inline /Fo"bar.dir\Debug\\" /Fd"bar.dir\Debug\vc142.pdb" /external:W4 /Gd /TC /wd4996 /wd4820 /wd5045 /wd4668 /errorReport:queue C:\Users\lambe\work\repository\bar\main_bar.c
main_bar.c
Generating Code...
Link:
C:\Program Files (x86)\Microsoft Visual Studio\2019\Community\VC\Tools\MSVC\14.29.30133\bin\HostX64\x64\link.exe /ERRORREPORT:QUEUE /OUT:"C:\Users\lambe\work\repository\bar\tutu\Debug\bar.exe" /INCREMENTAL /ILK:"bar.dir\Debug\bar.ilk" /NOLOGO ..\Foo\x64\foo.lib kernel32.lib user32.lib gdi32.lib winspool.lib shell32.lib ole32.lib oleaut32.lib uuid.lib comdlg32.lib advapi32.lib /MANIFEST /MANIFESTUAC:"level='asInvoker' uiAccess='false'" /manifest:embed /DEBUG /PDB:"C:/Users/lambe/work/repository/bar/tutu/Debug/bar.pdb" /SUBSYSTEM:CONSOLE /TLBID:1 /DYNAMICBASE /NXCOMPAT /IMPLIB:"C:/Users/lambe/work/repository/bar/tutu/Debug/bar.lib" /MACHINE:X64 /machine:x64 bar.dir\Debug\main_bar.obj
bar.dir\Debug\main_bar.obj
main_bar.obj : error LNK2019: unresolved external symbol foo_function referenced in function main [C:\Users\lambe\work\repository\bar\tutu\bar.vcxproj]
C:\Users\lambe\work\repository\bar\tutu\Debug\bar.exe : fatal error LNK1120: 1 unresolved externals [C:\Users\lambe\work\repository\bar\tutu\bar.vcxproj]
The compilation step is working great, the issue is during the linking step.
EDIT:
Ok after the comment from Ben Voigt, I choose to explore the solution to use the gcc/g++ compiler from mingw instead of using the CL/Visual Studio thing.
The new test procedure :
$ cmake .. -G "MinGW Makefiles" && cmake --build . -v
(...)
C:\MinGW\bin\gcc.exe -DSTAND_ALONE @CMakeFiles/bar.dir/includes_C.rsp -MD -MT CMakeFiles/bar.dir/main_bar.c.obj -MF
CMakeFiles\bar.dir\main_bar.c.obj.d -o CMakeFiles\bar.dir\main_bar.c.obj -c C:\Users\lambe\work\repository\bar\main_bar.c
[100%] Linking C executable bar.exe
"C:\Program Files\CMake\bin\cmake.exe" -E cmake_link_script CMakeFiles\bar.dir\link.txt --verbose=1
"C:\Program Files\CMake\bin\cmake.exe" -E rm -f CMakeFiles\bar.dir/objects.a
C:\MinGW\bin\ar.exe qc CMakeFiles\bar.dir/objects.a @CMakeFiles\bar.dir\objects1.rsp
C:\MinGW\bin\gcc.exe -Wl,--whole-archive CMakeFiles\bar.dir/objects.a -Wl,--no-whole-archive -o bar.exe -Wl,--out-implib,libbar.dll.a -Wl,--major-image-version,0,--minor-image-version,0 @CMakeFiles\bar.dir\linklibs.rsp
CMakeFiles\bar.dir/objects.a(main_bar.c.obj):main_bar.c:(.text+0x4f4e): undefined reference to `foo_function'
collect2.exe: error: ld returned 1 exit status
CMakeFiles\bar.dir\build.make:830: recipe for target 'bar.exe' failed
mingw32-make.exe[2]: *** [bar.exe] Error 1
mingw32-make.exe[2]: Leaving directory 'C:/Users/lambe/work/repository/bar/test'
CMakeFiles\Makefile2:81: recipe for target 'CMakeFiles/bar.dir/all' failed
mingw32-make.exe[1]: *** [CMakeFiles/bar.dir/all] Error 2
mingw32-make.exe[1]: Leaving directory 'C:/Users/lambe/work/repository/bar/test'
Makefile:89: recipe for target 'all' failed
mingw32-make.exe: *** [all] Error 2
Ok the result is the same but at least, the command line and tools are more familiar for me.
I cannot find any reference to the foo library in the command line. Then I check the file linklibs.rsp and here we are :
$ cat CMakeFiles/bar.dir/linklibs.rsp
-lm *Foo/x64/foo.lib* -lkernel32 -luser32 -lgdi32 -lwinspool -lshell32 -lole32 -loleaut32 -luuid -lcomdlg32 -ladvapi32
Is it the expected result?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论