-
Notifications
You must be signed in to change notification settings - Fork 11
Expand file tree
/
Copy pathcompat.cpptrace.lua
More file actions
212 lines (200 loc) · 10.1 KB
/
Copy pathcompat.cpptrace.lua
File metadata and controls
212 lines (200 loc) · 10.1 KB
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
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
-- compat.cpptrace — stack traces for C++11 and up, from source.
--
-- Here because `compat.libassert` cannot exist without it: libassert's whole
-- value proposition is an assertion that prints a stack trace, and upstream
-- gets that by FetchContent-ing this repository at a pinned commit. This index
-- does not run FetchContent, so the dependency becomes an ordinary package —
-- which is better anyway: one cpptrace in the graph rather than one per
-- consumer that vendored it.
--
-- ── Whole-source glob, because every backend guards itself ─────────────────
--
-- Shape E without the config header. cpptrace supports six symbol backends,
-- six unwinders and three demanglers, and CMake compiles only the selected
-- ones. That selection is unnecessary here: EVERY backend file opens with its
-- own `#ifdef` (`symbols_with_libdwarf.cpp` → `#ifdef
-- CPPTRACE_GET_SYMBOLS_WITH_LIBDWARF`, and so on down the list), so an
-- unselected backend compiles to an empty translation unit exactly the way
-- curl's `vtls/gtls.c` does. The source list is therefore a plain glob and the
-- whole configuration lives in the defines below.
--
-- ── The backends chosen, and what they cost ────────────────────────────────
--
-- The criterion is ZERO EXTERNAL DEPENDENCIES on every platform, because a
-- diagnostic library that drags in libdwarf, libunwind or libbacktrace makes
-- itself harder to adopt than the problem it solves.
--
-- unix `_Unwind_Backtrace` from libgcc (always present, it is what the
-- C++ runtime already uses to unwind), `dladdr` for symbols, and
-- `abi::__cxa_demangle` for names.
-- windows DbgHelp for all three. `dbghelp.dll` is part of Windows itself,
-- so `-ldbghelp` needs nothing installed.
--
-- ⚠️ THE COST IS LINE NUMBERS. `dladdr` resolves an address to a symbol name
-- and the object it came from — it does NOT read DWARF, so traces carry
-- function names without file:line. That is the price of not depending on
-- libdwarf, and it is the right trade for this index today: the alternative is
-- vendoring libdwarf (which upstream itself FetchContents) as a fourth
-- package, for information that matters to a developer at a debugger rather
-- than to CI. A future `libdwarf` feature can add it without changing anything
-- a consumer writes.
--
-- ── Two generated pieces ───────────────────────────────────────────────────
--
-- * `cpptrace/version.hpp` is a `configure_file` of `cmake/in/version-hpp.in`
-- whose only inputs are the three version numbers in `project()`. Snapshot,
-- not a build step.
-- * `CPPTRACE_STATIC_DEFINE` is upstream's own switch (it is checked in
-- `include/cpptrace/basic.hpp`, not generated), and it is required: without
-- it every declaration carries `__declspec(dllexport)` /
-- `visibility("default")` for a shared library this package does not build.
--
-- ⚠️ AND A FLAG CANNOT DELIVER IT, WHICH ONLY WINDOWS SAYS OUT LOUD. The
-- macro decorates DECLARATIONS, so it has to reach every TU that INCLUDES
-- the headers — not just this package's own. As `cxxflags` Linux stayed
-- green, because there the difference is `visibility("default")` versus
-- nothing and the link is unaffected. On the MSVC ABI it is `dllimport`
-- versus nothing, which is an ABI difference, and `compat.libassert` —
-- whose TUs include these headers — failed to link:
--
-- lld-link: warning: locally defined symbol imported:
-- cpptrace::v1::runtime_error::runtime_error(...) [LNK4217]
-- lld-link: error: undefined symbol: __declspec(dllimport)
-- cpptrace::v1::stacktrace_frame::operator!=(...) const
--
-- ⚠️⚠️ MOVING IT TO `defines` DOES NOT FIX THAT, and this was measured
-- rather than assumed: `defines` is package-private too. Read the compile
-- database of a build that has both packages in it and libassert's eight
-- TUs carry `-DLIBASSERT_STATIC_DEFINE` (its OWN package define) and zero
-- `-DCPPTRACE_STATIC_DEFINE`, while cpptrace's 45 carry the reverse.
-- `docs/repository-and-schema.md` says the same thing about a feature's
-- `defines`. THERE IS NO INTERFACE-DEFINE KEY IN THIS GRAMMAR.
--
-- So the delivery mechanism is a SHIM, the same lever `compat.gzip-hpp` and
-- `compat.catch2` use: `basic.hpp` is the only header that reads the macro,
-- and every public header funnels through it (`cpptrace.hpp`,
-- `exceptions.hpp`, `formatting.hpp`, `from_current.hpp`, `gdb_jit.hpp`,
-- `io.hpp`, `utils.hpp` — all of them include it), so ONE shim in front of
-- it serves this package's TUs, libassert's, and any consumer's alike.
-- `mcpp_generated` therefore sorts FIRST in include_dirs.
--
-- The BACKEND macros below stay in `cxxflags` on purpose: those select
-- which .cpp compiles to something and are nobody else's business.
--
-- Upstream also ships `src/cpptrace.cppm` (`export module cpptrace;`). It is
-- deliberately NOT built here: this entry is `compat.*`, which in this index
-- promises header consumption and nothing else, and libassert — the reason
-- this package exists — consumes the headers. A module entry under the owning
-- namespace can be added later without disturbing this one.
--
-- CN mirror: `gitcode.com/mcpp-res/cpptrace`, the upstream tarball re-hosted
-- BYTE-IDENTICALLY (verified: the mirror's sha256 equals the one declared
-- here, which is what lets one `sha256` serve both arms). GLOBAL stays the
-- default; CN is the fallback `mcpp self config --mirror CN` selects.
package = {
spec = "1",
namespace = "compat",
name = "cpptrace",
description = "cpptrace — simple, portable stack traces for C++",
licenses = {"MIT"},
repo = "https://github.com/jeremy-rifkin/cpptrace",
type = "package",
xpm = {
linux = {
["1.0.4"] = {
url = {
GLOBAL = "https://github.com/jeremy-rifkin/cpptrace/archive/refs/tags/v1.0.4.tar.gz",
CN = "https://gitcode.com/mcpp-res/cpptrace/releases/download/1.0.4/cpptrace-1.0.4.tar.gz",
},
sha256 = "5c9f5b301e903714a4d01f1057b9543fa540f7bfcc5e3f8bd1748e652e24f9ea",
},
},
macosx = {
["1.0.4"] = {
url = {
GLOBAL = "https://github.com/jeremy-rifkin/cpptrace/archive/refs/tags/v1.0.4.tar.gz",
CN = "https://gitcode.com/mcpp-res/cpptrace/releases/download/1.0.4/cpptrace-1.0.4.tar.gz",
},
sha256 = "5c9f5b301e903714a4d01f1057b9543fa540f7bfcc5e3f8bd1748e652e24f9ea",
},
},
windows = {
["1.0.4"] = {
url = {
GLOBAL = "https://github.com/jeremy-rifkin/cpptrace/archive/refs/tags/v1.0.4.tar.gz",
CN = "https://gitcode.com/mcpp-res/cpptrace/releases/download/1.0.4/cpptrace-1.0.4.tar.gz",
},
sha256 = "5c9f5b301e903714a4d01f1057b9543fa540f7bfcc5e3f8bd1748e652e24f9ea",
},
},
},
mcpp = {
language = "c++23",
import_std = false,
c_standard = "c11",
-- `*/src` carries private headers the sources include as `utils/…`,
-- `binary/…`; `mcpp_generated` carries the version header at the path
-- `<cpptrace/version.hpp>` upstream's public headers open.
-- ORDER MATTERS: mcpp_generated FIRST, so the basic.hpp shim below is
-- found before upstream's, which it then reaches with #include_next.
include_dirs = { "mcpp_generated", "*/include", "*/src" },
generated_files = {
-- Delivers CPPTRACE_STATIC_DEFINE to every TU that opens a cpptrace
-- header, which no descriptor key can do. See the header note.
["mcpp_generated/cpptrace/basic.hpp"] = [==[
// mcpp-index shim: cpptrace is built as objects here, not as a shared library,
// so every declaration must be plain rather than dllimport/visibility-default.
// Upstream reads CPPTRACE_STATIC_DEFINE in this header and nowhere else, and
// every public cpptrace header includes this one.
#ifndef MCPP_COMPAT_CPPTRACE_STATIC_SHIM
#define MCPP_COMPAT_CPPTRACE_STATIC_SHIM
#ifndef CPPTRACE_STATIC_DEFINE
# define CPPTRACE_STATIC_DEFINE
#endif
#include_next <cpptrace/basic.hpp>
#endif
]==],
["mcpp_generated/cpptrace/version.hpp"] = [==[
/* configure_file() of cmake/in/version-hpp.in for cpptrace 1.0.4. */
#ifndef CPPTRACE_VERSION_HPP
#define CPPTRACE_VERSION_HPP
#define CPPTRACE_VERSION_MAJOR 1
#define CPPTRACE_VERSION_MINOR 0
#define CPPTRACE_VERSION_PATCH 4
#define CPPTRACE_TO_VERSION(MAJOR, MINOR, PATCH) ((MAJOR) * 10000 + (MINOR) * 100 + (PATCH))
#define CPPTRACE_VERSION CPPTRACE_TO_VERSION(CPPTRACE_VERSION_MAJOR, CPPTRACE_VERSION_MINOR, CPPTRACE_VERSION_PATCH)
#endif
]==],
},
sources = { "*/src/**/*.cpp" },
targets = { ["cpptrace"] = { kind = "lib" } },
deps = { },
-- Belt and braces for this package's OWN TUs; the shim above is what
-- reaches everyone else's.
defines = { "CPPTRACE_STATIC_DEFINE" },
linux = {
cxxflags = {
"-DCPPTRACE_UNWIND_WITH_UNWIND",
"-DCPPTRACE_GET_SYMBOLS_WITH_LIBDL",
"-DCPPTRACE_DEMANGLE_WITH_CXXABI",
},
-- dladdr lives in libdl on glibc.
ldflags = { "-ldl" },
},
macosx = {
cxxflags = {
"-DCPPTRACE_UNWIND_WITH_UNWIND",
"-DCPPTRACE_GET_SYMBOLS_WITH_LIBDL",
"-DCPPTRACE_DEMANGLE_WITH_CXXABI",
},
},
windows = {
cxxflags = {
"-DCPPTRACE_UNWIND_WITH_DBGHELP",
"-DCPPTRACE_GET_SYMBOLS_WITH_DBGHELP",
"-DCPPTRACE_DEMANGLE_WITH_WINAPI",
},
ldflags = { "-ldbghelp" },
},
},
}