diff options
Diffstat (limited to 'Embed.cmake')
-rw-r--r-- | Embed.cmake | 119 |
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 | |||
5 | option (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 | |||
1 | function (embed_getname output fn) | 9 | function (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) |
17 | endfunction (embed_getname) | 25 | endfunction (embed_getname) |
18 | 26 | ||
@@ -42,25 +50,100 @@ endfunction (embed_write) | |||
42 | function (embed_make) | 50 | function (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 | ||
92 | iBool 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 | |||
98 | iDeclareType(EmbedChunk) | ||
99 | |||
100 | struct Impl_EmbedChunk { | ||
101 | size_t pos; | ||
102 | size_t size; | ||
103 | }; | ||
104 | |||
105 | static 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 | |||
128 | iBool 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 () |
66 | endfunction (embed_make) | 149 | endfunction (embed_make) |