Repository navigation
Expand file tree
/
Copy pathmcpp.toml
More file actions
175 lines (163 loc) · 8.24 KB
/
Copy pathmcpp.toml
File metadata and controls
175 lines (163 loc) · 8.24 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
[package]
namespace = "mcpplibs"
name = "openkal-windows"
version = "0.22.2"
description = "An implementation of openkal for Windows, written on the Win32 interfaces and the object manager beneath them, using no C runtime symbol."
license = "Apache-2.0"
# The layer this package supplies, in the vocabulary the engine resolves.
#
# `mcpp:kernel-abi` names the platform interface a C library sits on. On a
# traditional stack that seam is unnamed — a C library issues system calls or
# calls the platform's own entry points directly — and naming it is what lets
# one C library sit above several platforms. `=openkal` is the interface this
# package answers to; several packages answer to it and the engine knows none
# of them by name.
provides = ["mcpp:kernel-abi=openkal"]
authors = ["mcpplibs"]
repo = "https://github.com/mcpplibs/openkal-windows"
# WHICH INTERFACES THIS IMPLEMENTATION PROVIDES, DERIVED FROM THE ARTEFACT AND
# NOT WRITTEN BY HAND.
#
# openkal's specification names no set of interfaces: clause 3.3 withdrew the
# one it had named (`hosted`) because a name describing a class of environment
# is falsified by an environment nobody had in mind, and that one was falsified
# inside its own ecosystem within a release. Enumeration by the package
# replaced it, and a build tool reads this array at dependency resolution
# against the `requires-interfaces` a consumer states in its own manifest --
# the first of the three times clause 6.2 tabulates, and the earliest at which
# the question can be answered.
#
# EVERY ONE BUT ONE. `openkal.space` is absent: this environment has no
# operation upon an address space it can supply, and clause 3 says an
# implementation provides an interface in whole or not at all. A consumer that
# needs it is refused here and builds on openkal-linux, which is the whole
# point of stating the set rather than a name for a class of environment.
#
# GENERATED, AND CI DIFFS IT AGAINST THE OBJECTS:
#
# bash .spec/tools/check-surface.sh --toml .spec/SURFACE.txt \
# $(find target -path '*/obj/*' -name '*.o' ! -name '*.m.o')
#
# BACKWARD COMPATIBLE. An engine that predates the key reads `[kernel-abi]` as
# an unknown top-level table and ignores it, so this manifest loads unchanged
# everywhere it loaded before.
[kernel-abi]
provides-interfaces = [
"openkal.abort",
"openkal.stream",
"openkal.memory",
"openkal.env",
"openkal.time",
"openkal.random",
"openkal.fs",
"openkal.process",
"openkal.task",
"openkal.exec",
"openkal.terminal",
"openkal.net",
"openkal.datagram",
"openkal.timeout",
"openkal.map",
"openkal.region",
"openkal.prof",
"openkal.debug",
]
[dependencies]
# Every patch release of the specification's minor version (openkal clause 8).
openkal = "^0.25.0"
# The package contributes definitions and no modules. The interface it
# implements is declared by the specification package, which this package
# includes and does not re-export.
# The libraries this environment's own interfaces live in.
#
# ntdll carries the object manager, which is where a name relative to a
# directory is opened --- the operation openkal declares and Win32 does not
# offer. synchronization carries the suspension primitive. shell32 carries the
# operation that splits a command line into a vector, which is this
# environment's own definition of what its argument vector is and is therefore
# used rather than reimplemented.
#
# They are named twice because the two application binary interfaces this
# environment has spell a library differently: one names it as an argument to
# the linker and the other as an input file. Naming them once in the spelling of
# either would make this package build under two of the three toolchains it is
# written for.
# THE PREDICATE IS THE OBJECT ABI, NOT THE C LIBRARY.
#
# These four are Win32 import libraries — a property of the platform interface
# this package implements. `env = "gnu"` was standing in for "the GNU/PE ABI
# rather than the MSVC one", and on a traditional stack the two coincide. They
# stop coinciding the moment the C library comes from the dependency graph: a
# build of `x86_64-windows-gnu` over openkal resolves musl, and one spelled
# `x86_64-windows-musl` is the same build under an honest name. Under the old
# predicate the second one linked with none of these libraries and failed on
# `GetStdHandle`.
[target.'cfg(all(windows, not(env = "msvc")))'.build]
ldflags = ["-lntdll", "-lsynchronization", "-lshell32", "-lkernel32", "-lbcrypt"]
# Exceptions and run-time type information, on the one ABI where their absence
# is asserted.
#
# This package throws nothing and has no virtual function, but a compiler still
# emits a landing pad for every function holding an object with a destructor,
# and each landing pad references its own runtime's personality routine. On this
# ABI the property that the objects reference no C runtime symbol is checked, and
# a program that selects `standalone' here has no such runtime to supply that
# routine --- so the landing pads are not emitted.
#
# On the other ABI the flags are absent, and deliberately. A program using that
# ABI has a C runtime; there the toolchain's defaults are correct, one of the two
# toolchains that reach it would not recognise these spellings, and openkal has
# nothing to say about how a program that has a runtime unwinds.
#
# AND NO LOOP IS REPLACED BY A CALL, WHICH IS WHAT `-fno-builtin` IS FOR.
#
# An optimizing compiler recognises a loop that counts to a terminator and
# emits a call to the library function that does the same. `wide_length` in
# src/env.cpp counts sixteen-bit units and became `wcslen`; a byte loop in
# src/win.cpp became `strlen`. Neither is this environment's: the C library
# above is openkal-musl, whose `wchar_t` is thirty-two bits, so its `wcslen`
# read the command line two units at a time and every argument of a program
# built with `--release` came out shortened by a different amount. The dev
# profile does not optimize and never showed it, which is also why the check
# below now builds both profiles.
#
# The flags are attached to this package's own sources. The tests are
# consumers: they import the test library, which imports `std`, and the
# prebuilt `std` interface is compiled with exceptions and run-time type
# information, which a unit compiled without them cannot import.
flags = [
{ glob = "src/**", cxxflags = ["-fno-exceptions", "-fno-rtti", "-fno-builtin"] },
]
# The other ABI names them in the sources instead --- src/win.cpp for the four
# above and src/random.cpp for bcrypt --- where its compilers record
# the requirement in the object they produce. A library named on the link line
# there would have to be named again by every program that links this package;
# a library named in the object travels with it.
# There is deliberately no guard flag for a function-local static. An earlier
# version disabled it; every static in this package is initialised by a constant,
# so no guard is emitted and the flag was doing nothing under any toolchain.
[features]
default = []
# Whether this implementation is the whole of the program's environment.
#
# Ordinarily a program already carries a runtime that has received control from
# the loader, and this implementation adds nothing. Where it does not, the entry
# point is this implementation's, and the link line names it.
standalone = { defines = ["OKW_STANDALONE"] }
# The tests are written with the mtest library (mcpp-community/mtest): each file
# declares its cases, and a test that starts a copy of itself declares what the
# copy does as a `child'.
[dev-dependencies]
mcpplibs.mtest = "0.5.2"
# THE TESTS ON THE GNU ABI WITH GCC, which CI runs under this profile. GCC on PE
# emits the function-local static `std::_Sp_make_shared_tag::_S_ti()::__tag' of
# an imported std as a definition that is not COMDAT, once in every object that
# imports std --- the test library's and mcpplibs.os's --- and once in
# libstdc++.a, so the link of every test is refused as a multiple definition.
# The definitions are one entity, and this profile's link accepts the repeats.
# A profile is the root's own, so the option never reaches a consumer's link.
# Otherwise it is the dev profile, so the leg tests what dev tests.
[profile.gnu-odr]
opt = 0
debug = true
ldflags = ["-Wl,--allow-multiple-definition"]