I am including SDL and SDL_image as project dependencies via git submodules. SDL_image contains multiple external dependencies itself, including the problematic jpeg
library. The overall project structure looks like this:
│ 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
I am using the following top level 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)
The following build steps are successful on macOS:
$ cd build
$ cmake ..
$ make
The equivalent MSVC build steps fail with the error below while attempting to build the SDL_image target
$ 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]
Sure enough, that file is not there in build\external\SDL_image\external\jpeg-9d\Debug
, only the .dll
. The .lib
is there for all the other SDL_image external deps though...
$ 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
If I cd into external\SDL_image\external\jpeg-9d\
and build jpeg by itself it does generate a .lib
file, but my understanding of windows is that .lib
can be either a static link libary OR an export library for a corresponding .dll
. I assume when building jpeg
by itself I am building the static link library, and the .lib
that my main build actually needs is the export library.
If this is the case, why doesn't jpeg
also build the export lib when built with BUILD_SHARED_LIBS
? Isn't building a dll kind of useless with no export lib?
EDIT: I just found this answer indicating .lib
files are not produced if a library does not export any symbols. I think that is unlikely since jpeg is a popular library, but is there a way I can check to be sure?
https://stackoverflow.com/a/7615698/1800023
EDIT2: I found DUMPBIN and confirmed that there are no files exported by jpeg.dll
... How could that be?
EDIT3: Disabling JPG results in building SDL2_image.dll
but it also exports no symbols (causing link failure in main project build).