微信公众号搜"智元新知"关注
微信扫一扫可直接关注哦!

链接:致命错误 LNK1104:无法打开文件“external\jpeg-9d\Debug\jpeg.lib”

如何解决链接:致命错误 LNK1104:无法打开文件“external\jpeg-9d\Debug\jpeg.lib”

我通过 git 子模块包含 SDL 和 SDL_image 作为项目依赖项。 SDL_image 本身包含多个外部依赖项,包括有问题的 jpeg 库。整个项目结构如下所示:

│   CMakeLists.txt
├───build
├───src
└───external
    ├───SDL (git submodule)
    └───SDL_image (git submodule)
        │   CMakeLists.txt
        └───external
            ├───jpeg-9d
            ├───libpng-1.6.37
            ├───libwebp-1.0.3
            ├───tiff-4.2.0
            └───zlib-1.2.11

我正在使用以下顶级 CMakeLists.txt

cmake_minimum_required(VERSION 3.20)
project(GameTemplate    VERSION 1.0.0
                        LANGUAGES CXX)

# define common SOURCES variable as all files within src
file(GLOB_RECURSE SOURCES src/*)

# add main executable (entry point + SOURCES)
# in windows,WIN32 property adds /SUBSYstem:WINDOWS compiler flag 
# required for GUI applications
add_executable(${PROJECT_NAME} WIN32 ${SOURCES})

# SDL (shared only)
# NOTE: setting SDL_STATIC to ON has no effect on jpeg output,# it just prevents building the SDLstatic target unnecessarily
set(SDL_STATIC OFF CACHE BOOL "build SDL static lib" FORCE)
add_subdirectory(external/SDL EXCLUDE_FROM_ALL)
add_subdirectory(external/SDL_image EXCLUDE_FROM_ALL)

# includes
target_include_directories(GameTemplate
    PRIVATE external/SDL/include
    PRIVATE external/SDL_image
    PRIVATE src)

# linker
target_link_libraries(GameTemplate
    PRIVATE SDL2main
    PRIVATE SDL2
    PRIVATE SDL2_image)

以下构建步骤在 macOS 上成功:

$ cd build
$ cmake ..
$ make

尝试构建 SDL_image 目标时,等效的 MSVC 构建步骤失败并显示以下错误

$ cd build
$ cmake ..
$ MSBuild.exe .\GameTemplate.sln
...
Link:
  C:\Program Files (x86)\Microsoft Visual Studio\2019\BuildTools\VC\Tools\MSVC\14.29.30037\bin\HostX64\x64\link.exe /ERRORREPOR
  T:QUEUE /OUT:"C:\Users\colev\workspace\game-template\build\external\SDL_image\Debug\SDL2_image.dll" /INCREMENTAL /ILK:"SDL2_i
  mage.dir\Debug\SDL2_image.ilk" /NOlogo "external\jpeg-9d\Debug\jpeg.lib" "external\libpng-1.6.37\Debug\libpng16d.lib" ..\SDL\
  Debug\SDL2d.lib "external\zlib-1.2.11\Debug\zlibd.lib" kernel32.lib user32.lib gdi32.lib winspool.lib shell32.lib ole32.lib o
  leaut32.lib uuid.lib comdlg32.lib advapi32.lib /MANIFEST /MANIFESTUAC:"level='asInvoker' uiAccess='false'" /manifest:embed /D
  EBUG /PDB:"C:/Users/colev/workspace/game-template/build/external/SDL_image/Debug/SDL2_image.pdb" /SUBSYstem:CONSOLE /TLBID:1
  /DYNAMICBASE /NXCOMPAT /IMPLIB:"C:/Users/colev/workspace/game-template/build/external/SDL_image/Debug/SDL2_image.lib" /MACHIN
  E:X64  /machine:x64 /DLL SDL2_image.dir\Debug\IMG.obj
  SDL2_image.dir\Debug\IMG_png.obj
  SDL2_image.dir\Debug\IMG_bmp.obj
  SDL2_image.dir\Debug\IMG_gif.obj
  SDL2_image.dir\Debug\IMG_jpg.obj
  SDL2_image.dir\Debug\IMG_lbm.obj
  SDL2_image.dir\Debug\IMG_pcx.obj
  SDL2_image.dir\Debug\IMG_pnm.obj
  SDL2_image.dir\Debug\IMG_svg.obj
  SDL2_image.dir\Debug\IMG_tga.obj
  SDL2_image.dir\Debug\IMG_tif.obj
  SDL2_image.dir\Debug\IMG_webp.obj
  SDL2_image.dir\Debug\IMG_WIC.obj
  SDL2_image.dir\Debug\IMG_xcf.obj
  SDL2_image.dir\Debug\IMG_xpm.obj
  SDL2_image.dir\Debug\IMG_xv.obj
  SDL2_image.dir\Debug\IMG_xxx.obj
LINK : Fatal error LNK1104: cannot open file 'external\jpeg-9d\Debug\jpeg.lib' [C:\Users\me\workspace\game-template\build\ex
ternal\SDL_image\SDL2_image.vcxproj]

果然,那个文件不在build\external\SDL_image\external\jpeg-9d\Debug,只有.dll.lib 可用于所有其他 SDL_image 外部 deps...

$ ls build\external\SDL_image\external\jpeg-9d\Debug\
-a----          7/2/2021   2:19 PM         513024 jpeg.dll
-a----          7/2/2021   2:19 PM        1232896 jpeg.pdb

$ ls build\external\SDL_image\external\libpng-1.6.37\Debug\
-a----          7/2/2021   2:19 PM         423424 libpng16d.dll
-a----          7/2/2021   2:19 PM          33612 libpng16d.exp
-a----          7/2/2021   2:19 PM          56196 libpng16d.lib
-a----          7/2/2021   2:19 PM        1200128 libpng16d.pdb

如果我 cd 到 external\SDL_image\external\jpeg-9d\ 并自行构建 jpeg 它确实会生成一个 .lib 文件,但我对 windows 的理解是 .lib 可以是静态链接库或导出对应 .dll 的库。我假设在单独构建 jpeg 时我正在构建静态链接库,而我的主要构建实际需要的 .lib 是导出库。

如果是这种情况,为什么用 jpeg 构建时 BUILD_SHARED_LIBS 不也构建导出库?没有导出库的情况下构建 dll 是不是没用?

编辑:我刚刚发现这个答案表明如果库不导出任何符号,则不会生成 .lib 文件。我认为这不太可能,因为 jpeg 是一个流行的库,但有没有办法检查以确保? https://stackoverflow.com/a/7615698/1800023

EDIT2:我找到了 DUMPBIN 并确认 jpeg.dll 没有导出任何文件...怎么会这样?

EDIT3:禁用 JPG 会导致构建 SDL2_image.dll,但它也不会导出任何符号(导致主项目构建中的链接失败)。

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。