Packaged static libraries in debug config cause "LNK4099: PDB 'somelib.pdb' was not found"
Given a trivial library:
#pragma once
int somefunc(int);
#include <somelib.h>
int somefunc(int input)
{
return input;
}
and a buildsystem to install it:
cmake_minimum_required(VERSION 3.14)
project(SomeLib)
# string(REPLACE "/Zi" "" CMAKE_CXX_FLAGS_DEBUG ${CMAKE_CXX_FLAGS_DEBUG})
add_library(somelib
somelib.cpp
)
target_include_directories(somelib PUBLIC
$<BUILD_INTERFACE:${CMAKE_CURRENT_SOURCE_DIR}>
$<INSTALL_INTERFACE:include>
)
# target_compile_options(somelib PUBLIC
# /PDBSTRIPPED:somelib_static.pdb /pdbpath:none
# )
# set_property(TARGET somelib
# PROPERTY STATIC_LIBRARY_OPTIONS
# /PDBSTRIPPED:somelib_static.pdb /pdbpath:none
# )
install(TARGETS somelib EXPORT somelib_exp
ARCHIVE DESTINATION lib
)
install(FILES
somelib.h
DESTINATION include
)
install(EXPORT somelib_exp
NAMESPACE NS::
DESTINATION lib/cmake/somelib_exp
FILE somelib_exp-config.cmake
)
Run the build/install commands:
PWD=C:\Users\Stephen\dev\src\playground\cmake\somelib\build
$ cmake .. -G "Visual Studio 14 2015 Win64" -DCMAKE_INSTALL_PREFIX=../../prefix
$ cmake --build . --config debug --target install
Then remove the build artifacts:
rd /s /q .
Removing the build artifacts is important because the installed artifacts contain absolute paths to the build artifacts to locate (compiler-)PDB files.
Removing the build artifacts models the case of creating an installer and moving it to another computer where the build artifacts are not reachable.
Then build a consumer to use somelib
:
#include <somelib.h>
int main(int argc, char** argv)
{
return somefunc(argc);
}
cmake_minimum_required(VERSION 3.14)
project(Consumer)
find_package(somelib_exp CONFIG REQUIRED)
add_executable(consumer
consumer.cpp
)
target_link_libraries(consumer PRIVATE NS::somelib)
PWD=C:\Users\Stephen\dev\src\playground\cmake\consumer\build
$ cmake .. -G "Visual Studio 14 2015" -A x64 -DCMAKE_PREFIX_PATH=%CD%/../../prefix
cmake --build .
Output:
Checking Build System
Building Custom Rule C:/Users/Stephen/dev/src/playground/cmake/consumer/CMakeLists.txt
consumer.cpp
somelib.lib(somelib.obj) : warning LNK4099: PDB 'somelib.pdb' was not found with 'somelib.lib(somelib.obj)' or at 'C:\Users\Stephen\dev\src\playground\cmake\consumer\build\Deb
ug\somelib.pdb'; linking object as if no debug info [C:\Users\Stephen\dev\src\playground\cmake\consumer\build\consumer.vcxproj]
The LNK4099
warning is a problem which should be resolved, rather than requiring the consumer to globally disable that warning.
The (compiler-)PDB files are not shipped because the library is proprietary.
The MSVC linker supports a /PDBSTRIPPED
option to produce stripped PDBs which are suitable for installing/shipping. However, as this case concerns static libraries, the MSVC linker is not in use. Similar options do not seem to be available for the compiler-PDB files.
CMake could expose a target property to suppress generation of compiler PDB files in the case of static libraries. Buildsystems of proprietary static libraries could then set the option to generate libraries which do not cause LNK4099.
Removing /Zi
from the CMAKE_CXX_FLAGS_DEBUG
is a seemingly working workaround.