forked from pyrite-dev/pmake
subdirectory support
This commit is contained in:
parent
7ce5bd3cf3
commit
96f3fa1f70
9 changed files with 109 additions and 29 deletions
4
.gitignore
vendored
4
.gitignore
vendored
|
|
@ -3,8 +3,8 @@
|
||||||
*.o
|
*.o
|
||||||
*.lib
|
*.lib
|
||||||
*.a
|
*.a
|
||||||
/Makefile
|
Makefile
|
||||||
/*.make
|
*.make
|
||||||
/src/compiler/*.c
|
/src/compiler/*.c
|
||||||
/src/system/*.c
|
/src/system/*.c
|
||||||
/src/js/*.c
|
/src/js/*.c
|
||||||
|
|
|
||||||
|
|
@ -69,7 +69,7 @@ mk/js.mk:
|
||||||
mk: mk/js.mk
|
mk: mk/js.mk
|
||||||
|
|
||||||
format:
|
format:
|
||||||
clang-format --verbose -i src/*/*.js `find src -name "*.c" -or -name "*.h"`
|
clang-format --verbose -i `find pmake.js external src "(" -name "*.c" -or -name "*.h" -or -name "*.js" ")" -and -not -name "duk*" -and -not -name "stb_*.h"`
|
||||||
|
|
||||||
maint:
|
maint:
|
||||||
rm -f mk/*.mk
|
rm -f mk/*.mk
|
||||||
|
|
|
||||||
11
external/duktape/pmake.js
vendored
Normal file
11
external/duktape/pmake.js
vendored
Normal file
|
|
@ -0,0 +1,11 @@
|
||||||
|
function main() {
|
||||||
|
const duktape = new pmake.LibraryProject("duktape");
|
||||||
|
duktape.sources = fs.glob("*.c");
|
||||||
|
duktape.includes = [ "." ];
|
||||||
|
|
||||||
|
if(pmake.system.target == "Unix") {
|
||||||
|
duktape.libraries = [ "m" ];
|
||||||
|
}
|
||||||
|
|
||||||
|
pmake.register(duktape);
|
||||||
|
}
|
||||||
12
pmake.js
12
pmake.js
|
|
@ -16,15 +16,7 @@ function main() {
|
||||||
generate("src/system/*.js");
|
generate("src/system/*.js");
|
||||||
generate("src/js/*.js");
|
generate("src/js/*.js");
|
||||||
|
|
||||||
const Duktape = new pmake.LibraryProject("Duktape");
|
pmake.subdirectory("external/duktape");
|
||||||
Duktape.output = "duktape";
|
|
||||||
Duktape.sources = fs.glob("external/duktape/*.c");
|
|
||||||
Duktape.includes = [ "external/duktape" ];
|
|
||||||
Duktape.libdirs = ["a"];
|
|
||||||
|
|
||||||
if(pmake.system.target == "Unix") {
|
|
||||||
Duktape.libraries = [ "m" ];
|
|
||||||
}
|
|
||||||
|
|
||||||
const stb = new pmake.InterfaceProject("stb");
|
const stb = new pmake.InterfaceProject("stb");
|
||||||
stb.includes = [ "external/stb" ];
|
stb.includes = [ "external/stb" ];
|
||||||
|
|
@ -32,7 +24,7 @@ function main() {
|
||||||
const PMake = new pmake.ExecutableProject("PMake");
|
const PMake = new pmake.ExecutableProject("PMake");
|
||||||
PMake.output = "pmake";
|
PMake.output = "pmake";
|
||||||
PMake.sources = fs.glob("src/*.c", "src/compiler/*.c", "src/system/*.c", "src/js/*.c");
|
PMake.sources = fs.glob("src/*.c", "src/compiler/*.c", "src/system/*.c", "src/js/*.c");
|
||||||
PMake.libraries = [ Duktape, stb ];
|
PMake.libraries = [ "duktape", stb ];
|
||||||
|
|
||||||
pmake.register(PMake);
|
pmake.register(PMake);
|
||||||
}
|
}
|
||||||
|
|
|
||||||
40
src/js.c
40
src/js.c
|
|
@ -30,6 +30,24 @@ static void js_win32_init(void) {
|
||||||
duk_put_prop_string(js_ctx, 0, "WIN32");
|
duk_put_prop_string(js_ctx, 0, "WIN32");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void js_pmake_subdirectory_main(const char* name) {
|
||||||
|
duk_eval_string(js_ctx, "main();");
|
||||||
|
}
|
||||||
|
|
||||||
|
static duk_ret_t js_pmake_subdirectory(duk_context* self) {
|
||||||
|
const char* s = duk_to_string(self, 0);
|
||||||
|
char cwd[1024];
|
||||||
|
|
||||||
|
getcwd(cwd, 1024);
|
||||||
|
if(chdir(s) != 0) return 0;
|
||||||
|
|
||||||
|
js_run("pmake.js", js_pmake_subdirectory_main);
|
||||||
|
|
||||||
|
chdir(cwd);
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
int js_init(int argc, char** argv) {
|
int js_init(int argc, char** argv) {
|
||||||
int st;
|
int st;
|
||||||
|
|
||||||
|
|
@ -47,6 +65,11 @@ int js_init(int argc, char** argv) {
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
duk_get_prop_string(js_ctx, 0, "pmake");
|
||||||
|
duk_push_c_function(js_ctx, js_pmake_subdirectory, 1);
|
||||||
|
duk_put_prop_string(js_ctx, -2, "subdirectory");
|
||||||
|
duk_pop(js_ctx);
|
||||||
|
|
||||||
#define X(name, prefix) \
|
#define X(name, prefix) \
|
||||||
if(duk_peval_lstring(js_ctx, prefix##_##name, prefix##_##name##_len) != 0) { \
|
if(duk_peval_lstring(js_ctx, prefix##_##name, prefix##_##name##_len) != 0) { \
|
||||||
printf("JS error: %s: %s\n", #prefix "/" #name ".js", duk_safe_to_string(js_ctx, -1)); \
|
printf("JS error: %s: %s\n", #prefix "/" #name ".js", duk_safe_to_string(js_ctx, -1)); \
|
||||||
|
|
@ -56,7 +79,7 @@ int js_init(int argc, char** argv) {
|
||||||
|
|
||||||
X(postinit, js);
|
X(postinit, js);
|
||||||
|
|
||||||
if((st = js_run("pmake.js")) != 0) return st;
|
if((st = js_run("pmake.js", NULL)) != 0) return st;
|
||||||
|
|
||||||
X(cmdline, js);
|
X(cmdline, js);
|
||||||
#undef X
|
#undef X
|
||||||
|
|
@ -64,16 +87,21 @@ int js_init(int argc, char** argv) {
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
int js_run(const char* file) {
|
int js_run(const char* file, void (*call)(const char*)) {
|
||||||
FILE* f;
|
FILE* f;
|
||||||
char* buffer;
|
char* buffer;
|
||||||
int len;
|
int len;
|
||||||
|
char name[512];
|
||||||
|
int i;
|
||||||
|
char js[1024];
|
||||||
|
|
||||||
if((f = fopen(file, "rb")) == NULL) {
|
if((f = fopen(file, "rb")) == NULL) {
|
||||||
printf("No PMake script (pmake.js) found!\n");
|
printf("No PMake script (pmake.js) found!\n");
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
sprintf(name, "main_%d", (int)rand());
|
||||||
|
|
||||||
fseek(f, 0, SEEK_END);
|
fseek(f, 0, SEEK_END);
|
||||||
len = ftell(f);
|
len = ftell(f);
|
||||||
fseek(f, 0, SEEK_SET);
|
fseek(f, 0, SEEK_SET);
|
||||||
|
|
@ -81,6 +109,9 @@ int js_run(const char* file) {
|
||||||
buffer = malloc(len);
|
buffer = malloc(len);
|
||||||
fread(buffer, 1, len, f);
|
fread(buffer, 1, len, f);
|
||||||
|
|
||||||
|
sprintf(js, "var %s;\nif(this.main){\n %s = main;\n delete main;}\n", name, name);
|
||||||
|
duk_eval_string(js_ctx, js);
|
||||||
|
|
||||||
if(duk_peval_lstring(js_ctx, buffer, len) != 0) {
|
if(duk_peval_lstring(js_ctx, buffer, len) != 0) {
|
||||||
printf("JS error: %s: %s\n", file, duk_safe_to_string(js_ctx, -1));
|
printf("JS error: %s: %s\n", file, duk_safe_to_string(js_ctx, -1));
|
||||||
|
|
||||||
|
|
@ -90,6 +121,11 @@ int js_run(const char* file) {
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if(call != NULL) call(name);
|
||||||
|
|
||||||
|
sprintf(js, "if(%s) main = %s;", name, name);
|
||||||
|
duk_eval_string(js_ctx, js);
|
||||||
|
|
||||||
free(buffer);
|
free(buffer);
|
||||||
fclose(f);
|
fclose(f);
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -73,6 +73,10 @@ for(var i = 1; i < ARGV.length; i++) {
|
||||||
main();
|
main();
|
||||||
|
|
||||||
(function() {
|
(function() {
|
||||||
|
function makefile(target) {
|
||||||
|
return target.base + "/" + target.target + ".make";
|
||||||
|
}
|
||||||
|
|
||||||
function make(output) {
|
function make(output) {
|
||||||
const targets = pmake.resolveProjects(pmake.projects);
|
const targets = pmake.resolveProjects(pmake.projects);
|
||||||
|
|
||||||
|
|
@ -101,21 +105,25 @@ function make(output) {
|
||||||
|
|
||||||
for(var i = 0; i < targets.length; i++) {
|
for(var i = 0; i < targets.length; i++) {
|
||||||
mk.write(targets[i].target + ": " + pmake.resolveProjects(targets[i].libraries).map(target_map).join(" ") + "\n");
|
mk.write(targets[i].target + ": " + pmake.resolveProjects(targets[i].libraries).map(target_map).join(" ") + "\n");
|
||||||
mk.write(" @$(MAKE) $(MAKEARGS) -f " + targets[i].target + ".make\n");
|
mk.write(" @cd " + targets[i].base + " ; $(MAKE) $(MAKEARGS) -f " + makefile(targets[i]) + "\n");
|
||||||
mk.write("\n");
|
mk.write("\n");
|
||||||
}
|
}
|
||||||
|
|
||||||
mk.write("clean:\n");
|
mk.write("clean:\n");
|
||||||
for(var i = 0; i < targets.length; i++) {
|
for(var i = 0; i < targets.length; i++) {
|
||||||
mk.write(" @$(MAKE) $(MAKEARGS) -f " + targets[i].target + ".make clean\n");
|
mk.write(" @cd " + targets[i].base + " ; $(MAKE) $(MAKEARGS) -f " + makefile(targets[i]) + " clean\n");
|
||||||
}
|
}
|
||||||
mk.write("\n");
|
mk.write("\n");
|
||||||
|
|
||||||
mk.write("distclean: clean\n");
|
mk.write("distclean: clean\n");
|
||||||
mk.write(" $(SILENT)rm -f *.make Makefile\n");
|
mk.write(" $(SILENT)rm -f Makefile\n");
|
||||||
|
for(var i = 0; i < targets.length; i++) {
|
||||||
|
mk.write(" $(SILENT)rm -f " + makefile(targets[i]) + "\n");
|
||||||
|
}
|
||||||
} else {
|
} else {
|
||||||
function target_filter(x) {
|
function target_filter(x) {
|
||||||
return x.target == output.replace(/\.make$/, "");
|
const p = output.replace(/\.make$/, "").split("/");
|
||||||
|
return x.target == p[p.length - 1];
|
||||||
}
|
}
|
||||||
|
|
||||||
const self = targets.filter(target_filter)[0];
|
const self = targets.filter(target_filter)[0];
|
||||||
|
|
@ -150,6 +158,6 @@ function make(output) {
|
||||||
make("Makefile");
|
make("Makefile");
|
||||||
const targets = pmake.resolveProjects(pmake.projects);
|
const targets = pmake.resolveProjects(pmake.projects);
|
||||||
for(var i = 0; i < targets.length; i++) {
|
for(var i = 0; i < targets.length; i++) {
|
||||||
make(targets[i].target + ".make");
|
make(makefile(targets[i]));
|
||||||
}
|
}
|
||||||
})();
|
})();
|
||||||
|
|
|
||||||
|
|
@ -72,8 +72,12 @@ pmake.resolveProjects = function(arr, if_str) {
|
||||||
for(var i = 0; i < arr.length; i++) {
|
for(var i = 0; i < arr.length; i++) {
|
||||||
var proj = arr[i];
|
var proj = arr[i];
|
||||||
|
|
||||||
if((typeof proj) == "string" && pmake.projects[proj]) {
|
function filter_project(x) {
|
||||||
proj = pmake.projects[proj];
|
return x.target == proj;
|
||||||
|
}
|
||||||
|
|
||||||
|
if((typeof proj) == "string" && pmake.projects.filter(filter_project)[0]) {
|
||||||
|
proj = pmake.projects.filter(filter_project)[0];
|
||||||
}
|
}
|
||||||
|
|
||||||
if(proj instanceof pmake.Project) {
|
if(proj instanceof pmake.Project) {
|
||||||
|
|
@ -95,26 +99,36 @@ pmake.isCxx = function(src) {
|
||||||
return src.endsWith(".cc") || src.endsWith(".cxx") || src.endsWith(".cpp");
|
return src.endsWith(".cc") || src.endsWith(".cxx") || src.endsWith(".cpp");
|
||||||
};
|
};
|
||||||
|
|
||||||
|
pmake.pathTransform = function(target) {
|
||||||
|
return function(x) {
|
||||||
|
if(x == "." || x == ".." || x.startsWith("./") || x.startsWith("../")) {
|
||||||
|
return target.base + "/" + x;
|
||||||
|
} else {
|
||||||
|
return x;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
pmake.includes = function(target) {
|
pmake.includes = function(target) {
|
||||||
function includes(x) {
|
function includes(x) {
|
||||||
return x.includes;
|
return x.includes.map(pmake.pathTransform(x));
|
||||||
}
|
}
|
||||||
|
|
||||||
const targets = pmake.resolveProjects(target.libraries);
|
const targets = pmake.resolveProjects(target.libraries);
|
||||||
|
|
||||||
return targets.map(includes).flat();
|
return target.includes.concat(targets.map(includes).flat());
|
||||||
};
|
};
|
||||||
|
|
||||||
pmake.libdirs = function(target, if_str) {
|
pmake.libdirs = function(target) {
|
||||||
function libdirs(x) {
|
function libdirs(x) {
|
||||||
if(x instanceof pmake.LibraryProject) {
|
if(x instanceof pmake.LibraryProject) {
|
||||||
return x.libdirs;
|
return x.libdirs.map(pmake.pathTransform(x));
|
||||||
}
|
}
|
||||||
|
|
||||||
return [];
|
return [];
|
||||||
}
|
}
|
||||||
|
|
||||||
const targets = pmake.resolveProjects(target.libraries, if_str);
|
const targets = pmake.resolveProjects(target.libraries);
|
||||||
|
|
||||||
return target.libdirs.concat(targets.map(libdirs).flat());
|
return target.libdirs.concat(targets.map(libdirs).flat());
|
||||||
};
|
};
|
||||||
|
|
@ -122,7 +136,7 @@ pmake.libdirs = function(target, if_str) {
|
||||||
pmake.libs = function(target, if_str) {
|
pmake.libs = function(target, if_str) {
|
||||||
function libs(x) {
|
function libs(x) {
|
||||||
if(x instanceof pmake.LibraryProject) {
|
if(x instanceof pmake.LibraryProject) {
|
||||||
const r = pmake.resolveProjects(x.libraries, if_str).concat([ pmake.compiler.output(x) ]);
|
const r = pmake.resolveProjects(x.libraries, if_str).concat([ x.base + "/" + pmake.compiler.output(x) ]);
|
||||||
|
|
||||||
return r;
|
return r;
|
||||||
} else if((typeof x) == "string") {
|
} else if((typeof x) == "string") {
|
||||||
|
|
@ -236,6 +250,7 @@ const Project = function(target) {
|
||||||
this.libdirs = [];
|
this.libdirs = [];
|
||||||
this.libraries = [];
|
this.libraries = [];
|
||||||
this.output = target;
|
this.output = target;
|
||||||
|
this.base = fs.cwd();
|
||||||
};
|
};
|
||||||
|
|
||||||
Project.prototype.generate = function() {
|
Project.prototype.generate = function() {
|
||||||
|
|
|
||||||
12
src/js_fs.c
12
src/js_fs.c
|
|
@ -95,6 +95,15 @@ static duk_ret_t js_fs_close(duk_context* self) {
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static duk_ret_t js_fs_cwd(duk_context* self) {
|
||||||
|
char path[1024];
|
||||||
|
|
||||||
|
getcwd(path, 1024);
|
||||||
|
duk_push_string(self, path);
|
||||||
|
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
void js_fs_init(void) {
|
void js_fs_init(void) {
|
||||||
int obj;
|
int obj;
|
||||||
|
|
||||||
|
|
@ -112,5 +121,8 @@ void js_fs_init(void) {
|
||||||
duk_push_c_function(js_ctx, js_fs_close, 1);
|
duk_push_c_function(js_ctx, js_fs_close, 1);
|
||||||
duk_put_prop_string(js_ctx, obj, "close");
|
duk_put_prop_string(js_ctx, obj, "close");
|
||||||
|
|
||||||
|
duk_push_c_function(js_ctx, js_fs_cwd, 0);
|
||||||
|
duk_put_prop_string(js_ctx, obj, "cwd");
|
||||||
|
|
||||||
duk_put_prop_string(js_ctx, 0, "fs");
|
duk_put_prop_string(js_ctx, 0, "fs");
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -7,6 +7,12 @@
|
||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
|
|
||||||
|
#ifdef _WIN32
|
||||||
|
#include <direct.h>
|
||||||
|
#else
|
||||||
|
#include <unistd.h>
|
||||||
|
#endif
|
||||||
|
|
||||||
#include <duktape.h>
|
#include <duktape.h>
|
||||||
#include <stb_ds.h>
|
#include <stb_ds.h>
|
||||||
|
|
||||||
|
|
@ -21,7 +27,7 @@ JS;
|
||||||
/* js.c */
|
/* js.c */
|
||||||
extern duk_context* js_ctx;
|
extern duk_context* js_ctx;
|
||||||
int js_init(int argc, char** argv);
|
int js_init(int argc, char** argv);
|
||||||
int js_run(const char* file);
|
int js_run(const char* file, void (*call)(const char*));
|
||||||
void js_uninit(void);
|
void js_uninit(void);
|
||||||
|
|
||||||
/* js_*.c */
|
/* js_*.c */
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue