datatoc: exclude the initial C-style comment from GLSL/MSL/Cuda files

Add optional argument `STRIP_LEADING_C_COMMENTS` to CMake macros:
data_to_c_simple & data_to_c.

Strip leading C-style comments that don't bloat binary size.
Comments are replaced with blank lines so line numbers in error messages
match. Reduces Blender's binary size by ~70kb.
This commit is contained in:
Campbell Barton
2023-08-19 17:56:50 +10:00
parent 63c1a26069
commit 20b4a77872
8 changed files with 169 additions and 12 deletions

View File

@@ -1096,7 +1096,8 @@ function(delayed_do_install
endif()
endfunction()
# Same as above but generates the var name and output automatic.
# Takes optional: `STRIP_LEADING_C_COMMENTS` argument.
function(data_to_c
file_from file_to
list_to_add
@@ -1107,17 +1108,27 @@ function(data_to_c
get_filename_component(_file_to_path ${file_to} PATH)
set(optional_args "")
foreach(f ${ARGN})
if (f STREQUAL "STRIP_LEADING_C_COMMENTS")
set(optional_args "--options=strip_leading_c_comments")
else()
message(FATAL_ERROR "Unknown optional argument ${f} to \"data_to_c\"")
endif()
endforeach()
add_custom_command(
OUTPUT ${file_to}
COMMAND ${CMAKE_COMMAND} -E make_directory ${_file_to_path}
COMMAND "$<TARGET_FILE:datatoc>" ${file_from} ${file_to}
COMMAND "$<TARGET_FILE:datatoc>" ${file_from} ${file_to} ${optional_args}
DEPENDS ${file_from} datatoc)
set_source_files_properties(${file_to} PROPERTIES GENERATED TRUE)
endfunction()
# same as above but generates the var name and output automatic.
# Same as above but generates the var name and output automatic.
# Takes optional: `STRIP_LEADING_C_COMMENTS` argument.
function(data_to_c_simple
file_from
list_to_add
@@ -1134,10 +1145,19 @@ function(data_to_c_simple
get_filename_component(_file_to_path ${_file_to} PATH)
set(optional_args "")
foreach(f ${ARGN})
if (f STREQUAL "STRIP_LEADING_C_COMMENTS")
set(optional_args "--options=strip_leading_c_comments")
else()
message(FATAL_ERROR "Unknown optional argument ${f} to \"data_to_c_simple\"")
endif()
endforeach()
add_custom_command(
OUTPUT ${_file_to}
COMMAND ${CMAKE_COMMAND} -E make_directory ${_file_to_path}
COMMAND "$<TARGET_FILE:datatoc>" ${_file_from} ${_file_to}
COMMAND "$<TARGET_FILE:datatoc>" ${_file_from} ${_file_to} ${optional_args}
DEPENDS ${_file_from} datatoc)
set_source_files_properties(${_file_to} PROPERTIES GENERATED TRUE)

View File

@@ -66,7 +66,7 @@ if(WITH_OPENCOLORIO)
set(GLSL_C)
foreach(GLSL_FILE ${GLSL_SRC})
data_to_c_simple(${GLSL_FILE} GLSL_C)
data_to_c_simple(${GLSL_FILE} GLSL_C STRIP_LEADING_C_COMMENTS)
endforeach()
blender_add_lib(bf_ocio_shaders "${GLSL_C}" "" "" "")

View File

@@ -87,7 +87,11 @@ if(WITH_OPENSUBDIV)
add_definitions(-D_USE_MATH_DEFINES)
endif()
data_to_c_simple(internal/evaluator/shaders/glsl_compute_kernel.glsl SRC)
data_to_c_simple(
internal/evaluator/shaders/glsl_compute_kernel.glsl
SRC
STRIP_LEADING_C_COMMENTS
)
else()
list(APPEND SRC
stub/opensubdiv_stub.cc

View File

@@ -612,6 +612,7 @@ if(WITH_COMPOSITOR_CPU)
${CMAKE_CURRENT_SOURCE_DIR}/operations/COM_OpenCLKernels.cl
${CMAKE_CURRENT_BINARY_DIR}/operations/COM_OpenCLKernels.cl.h
SRC
STRIP_LEADING_C_COMMENTS
)
add_definitions(-DCL_USE_DEPRECATED_OPENCL_1_1_APIS)

View File

@@ -213,7 +213,7 @@ set(GLSL_SRC
set(GLSL_C)
foreach(GLSL_FILE ${GLSL_SRC})
data_to_c_simple(${GLSL_FILE} GLSL_C)
data_to_c_simple(${GLSL_FILE} GLSL_C STRIP_LEADING_C_COMMENTS)
endforeach()
blender_add_lib(bf_compositor_shaders "${GLSL_C}" "" "" "")

View File

@@ -15,6 +15,8 @@
#define MAX2(x, y) ((x) > (y) ? (x) : (y))
#define MAX3(x, y, z) MAX2(MAX2((x), (y)), (z))
#define STRPREFIX(a, b) (strncmp((a), (b), strlen(b)) == 0)
static char *arg_basename(char *string)
{
char *lfslash, *lbslash;
@@ -31,6 +33,95 @@ static char *arg_basename(char *string)
return MAX3(string, lfslash, lbslash);
}
/**
* Detect leading C-style comments and seek the file to it's end,
* returning the number of bytes skipped and setting `r_newlines`
* or return zero and seek to the file start.
*
* The number of newlines is used so the number of lines matches
* the generated data, so any errors provide useful line numbers
* (this could be made optional, as there may be cases where it's not helpful).
*/
static int strip_leading_c_comment(FILE *fpin, int size, int *r_newlines)
{
*r_newlines = 0;
if (size < 4) {
return 0;
}
enum {
IS_SPACE = 1,
IS_COMMENT = 2,
IS_COMMENT_MAYBE_BEG = 3,
IS_COMMENT_MAYBE_END = 4,
} context = IS_SPACE;
/* Last known valid offset. */
int offset_checkpoint = 0;
int newlines_checkpoint = 0;
int offset = 0;
int newlines = 0;
while (offset < size) {
const char c_curr = getc(fpin);
offset += 1;
if (context == IS_SPACE) {
if (c_curr == ' ' || c_curr == '\t' || c_curr == '\n') {
/* Pass. */
}
else if (c_curr == '/') {
context = IS_COMMENT_MAYBE_BEG;
}
else {
/* Non-space and non-comment, exit. */
break;
}
}
else if (context == IS_COMMENT) {
if (c_curr == '*') {
context = IS_COMMENT_MAYBE_END;
}
}
else if (context == IS_COMMENT_MAYBE_BEG) {
if (c_curr == '*') {
context = IS_COMMENT;
}
else {
/* Non-comment text, exit. */
break;
}
}
else if (context == IS_COMMENT_MAYBE_END) {
if (c_curr == '/') {
context = IS_SPACE;
}
else if (c_curr == '*') {
/* Pass. */
}
else {
context = IS_COMMENT;
}
}
if (c_curr == '\n') {
newlines += 1;
}
if (context == IS_SPACE) {
offset_checkpoint = offset;
newlines_checkpoint = newlines;
}
}
if (offset != offset_checkpoint) {
fseek(fpin, offset_checkpoint, SEEK_SET);
}
*r_newlines = newlines_checkpoint;
return offset_checkpoint;
}
int main(int argc, char **argv)
{
FILE *fpin, *fpout;
@@ -38,11 +129,36 @@ int main(int argc, char **argv)
int i;
int argv_len;
bool strip_leading_c_comments_test = false;
int leading_newlines = 0;
if (argc < 2) {
printf("Usage: datatoc <data_file_from> <data_file_to>\n");
printf(
"Usage: "
"datatoc <data_file_from> <data_file_to> [--options=strip_leading_c_comments]\n");
exit(1);
}
if (argc > 3) {
const char *arg_extra = argv[3];
const char *arg_transform = "--options=";
if (STRPREFIX(arg_extra, arg_transform)) {
/* We may want to have other options in the future. */
const char *options = arg_extra + strlen(arg_transform);
if (strcmp(options, "strip_leading_c_comments") == 0) {
strip_leading_c_comments_test = true;
}
else {
printf("Unknown --options=<%s>\n", options);
exit(1);
}
}
else {
printf("Unknown argument <%s>, expected --options=[...] or none.\n", arg_extra);
exit(1);
}
}
fpin = fopen(argv[1], "rb");
if (!fpin) {
printf("Unable to open input <%s>\n", argv[1]);
@@ -55,6 +171,11 @@ int main(int argc, char **argv)
size = ftell(fpin);
fseek(fpin, 0L, SEEK_SET);
if (strip_leading_c_comments_test) {
const int size_offset = strip_leading_c_comment(fpin, size, &leading_newlines);
size -= size_offset; /* The comment is skipped, */
}
if (argv[1][0] == '.') {
argv[1]++;
}
@@ -82,8 +203,19 @@ int main(int argc, char **argv)
fprintf(fpout, "extern const int datatoc_%s_size;\n", argv[1]);
fprintf(fpout, "extern const char datatoc_%s[];\n\n", argv[1]);
fprintf(fpout, "const int datatoc_%s_size = %d;\n", argv[1], int(size));
fprintf(fpout, "const int datatoc_%s_size = %d;\n", argv[1], int(leading_newlines + size));
fprintf(fpout, "const char datatoc_%s[] = {\n", argv[1]);
if (leading_newlines) {
while (leading_newlines--) {
if (leading_newlines % 32 == 31) {
fprintf(fpout, "\n");
}
fprintf(fpout, "%3d,", '\n');
}
fprintf(fpout, "\n");
}
while (size--) {
/* Even though this file is generated and doesn't need new-lines,
* these files may be loaded by developers when looking up symbols.

View File

@@ -834,7 +834,7 @@ set(GLSL_SRC
set(GLSL_C)
foreach(GLSL_FILE ${GLSL_SRC})
data_to_c_simple(${GLSL_FILE} GLSL_C)
data_to_c_simple(${GLSL_FILE} GLSL_C STRIP_LEADING_C_COMMENTS)
endforeach()
blender_add_lib(bf_draw_shaders "${GLSL_C}" "" "" "")

View File

@@ -610,13 +610,13 @@ if(WITH_METAL_BACKEND)
set(MSL_C)
foreach(MSL_FILE ${MSL_SRC})
data_to_c_simple(${MSL_FILE} MSL_C)
data_to_c_simple(${MSL_FILE} MSL_C STRIP_LEADING_C_COMMENTS)
endforeach()
endif()
set(GLSL_C)
foreach(GLSL_FILE ${GLSL_SRC})
data_to_c_simple(${GLSL_FILE} GLSL_C)
data_to_c_simple(${GLSL_FILE} GLSL_C STRIP_LEADING_C_COMMENTS)
endforeach()
set(SHADER_C)