Skip to content

Commit 873c5ec

Browse files
committed
feat(proxy): use less cmake code generation; simplify symbols dump
1 parent 17426cc commit 873c5ec

2 files changed

Lines changed: 85 additions & 160 deletions

File tree

.github/workflows/build_and_package.yml

Lines changed: 29 additions & 35 deletions
Original file line numberDiff line numberDiff line change
@@ -4,41 +4,35 @@ on:
44
push:
55
branches: [main]
66
paths-ignore:
7-
- 'readme.md'
8-
- 'license.md'
9-
- '.github/contributing.md'
10-
- '.github/security.md'
11-
- '.github/ISSUE_TEMPLATE/**'
12-
- '.github/pull_request_template.md'
13-
- 'scripts/**'
14-
- 'ghidra/**'
15-
- '.clang*'
16-
- '.editorconfig'
17-
- '.cursorignore'
18-
- '.gitignore'
19-
- '2_06/**'
20-
- '2_71/**'
21-
- '.cmake-format.py'
22-
- '.github/workflows/publish_release.yml'
7+
- "readme.md"
8+
- "license.md"
9+
- ".github/contributing.md"
10+
- ".github/security.md"
11+
- ".github/ISSUE_TEMPLATE/**"
12+
- ".github/pull_request_template.md"
13+
- "scripts/**"
14+
- "ghidra/**"
15+
- ".editorconfig"
16+
- ".cursorignore"
17+
- ".gitignore"
18+
- ".cmake-format.py"
19+
- ".github/workflows/publish_release.yml"
2320
pull_request:
2421
branches: [main]
2522
paths-ignore:
26-
- 'readme.md'
27-
- 'license.md'
28-
- '.github/contributing.md'
29-
- '.github/security.md'
30-
- '.github/ISSUE_TEMPLATE/**'
31-
- '.github/pull_request_template.md'
32-
- 'scripts/**'
33-
- 'ghidra/**'
34-
- '.clang*'
35-
- '.editorconfig'
36-
- '.cursorignore'
37-
- '.gitignore'
38-
- '2_06/**'
39-
- '2_71/**'
40-
- '.cmake-format.py'
41-
- '.github/workflows/publish_release.yml'
23+
- "readme.md"
24+
- "license.md"
25+
- ".github/contributing.md"
26+
- ".github/security.md"
27+
- ".github/ISSUE_TEMPLATE/**"
28+
- ".github/pull_request_template.md"
29+
- "scripts/**"
30+
- "ghidra/**"
31+
- ".editorconfig"
32+
- ".cursorignore"
33+
- ".gitignore"
34+
- ".cmake-format.py"
35+
- ".github/workflows/publish_release.yml"
4236

4337
permissions:
4438
contents: read
@@ -64,7 +58,7 @@ jobs:
6458
- name: setup_python
6559
uses: actions/setup-python@v6
6660
with:
67-
python-version: '3.13'
61+
python-version: "3.13"
6862

6963
- name: cache_dependencies
7064
uses: actions/cache@v5
@@ -101,7 +95,7 @@ jobs:
10195
- name: setup_python
10296
uses: actions/setup-python@v6
10397
with:
104-
python-version: '3.13'
98+
python-version: "3.13"
10599

106100
- name: cache_dependencies
107101
uses: actions/cache@v5
@@ -122,4 +116,4 @@ jobs:
122116
with:
123117
name: airstrike3d_tools_clang_windows_x86
124118
path: build/clang_windows_x86/*.zip
125-
if-no-files-found: warn
119+
if-no-files-found: warn

cmake/proxy_utils.cmake

Lines changed: 56 additions & 125 deletions
Original file line numberDiff line numberDiff line change
@@ -1,171 +1,102 @@
1-
# proxy_utils.cmake — reusable helpers for DLL proxy generation
1+
# proxy_utils.cmake — DLL proxy generation helpers (requires CMake 3.25+)
22
#
33
# Provides:
4-
# generate_proxy_def(input_dll output_var)
5-
# Parses exports from a Windows DLL using llvm-objdump/objdump and
6-
# writes a .def module-definition file that forwards every export
7-
# through an "original." prefix.
8-
#
4+
# generate_proxy_def(<input_dll> <output_var>)
95
# add_bass_proxy(VERSION <v> BASS_DLL <path> SDK_TARGET <tgt>)
10-
# Creates a SHARED library bass_proxy_<v> in the caller's directory
11-
# scope. Links <SDK_TARGET> (usually bass_proxy_sdk). The .def is
12-
# generated from the version-specific bass.dll so each proxy matches
13-
# its runtime export table.
14-
#
15-
# Output lands in CMAKE_CURRENT_BINARY_DIR (unique per 2_XX/), so
16-
# multiple versions never collide.
176

187
include_guard(GLOBAL)
198

20-
# ─── generate_proxy_def ───────────────────────────────────────────────────────
21-
# Parse the export table of a PE DLL and emit a .def file that forwards every
22-
# exported symbol through an "original." prefix, preserving ordinals.
23-
#
24-
# generate_proxy_def(
25-
# input_dll # absolute path to the bass.dll for this version
26-
# output_var # name of variable to hold the generated .def path
27-
# )
28-
#
29-
# The .def is written to CMAKE_CURRENT_BINARY_DIR/<dll_stem>.def.
30-
# A directory-level configure dependency on input_dll is registered so that
31-
# the build system re-generates if the DLL changes.
32-
function(generate_proxy_def input_dll output_var)
33-
find_program(objdump_bin NAMES llvm-objdump objdump
34-
HINTS "${CMAKE_SOURCE_DIR}/llvm_mingw/bin" REQUIRED)
9+
find_program(
10+
OBJDUMP_EXECUTABLE
11+
NAMES llvm-objdump objdump
12+
HINTS "${CMAKE_SOURCE_DIR}/llvm_mingw/bin" REQUIRED
13+
DOC "PE object dump utility for export parsing")
3514

15+
function(generate_proxy_def input_dll output_var)
3616
cmake_path(
3717
GET
3818
input_dll
3919
STEM
4020
LAST_ONLY
4121
dll_stem)
4222
set(def_file "${CMAKE_CURRENT_BINARY_DIR}/${dll_stem}.def")
43-
4423
set_property(DIRECTORY APPEND PROPERTY CMAKE_CONFIGURE_DEPENDS
4524
"${input_dll}")
4625

47-
message(STATUS "parsing exports '${objdump_bin}': ${input_dll}")
48-
26+
message(STATUS "Parsing exports: ${input_dll}")
4927
execute_process(
50-
COMMAND "${objdump_bin}" -p "${input_dll}"
51-
OUTPUT_VARIABLE dump_output
52-
OUTPUT_STRIP_TRAILING_WHITESPACE
53-
COMMAND_ERROR_IS_FATAL
54-
ANY
55-
COMMAND_ECHO
56-
STDOUT)
28+
COMMAND "${OBJDUMP_EXECUTABLE}" -p "${input_dll}"
29+
OUTPUT_VARIABLE dump_output OUTPUT_STRIP_TRAILING_WHITESPACE
30+
COMMAND_ERROR_IS_FATAL ANY)
5731

5832
string(
5933
REGEX MATCHALL
6034
"[0-9]+[ \t]+0x[0-9a-fA-F]+[ \t]+[^ \t\r\n]+"
6135
raw_exports
6236
"${dump_output}")
63-
64-
list(LENGTH raw_exports export_count)
65-
if(export_count EQUAL 0)
66-
message(
67-
FATAL_ERROR "generate_proxy_def: no exports found in '${input_dll}'"
68-
)
37+
if(NOT raw_exports)
38+
message(FATAL_ERROR "No exports found in '${input_dll}'")
6939
endif()
7040

71-
set(content "LIBRARY \"${dll_stem}.dll\"\nEXPORTS\n")
72-
73-
foreach(row IN LISTS raw_exports)
74-
string(
75-
REGEX
76-
REPLACE "([0-9]+)[ \t]+0x[0-9a-fA-F]+[ \t]+([^ \t\r\n]+)"
77-
"\\2"
78-
sym_name
79-
"${row}")
80-
string(
81-
REGEX
82-
REPLACE "([0-9]+)[ \t]+0x[0-9a-fA-F]+[ \t]+([^ \t\r\n]+)"
83-
"\\1"
84-
ordinal
85-
"${row}")
86-
string(APPEND content
87-
" ${sym_name}=original.${sym_name} @${ordinal}\n")
88-
endforeach()
41+
list(TRANSFORM raw_exports
42+
REPLACE "([0-9]+)[ \t]+0x[0-9a-fA-F]+[ \t]+([^ \t\r\n]+)"
43+
" \\2=original.\\2 @\\1")
44+
list(
45+
JOIN
46+
raw_exports
47+
"\n"
48+
exports_block)
8949

90-
file(WRITE "${def_file}" "${content}")
91-
message(STATUS "generated '${def_file}' (${export_count} exports)")
50+
file(WRITE "${def_file}"
51+
"LIBRARY \"${dll_stem}.dll\"\nEXPORTS\n${exports_block}\n")
52+
53+
list(LENGTH raw_exports export_count)
54+
message(STATUS "Generated '${def_file}' (${export_count} exports)")
9255

9356
set(${output_var} "${def_file}")
9457
return(PROPAGATE ${output_var})
9558
endfunction()
9659

97-
# ─── add_bass_proxy ───────────────────────────────────────────────────────────
98-
# Create a SHARED library bass_proxy_<VERSION> in the caller's directory scope.
99-
#
100-
# add_bass_proxy(
101-
# VERSION <version_id> # e.g. "2_06"
102-
# BASS_DLL <path> # absolute path to that version's bass.dll
103-
# SDK_TARGET <target_name> # the STATIC/OBJECT lib with the SDK code
104-
# )
105-
#
106-
# The resulting target is bass_proxy_<VERSION>. Its output file lives in
107-
# CMAKE_CURRENT_BINARY_DIR (build/<version>/), so parallel versions never
108-
# collide. The deploy step in the 2_XX CMakeLists copies it to bass.dll.
10960
function(add_bass_proxy)
110-
set(options "")
111-
set(one_value_args VERSION BASS_DLL SDK_TARGET)
112-
set(multi_value_args "")
11361
cmake_parse_arguments(
11462
PARSE_ARGV
11563
0
116-
ARG
117-
"${options}"
118-
"${one_value_args}"
119-
"${multi_value_args}")
120-
121-
if(NOT ARG_VERSION OR NOT ARG_BASS_DLL OR NOT ARG_SDK_TARGET)
122-
message(
123-
FATAL_ERROR
124-
"add_bass_proxy: VERSION, BASS_DLL, SDK_TARGET are required")
125-
endif()
64+
arg
65+
""
66+
"VERSION;BASS_DLL;SDK_TARGET"
67+
"")
68+
69+
foreach(required IN ITEMS VERSION BASS_DLL SDK_TARGET)
70+
if(NOT arg_${required})
71+
message(FATAL_ERROR "add_bass_proxy: ${required} is required")
72+
endif()
73+
endforeach()
12674

127-
if(NOT TARGET ${ARG_SDK_TARGET})
128-
message(
129-
FATAL_ERROR
130-
"add_bass_proxy: SDK target '${ARG_SDK_TARGET}' not found. "
131-
"Ensure src/proxy/CMakeLists.txt is processed first.")
75+
if(NOT TARGET "${arg_SDK_TARGET}")
76+
message(FATAL_ERROR "SDK target '${arg_SDK_TARGET}' not found")
13277
endif()
13378

134-
generate_proxy_def("${ARG_BASS_DLL}" def_file)
79+
generate_proxy_def("${arg_BASS_DLL}" def_file)
80+
set(proxy_target "bass_proxy_${arg_VERSION}")
13581

136-
set(target_name "bass_proxy_${ARG_VERSION}")
137-
138-
add_library(${target_name} SHARED "${def_file}")
139-
140-
target_link_libraries(${target_name} PRIVATE ${ARG_SDK_TARGET})
82+
add_library(${proxy_target} SHARED "${def_file}")
83+
target_link_libraries(${proxy_target} PRIVATE "${arg_SDK_TARGET}")
14184

14285
set_target_properties(
143-
${target_name}
144-
PROPERTIES CXX_EXTENSIONS OFF PREFIX "" WINDOWS_EXPORT_ALL_SYMBOLS OFF
145-
# No OUTPUT_NAME — the target's natural name is fine.
146-
# Deploy step copies to bass.dll.
147-
)
148-
149-
if(CMAKE_SYSTEM_NAME STREQUAL "Windows" AND MINGW)
150-
target_link_options(
151-
${target_name}
152-
PRIVATE
153-
$<$<CXX_COMPILER_ID:GNU,Clang>:-static>
154-
$<$<CXX_COMPILER_ID:GNU,Clang>:-s>)
155-
endif()
86+
${proxy_target}
87+
PROPERTIES PREFIX "" CXX_EXTENSIONS OFF
88+
MSVC_RUNTIME_LIBRARY "MultiThreaded$<$<CONFIG:Debug>:Debug>")
15689

157-
if(CMAKE_SYSTEM_NAME STREQUAL "Windows" AND CMAKE_CXX_COMPILER_ID STREQUAL
158-
"Clang"
159-
AND CMAKE_CXX_COMPILER_TARGET MATCHES "windows-msvc")
90+
target_link_options(${proxy_target} PRIVATE
91+
$<$<NOT:$<CXX_COMPILER_FRONTEND_VARIANT:MSVC>>:-static>)
92+
93+
if(CMAKE_CXX_COMPILER_TARGET MATCHES "windows-msvc")
16094
target_link_libraries(
161-
"${target_name}"
162-
PRIVATE $<$<CONFIG:Debug>:msvcrtd.lib>
163-
$<$<NOT:$<CONFIG:Debug>>:msvcrt.lib>
164-
$<$<CONFIG:Debug>:vcruntimed.lib>
165-
$<$<NOT:$<CONFIG:Debug>>:vcruntime.lib>
166-
$<$<CONFIG:Debug>:ucrtd.lib>
167-
$<$<NOT:$<CONFIG:Debug>>:ucrt.lib>)
95+
${proxy_target}
96+
PRIVATE $<IF:$<CONFIG:Debug>,msvcrtd,msvcrt>.lib
97+
$<IF:$<CONFIG:Debug>,vcruntimed,vcruntime>.lib
98+
$<IF:$<CONFIG:Debug>,ucrtd,ucrt>.lib)
16899
endif()
169100

170-
message(STATUS "proxy target '${target_name}' — bass: ${ARG_BASS_DLL}")
171-
endfunction()
101+
message(STATUS "Proxy target '${proxy_target}' -> ${arg_BASS_DLL}")
102+
endfunction()

0 commit comments

Comments
 (0)