Browse Source

Added DataBundle for Unix

This is using the objcopy utility to package data into an object file,
utilizing the linker, as we ought to.
zig-compilation
Macoy Madson 2 months ago
parent
commit
297925d6c7
  1. 122
      src/DataBundle.cake
  2. 8
      test/src/GameLibTests.cake

122
src/DataBundle.cake

@ -0,0 +1,122 @@
;; DataBundle.cake: Bundle data into the executable to avoid loose files
;; Important caveat: The bundled data is not null-terminated, so don't just go printing it as a
;; string or you'll get garbage at the end
(import "CHelpers.cake" "CppHelpers.cake" "ComptimeHelpers.cake")
;; I don't want to expose this until I've determined a clean way to do this.
(defgenerator declare-extern (statement-token (arg-index array))
(var statement (const ([] CStatementOperation))
(array
(array Keyword "extern" -1)
(array Statement null statement-token)))
(return (c-statement-out statement))
(return true))
(defmacro bundle-file (start-var-name symbol end-var-name symbol var-base-type array
filename-token string)
(when (and (= TokenType_Symbol (field (at 1 var-base-type) type))
(std-str-equals (field (at 1 var-base-type) contents) "*"))
(ErrorAtToken (at 1 var-base-type)
"bundled file variable type must not be a pointer. It will be automatically pointerized")
(return false))
(var filename (* (const char)) (call-on c_str (path filename-token > contents)))
(get-or-create-comptime-var files-to-bundle (<> (in std vector) (in std string)))
(call-on-ptr push_back files-to-bundle filename)
(var data-var-name ([] 1024 char) (array 0))
(comptime-cond
('Unix
(var data-var-name-write (* char) data-var-name)
(strncpy data-var-name "_binary_" (array-size data-var-name))
(set data-var-name-write
(+ data-var-name-write (strlen data-var-name)))
(each-char-in-string-const filename current-char
(if (isalnum (deref current-char))
(set (deref data-var-name-write) (deref current-char))
(set (deref data-var-name-write) '_'))
(incr data-var-name-write))
(set (deref data-var-name-write) 0))
('Windows
(Logf "Need to port DataBundle to Windows")
(return false)))
(var data-var-name-start-token Token (deref start-var-name))
(token-contents-snprintf data-var-name-start-token "%s_start" data-var-name)
(var data-var-name-end-token Token (deref end-var-name))
(token-contents-snprintf data-var-name-end-token "%s_end" data-var-name)
(tokenize-push output
(declare-extern (var (token-splice-addr data-var-name-start-token)
(token-splice var-base-type)))
(declare-extern (var (token-splice-addr data-var-name-end-token)
(token-splice var-base-type)))
(var (token-splice start-var-name) (* (token-splice var-base-type))
(addr (token-splice-addr data-var-name-start-token)))
(var (token-splice end-var-name) (* (token-splice var-base-type))
(addr (token-splice-addr data-var-name-end-token))))
(return true))
(defun-comptime convert-all-bundle-files (manager (& ModuleManager) module (* Module) &return bool)
(var environment (& EvaluatorEnvironment) (field manager environment))
(get-or-create-comptime-var files-to-bundle (<> (in std vector) (in std string)))
(var results (<> (in std vector) int))
(call-on resize results (call-on-ptr size files-to-bundle))
(var current-result (* int) (addr (at 0 results)))
(for-in filename (& (in std string)) (deref files-to-bundle)
(var cache-filename ([] MAX_PATH_LENGTH char) (array 0))
(unless (outputFilenameFromSourceFilename
(call-on c_str (field manager buildOutputDir))
(call-on c_str filename)
;; Add to end of file for type. Add bundle in case it's a cpp that we're also building,
;; to prevent name collisions in the cache
"data.o"
cache-filename (sizeof cache-filename))
(return false))
(call-on push_back (path module > compilerLinkOptions) cache-filename)
(unless (fileIsMoreRecentlyModified (call-on c_str filename) cache-filename)
(continue))
(Logf "Bundle filename to: %s => %s\n" (call-on c_str filename) cache-filename)
(comptime-cond
('Unix
(run-process-start-or current-result
("objcopy" "--input" "binary" "--output" "elf64-x86-64" "--binary-architecture" "i386"
(call-on c_str filename) cache-filename)
(return false)))
('Windows
(Logf "Need to port DataBundle to Windows")
(return false)))
(incr current-result))
(waitForAllProcessesClosed null)
(var result-index int 0)
(for-in result bool results
(unless (= 0 result)
(Logf "Failed to bundle file %s\n" (call-on c_str (at result-index (deref files-to-bundle))))
(return false))
(incr result-index))
(return true))
(add-compile-time-hook-module pre-build convert-all-bundle-files)
(comptime-cond
('auto-test
(c-import "<stdio.h>")
;; Bundle our own source code
(bundle-file data-start data-end (const char)
"../src/DataBundle.cake")
(defun-nodecl test--bundle-file (&return int)
(fprintf stderr "Bundled data:\n")
;; We can't simply fprintf it because it's not null-terminated
(each-in-range (- data-end data-start) current-char-index
(putc (at data-start current-char-index) stderr))
(return 0))))

8
test/src/GameLibTests.cake

@ -35,8 +35,8 @@
(true
"src/Config_Linux.cake")))
;; (var test-minimal bool true)
(var test-minimal bool false)
(var test-minimal bool true)
;; (var test-minimal bool false)
;; (var test-opengl-only bool true)
(var test-opengl-only bool false)
@ -51,7 +51,7 @@
(array platform-config
"../src/AutoTest.cake" "../src/Introspection.cake"
"../src/Dictionary.cake" "../src/DynamicArray.cake"
"../src/TaskSystem.cake" "../src/Image.cake")))
"../src/TaskSystem.cake" "../src/Image.cake" "../src/DataBundle.cake")))
(test-opengl-only
(gamelib-run-test
@ -67,7 +67,7 @@
"../src/Aubio.cake" "../src/ImGui.cake" "../src/Dictionary.cake"
"../src/DynamicArray.cake" "../src/Introspection.cake" "../src/OpenGL.cake"
"../src/Tracy.cake" "../src/TaskSystem.cake" "../src/Image.cake"
"../src/ProfilerAutoInstrument.cake"))
"../src/DataBundle.cake" "../src/ProfilerAutoInstrument.cake"))
(when test-ogre
(gamelib-run-test "Ogre" (array platform-config "src/OgreApp.cake"))

Loading…
Cancel
Save