Skip to content

Commit 22b64a4

Browse files
authored
Split debug info for all targets (#5732)
* Split debug info for all targets Work towards #5724 * release separate debug info Closes #5724 * Add split debug info support for MacOS * Add SLANG_ENABLE_SPLIT_DEBUG_INFO option * Sign and package debug info on MacOS * Set --build-id where available * Correct debug info installing * Keep cpack macos signing workaround * Neaten cmake * Disable sccache if building split debug info on Windows * Only repack necessary files on MacOS releases
1 parent 7dabfa7 commit 22b64a4

File tree

6 files changed

+221
-32
lines changed

6 files changed

+221
-32
lines changed

.github/workflows/release.yml

+26-8
Original file line numberDiff line numberDiff line change
@@ -109,23 +109,18 @@ jobs:
109109
brew install Bearer/tap/gon
110110
security find-identity -v
111111
brew install coreutils
112-
113112
# create variables
114113
CERTIFICATE_PATH=$RUNNER_TEMP/build_certificate.p12
115114
KEYCHAIN_PATH=$RUNNER_TEMP/app-signing.keychain-db
116-
117115
# import certificate and provisioning profile from secrets
118116
echo -n "$BUILD_CERTIFICATE_BASE64" | base64 --decode --output "$CERTIFICATE_PATH"
119-
120117
# create temporary keychain
121118
security create-keychain -p "$KEYCHAIN_PASSWORD" "$KEYCHAIN_PATH"
122119
security set-keychain-settings -lut 21600 "$KEYCHAIN_PATH"
123120
security unlock-keychain -p "$KEYCHAIN_PASSWORD" "$KEYCHAIN_PATH"
124-
125121
# import certificate to keychain
126122
security import "$CERTIFICATE_PATH" -P "$P12_PASSWORD" -A -t cert -f pkcs12 -k "$KEYCHAIN_PATH"
127123
security list-keychain -d user -s "$KEYCHAIN_PATH"
128-
129124
security set-key-partition-list -S apple-tool:,apple:,codesign: -s -k "${KEYCHAIN_PASSWORD}" "$KEYCHAIN_PATH"
130125
131126
binaries=(
@@ -137,6 +132,8 @@ jobs:
137132
"${bin_dir}/slangd"
138133
"${bin_dir}/slangc"
139134
)
135+
136+
# Sign main binaries
140137
for b in "${binaries[@]}"; do
141138
if [[ -f "$b" ]]; then
142139
echo "Signing binary '$b'..."
@@ -152,32 +149,51 @@ jobs:
152149
- name: Package Slang
153150
id: package
154151
run: |
155-
# For the release, also generate a tar.gz file
152+
# Package main binaries
156153
cpack --preset "$config" -G ZIP
157154
cpack --preset "$config" -G TGZ
155+
# Package debug info
156+
cpack --preset "$config-debug-info" -G ZIP
157+
cpack --preset "$config-debug-info" -G TGZ
158+
158159
triggering_ref=${{ github.ref_name }}
159160
base=slang-${triggering_ref#v}-${{matrix.os}}-${{matrix.platform}}
161+
162+
# Move main packages
160163
mv "$(pwd)/build/dist-${config}/slang.zip" "${base}.zip"
161164
echo "SLANG_BINARY_ARCHIVE_ZIP=${base}.zip" >> "$GITHUB_OUTPUT"
162165
mv "$(pwd)/build/dist-${config}/slang.tar.gz" "${base}.tar.gz"
163166
echo "SLANG_BINARY_ARCHIVE_TAR=${base}.tar.gz" >> "$GITHUB_OUTPUT"
164167
168+
# Move debug info packages
169+
mv "$(pwd)/build/dist-${config}-debug-info/slang-debug-info.zip" "${base}-debug-info.zip"
170+
echo "SLANG_DEBUG_INFO_ARCHIVE_ZIP=${base}-debug-info.zip" >> "$GITHUB_OUTPUT"
171+
mv "$(pwd)/build/dist-${config}-debug-info/slang-debug-info.tar.gz" "${base}-debug-info.tar.gz"
172+
echo "SLANG_DEBUG_INFO_ARCHIVE_TAR=${base}-debug-info.tar.gz" >> "$GITHUB_OUTPUT"
173+
165174
# For some reason, the binaries packed by cpack for macos is modified
166175
# by cpack and considered damanged by macos. For now we workaround this
167176
# by repacking all the binaries into the release package.
168177
if [[ "${{ matrix.os }}" == "macos" ]]; then
169178
mkdir ./ttmp
170179
unzip "${base}.zip" -d ./ttmp
171180
172-
/bin/cp -rf build/$cmake_config/bin/* ./ttmp/bin/
173-
/bin/cp -rf build/$cmake_config/lib/* ./ttmp/lib/
181+
# Copy only existing files from build directory
182+
find ./ttmp/{bin,lib} -type f | while read -r file; do
183+
src_file="build/$cmake_config/${file#./ttmp/}"
184+
if [ -f "$src_file" ]; then
185+
cp "$src_file" "$file"
186+
fi
187+
done
188+
174189
rm ${base}.zip
175190
rm ${base}.tar.gz
176191
cd ./ttmp
177192
7z a ../${base}.zip .
178193
tar -czvf ../${base}.tar.gz .
179194
cd ../
180195
fi
196+
181197
- name: File check
182198
run: |
183199
find "build/dist-$config" -print0 ! -iname '*.md' ! -iname '*.h' -type f | xargs -0 file
@@ -191,6 +207,8 @@ jobs:
191207
files: |
192208
${{ steps.package.outputs.SLANG_BINARY_ARCHIVE_ZIP }}
193209
${{ steps.package.outputs.SLANG_BINARY_ARCHIVE_TAR }}
210+
${{ steps.package.outputs.SLANG_DEBUG_INFO_ARCHIVE_ZIP }}
211+
${{ steps.package.outputs.SLANG_DEBUG_INFO_ARCHIVE_TAR }}
194212
${{ steps.notarize.outputs.SLANG_NOTARIZED_DIST }}
195213
env:
196214
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}

CMakeLists.txt

+6
Original file line numberDiff line numberDiff line change
@@ -185,6 +185,12 @@ enum_option(
185185
"Build slang as a static library"
186186
)
187187

188+
option(
189+
SLANG_ENABLE_SPLIT_DEBUG_INFO
190+
"Generate split debug info for debug builds"
191+
ON
192+
)
193+
188194
set(SLANG_GENERATORS_PATH
189195
""
190196
CACHE PATH

CMakePresets.json

+27-1
Original file line numberDiff line numberDiff line change
@@ -119,7 +119,15 @@
119119
"generators": ["ZIP"],
120120
"variables": {
121121
"CPACK_PACKAGE_FILE_NAME": "slang",
122-
"CPACK_COMPONENTS_ALL": "Unspecified;metadata;debug-info;slang-llvm"
122+
"CPACK_COMPONENTS_ALL": "Unspecified;metadata;slang-llvm"
123+
}
124+
},
125+
{
126+
"name": "base-debug-info",
127+
"inherits": "base",
128+
"variables": {
129+
"CPACK_PACKAGE_FILE_NAME": "slang-debug-info",
130+
"CPACK_COMPONENTS_ALL": "debug-info"
123131
}
124132
},
125133
{
@@ -140,6 +148,24 @@
140148
"configurations": ["Debug"],
141149
"packageDirectory": "dist-debug"
142150
},
151+
{
152+
"name": "release-debug-info",
153+
"inherits": "base-debug-info",
154+
"configurations": ["Release"],
155+
"packageDirectory": "dist-release-debug-info"
156+
},
157+
{
158+
"name": "releaseWithDebugInfo-debug-info",
159+
"inherits": "base-debug-info",
160+
"configurations": ["RelWithDebInfo"],
161+
"packageDirectory": "dist-releaseWithDebugInfo-debug-info"
162+
},
163+
{
164+
"name": "debug-debug-info",
165+
"inherits": "base-debug-info",
166+
"configurations": ["Debug"],
167+
"packageDirectory": "dist-debug-debug-info"
168+
},
143169
{
144170
"name": "generators",
145171
"inherits": "release",

cmake/CompilerFlags.cmake

+8-2
Original file line numberDiff line numberDiff line change
@@ -152,8 +152,14 @@ function(set_default_compile_options target)
152152

153153
add_supported_cxx_flags(${target} PRIVATE ${warning_flags})
154154

155-
# Don't assume that symbols will be resolved at runtime
156-
add_supported_cxx_linker_flags(${target} PRIVATE "-Wl,--no-undefined")
155+
add_supported_cxx_linker_flags(
156+
${target}
157+
PRIVATE
158+
# Don't assume that symbols will be resolved at runtime
159+
"-Wl,--no-undefined"
160+
# No reason not to do this? Useful when using split debug info
161+
"-Wl,--build-id"
162+
)
157163

158164
set_target_properties(
159165
${target}

cmake/SlangTarget.cmake

+153-21
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
#
2-
# A function to make target creation a little more declarative
2+
# A function to make target specification a little more declarative
33
#
44
# See the comments on the options below for usage
55
#
@@ -21,6 +21,8 @@ function(slang_add_target dir type)
2121
# Don't include any source in this target, this is a complement to
2222
# EXPLICIT_SOURCE, and doesn't interact with EXTRA_SOURCE_DIRS
2323
NO_SOURCE
24+
# Don't generate split debug info for this target
25+
NO_SPLIT_DEBUG_INFO
2426
)
2527
set(single_value_args
2628
# Set the target name, useful for multiple targets from the same
@@ -49,7 +51,7 @@ function(slang_add_target dir type)
4951
DEBUG_DIR
5052
# Install this target as part of a component
5153
INSTALL_COMPONENT
52-
# Don't install debug info by default for this target and use this
54+
# Override the debug info component name for installation
5355
# explicit name instead, used for externally built things such as
5456
# slang-glslang and slang-llvm which have large pdb files
5557
DEBUG_INFO_INSTALL_COMPONENT
@@ -198,6 +200,15 @@ function(slang_add_target dir type)
198200
PDB_OUTPUT_DIRECTORY "${output_dir}/${runtime_subdir}"
199201
)
200202

203+
if(NOT MSVC)
204+
set_target_properties(
205+
${target}
206+
PROPERTIES
207+
COMPILE_OPTIONS
208+
"$<$<CONFIG:Debug,RelWithDebInfo>:-fdebug-prefix-map=${CMAKE_CURRENT_BINARY_DIR}=${output_dir}>"
209+
)
210+
endif()
211+
201212
#
202213
# Set common compile options and properties
203214
#
@@ -209,6 +220,118 @@ function(slang_add_target dir type)
209220
set_default_compile_options(${target})
210221
endif()
211222

223+
# Set debug info options if not disabled
224+
# Determine if this target produces a binary that can have debug info
225+
if(
226+
NOT ARG_NO_SPLIT_DEBUG_INFO
227+
AND type MATCHES "^(EXECUTABLE|SHARED|MODULE)$"
228+
AND SLANG_ENABLE_SPLIT_DEBUG_INFO
229+
)
230+
set(generate_split_debug_info TRUE)
231+
else()
232+
set(generate_split_debug_info FALSE)
233+
endif()
234+
235+
if(generate_split_debug_info)
236+
if(MSVC)
237+
get_target_property(
238+
c_compiler_launcher
239+
${target}
240+
C_COMPILER_LAUNCHER
241+
)
242+
get_target_property(
243+
cxx_compiler_launcher
244+
${target}
245+
CXX_COMPILER_LAUNCHER
246+
)
247+
248+
if(
249+
c_compiler_launcher MATCHES "ccache"
250+
OR cxx_compiler_launcher MATCHES "ccache"
251+
)
252+
message(
253+
WARNING
254+
"(s)ccache detected for target ${target}. Removing launcher as it's incompatible with split debug info compiled with MSVC."
255+
)
256+
set_target_properties(
257+
${target}
258+
PROPERTIES C_COMPILER_LAUNCHER "" CXX_COMPILER_LAUNCHER ""
259+
)
260+
endif()
261+
262+
get_target_property(
263+
msvc_debug_information_format
264+
${target}
265+
MSVC_DEBUG_INFORMATION_FORMAT
266+
)
267+
if(
268+
NOT msvc_debug_information_format
269+
MATCHES
270+
"(ProgramDatabase|EditAndContinue)"
271+
)
272+
message(
273+
WARNING
274+
"Debug format must be ProgramDatabase or EditAndContinue to generate split debug info with MSVC"
275+
)
276+
endif()
277+
278+
set_target_properties(
279+
${target}
280+
PROPERTIES
281+
# While it would be nice to set this here, we don't know if
282+
# the user wants ProgramDatabase or EditAndContinue, so
283+
# just check above
284+
# MSVC_DEBUG_INFORMATION_FORMAT
285+
# "$<$<CONFIG:Debug,RelWithDebInfo>:ProgramDatabase>"
286+
COMPILE_PDB_NAME "${target}"
287+
COMPILE_PDB_OUTPUT_DIRECTORY "${output_dir}"
288+
)
289+
else()
290+
# Common debug flags for GCC/Clang
291+
target_compile_options(
292+
${target}
293+
PRIVATE
294+
$<$<CONFIG:Debug,RelWithDebInfo>:
295+
-g
296+
-fdebug-prefix-map=${CMAKE_SOURCE_DIR}=.
297+
-fdebug-prefix-map=${CMAKE_BINARY_DIR}=.
298+
>
299+
)
300+
301+
if(CMAKE_SYSTEM_NAME MATCHES "Darwin")
302+
# macOS - use dsymutil with --flat to create separate debug file
303+
add_custom_command(
304+
TARGET ${target}
305+
POST_BUILD
306+
COMMAND
307+
dsymutil --flat $<TARGET_FILE:${target}> -o
308+
$<TARGET_FILE:${target}>.dwarf
309+
COMMAND chmod 644 $<TARGET_FILE:${target}>.dwarf
310+
COMMAND ${CMAKE_STRIP} -S $<TARGET_FILE:${target}>
311+
WORKING_DIRECTORY ${output_dir}
312+
VERBATIM
313+
)
314+
else()
315+
add_custom_command(
316+
TARGET ${target}
317+
POST_BUILD
318+
COMMAND
319+
${CMAKE_OBJCOPY} --only-keep-debug
320+
$<TARGET_FILE:${target}> $<TARGET_FILE:${target}>.dwarf
321+
COMMAND chmod 644 $<TARGET_FILE:${target}>.dwarf
322+
COMMAND
323+
${CMAKE_STRIP} --strip-debug $<TARGET_FILE:${target}>
324+
COMMAND
325+
${CMAKE_OBJCOPY}
326+
--add-gnu-debuglink=$<TARGET_FILE:${target}>.dwarf
327+
$<TARGET_FILE:${target}>
328+
WORKING_DIRECTORY ${output_dir}
329+
VERBATIM
330+
)
331+
endif()
332+
endif()
333+
endif()
334+
212335
set_target_properties(
213336
${target}
214337
PROPERTIES EXCLUDE_FROM_ALL ${ARG_EXCLUDE_FROM_ALL}
@@ -429,32 +552,41 @@ function(slang_add_target dir type)
429552
PUBLIC_HEADER DESTINATION ${CMAKE_INSTALL_INCLUDEDIR} ${ARGN}
430553
)
431554
endmacro()
555+
432556
if(ARG_INSTALL_COMPONENT)
433557
i(EXCLUDE_FROM_ALL COMPONENT ${ARG_INSTALL_COMPONENT})
434-
set(pdb_component "${ARG_INSTALL_COMPONENT}-debug-info")
558+
set(debug_component "${ARG_INSTALL_COMPONENT}-debug-info")
435559
elseif(ARG_INSTALL)
436560
i()
437-
set(pdb_component "debug-info")
561+
set(debug_component "debug-info")
438562
endif()
439-
if(ARG_DEBUG_INFO_INSTALL_COMPONENT)
440-
set(pdb_component ${ARG_DEBUG_INFO_INSTALL_COMPONENT})
563+
564+
if(DEFINED ARG_DEBUG_INFO_INSTALL_COMPONENT)
565+
set(debug_component "${ARG_DEBUG_INFO_INSTALL_COMPONENT}")
441566
endif()
442-
if(MSVC AND DEFINED pdb_component)
443-
if(
444-
type STREQUAL "EXECUTABLE"
445-
OR type STREQUAL "SHARED"
446-
OR type STREQUAL "MODULE"
447-
)
448-
install(
449-
FILES $<TARGET_PDB_FILE:${target}>
450-
DESTINATION ${runtime_subdir}
451-
# Optional, because if we're building without debug info (like
452-
# a release build) then we don't want to fail here.
453-
OPTIONAL
454-
COMPONENT ${pdb_component}
455-
EXCLUDE_FROM_ALL
456-
)
567+
568+
# Install debug info only if target is being installed
569+
if((ARG_INSTALL OR ARG_INSTALL_COMPONENT) AND generate_split_debug_info)
570+
if(type STREQUAL "EXECUTABLE" OR WIN32)
571+
set(debug_dest ${runtime_subdir})
572+
else()
573+
set(debug_dest ${library_subdir})
457574
endif()
575+
576+
if(MSVC)
577+
set(debug_file $<TARGET_PDB_FILE:${target}>)
578+
else()
579+
set(debug_file "$<TARGET_FILE:${target}>.dwarf")
580+
endif()
581+
582+
install(
583+
FILES ${debug_file}
584+
DESTINATION ${debug_dest}
585+
CONFIGURATIONS Debug RelWithDebInfo
586+
COMPONENT ${debug_component}
587+
EXCLUDE_FROM_ALL
588+
OPTIONAL
589+
)
458590
endif()
459591
endfunction()
460592

docs/building.md

+1
Original file line numberDiff line numberDiff line change
@@ -163,6 +163,7 @@ See the [documentation on testing](../tools/slang-test/README.md) for more infor
163163
| `SLANG_ENABLE_TESTS` | `TRUE` | Enable test targets, requires SLANG_ENABLE_GFX, SLANG_ENABLE_SLANGD and SLANG_ENABLE_SLANGRT |
164164
| `SLANG_ENABLE_EXAMPLES` | `TRUE` | Enable example targets, requires SLANG_ENABLE_GFX |
165165
| `SLANG_LIB_TYPE` | `SHARED` | How to build the slang library |
166+
| `SLANG_ENABLE_SPLIT_DEBUG_INFO` | `TRUE` | Enable generating split debug info for Debug and RelWithDebInfo configs |
166167
| `SLANG_SLANG_LLVM_FLAVOR` | `FETCH_BINARY_IF_POSSIBLE` | How to set up llvm support |
167168
| `SLANG_SLANG_LLVM_BINARY_URL` | System dependent | URL specifying the location of the slang-llvm prebuilt library |
168169
| `SLANG_GENERATORS_PATH` | `` | Path to an installed `all-generators` target for cross compilation |

0 commit comments

Comments
 (0)