forked from uNetworking/uWebSockets.js
-
Notifications
You must be signed in to change notification settings - Fork 0
/
build.c
189 lines (159 loc) · 6.86 KB
/
build.c
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
#include <stdio.h>
#include <stdlib.h>
#include <stdarg.h>
#include <string.h>
/* List of platform features */
#ifdef _WIN32
#define OS "win32"
#define IS_WINDOWS
#endif
#ifdef __linux
#define OS "linux"
#define IS_LINUX
#endif
#ifdef __APPLE__
#define OS "darwin"
#define IS_MACOS
#endif
const char *ARM = "arm";
const char *ARM64 = "arm64";
const char *X64 = "x64";
/* System, but with string replace */
int run(const char *cmd, ...) {
char buf[2048];
va_list args;
va_start(args, cmd);
vsprintf(buf, cmd, args);
va_end(args);
printf("--> %s\n\n", buf);
return system(buf);
}
/* List of Node.js versions */
struct node_version {
char *name;
char *abi;
} versions[] = {
{"v18.0.0", "108"},
{"v20.0.0", "115"},
{"v21.0.0", "120"},
{"v22.0.0", "127"}
};
/* Downloads headers, creates folders */
void prepare() {
if (run("mkdir dist") || run("mkdir targets")) {
return;
}
/* For all versions */
for (unsigned int i = 0; i < sizeof(versions) / sizeof(struct node_version); i++) {
run("curl -OJ https://nodejs.org/dist/%s/node-%s-headers.tar.gz", versions[i].name, versions[i].name);
run("tar xzf node-%s-headers.tar.gz -C targets", versions[i].name);
run("curl https://nodejs.org/dist/%s/win-x64/node.lib > targets/node-%s/node.lib", versions[i].name, versions[i].name);
}
}
void build_lsquic(const char *arch) {
#ifndef IS_WINDOWS
/* Build for x64 or arm/arm64 (depending on the host) */
run("cd uWebSockets/uSockets/lsquic && cmake -DCMAKE_POSITION_INDEPENDENT_CODE=ON -DBORINGSSL_DIR=../boringssl -DCMAKE_BUILD_TYPE=Release -DLSQUIC_BIN=Off . && make lsquic");
#else
/* Download zlib */
run("curl -OL https://github.com/madler/zlib/releases/download/v1.3.1/zlib-1.3.1.tar.gz");
run("tar xzf zlib-1.3.1.tar.gz");
run("cd uWebSockets/uSockets/lsquic && cmake -DZLIB_INCLUDE_DIRS=./zlib-1.3.1 -DZLIB_FOUND=True -DCMAKE_POSITION_INDEPENDENT_CODE=ON -DBORINGSSL_DIR=../boringssl -DCMAKE_BUILD_TYPE=Release -DLSQUIC_BIN=Off . && msbuild ALL_BUILD.vcxproj");
#endif
}
/* Build boringssl */
void build_boringssl(const char *arch) {
#ifdef IS_MACOS
/* Build for x64 (the host) */
run("cd uWebSockets/uSockets/boringssl && mkdir -p x64 && cd x64 && cmake -DCMAKE_BUILD_TYPE=Release -DCMAKE_OSX_DEPLOYMENT_TARGET=10.14 .. && make crypto ssl");
/* Build for arm64 (cross compile) */
run("cd uWebSockets/uSockets/boringssl && mkdir -p arm64 && cd arm64 && cmake -DCMAKE_BUILD_TYPE=Release -DCMAKE_OSX_ARCHITECTURES=arm64 .. && make crypto ssl");
#endif
#ifdef IS_LINUX
/* Build for x64 or arm/arm64 (depending on the host) */
run("cd uWebSockets/uSockets/boringssl && mkdir -p %s && cd %s && cmake -DCMAKE_POSITION_INDEPENDENT_CODE=ON -DCMAKE_BUILD_TYPE=Release .. && make crypto ssl", arch, arch);
#endif
#ifdef IS_WINDOWS
/* Build for x64 (the host) */
run("cd uWebSockets/uSockets/boringssl && mkdir -p x64 && cd x64 && cmake -DCMAKE_C_COMPILER=clang -DCMAKE_CXX_COMPILER=clang++ -DCMAKE_BUILD_TYPE=Release -GNinja .. && ninja crypto ssl");
#endif
}
/* Build for Unix systems */
void build(char *compiler, char *cpp_compiler, char *cpp_linker, char *os, const char *arch) {
char *c_shared = "-DWIN32_LEAN_AND_MEAN -DLIBUS_USE_LIBUV -DLIBUS_USE_QUIC -I uWebSockets/uSockets/lsquic/include -I uWebSockets/uSockets/boringssl/include -pthread -DLIBUS_USE_OPENSSL -flto -O3 -c -fPIC -I uWebSockets/uSockets/src uWebSockets/uSockets/src/*.c uWebSockets/uSockets/src/eventing/*.c uWebSockets/uSockets/src/crypto/*.c";
char *cpp_shared = "-DWIN32_LEAN_AND_MEAN -DUWS_WITH_PROXY -DLIBUS_USE_LIBUV -DLIBUS_USE_QUIC -I uWebSockets/uSockets/boringssl/include -pthread -DLIBUS_USE_OPENSSL -flto -O3 -c -fPIC -std=c++17 -I uWebSockets/uSockets/src -I uWebSockets/src src/addon.cpp uWebSockets/uSockets/src/crypto/sni_tree.cpp";
for (unsigned int i = 0; i < sizeof(versions) / sizeof(struct node_version); i++) {
run("%s %s -I targets/node-%s/include/node", compiler, c_shared, versions[i].name);
run("%s %s -I targets/node-%s/include/node", cpp_compiler, cpp_shared, versions[i].name);
run("%s -pthread -flto -O3 *.o uWebSockets/uSockets/boringssl/%s/ssl/libssl.a uWebSockets/uSockets/boringssl/%s/crypto/libcrypto.a uWebSockets/uSockets/lsquic/src/liblsquic/liblsquic.a -std=c++17 -shared %s -o dist/uws_%s_%s_%s.node", cpp_compiler, arch, arch, cpp_linker, os, arch, versions[i].abi);
}
}
void copy_files() {
#ifdef IS_WINDOWS
run("copy \"src\\uws.js\" dist /Y");
#else
run("cp src/uws.js dist/uws.js");
#endif
}
/* Special case for windows */
void build_windows(char *compiler, char *cpp_compiler, char *cpp_linker, char *os, const char *arch) {
/* For all versions */
for (unsigned int i = 0; i < sizeof(versions) / sizeof(struct node_version); i++) {
run("cl /MD /W3 /D WIN32_LEAN_AND_MEAN /D \"UWS_WITH_PROXY\" /D \"LIBUS_USE_LIBUV\" /I uWebSockets/uSockets/lsquic/include /I uWebSockets/uSockets/lsquic/wincompat /I uWebSockets/uSockets/boringssl/include /D \"LIBUS_USE_OPENSSL\" /std:c++17 /I uWebSockets/uSockets/src uWebSockets/uSockets/src/*.c uWebSockets/uSockets/src/crypto/sni_tree.cpp "
"uWebSockets/uSockets/src/eventing/*.c uWebSockets/uSockets/src/crypto/*.c /I targets/node-%s/include/node /I uWebSockets/src /EHsc "
"/Ox /LD /Fedist/uws_win32_%s_%s.node src/addon.cpp advapi32.lib uWebSockets/uSockets/boringssl/x64/ssl/ssl.lib uWebSockets/uSockets/boringssl/x64/crypto/crypto.lib targets/node-%s/node.lib",
versions[i].name, arch, versions[i].abi, versions[i].name);
}
}
int main() {
printf("[Preparing]\n");
prepare();
printf("\n[Building]\n");
const char *arch = X64;
#ifdef __arm__
arch = ARM;
#endif
#ifdef __aarch64__
arch = ARM64;
#endif
/* Build for x64 and/or arm/arm64 */
build_boringssl(arch);
build_lsquic(arch);
#ifdef IS_WINDOWS
/* We can use clang, but we currently do use cl.exe still */
build_windows("clang",
"clang++",
"",
OS,
X64);
#else
#ifdef IS_MACOS
/* Apple special case */
build("clang -mmacosx-version-min=10.14",
"clang++ -stdlib=libc++ -mmacosx-version-min=10.14",
"-undefined dynamic_lookup",
OS,
X64);
/* Try and build for arm64 macOS 11 */
build("clang -target arm64-apple-macos11",
"clang++ -stdlib=libc++ -target arm64-apple-macos11",
"-undefined dynamic_lookup",
OS,
ARM64);
#else
/* Linux does not cross-compile but picks whatever arch the host is on */
build("clang",
"clang++",
"-static-libstdc++ -static-libgcc -s",
OS,
arch);
/* If linux we also want arm64 */
/*build("aarch64-linux-gnu-gcc",
"aarch64-linux-gnu-g++",
"-static-libstdc++ -static-libgcc -s",
OS,
ARM64);*/
#endif
#endif
copy_files();
}