Swift: support PDB emission with Swift

Swift supports CodeView/PDB for Windows (with active development ongoing
to make it the default). It is currently usable but does not have the
same fidelity as DWARF, but can be sufficient for many use cases. The
user is able to control this via flags. Wire up the necessary support to
allow `TARGET_PDB_FILE` to be used with Swift/Swift-only targets.
This commit is contained in:
Saleem Abdulrasool
2026-05-14 18:53:37 -07:00
committed by Brad King
parent 84a843cfb6
commit 404f6bac3c
12 changed files with 101 additions and 7 deletions

View File

@@ -0,0 +1,5 @@
swift-target-pdb-file
---------------------
* Swift targets on Windows now support the ``$<TARGET_PDB_FILE:...>``
family of generator expressions.

View File

@@ -130,7 +130,7 @@ if(CMAKE_Swift_COMPILATION_MODE_DEFAULT)
endif()
if(NOT CMAKE_Swift_CREATE_SHARED_LIBRARY)
set(CMAKE_Swift_CREATE_SHARED_LIBRARY "<CMAKE_Swift_COMPILER> ${CMAKE_Swift_PARALLEL_FLAGS} -emit-library <LANGUAGE_COMPILE_FLAGS> <LINK_FLAGS> ${CMAKE_Swift_IMPLIB_LINKER_FLAGS} <SONAME_FLAG> <TARGET_INSTALLNAME_DIR><TARGET_SONAME> -o <TARGET> <OBJECTS> <LINK_LIBRARIES>")
set(CMAKE_Swift_CREATE_SHARED_LIBRARY "<CMAKE_Swift_COMPILER> ${CMAKE_Swift_PARALLEL_FLAGS} -emit-library <LANGUAGE_COMPILE_FLAGS> <LINK_FLAGS> ${CMAKE_Swift_IMPLIB_LINKER_FLAGS} <SONAME_FLAG> <TARGET_INSTALLNAME_DIR><TARGET_SONAME> -o <TARGET> ${CMAKE_Swift_PDB_LINKER_FLAGS} <OBJECTS> <LINK_LIBRARIES>")
endif()
if(NOT CMAKE_Swift_CREATE_SHARED_MODULE)
@@ -138,7 +138,7 @@ if(CMAKE_Swift_COMPILATION_MODE_DEFAULT)
endif()
if(NOT CMAKE_Swift_LINK_EXECUTABLE)
set(CMAKE_Swift_LINK_EXECUTABLE "<CMAKE_Swift_COMPILER> ${CMAKE_Swift_PARALLEL_FLAGS} -emit-executable -o <TARGET> <FLAGS> <OBJECTS> <LINK_FLAGS> <LINK_LIBRARIES>")
set(CMAKE_Swift_LINK_EXECUTABLE "<CMAKE_Swift_COMPILER> ${CMAKE_Swift_PARALLEL_FLAGS} -emit-executable -o <TARGET> <FLAGS> <OBJECTS> <LINK_FLAGS> ${CMAKE_Swift_PDB_LINKER_FLAGS} <LINK_LIBRARIES>")
endif()
if(NOT CMAKE_Swift_CREATE_STATIC_LIBRARY)
@@ -154,7 +154,7 @@ else()
endif()
if(NOT CMAKE_Swift_CREATE_SHARED_LIBRARY)
set(CMAKE_Swift_CREATE_SHARED_LIBRARY "<CMAKE_Swift_COMPILER> -j ${CMAKE_Swift_NUM_THREADS} -num-threads ${CMAKE_Swift_NUM_THREADS} -emit-library -o <TARGET> -module-name <SWIFT_MODULE_NAME> -module-link-name <SWIFT_LIBRARY_NAME> -emit-module -emit-module-path <SWIFT_MODULE> -emit-dependencies <DEFINES> <FLAGS> <INCLUDES> <SWIFT_SOURCES> <LINK_FLAGS> <SONAME_FLAG> <TARGET_INSTALLNAME_DIR><TARGET_SONAME> ${CMAKE_Swift_IMPLIB_LINKER_FLAGS} <LINK_LIBRARIES>")
set(CMAKE_Swift_CREATE_SHARED_LIBRARY "<CMAKE_Swift_COMPILER> -j ${CMAKE_Swift_NUM_THREADS} -num-threads ${CMAKE_Swift_NUM_THREADS} -emit-library -o <TARGET> -module-name <SWIFT_MODULE_NAME> -module-link-name <SWIFT_LIBRARY_NAME> -emit-module -emit-module-path <SWIFT_MODULE> -emit-dependencies <DEFINES> <FLAGS> <INCLUDES> <SWIFT_SOURCES> <LINK_FLAGS> <SONAME_FLAG> <TARGET_INSTALLNAME_DIR><TARGET_SONAME> ${CMAKE_Swift_IMPLIB_LINKER_FLAGS} ${CMAKE_Swift_PDB_LINKER_FLAGS} <LINK_LIBRARIES>")
endif()
if(NOT CMAKE_Swift_CREATE_SHARED_MODULE)
@@ -162,7 +162,7 @@ else()
endif()
if(NOT CMAKE_Swift_LINK_EXECUTABLE)
set(CMAKE_Swift_LINK_EXECUTABLE "<CMAKE_Swift_COMPILER> -j ${CMAKE_Swift_NUM_THREADS} -num-threads ${CMAKE_Swift_NUM_THREADS} -emit-executable -o <TARGET> -emit-dependencies <DEFINES> <FLAGS> <INCLUDES> <SWIFT_SOURCES> <LINK_FLAGS> <LINK_LIBRARIES>")
set(CMAKE_Swift_LINK_EXECUTABLE "<CMAKE_Swift_COMPILER> -j ${CMAKE_Swift_NUM_THREADS} -num-threads ${CMAKE_Swift_NUM_THREADS} -emit-executable -o <TARGET> -emit-dependencies <DEFINES> <FLAGS> <INCLUDES> <SWIFT_SOURCES> <LINK_FLAGS> ${CMAKE_Swift_PDB_LINKER_FLAGS} <LINK_LIBRARIES>")
endif()
if(NOT CMAKE_Swift_LINK_EXECUTABLE_WITH_EXPORTS)

View File

@@ -1,4 +1,6 @@
set(CMAKE_Swift_IMPLIB_LINKER_FLAGS "-Xlinker -implib:<TARGET_IMPLIB>")
set(CMAKE_Swift_PDB_LINKER_FLAGS "-Xlinker -pdb:<TARGET_PDB>")
set(CMAKE_Swift_LINKER_SUPPORTS_PDB ON)
set(CMAKE_Swift_FLAGS_DEBUG_LINKER_FLAGS "-Xlinker -debug")
set(CMAKE_Swift_FLAGS_RELWITHDEBINFO_LINKER_FLAGS "-Xlinker -debug")

View File

@@ -580,9 +580,16 @@ bool cmNinjaTargetGenerator::SetMsvcTargetPdbVariable(
cmNinjaVars& vars, std::string const& config) const
{
cmMakefile* mf = this->GetMakefile();
if (mf->GetDefinition("MSVC_C_ARCHITECTURE_ID") ||
mf->GetDefinition("MSVC_CXX_ARCHITECTURE_ID") ||
mf->GetDefinition("MSVC_CUDA_ARCHITECTURE_ID")) {
bool supportsPDB = mf->GetDefinition("MSVC_C_ARCHITECTURE_ID") ||
mf->GetDefinition("MSVC_CXX_ARCHITECTURE_ID") ||
mf->GetDefinition("MSVC_CUDA_ARCHITECTURE_ID");
if (!supportsPDB) {
std::string const linkLanguage =
this->GeneratorTarget->GetLinkerLanguage(config);
supportsPDB =
mf->IsOn(cmStrCat("CMAKE_", linkLanguage, "_LINKER_SUPPORTS_PDB"));
}
if (supportsPDB) {
std::string pdbPath;
std::string compilePdbPath = this->ComputeTargetCompilePDB(config);
if (this->GeneratorTarget->GetType() == cmStateEnums::EXECUTABLE ||

View File

@@ -199,6 +199,26 @@ if(RunCMake_GENERATOR MATCHES "Ninja")
endif()
endblock()
block()
if(CMAKE_SYSTEM_NAME MATCHES Windows)
set(RunCMake_TEST_BINARY_DIR ${RunCMake_BINARY_DIR}/TargetPDBFile-build)
run_cmake(TargetPDBFile)
set(RunCMake_TEST_NO_CLEAN 1)
run_cmake_command(TargetPDBFile-build ${CMAKE_COMMAND} --build . -- -n -v)
endif()
endblock()
block()
if(CMAKE_SYSTEM_NAME MATCHES Windows)
set(RunCMake_TEST_BINARY_DIR ${RunCMake_BINARY_DIR}/TargetPDBFileDwarf-build)
run_cmake(TargetPDBFileDwarf)
set(RunCMake_TEST_NO_CLEAN 1)
run_cmake_command(TargetPDBFileDwarf-build ${CMAKE_COMMAND} --build . -- -v)
run_cmake_command(TargetPDBFileDwarf-install ${CMAKE_COMMAND} --install .
--prefix "${RunCMake_TEST_BINARY_DIR}/install")
endif()
endblock()
block()
set(RunCMake_TEST_BINARY_DIR ${RunCMake_BINARY_DIR}/SwiftModuleNameHyphen-build)
run_cmake(SwiftModuleNameHyphen)

View File

@@ -0,0 +1,4 @@
.*swiftc(\.exe)?"?[^
]* -Xlinker -pdb:[^
]*SwiftPDBCustom\.pdb[^
]*

View File

@@ -0,0 +1,9 @@
file(READ "${RunCMake_TEST_BINARY_DIR}/cmake_install.cmake" install_script)
if(NOT install_script MATCHES "SwiftPDBCustom\\.pdb")
string(APPEND RunCMake_TEST_FAILED
"Generated install script does not reference SwiftPDBCustom.pdb\n")
endif()
if(NOT install_script MATCHES "OPTIONAL")
string(APPEND RunCMake_TEST_FAILED
"Generated install script does not preserve OPTIONAL install\n")
endif()

View File

@@ -0,0 +1,12 @@
cmake_policy(SET CMP0157 NEW)
enable_language(Swift)
add_executable(SwiftPDB E.swift)
set_property(TARGET SwiftPDB PROPERTY PDB_NAME SwiftPDBCustom)
set_property(TARGET SwiftPDB PROPERTY PDB_OUTPUT_DIRECTORY
"$<1:${CMAKE_CURRENT_BINARY_DIR}/pdb>")
install(FILES "$<TARGET_PDB_FILE:SwiftPDB>"
DESTINATION bin
OPTIONAL)

View File

@@ -0,0 +1,9 @@
file(GLOB_RECURSE pdb_files LIST_DIRECTORIES false
"${RunCMake_TEST_BINARY_DIR}/*.pdb")
foreach(pdb_file IN LISTS pdb_files)
get_filename_component(pdb_name "${pdb_file}" NAME)
if(pdb_name STREQUAL "SwiftPDBDwarf.pdb")
string(APPEND RunCMake_TEST_FAILED
"DWARF link unexpectedly produced ${pdb_file}\n")
endif()
endforeach()

View File

@@ -0,0 +1,10 @@
.*swiftc(\.exe)?"?[^
]* -g[^
]* -debug-info-format=dwarf[^
]*
.*swiftc(\.exe)?"?[^
]* -Xlinker -debug:dwarf[^
]* -use-ld=lld[^
]* -Xlinker -pdb:[^
]*SwiftPDBDwarf\.pdb[^
]*

View File

@@ -0,0 +1,4 @@
if(EXISTS "${RunCMake_TEST_BINARY_DIR}/install/bin/SwiftPDBDwarf.pdb")
string(APPEND RunCMake_TEST_FAILED
"OPTIONAL install unexpectedly copied SwiftPDBDwarf.pdb\n")
endif()

View File

@@ -0,0 +1,12 @@
cmake_policy(SET CMP0157 NEW)
enable_language(Swift)
add_executable(SwiftPDBDwarf E.swift)
set_property(TARGET SwiftPDBDwarf PROPERTY LINKER_TYPE LLD)
target_compile_options(SwiftPDBDwarf PRIVATE -g -debug-info-format=dwarf)
target_link_options(SwiftPDBDwarf PRIVATE LINKER:-debug:dwarf)
install(FILES "$<TARGET_PDB_FILE:SwiftPDBDwarf>"
DESTINATION bin
OPTIONAL)