Home > other >  How to link .pdbs to a project using CMake?
How to link .pdbs to a project using CMake?

Time:01-27

I've run into a problem that I cannot seem to find anywhere else. If there is a solution to this, please mark as a duplicate and link to the correct page.

I am compiling a program that Visual Studio complains about not finding the corresponding .pdb file:

foo.lib(func.obj) : Warning LNK4099: PDB 'foo.pdb' was not found with 'foo.lib(func.obj)' or at '<Source_DIR>\build\Debug\foo.pdb'; linking object as if no debug info.

So I found a helpful link here describing that installing the .pdb files is as simple as:

install(FILES $<TARGET_PDB_FILE:foo> DESTINATION ${CMAKE_INSTALL_BINDIR}/$<CONFIG> OPTIONAL)

So in my foo lib I have my CMakeLists.txt file set up as such:

cmake_minimum_required(VERSION 3.18)
project(foo)

include(GNUInstallDirs)
include(CMakePackageConfigHelpers)

set(version 1)

set(CMAKE_CXX_STANDARD 17)
set(CMAKE_CXX_STANDARD_REQUIRED True)

add_library(foo SHARED foo.hpp foo.cpp)

set_target_properties(foo PROPERTIES DEBUG_POSTFIX "d")

target_include_directories(foo
  PUBLIC 
  "$<BUILD_INTERFACE:${CMAKE_CURRENT_SOURCE_DIR}>"
  "$<INSTALL_INTERFACE:${CMAKE_INSTALL_INCLUDEDIR}>"
)

add_library(foo::foo ALIAS foo)

install(TARGETS foo
    EXPORT fooTargets
    LIBRARY DESTINATION ${CMAKE_INSTALL_LIBDIR}/$<CONFIG> 
    ARCHIVE DESTINATION ${CMAKE_INSTALL_LIBDIR}/$<CONFIG>
    RUNTIME DESTINATION ${CMAKE_INSTALL_BINDIR}/$<CONFIG> 
    INCLUDES DESTINATION ${CMAKE_INSTALL_INCLUDEDIR}
)

install(FILES foo.hpp DESTINATION ${CMAKE_INSTALL_INCLUDEDIR})

install(FILES $<TARGET_PDB_FILE:foo> DESTINATION ${CMAKE_INSTALL_BINDIR}/$<CONFIG> 
OPTIONAL)


install(EXPORT fooTargets
    FILE footargets.cmake
    NAMESPACE foo::
    DESTINATION ${CMAKE_INSTALL_LIBDIR}/cmake
)

# generate the version file for the config file
write_basic_package_version_file(
  "${CMAKE_CURRENT_BINARY_DIR}/fooConfigVersion.cmake"
  VERSION "${version}"
  COMPATIBILITY AnyNewerVersion
)

# create config file
configure_package_config_file(${CMAKE_CURRENT_SOURCE_DIR}/Config.cmake.in
  "${CMAKE_CURRENT_BINARY_DIR}/fooConfig.cmake"
  INSTALL_DESTINATION ${CMAKE_INSTALL_LIBDIR}/cmake
)

# install config files
install(FILES
      "${CMAKE_CURRENT_BINARY_DIR}/fooConfig.cmake"
      "${CMAKE_CURRENT_BINARY_DIR}/fooConfigVersion.cmake"
    DESTINATION ${CMAKE_INSTALL_LIBDIR}/cmake
)

# generate the export targets for the build tree
export(EXPORT fooTargets
   FILE "${CMAKE_CURRENT_BINARY_DIR}/cmake/footargets.cmake"
   NAMESPACE foo::
)

Which installs everything nicely into something like this:

InstallDir
-- include
-- bin
-- lib

However, when I link against foo in my CMakeLists.txt I get the warning that is provided above on how it cannot find the .pdb file. However, the .pdb file is living in the InstallDir -> bin -> food.pdb.

Is there a way to link to this using CMake? Or do I have to manually copy over the .pdb file into the Debug directory even before it exists? This is where I'm stuck and I'm not sure how to proceed. This is the current CMake file:

cmake_minimum_required(VERSION 3.18)

project(Test_foo)

set(CMAKE_CXX_STANDARD 17)
set(CMAKE_CXX_STANDARD_REQUIRED True)

set(foo_DIR ${CMAKE_CURRENT_LIST_DIR}/foo/lib/cmake)

find_package(foo 1 EXACT REQUIRED)

add_executable(Test_foo main.cpp)
target_link_libraries(Test_foo PUBLIC foo::foo)
set_property(TARGET Test_foo PROPERTY NO_SYSTEM_FROM_IMPORTED 1)

This will link happily. However, when I build I get the warning as described from above. I want to be able to point it to the .pdb file that is installed. However I am not sure how to do that. Any tips?

CodePudding user response:

The linker expects the .pdb to be next to the .lib.

When you link in a static library, its debug info is merged into the thing you're building. So you should put the .pdb next to the lib so the linker can find it.

When you link in a shared library, its debug info is not touched by the linker and should be next to the .dll, where the debugger will find it when debugging. So in this case it is better to have the .pdb in your bin folder – next to the dll.

  • Related