aboutsummaryrefslogtreecommitdiff
path: root/scripts/cmake/vcpkg_copy_pdbs.cmake
blob: 12154d91c4d94dd21e26c9abd3da7108d0962212 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
## # vcpkg_copy_pdbs
##
## Automatically locate pdbs in the build tree and copy them adjacent to all DLLs.
##
## ## Usage
## ```cmake
## vcpkg_copy_pdbs([BUILD_PATHS <${CURRENT_PACKAGES_DIR}/bin/*.dll> ...])
## ```
##
## ## Notes
## This command should always be called by portfiles after they have finished rearranging the binary output.
##
## ## Parameters
## ### BUILD_PATHS
## Path patterns passed to `file(GLOB_RECURSE)` for locating dlls.
##
## Defaults to `${CURRENT_PACKAGES_DIR}/bin/*.dll` and `${CURRENT_PACKAGES_DIR}/debug/bin/*.dll`.
##
## ## Examples
##
## * [zlib](https://github.com/Microsoft/vcpkg/blob/master/ports/zlib/portfile.cmake)
## * [cpprestsdk](https://github.com/Microsoft/vcpkg/blob/master/ports/cpprestsdk/portfile.cmake)
function(vcpkg_copy_pdbs)
    cmake_parse_arguments(_vcp "" "" "BUILD_PATHS" ${ARGN})
    
    if(NOT _vcp_BUILD_PATHS)
        set(
            _vcp_BUILD_PATHS
            ${CURRENT_PACKAGES_DIR}/bin/*.dll
            ${CURRENT_PACKAGES_DIR}/debug/bin/*.dll
        )
    endif()

    function(merge_filelist OUTVAR INVAR)
        set(MSG "")
        foreach(VAR ${${INVAR}})
            set(MSG "${MSG}    ${VAR}\n")
        endforeach()
        set(${OUTVAR} ${MSG} PARENT_SCOPE)
    endfunction()

    if(VCPKG_LIBRARY_LINKAGE STREQUAL dynamic AND NOT VCPKG_TARGET_IS_MINGW)
        file(GLOB_RECURSE DLLS ${_vcp_BUILD_PATHS})

        set(DLLS_WITHOUT_MATCHING_PDBS)

        set(PREVIOUS_VSLANG $ENV{VSLANG})
        set(ENV{VSLANG} 1033)

        foreach(DLL ${DLLS})
            execute_process(COMMAND dumpbin /PDBPATH ${DLL}
                            COMMAND findstr PDB
                OUTPUT_VARIABLE PDB_LINE
                ERROR_QUIET
                RESULT_VARIABLE error_code
            )

            if(NOT error_code AND PDB_LINE MATCHES "PDB file found at")
                string(REGEX MATCH '.*' PDB_PATH ${PDB_LINE}) # Extract the path which is in single quotes
                string(REPLACE ' "" PDB_PATH ${PDB_PATH}) # Remove single quotes
                get_filename_component(DLL_DIR ${DLL} DIRECTORY)
                file(COPY ${PDB_PATH} DESTINATION ${DLL_DIR})
            else()
                list(APPEND DLLS_WITHOUT_MATCHING_PDBS ${DLL})
            endif()
        endforeach()

        set(ENV{VSLANG} ${PREVIOUS_VSLANG})

        list(LENGTH DLLS_WITHOUT_MATCHING_PDBS UNMATCHED_DLLS_LENGTH)
        if(UNMATCHED_DLLS_LENGTH GREATER 0)
            merge_filelist(MSG DLLS_WITHOUT_MATCHING_PDBS)
            message(STATUS "Warning: Could not find a matching pdb file for:\n${MSG}")
        endif()
    endif()

endfunction()