关于C#:无法在CMake中创建动态库并将其链接到另一个动态库?

Unable to create a dynamic library in CMake and link it against another dynamic library?

我目前正在努力开发使用不同库的Windows 10下的小型应用程序。首先,我想说我已经从事专业开发工作了很多年,但是我一直在不同的环境(主要是GNU / Linux和MacOS)上进行开发,而对于Windows而言,它始终比起工作的操作系统,更多的是游戏操作系统;既然Windows 10似乎更加开源友好,我想试一试,看看通过将WSL-2和vcpkg结合使用是否可以使我工作。因此,我认为使用allegro库开发一个简单的跨平台2D应用程序可能是一个好主意。

我使用Visual Studio 2019 Community Edition创建了一个新的CMake项目,并在项目本身内部设置了vcpkg克隆(我觉得这不是一个好主意,但我有点喜欢拥有一切都放在一个地方)。使用vcpkg,我安装了两个我想使用的库:allegro和sqlite3。两种安装都很好,实际上我对vcpkg感到很惊讶。

我设置了项目结构:由于这是一个模块化项目,因此我开始通过add_library(lib_name SHARED sources)函数在CMake中创建一堆共享库,最终得到的结构类似于以下内容:

1
2
3
4
5
6
7
8
9
10
11
12
project_root/CMakeLists.txt
project_root/src/main.cpp

project_root/core
project_root/core/CMakeLists.txt
project_root/core/include/core/bunch_of_headers.hpp
project_root/core/src/bunch_of_sources.cpp

project_root/model
project_root/model/CMakeLists.txt
project_root/model/include/model/bunch_of_headers.hpp
project_root/model/src/bunch_of_sources.cpp

以此类推..

project_root中的每个文件夹都包含一个模块,并且所有CMakeLists文件如下所示:

1
2
3
4
5
6
7
add_library(model SHARED all_the_source_files.cpp)

include(DeclareNewSharedLibrary)
declare_new_shared_library(model)

find_package(sqlite3 CONFIG REQUIRED)
target_link_libraries(model sqlite3)

其中declare_new_shared_library()在单独的cmake模块中定义为以下函数

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
function(declare_new_shared_library lib_name)
    message(STATUS"Declaring new library ${lib_name}")
    include(GenerateExportHeader)
    generate_export_header(${lib_name})

    target_include_directories(${lib_name}
        PUBLIC"${CMAKE_CURRENT_SOURCE_DIR}/include"
        PUBLIC"${CMAKE_CURRENT_BINARY_DIR}"
    )

    set_target_properties(${lib_name} PROPERTIES
        IMPORTED_IMPLIB"${CMAKE_CURRENT_BINARY_DIR}/${lib_name}.lib"
        IMPORTED_LOCATION"${CMAKE_CURRENT_BINARY_DIR}/${lib_name}.dll"
    )
endfunction(declare_new_shared_library)

到目前为止没有幻想。

现在,即使我将共享库链接到已通过vcpkg下载的库(如上例所示),每个模块都可以正常编译。 Windows上的ld正确输出所需的文件(.lib.dll),并按预期方式将它们复制到${CMAKE_RUNTIME_OUTPUT_DIRECTORY}中。

我在这里遇到的问题是,有一个库无法编译。 CMake文件与其他文件相同,除了我链接的是allegro库(已通过vcpkg像其他所有库一样安装)。这是用于比较的CMake文件:

1
2
3
4
5
6
7
add_library(core SHARED all_the_sources.cpp)

include(DeclareNewSharedLibrary)
declare_new_shared_library(core)

find_package(allegro CONFIG REQUIRED)
target_link_libraries(core allegro)

当我尝试直接(或通过依赖项系统)编译此目标时,出现以下错误

TL; DR:

1
2
C:\\Dev\\ConsultantLife\\msvcrtd.lib(exe_main.obj) : error LNK2019: unresolved external symbol main referenced in function"int __cdecl invoke_main(void)" (?invoke_main@@YAHXZ)
C:\\Dev\\ConsultantLife\\bin\\core.dll : fatal error LNK1120: 1 unresolved externals

这是勇敢者的加长版:

1
2
3
4
5
6
7
8
9
10
11
12
  Cleaning... 3 files.
  [1/2] C:\\PROGRA~2\\MICROS~1\\2019\\COMMUN~1\\VC\\Tools\\Llvm\\80D306~1.0\\bin\\clang-cl.exe  /nologo -TP -Dcore_EXPORTS -I..\\..\\..\\core\\include -Icore -I..\\..\\..\\vcpkg\\installed\\x64-windows\\include -m64 -fdiagnostics-absolute-paths  /DWIN32 /D_WINDOWS /W3 /GR /EHsc /MDd /Zi /Ob0 /Od /RTC1 /showIncludes /Focore\\CMakeFiles\\core.dir\\Game.cpp.obj /Fdcore\\CMakeFiles\\core.dir\\ -c ..\\..\\..\\core\\Game.cpp
  [2/2] cmd.exe /C"cd . &&"C:\\Program Files (x86)\\Microsoft Visual Studio\\2019\\Community\\Common7\\IDE\\CommonExtensions\\Microsoft\\CMake\\CMake\\bin\\cmake.exe" -E vs_link_dll --intdir=core\\CMakeFiles\\core.dir --rc=C:\\PROGRA~2\\WI3CF2~1\\10\\bin\\100183~1.0\\x64\
c.exe --mt=C:\\PROGRA~2\\WI3CF2~1\\10\\bin\\100183~1.0\\x64\\mt.exe --manifests  -- C:\\PROGRA~2\\MICROS~1\\2019\\COMMUN~1\\VC\\Tools\\MSVC\\1422~1.279\\bin\\Hostx64\\x64\\link.exe /nologo core\\CMakeFiles\\core.dir\\Game.cpp.obj  /out:bin\\core.dll /implib:core\\core.lib /pdb:bin\\core.pdb /dll /version:0.0 /machine:x64 /debug /INCREMENTAL  ..\\..\\..\\vcpkg\\installed\\x64-windows\\debug\\lib\\allegro-debug.lib kernel32.lib user32.lib gdi32.lib winspool.lib shell32.lib ole32.lib oleaut32.lib uuid.lib comdlg32.lib advapi32.lib  && cmd.exe /C"
cd /D C:\\Dev\\ConsultantLife\\out\\build\\x64-Debug\\core && powershell -noprofile -executionpolicy Bypass -file C:/Dev/ConsultantLife/vcpkg/scripts/buildsystems/msbuild/applocal.ps1 -targetBinary C:/Dev/ConsultantLife/out/build/x64-Debug/bin/core.dll -installedDir C:/Dev/ConsultantLife/vcpkg/installed/x64-windows/debug/bin -OutVariable out""
  FAILED: bin/core.dll core/core.lib
  cmd.exe /C"cd . &&"C:\\Program Files (x86)\\Microsoft Visual Studio\\2019\\Community\\Common7\\IDE\\CommonExtensions\\Microsoft\\CMake\\CMake\\bin\\cmake.exe" -E vs_link_dll --intdir=core\\CMakeFiles\\core.dir --rc=C:\\PROGRA~2\\WI3CF2~1\\10\\bin\\100183~1.0\\x64\
c.exe --mt=C:\\PROGRA~2\\WI3CF2~1\\10\\bin\\100183~1.0\\x64\\mt.exe --manifests  -- C:\\PROGRA~2\\MICROS~1\\2019\\COMMUN~1\\VC\\Tools\\MSVC\\1422~1.279\\bin\\Hostx64\\x64\\link.exe /nologo core\\CMakeFiles\\core.dir\\Game.cpp.obj  /out:bin\\core.dll /implib:core\\core.lib /pdb:bin\\core.pdb /dll /version:0.0 /machine:x64 /debug /INCREMENTAL  ..\\..\\..\\vcpkg\\installed\\x64-windows\\debug\\lib\\allegro-debug.lib kernel32.lib user32.lib gdi32.lib winspool.lib shell32.lib ole32.lib oleaut32.lib uuid.lib comdlg32.lib advapi32.lib  && cmd.exe /C"
cd /D C:\\Dev\\ConsultantLife\\out\\build\\x64-Debug\\core && powershell -noprofile -executionpolicy Bypass -file C:/Dev/ConsultantLife/vcpkg/scripts/buildsystems/msbuild/applocal.ps1 -targetBinary C:/Dev/ConsultantLife/out/build/x64-Debug/bin/core.dll -installedDir C:/Dev/ConsultantLife/vcpkg/installed/x64-windows/debug/bin -OutVariable out""
  LINK Pass 1: command"C:\\PROGRA~2\\MICROS~1\\2019\\COMMUN~1\\VC\\Tools\\MSVC\\1422~1.279\\bin\\Hostx64\\x64\\link.exe /nologo core\\CMakeFiles\\core.dir\\Game.cpp.obj /out:bin\\core.dll /implib:core\\core.lib /pdb:bin\\core.pdb /dll /version:0.0 /machine:x64 /debug /INCREMENTAL ..\\..\\..\\vcpkg\\installed\\x64-windows\\debug\\lib\\allegro-debug.lib kernel32.lib user32.lib gdi32.lib winspool.lib shell32.lib ole32.lib oleaut32.lib uuid.lib comdlg32.lib advapi32.lib /MANIFEST /MANIFESTFILE:core\\CMakeFiles\\core.dir/intermediate.manifest core\\CMakeFiles\\core.dir/manifest.res" failed (exit code 1120) with the following output:
     Creating library core\\core.lib and object core\\core.exp
C:\\Dev\\ConsultantLife\\msvcrtd.lib(exe_main.obj) : error LNK2019: unresolved external symbol main referenced in function"int __cdecl invoke_main(void)" (?invoke_main@@YAHXZ)
C:\\Dev\\ConsultantLife\\bin\\core.dll : fatal error LNK1120: 1 unresolved externals
  ninja: build stopped: subcommand failed.

现在,据我了解,链接器正在尝试将我的库链接为可执行文件,并且由于找不到main函数(是的,这是一个库,亲爱的..),它抱怨并给出了错误。

项目中其他库的编译具有完全相同的link.exe命令(除了系统库以外的其他库除外),并且不会失败。.

现在,我想问一问:我是否在做某些非常错误的事情,allegro-5.2中是否有错误(即使我看不到库如何查找主要方法以及链接器如何也可以) ..好吧,您明白我的意思了吗?还是我应该放弃一切?

在Allegro.cmake文件上可能有问题吗?我必须承认,我从来没有将CMake用于专业项目(我们仍然使用GNU Autotools,这是一堆老歌


通常情况下,我在寻求帮助后仅几分钟就找到了答案。

liballegro似乎试图找到一种主要方法,这就是链接失败的原因。

解决方案是将以下行添加到Allegro-config.cmake文件

1
target_compile_definitions(allegro INTERFACE ALLEGRO_NO_MAGIC_MAIN)