Skip to content

Commit 5cf5e7d

Browse files
authored
build: generate hex dump of server assets during build (#6661)
* `build`: generate hex dumps of server assets on the fly * build: workaround lack of -n on gnu xxd * build: don't use xxd in cmake * build: don't call xxd from build.zig * build: more idiomatic hexing * build: don't use xxd in Makefile (od hackery instead) * build: avoid exceeding max cmd line limit in makefile hex dump * build: hex dump assets at cmake build time (not config time)
1 parent 40f74e4 commit 5cf5e7d

10 files changed

+78
-7129
lines changed

.gitignore

+4
Original file line numberDiff line numberDiff line change
@@ -34,6 +34,7 @@ lcov-report/
3434
gcovr-report/
3535

3636
build*
37+
!build.zig
3738
cmake-build-*
3839
out/
3940
tmp/
@@ -100,6 +101,9 @@ qnt-*.txt
100101
perf-*.txt
101102

102103
examples/jeopardy/results.txt
104+
examples/server/*.html.hpp
105+
examples/server/*.js.hpp
106+
examples/server/*.mjs.hpp
103107

104108
poetry.lock
105109
poetry.toml

Makefile

+10-1
Original file line numberDiff line numberDiff line change
@@ -800,10 +800,19 @@ save-load-state: examples/save-load-state/save-load-state.cpp ggml.o llama.o $(C
800800
$(CXX) $(CXXFLAGS) -c $< -o $(call GET_OBJ_FILE, $<)
801801
$(CXX) $(CXXFLAGS) $(filter-out %.h $<,$^) $(call GET_OBJ_FILE, $<) -o $@ $(LDFLAGS)
802802

803-
server: examples/server/server.cpp examples/server/utils.hpp examples/server/httplib.h common/json.hpp examples/server/index.html.hpp examples/server/index.js.hpp examples/server/completion.js.hpp common/stb_image.h ggml.o llama.o $(COMMON_DEPS) grammar-parser.o $(OBJS)
803+
server: examples/server/server.cpp examples/server/utils.hpp examples/server/httplib.h common/json.hpp examples/server/index.html.hpp examples/server/index.js.hpp examples/server/completion.js.hpp examples/server/json-schema-to-grammar.mjs.hpp common/stb_image.h ggml.o llama.o $(COMMON_DEPS) grammar-parser.o $(OBJS)
804804
$(CXX) $(CXXFLAGS) -c $< -o $(call GET_OBJ_FILE, $<)
805805
$(CXX) $(CXXFLAGS) $(filter-out %.h %.hpp $<,$^) -Iexamples/server $(call GET_OBJ_FILE, $<) -o $@ $(LDFLAGS) $(LWINSOCK2)
806806

807+
# Portable equivalent of `cd examples/server/public && xxd -i $(notdir $<) ../$(notdir $<).hpp`:
808+
examples/server/%.hpp: examples/server/public/% Makefile
809+
@( export NAME=$(subst .,_,$(subst -,_,$(notdir $<))) && \
810+
echo "unsigned char $${NAME}[] = {" && \
811+
cat $< | od -v -t x1 -An | sed -E 's/([0-9a-fA-F]+)/0x\1, /g' && \
812+
echo "};" && \
813+
echo "unsigned int $${NAME}_len = $(shell cat $< | wc -c );" \
814+
) > $@
815+
807816
gguf: examples/gguf/gguf.cpp ggml.o $(OBJS)
808817
$(CXX) $(CXXFLAGS) -c $< -o $(call GET_OBJ_FILE, $<)
809818
$(CXX) $(CXXFLAGS) $(filter-out %.h $<,$^) $(call GET_OBJ_FILE, $<) -o $@ $(LDFLAGS)

build.zig

+29
Original file line numberDiff line numberDiff line change
@@ -140,4 +140,33 @@ pub fn build(b: *std.build.Builder) !void {
140140
if (server.target.isWindows()) {
141141
server.linkSystemLibrary("ws2_32");
142142
}
143+
144+
const server_assets = [_][]const u8{ "index.html", "index.js", "completion.js", "json-schema-to-grammar.mjs" };
145+
for (server_assets) |asset| {
146+
const input_path = b.fmt("examples/server/public/{s}", .{asset});
147+
const output_path = b.fmt("examples/server/{s}.hpp", .{asset});
148+
149+
// Portable equivalent of `b.addSystemCommand(&.{ "xxd", "-n", asset, "-i", input_path, output_path }) })`:
150+
151+
const input = try std.fs.cwd().readFileAlloc(b.allocator, input_path, std.math.maxInt(usize));
152+
defer b.allocator.free(input);
153+
154+
var buf = std.ArrayList(u8).init(b.allocator);
155+
defer buf.deinit();
156+
157+
for (input) |byte| {
158+
try std.fmt.format(buf.writer(), "0x{X:0>2}, ", .{byte});
159+
}
160+
161+
var name = try std.mem.replaceOwned(u8, b.allocator, asset, "-", "_");
162+
defer b.allocator.free(name);
163+
std.mem.replaceScalar(u8, name, '.', '_');
164+
165+
try std.fs.cwd().writeFile(output_path, b.fmt(
166+
"unsigned char {s}[] = {{{s}}};\nunsigned int {s}_len = {d};\n",
167+
.{ name, buf.items, name, input.len },
168+
));
169+
170+
std.debug.print("Dumped hex of \"{s}\" ({s}) to {s}\n", .{ input_path, name, output_path });
171+
}
143172
}

examples/server/CMakeLists.txt

+19-2
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,29 @@
11
set(TARGET server)
22
option(LLAMA_SERVER_VERBOSE "Build verbose logging option for Server" ON)
33
option(LLAMA_SERVER_SSL "Build SSL support for the server" OFF)
4-
include_directories(${CMAKE_CURRENT_SOURCE_DIR})
5-
add_executable(${TARGET}
4+
include_directories(${CMAKE_CURRENT_SOURCE_DIR} ${CMAKE_CURRENT_BINARY_DIR})
5+
set(TARGET_SRCS
66
server.cpp
77
utils.hpp
88
httplib.h
99
)
10+
set(PUBLIC_ASSETS
11+
index.html
12+
index.js
13+
completion.js
14+
json-schema-to-grammar.mjs
15+
)
16+
foreach(asset ${PUBLIC_ASSETS})
17+
set(input "${CMAKE_CURRENT_SOURCE_DIR}/public/${asset}")
18+
set(output "${CMAKE_CURRENT_BINARY_DIR}/${asset}.hpp")
19+
list(APPEND TARGET_SRCS ${output})
20+
add_custom_command(
21+
DEPENDS "${input}"
22+
OUTPUT "${output}"
23+
COMMAND "${CMAKE_COMMAND}" "-DINPUT=${input}" "-DOUTPUT=${output}" -P "${PROJECT_SOURCE_DIR}/scripts/xxd.cmake"
24+
)
25+
endforeach()
26+
add_executable(${TARGET} ${TARGET_SRCS})
1027
install(TARGETS ${TARGET} RUNTIME)
1128
target_compile_definitions(${TARGET} PRIVATE
1229
SERVER_VERBOSE=$<BOOL:${LLAMA_SERVER_VERBOSE}>

examples/server/completion.js.hpp

-496
This file was deleted.

examples/server/deps.sh

-10
Original file line numberDiff line numberDiff line change
@@ -8,13 +8,3 @@ PUBLIC=$DIR/public
88
echo "download js bundle files"
99
curl https://npm.reversehttp.com/@preact/signals-core,@preact/signals,htm/preact,preact,preact/hooks > $PUBLIC/index.js
1010
echo >> $PUBLIC/index.js # add newline
11-
12-
FILES=$(ls $PUBLIC)
13-
14-
cd $PUBLIC
15-
for FILE in $FILES; do
16-
echo "generate $FILE.hpp"
17-
18-
# use simple flag for old version of xxd
19-
xxd -i $FILE > $DIR/$FILE.hpp
20-
done

0 commit comments

Comments
 (0)