summaryrefslogtreecommitdiff
path: root/Embed.cmake
diff options
context:
space:
mode:
authorJaakko Keränen <jaakko.keranen@iki.fi>2020-07-28 13:50:00 +0300
committerJaakko Keränen <jaakko.keranen@iki.fi>2020-07-28 13:50:00 +0300
commitd1b4d7ec00e83d9f57ad4507233db94ba036f120 (patch)
treede139d77ed4fdaac3e7cda2dfb10b1cb516e3966 /Embed.cmake
parent57ca0f82de3540b0e73c46970e91516e7371913b (diff)
Added EMBED_IN_EXECUTABLE build option
The embedded resources can alternatively be read from a file called 'resources.bin'.
Diffstat (limited to 'Embed.cmake')
-rw-r--r--Embed.cmake119
1 files changed, 101 insertions, 18 deletions
diff --git a/Embed.cmake b/Embed.cmake
index 9b506905..16c47683 100644
--- a/Embed.cmake
+++ b/Embed.cmake
@@ -1,3 +1,11 @@
1# CMake Helper for Binary Resources
2# Copyright: 2020 Jaakko Keränen <jaakko.keranen@iki.fi>
3# License: BSD 2-Clause
4
5option (EMBED_IN_EXECUTABLE "Embed resources inside the executable" ON)
6# Note: If disabled, the Unix "cat" tool is required for concatenating
7# the resources into a single "resources.bin" file.
8
1function (embed_getname output fn) 9function (embed_getname output fn)
2 get_filename_component (name ${fn} NAME_WE) 10 get_filename_component (name ${fn} NAME_WE)
3 string (REPLACE "-" "" name ${name}) 11 string (REPLACE "-" "" name ${name})
@@ -12,7 +20,7 @@ function (embed_getname output fn)
12 set (resName "image") 20 set (resName "image")
13 else () 21 else ()
14 set (resName "blob") 22 set (resName "blob")
15 endif () 23 endif ()
16 set (resName "${resName}${name}_Embedded" PARENT_SCOPE) 24 set (resName "${resName}${name}_Embedded" PARENT_SCOPE)
17endfunction (embed_getname) 25endfunction (embed_getname)
18 26
@@ -42,25 +50,100 @@ endfunction (embed_write)
42function (embed_make) 50function (embed_make)
43 set (EMB_H ${CMAKE_CURRENT_BINARY_DIR}/embedded.h) 51 set (EMB_H ${CMAKE_CURRENT_BINARY_DIR}/embedded.h)
44 set (EMB_C ${CMAKE_CURRENT_BINARY_DIR}/embedded.c) 52 set (EMB_C ${CMAKE_CURRENT_BINARY_DIR}/embedded.c)
45 set (needGen NO) 53 if (EMBED_IN_EXECUTABLE)
46 if (NOT EXISTS ${EMB_H} OR NOT EXISTS ${EMB_C}) 54 set (needGen NO)
47 set (needGen YES) 55 if (NOT EXISTS ${EMB_H} OR NOT EXISTS ${EMB_C})
56 set (needGen YES)
57 else ()
58 file (TIMESTAMP ${EMB_H} genTime %s)
59 foreach (resPath ${ARGV})
60 set (fn "${CMAKE_CURRENT_LIST_DIR}/${resPath}")
61 file (TIMESTAMP ${fn} resTime %s)
62 if (${resTime} GREATER ${genTime})
63 set (needGen YES)
64 endif ()
65 endforeach (resPath)
66 endif ()
48 else () 67 else ()
49 file (TIMESTAMP ${EMB_H} genTime %s) 68 set (needGen YES)
50 foreach (resPath ${ARGV})
51 set (fn "${CMAKE_CURRENT_LIST_DIR}/${resPath}")
52 file (TIMESTAMP ${fn} resTime %s)
53 if (${resTime} GREATER ${genTime})
54 set (needGen YES)
55 endif ()
56 endforeach (resPath)
57 endif () 69 endif ()
58 if (needGen) 70 if (needGen)
59 file (WRITE ${EMB_H} "#include <the_Foundation/block.h>\n") 71 if (EMBED_IN_EXECUTABLE)
60 file (WRITE ${EMB_C} "#include \"embedded.h\"\n") 72 file (WRITE ${EMB_H} "#include <the_Foundation/block.h>\n")
61 foreach (fn ${ARGV}) 73 file (WRITE ${EMB_C} "#include \"embedded.h\"\n")
62 embed_getname (resName ${fn}) 74 foreach (fn ${ARGV})
63 embed_write (${fn} ${resName} ${EMB_C} ${EMB_H}) 75 embed_getname (resName ${fn})
64 endforeach (fn) 76 embed_write (${fn} ${resName} ${EMB_C} ${EMB_H})
77 endforeach (fn)
78 else ()
79 set (EMB_BIN ${CMAKE_CURRENT_BINARY_DIR}/resources.bin)
80 file (REMOVE ${EMB_BIN})
81 execute_process (COMMAND cat ${ARGV} OUTPUT_FILE ${EMB_BIN}
82 WORKING_DIRECTORY ${CMAKE_SOURCE_DIR})
83 set (offsets)
84 set (fpos 0)
85 foreach (fn ${ARGV})
86 file (SIZE ${CMAKE_SOURCE_DIR}/${fn} fileSize)
87 list (APPEND offsets "${fpos}")
88 math (EXPR fpos "${fpos} + ${fileSize}")
89 endforeach (fn)
90 file (WRITE ${EMB_H} "#include <the_Foundation/block.h>\n
91#define iHaveLoadEmbed 1
92iBool load_Embed(const char *path);\n\n")
93 file (WRITE ${EMB_C} [[
94#include "embedded.h"
95#include <the_Foundation/file.h>
96#include <the_Foundation/fileinfo.h>
97
98iDeclareType(EmbedChunk)
99
100struct Impl_EmbedChunk {
101 size_t pos;
102 size_t size;
103};
104
105static const iEmbedChunk chunks_Embed_[] = {
106]])
107 set (index 0)
108 foreach (fn ${ARGV})
109 file (SIZE ${CMAKE_SOURCE_DIR}/${fn} fileSize)
110 list (GET offsets ${index} fpos)
111 file (APPEND ${EMB_C} " { ${fpos}, ${fileSize} },\n")
112 math (EXPR index "${index} + 1")
113 endforeach (fn)
114 file (APPEND ${EMB_C} "};\n\n")
115 foreach (fn ${ARGV})
116 embed_getname (resName ${fn})
117 file (APPEND ${EMB_H} "extern const iBlock ${resName};\n")
118 file (APPEND ${EMB_C} "const iBlock ${resName};\n")
119 endforeach (fn)
120 file (APPEND ${EMB_C} "\nstatic iBlock *blocks_Embed_[] = {\n")
121 foreach (fn ${ARGV})
122 embed_getname (resName ${fn})
123 file (APPEND ${EMB_C} " iConstCast(iBlock *, &${resName}),\n")
124 endforeach (fn)
125 file (APPEND ${EMB_C} [[
126};
127
128iBool load_Embed(const char *path) {
129 const size_t fileSize = (size_t) fileSizeCStr_FileInfo(path);
130 iFile *f = newCStr_File(path);
131 if (open_File(f, readOnly_FileMode)) {
132 iForIndices(i, blocks_Embed_) {
133 const iEmbedChunk *chunk = &chunks_Embed_[i];
134 iBlock *data = blocks_Embed_[i];
135 if (chunk->pos + chunk->size > fileSize) {
136 return iFalse;
137 }
138 init_Block(data, chunk->size);
139 seek_File(f, chunk->pos);
140 readData_File(f, chunk->size, data_Block(data));
141 }
142 }
143 iRelease(f);
144 return iTrue;
145}
146]])
147 endif ()
65 endif () 148 endif ()
66endfunction (embed_make) 149endfunction (embed_make)