-*build
*.o
-clean
+*build
Finally, with an XPM file loaded, color modes can be changed by pressing corresponding keys (see a complete list of key bindings by using the `-h` flag).
```console
-$ ./bin/simplexpm -f images/test.xpm
+$ ./bin/simplexpm -f assets/test.xpm
```
-
+
## Theory of Operation
-#define ROOT
-#include "build.h"
-
#include "external/cbs/cbs.c"
int main(void) {
- build(NULL);
+ build("./");
build("external/");
build("src/");
- compile("clean", NULL);
-
- load('x', "clean", "clean", NULL);
-
return 0;
}
-/* Switch the following #define to change whether or not raylib is built as a
- * static or dynamic library; be sure to `clean' before you `build' again.
- */
+// Rebuild with the following #define to use Raylib as a dynamic library
// #define DYNAMICLIBS
-#ifdef DYNAMICLIBS
-#define LIBEXT DYEXT
-#else
-#define LIBEXT ".a"
-#endif
-
-#define CBSROOT ROOT "external/cbs/"
-#define CBSLIB CBSROOT "cbs" LIBEXT
-#define RLROOT ROOT "external/raylib/"
-#define RLLIB RLROOT "raylib" LIBEXT
-#define RLSRC RLROOT "src/"
-#define RLHDR RLSRC "raylib"
-#define SIMPLEXPM ROOT "bin/simplexpm"
-#define SRC ROOT "src/"
-
-#define CFRAYLIB "-I" RLSRC
-
#ifdef __APPLE__
#define LFRAYLIB \
"-framework", "Cocoa", \
+++ /dev/null
-#define ROOT
-#include "build.h"
-
-#include "external/cbs/cbs.c"
-
-#define FIND "/usr/bin/find"
-#define RM "/bin/rm"
-#define GENCOLORS SRC "colors/gencolors"
-#define GENFONT SRC "font/genfont"
-#define COLORS SRC "colors.c"
-#define FONT SRC "font.c"
-
-int main(void) {
- char *what, **whos, **regexes, ***rms;
- size_t i;
- pid_t cpid;
-
- what = "remove";
-
- // Remove build executables and object files
- whos = (char *[2]){"{*/*build,*/*/*build}", "{*/*.o,*/*/*.o,*/*/*/*.o}"};
- regexes = (char *[2]){".*[^\\.]/build$", ".*\\.o$"};
- for (i = 0; i < 2; ++i) {
- if ((cpid = fork()) == 0)
- run(FIND, (char *[]){"find", ".", "-regex", regexes[i],
- "-exec", "rm", "{}", "+", NULL}, what, whos[i]);
- await(cpid, what, whos[i]);
- }
-
- /* Remove cbs and raylib libraries, application executables,
- * automatically generated source files, and ourself
- */
- whos = (char *[5]){extend(CBSLIB, LIBEXT), extend(RLLIB, LIBEXT),
- "{" GENCOLORS "," GENFONT "," SIMPLEXPM "}",
- "{" COLORS "," FONT "}", "clean"};
- rms = (char **[5]){(char *[3]){whos[0]}, (char *[3]){whos[1]},
- (char *[3]){GENCOLORS, GENFONT, SIMPLEXPM},
- (char *[3]){COLORS, FONT}, (char *[3]){whos[4]}};
- for (i = 0; i < 5; ++i) {
- if ((cpid = fork()) == 0)
- run(RM, (char *[]){"rm", "-f", rms[i][0], rms[i][1], rms[i][2], NULL},
- what, whos[i]);
- await(cpid, what, whos[i]);
- }
- free(whos[0]);
-
- return EXIT_SUCCESS;
-}
-#define ROOT "../"
#include "../build.h"
-
#include "cbs/cbs.c"
+#include "cbsfile.c"
-#define CBSSRC CBSROOT "cbs"
-#define RLSRCS \
- RLSRC "raudio", RLSRC "rmodels", \
- RLSRC "rshapes", RLSRC "rtext", \
- RLSRC "rtextures", RLSRC "utils", \
- RLSRC "rcore", RLSRC "rglfw"
-
+#define CFGLFW "-I" RLSRC "external/glfw/include"
#ifdef __APPLE__
#define CFGRAPHICS "-x", "objective-c"
#else
#define CFGRAPHICS "-D_GLFW_X11"
#endif
-#define CFGLFW "-I" RLSRC "external/glfw/include"
-#ifdef DYNAMICLIBS
-#define CFPIC "-fPIC"
-#else
-#define CFPIC NULL
-#endif
-#define CFGLOBALS "-DPLATFORM_DESKTOP", CFPIC
-
-#ifndef DYNAMICLIBS
-#undef LFRAYLIB
-#define LFRAYLIB NULL
-#endif
-
#ifdef DYNAMICLIBS
+#define CLPIC LIST("-fPIC")
+#define CFGENERAL "-DPLATFORM_DESKTOP", "-fPIC"
#define LIBTYPE 'd'
+#define LLRAYLIB LIST(LFRAYLIB)
#else
+#define CLPIC NONE
+#define CFGENERAL "-DPLATFORM_DESKTOP"
#define LIBTYPE 's'
+#define LLRAYLIB NONE
#endif
-void cbs(void) {
- cflags = (char *[]){CFPIC, NULL};
- compile(CBSSRC, NULL);
+#define RLLIB "raylib/raylib"
+#define RLSRC "raylib/src/"
+
+void buildcbs(void) {
+ char **c, **l;
+
+ c = cflags;
+ l = lflags;
- load(LIBTYPE, CBSLIB, CBSSRC, NULL);
+ cflags = CLPIC;
+ compile("cbs/cbs");
+
+ lflags = NONE;
+ load(LIBTYPE, "cbs/cbs", LIST("cbs/cbs"));
+
+ cflags = c;
+ lflags = l;
}
-void raylib(void) {
- char **src;
- size_t i;
+void buildraylib(void) {
+ struct cbsfile *files;
+
+ files = (struct cbsfile []){
+ {RLLIB, LLRAYLIB, LIBTYPE},
+
+ {RLSRC "raudio", LIST(CFGENERAL)},
+ {RLSRC "rcore", LIST(CFGLFW, CFGENERAL)},
+ {RLSRC "rglfw", LIST(CFGLFW, CFGRAPHICS, CFGENERAL)},
+ {RLSRC "rmodels", LIST(CFGENERAL)},
+ {RLSRC "rshapes", LIST(CFGENERAL)},
+ {RLSRC "rtext", LIST(CFGENERAL)},
+ {RLSRC "rtextures", LIST(CFGENERAL)},
+ {RLSRC "utils", LIST(CFGENERAL)},
- src = (char *[]){RLSRCS, NULL};
- cflags = (char *[]){CFGLOBALS, NULL};
- for (i = 0; i < 6; ++i) compile(src[i], NULL);
- cflags = (char *[]){CFGLFW, CFGLOBALS, NULL};
- compile(src[6], NULL);
- cflags = (char *[]){CFGRAPHICS, CFGLFW, CFGLOBALS, NULL};
- compile(src[7], NULL);
+ {NULL}
+ };
- lflags = (char *[]){LFRAYLIB, NULL};
- load(LIBTYPE, RLLIB, RLSRCS, NULL);
+ buildfiles(files);
}
int main(void) {
- build(NULL);
+ build("./");
- cbs();
- raylib();
+ buildcbs();
+ buildraylib();
return EXIT_SUCCESS;
}
-Subproject commit a2cb47c262bee92a2f7cab689e42ae8452c9e952
+Subproject commit 280a887eb0b54773a149cbc15b0f911c981edb97
--- /dev/null
+struct cbsfile {
+ char *name, **flags, type;
+};
+
+void buildfiles(struct cbsfile *files) {
+ char **c, **l, **names;
+ struct cbsfile *target;
+ size_t i;
+
+ c = cflags;
+ l = lflags;
+
+ target = files++;
+
+ for (i = 0; files[i].name; ++i) if (files[i].flags) {
+ cflags = files[i].flags;
+ compile(files[i].name);
+ }
+
+ names = allocate((i + 1) * sizeof *names);
+ for (i = 0; files[i].name; ++i) names[i] = files[i].name;
+
+ lflags = target->flags;
+ load(target->type, target->name, names);
+
+ free(names);
+
+ cflags = c;
+ lflags = l;
+}
colors.c
font.c
+buildfont
-#define ROOT "../"
-#include "../build.h"
+#include <sys/mman.h>
+#include "../build.h"
#include "../external/cbs/cbs.c"
+#include "../external/cbsfile.c"
-#define CFDYEXT "-DDYEXT=\"" DYEXT "\""
-
+#define CLRAYLIB LIST("-I../external/raylib/src/")
#ifdef DYNAMICLIBS
-#undef LFRAYLIB
-#define LFRAYLIB NULL
+#define LIBEXT DYEXT
+#define LLRAYLIB NONE
+#else
+#define LIBEXT ".a"
+#define LLRAYLIB LIST(LFRAYLIB)
#endif
+#define RLLIB "../external/raylib/raylib" LIBEXT
+#define CBSLIB "../external/cbs/cbs" LIBEXT
+
+static void buildcolors(void) {
+ int quit, txtfd, codefd;
+ char *txt, *code, *p;
+ struct stat txtstat;
+ size_t l, i;
+ void *map;
+ unsigned char r, g, b;
+
+ quit = 1;
+ txt = "../assets/rgb.txt";
+ code = "colors.c";
+ if ((txtfd = open(txt, O_RDONLY)) == -1)
+ err(EXIT_FAILURE, "Unable to open `%s' for reading", txt);
+ if (fstat(txtfd, &txtstat) == -1) {
+ warn("Unable to stat `%s'", txt);
+ goto closetxt;
+ }
+ l = txtstat.st_size;
+ if ((p = map = mmap(NULL, l, PROT_READ | PROT_WRITE,
+ MAP_PRIVATE, txtfd, 0)) == MAP_FAILED) {
+ warn("Unable to map `%s' to memory", txt);
+ goto closetxt;
+ }
+ if ((codefd = open(code, O_WRONLY | O_CREAT | O_TRUNC, 0644)) == -1) {
+ warn("Unable to open `%s' for writing", code);
+ goto munmap;
+ }
+
+ if (dprintf(codefd, "#include <stddef.h>\n\n"
+ "#include \"colors.h\"\n\n"
+ "struct color colors[] = {\n"
+ "\t{\"None\", 0x00ffffff},\n") == -1) {
+ warn("Unable to write to `%s'", code);
+ goto closecode;
+ }
+ for (i = 1; p < (char *)map + l; ++i) {
+ r = strtol(p, &p, 10);
+ g = strtol(p, &p, 10);
+ b = strtol(p, &p, 10);
+ if (dprintf(codefd, "\t{\"%s\", 0x%02x%02x%02x},\n",
+ strsep(&p, "\n") + 2, r, g, b) == -1) {
+ warn("Unable to write to `%s'", code);
+ goto closecode;
+ }
+ }
+ if (dprintf(codefd, "};\n\nsize_t numcolors = %zu;\n", i) == -1)
+ warn("Unable to write to `%s'", code);
+
+ quit = 0;
+
+closecode:
+ if (close(codefd) == -1) {
+ warn("Unable to close `%s'", code);
+ quit = 1;
+ }
+
+munmap:
+ if (munmap(map, l) == -1) {
+ warn("Unable to unmap memory associated with `%s'", txt);
+ quit = 1;
+ }
+
+closetxt:
+ if (close(txtfd) == -1) {
+ warn("Unable to close `%s'", txt);
+ quit = 1;
+ }
+
+ if (quit) exit(EXIT_FAILURE);
+}
+
+static void buildfont(void) {
+ char **c, **l;
+ pid_t cpid;
+
+ c = cflags;
+ l = lflags;
+
+ cflags = CLRAYLIB;
+ compile("buildfont");
+
+ lflags = LLRAYLIB;
+ load('x', "buildfont", LIST("buildfont", RLLIB));
+
+ if ((cpid = fork()) == 0)
+ run("buildfont", LIST("buildfont"), "run", "buildfont");
+ await(cpid, "run", "buildfont");
+
+ cflags = c;
+ lflags = l;
+}
+
int main(void) {
- build(NULL);
+ struct cbsfile *files;
+
+ build("./");
+
+ buildcolors();
+ buildfont();
+
+ files = (struct cbsfile []){
+ {"../bin/simplexpm", LLRAYLIB, 'x'},
+
+ {"colors", NONE},
+ {"main", CLRAYLIB},
+ {"options", NONE},
+ {"xpm", CLRAYLIB},
- build("colors/");
- build("font/");
+ {CBSLIB},
+ {RLLIB},
- compile("colors", "colors", NULL);
- cflags = (char *[]){CFRAYLIB, NULL};
- compile("main", "cbs", "options", RLHDR, "xpm", "font.c", NULL);
- cflags = NULL;
- compile("options", "cbs", NULL);
- cflags = (char *[]){CFDYEXT, CFRAYLIB, NULL};
- compile("xpm", "cbs", "colors", RLHDR, "xpm", "colors.c", NULL);
+ {NULL}
+ };
- lflags = (char *[]){LFRAYLIB, NULL};
- load('x', SIMPLEXPM, "colors", "main", "options", "xpm", CBSLIB, RLLIB, NULL);
+ buildfiles(files);
return EXIT_SUCCESS;
}
--- /dev/null
+#include <err.h>
+#include <stdlib.h>
+
+#include "raylib.h"
+
+int main(void) {
+ char *ttf, *code;
+ Font font;
+
+ ttf = "../assets/font.ttf";
+ code = "font.c";
+
+ SetTraceLogLevel(LOG_WARNING);
+ InitWindow(0, 0, "");
+
+ if (!ExportFontAsCode(font = LoadFontEx(ttf, 48, NULL, 95), code))
+ errx(EXIT_FAILURE, "Unable to generate `%s' from `%s'", code, ttf);
+
+ UnloadFont(font);
+
+ return EXIT_SUCCESS;
+}
+#ifdef __APPLE__
+#define DYEXT ".dylib"
+#else
+#define DYEXT ".so"
+#endif
+
+#define LIST(...) (char *[]){__VA_ARGS__, NULL}
+
void *allocate(size_t s);
-void compile(char *src, ...);
-void load(char type, char *target, char *obj, ...);
+void compile(char *src);
+void load(char type, char *target, char **objs);
+++ /dev/null
-#define ROOT "../../"
-#include "../../build.h"
-
-#include "../../external/cbs/cbs.c"
-
-#define COLORS SRC "colors.c"
-
-int main(void) {
- build(NULL);
-
- compile("gencolors", NULL);
-
- load('x', "gencolors", "gencolors", NULL);
-
- if (modified(COLORS, "gencolors.c") || modified(COLORS, "rgb.txt"))
- run("gencolors", (char *[]){"./gencolors", "rgb.txt", COLORS, NULL},
- "run", "gencolors");
-
- return EXIT_SUCCESS;
-}
+++ /dev/null
-#include <err.h>
-#include <fcntl.h>
-#include <stdio.h>
-#include <stdlib.h>
-#include <string.h>
-#include <sys/mman.h>
-#include <sys/stat.h>
-#include <unistd.h>
-
-int main(int argc, char **argv) {
- int result, infd, outfd;
- struct stat instat;
- size_t l, i;
- void *map;
- char *p;
- unsigned char r, g, b;
-
- result = EXIT_FAILURE;
- if (argc != 3)
- errx(EXIT_FAILURE, "Incorrect number of arguments: %s <input.txt> <output.c>",
- argv[0]);
- if ((infd = open(argv[1], O_RDONLY)) == -1)
- err(EXIT_FAILURE, "Unable to open `%s' for reading", argv[1]);
- if (fstat(infd, &instat) == -1) {
- warn("Unable to stat `%s'", argv[1]);
- goto closein;
- }
- l = instat.st_size;
- if ((p = map = mmap(NULL, l, PROT_READ | PROT_WRITE,
- MAP_PRIVATE, infd, 0)) == MAP_FAILED) {
- warn("Unable to map `%s' to memory", argv[1]);
- goto closein;
- }
- if ((outfd = open(argv[2], O_WRONLY | O_CREAT | O_TRUNC, 0644)) == -1) {
- warn("Unable to open `%s' for writing", argv[2]);
- goto munmap;
- }
-
- if (dprintf(outfd, "#include <stddef.h>\n\n"
- "#include \"colors.h\"\n\n"
- "struct color colors[] = {\n"
- "\t{\"None\", 0x00ffffff},\n") == -1) {
- warn("Unable to write to `%s'", argv[2]);
- goto closeout;
- }
- for (i = 1; p < (char *)map + l; ++i) {
- r = strtol(p, &p, 10);
- g = strtol(p, &p, 10);
- b = strtol(p, &p, 10);
- if (dprintf(outfd, "\t{\"%s\", 0x%02x%02x%02x},\n",
- strsep(&p, "\n") + 2, r, g, b) == -1) {
- warn("Unable to write to `%s'", argv[2]);
- goto closeout;
- }
- }
- if (dprintf(outfd, "};\n\nsize_t numcolors = %zu;\n", i) == -1)
- warn("Unable to write to `%s'", argv[2]);
-
- result = EXIT_SUCCESS;
-
-closeout:
- if (close(outfd) == -1) {
- warn("Unable to close `%s'", argv[2]);
- result = EXIT_FAILURE;
- }
-
-munmap:
- if (munmap(map, l) == -1) {
- warn("Unable to unmap memory associated with `%s'", argv[1]);
- result = EXIT_FAILURE;
- }
-
-closein:
- if (close(infd) == -1) {
- warn("Unable to close `%s'", argv[1]);
- result = EXIT_FAILURE;
- }
-
- return result;
-}
+++ /dev/null
-#define ROOT "../../"
-#include "../../build.h"
-
-#include "../../external/cbs/cbs.c"
-
-#define FONT SRC "font.c"
-
-#ifdef DYNAMICLIBS
-#undef LFRAYLIB
-#define LFRAYLIB NULL
-#endif
-
-int main(void) {
- build(NULL);
-
- cflags = (char *[]){CFRAYLIB, NULL};
- compile("genfont", RLHDR, NULL);
-
- lflags = (char *[]){LFRAYLIB, NULL};
- load('x', "genfont", "genfont", RLLIB, NULL);
-
- if (modified(FONT, "genfont.c") || modified(FONT, "font.ttf"))
- run("genfont", (char *[]){"./genfont", "font.ttf", FONT, NULL},
- "run", "genfont");
-
- return EXIT_SUCCESS;
-}
+++ /dev/null
-#include <err.h>
-#include <stdlib.h>
-
-#include "raylib.h"
-
-int main(int argc, char **argv) {
- Font font;
-
- if (argc != 3)
- errx(EXIT_FAILURE, "Incorrect number of arguments: %s <input.ttf> <output.c>",
- argv[0]);
-
- SetTraceLogLevel(LOG_WARNING);
- InitWindow(0, 0, "");
-
- font = LoadFontEx(argv[1], 48, NULL, 95);
- if (!ExportFontAsCode(font, argv[2]))
- errx(EXIT_FAILURE, "Unable to generate `%s' from `%s'", argv[2], argv[1]);
-
- UnloadFont(font);
-
- /* Don't call CloseWindow() so focus doesn't shift to
- * the transient application we open to load the font
- */
-
- return EXIT_SUCCESS;
-}
}
if ((cpid = fork()) == 0) {
- compile(TMP, NULL);
- load('d', TMP, TMP, NULL);
+ compile(TMP);
+ load('d', TMP, LIST(TMP));
exit(EXIT_SUCCESS);
}
if (cpid == -1 || waitpid(cpid, &status, 0) == -1) {