2

I am using the CMAKE_MSVC_RUNTIME_LIBRARY option so that MSVC uses /MTd to statically link an executable.

CMakeLists.txt

    cmake_minimum_required (VERSION 3.15 FATAL_ERROR)
    cmake_policy(SET CMP0091 NEW)
    set(CMAKE_MSVC_RUNTIME_LIBRARY "MultiThreaded$<$<CONFIG:Debug>:Debug>")

    project ("cmaketoy")

    find_package(GDAL REQUIRED)
    add_executable (cmaketoy "cmaketoy.cpp" )
    target_include_directories(cmaketoy PUBLIC ${GDAL_INCLUDE_DIR})
    target_link_libraries(cmaketoy PRIVATE ${GDAL_LIBRARY})

cmaketoy.cpp

#include <iostream>
#include "gdal_priv.h"

int main() {
    std::cout << "Hello CMake.\n";
    GDALAllRegister();
    return 0;
}

CMakeSettings.json (Visual Studio specific configuration)

{
    "configurations": [
        {
            "name": "x64-Debug",
            "generator": "Ninja",
            "configurationType": "Debug",
            "inheritEnvironments": [ "msvc_x64_x64" ],
            "buildRoot": "${projectDir}\\out\\build\\${name}",
            "installRoot": "${projectDir}\\out\\install\\${name}",
            "cmakeCommandArgs": "",
            "buildCommandArgs": "-v",
            "ctestCommandArgs": "",
            "environments": [
                { "GDAL_ROOT": "C:\\OSGeo4W64" }
            ]
        }
    ]
}

Compiler output confirms that the MTd option is being used:

  [1/2] "C:\PROGRA~2\Microsoft Visual Studio\2019\Community\VC\Tools\MSVC\14.25.28610\bin\HostX64\x64\cl.exe"  
/nologo /TP  -IC:\OSGeo4W64\include /DWIN32 /D_WINDOWS /GR /EHsc /Zi /Ob0 /Od /RTC1 -MTd 
/showIncludes /FoCMakeFiles\cmaketoy.dir\cmaketoy.cpp.obj /FdCMakeFiles\cmaketoy.dir\ /FS -c ..\..\..\cmaketoy.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_exe --intdir=CMakeFiles\cmaketoy.dir --rc="C:\PROGRA~2\Windows Kits\10\bin\10.0.18362.0\x64\rc.exe" 
--mt="C:\PROGRA~2\Windows Kits\10\bin\10.0.18362.0\x64\mt.exe" --manifests  -- "C:\PROGRA~2\Microsoft Visual Studio\2019\Community\VC\Tools\MSVC\14.25.28610\bin\Hostx64\x64\link.exe" 
/nologo CMakeFiles\cmaketoy.dir\cmaketoy.cpp.obj  /out:cmaketoy.exe /implib:cmaketoy.lib /pdb:cmaketoy.pdb 
/version:0.0  /machine:x64 /debug /INCREMENTAL /subsystem:console  
C:\OSGeo4W64\lib\gdal_i.lib  kernel32.lib user32.lib gdi32.lib winspool.lib 
shell32.lib ole32.lib oleaut32.lib uuid.lib comdlg32.lib advapi32.lib && cd ."

But when I run the exe, it tries to locate gdal300.dll, which is not on the PATH, and fails with

The program '[19452] cmaketoy.exe' has exited with code -1073741515 (0xc0000135) 'A dependent dll was not found'.

What modifications are needed to create a standalone, statically linked executable?

Update

Digging some more, this issue is not specific to CMake, but rather relates to the way the GDAL library is built in OS4GeoW. I get the same problem using a normal Visual Studio solution without CMake.

I had assumed I could statically link to gdal_i.lib to create a standalone executable, but dumpbin /symbols gdal_i.lib is just a stub library that accompanies gdal300.dll (see here)

001 00000000 SECT2  notype       External     | __IMPORT_DESCRIPTOR_gdal300

See also this answer about the two types of .lib file.

hertzsprung
  • 9,445
  • 4
  • 42
  • 77

0 Answers0