Windows上的Cmake和dll/lib链接

发布于 2025-02-07 04:31:28 字数 5730 浏览 4 评论 0原文

我正在使用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)
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]

汇编步骤运行良好,问题在链接步骤中。

编辑:

确定在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 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。
列表为空,暂无数据
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文