Provides an entry point that builds and returns a combined LH + RH keyboard firmware when provided a keymap via a POST body. Wraps compilation with ccache, and includes a pre-warmed cache of the build in /tmp/ccache. To maximize chance of a direct cache hit, changes the lambda driver to always build in /tmp/build. some back of the envelope measurements (2012 xeon e3-1230v2, nixos) clean build, no cache -> 21.308 clean build, cache -> 7.145 modified keymap, clean build, cache -> 12.127
59 lines
1.4 KiB
Ruby
59 lines
1.4 KiB
Ruby
# frozen_string_literal: true
|
|
|
|
require 'tmpdir'
|
|
require 'json'
|
|
require 'base64'
|
|
|
|
class Compiler
|
|
class CompileError < RuntimeError
|
|
attr_reader :status, :log
|
|
|
|
def initialize(message, status: 400, log:)
|
|
super(message)
|
|
@status = status
|
|
@log = log
|
|
end
|
|
end
|
|
|
|
def compile(keymap_data)
|
|
in_build_dir do
|
|
File.open('build.keymap', 'w') do |io|
|
|
io.write(keymap_data)
|
|
end
|
|
|
|
compile_output = nil
|
|
|
|
IO.popen(['compileZmk', './build.keymap'], err: [:child, :out]) do |io|
|
|
compile_output = io.read
|
|
end
|
|
|
|
compile_output = compile_output.split("\n")
|
|
|
|
unless $?.success?
|
|
status = $?.exitstatus
|
|
raise CompileError.new("Compile failed with exit status #{status}", log: compile_output)
|
|
end
|
|
|
|
unless File.exist?('zephyr/combined.uf2')
|
|
raise CompileError.new('Compile failed to produce result binary', status: 500, log: compile_output)
|
|
end
|
|
|
|
result = File.read('zephyr/combined.uf2')
|
|
|
|
[result, compile_output]
|
|
end
|
|
end
|
|
|
|
# Lambda is single-process per container, and we get substantial speedups
|
|
# from ccache by always building in the same path
|
|
BUILD_DIR = '/tmp/build'
|
|
|
|
def in_build_dir
|
|
FileUtils.remove_entry(BUILD_DIR, true)
|
|
Dir.mkdir(BUILD_DIR)
|
|
Dir.chdir(BUILD_DIR)
|
|
yield
|
|
ensure
|
|
FileUtils.remove_entry(BUILD_DIR, true) rescue nil
|
|
end
|
|
end
|