diff --git a/src/waforthc/README.md b/src/waforthc/README.md index 92d3707..84f140e 100644 --- a/src/waforthc/README.md +++ b/src/waforthc/README.md @@ -55,6 +55,10 @@ Contrary to the [standalone native WAForth](https://github.com/remko/waforth/tre : SAY_BYE ." Bye" CR ; Compilation is not available in native compiled mode +If you have a cross-compiling C compiler, you can also cross-compile your Forth program to a different architecture: + + $ waforthc --cc=arm-linux-gnueabi-gcc --ccflag=-static --output=hello --init=SAY_HELLO hello.fs↩ + ## How it works The `waforthc` compiler ([`waforthc.cpp`](https://github.com/remko/waforth/blob/master/src/waforthc/waforthc.cpp)) works as follows: @@ -93,4 +97,4 @@ Currently, all the compiler does is combine the modules generated by WAForth int - A dead-code elimination pass could remove unnecessary words from the WAForth core. -Instead of compiling the resulting module to native, it can also be used in e.g. the web environment. \ No newline at end of file +Instead of compiling the resulting module to native, it can also be used in e.g. the web environment. diff --git a/src/waforthc/waforthc.cpp b/src/waforthc/waforthc.cpp index 8d755ba..fdc16c5 100644 --- a/src/waforthc/waforthc.cpp +++ b/src/waforthc/waforthc.cpp @@ -45,7 +45,8 @@ static std::unique_ptr stderrStream; /** * Compiles a WASM module to a native file named `outfile`. */ -wabt::Result compileToNative(wabt::Module &mod, const std::string &init, const std::string &outfile) { +wabt::Result compileToNative(wabt::Module &mod, const std::string &init, const std::string &outfile, const std::string &cc, + const std::vector &cflags) { CHECK_RESULT(GenerateNames(&mod)); CHECK_RESULT(ApplyNames(&mod)); // CHECK_RESULT(wabt::ResolveNamesModule(&mod, &errors)); @@ -83,7 +84,9 @@ wabt::Result compileToNative(wabt::Module &mod, const std::string &init, const s wabt::FileStream((wd / "wasm-rt.h").string()).WriteData(waforth_wabt_wasm_rt_h, sizeof(waforth_wabt_wasm_rt_h)); } - bp::child c(bp::search_path("gcc"), "-o", outfile, (wd / "_waforth_rt.c").string(), (wd / "_waforth.c").string(), (wd / "wasm-rt-impl.c").string(), "-lm"); + std::ostringstream cmd; + bp::child c(bp::search_path(cc), "-o", outfile, (wd / "_waforth_rt.c").string(), (wd / "_waforth.c").string(), (wd / "wasm-rt-impl.c").string(), + bp::args(cflags)); c.wait(); int result = c.exit_code(); if (result != 0) { @@ -324,7 +327,8 @@ wabt::Result compileToModule(std::vector &words, const std::vector /////////////////////////////////////////////////////////////////////////////////////////////////////////////////// -wabt::Result main_(const std::string &infile, const std::string &outfile, const std::string &init, wabt::Errors &errors) { +wabt::Result main_(const std::string &infile, const std::string &outfile, const std::string &init, const std::string &cc, + const std::vector &cflags, wabt::Errors &errors) { stderrStream = wabt::FileStream::CreateStderr(); std::vector in; @@ -346,7 +350,7 @@ wabt::Result main_(const std::string &infile, const std::string &outfile, const if (boost::ends_with(outfile, ".wasm")) { CHECK_RESULT(writeModule(outfile, compiled)); } else { - CHECK_RESULT(compileToNative(compiled, init, outfile)); + CHECK_RESULT(compileToNative(compiled, init, outfile, cc, cflags)); } return wabt::Result::Ok; @@ -356,11 +360,15 @@ int main(int argc, char *argv[]) { std::string outfile; std::string infile; std::string init; + std::string cc; + std::vector ccflags; bpo::options_description desc("Options"); desc.add_options()("help", "Show this help message")( "output,o", bpo::value(&outfile)->default_value("out"), "Output file\nIf `arg` ends with .wasm, the result will be a WebAssembly module. Otherwise, the result will be a native executable.")( + "cc", bpo::value(&cc)->default_value("gcc"), "C compiler")("ccflag", bpo::value>(&ccflags), + "C compiler flag")( "init", bpo::value(&init), "Initialization program\nIf specified, PROGRAM will be executed when the resulting executable is run. Otherwise, the resulting executable will " "start an interactive session.")("input", bpo::value(&infile)->required(), "Input file"); @@ -379,8 +387,10 @@ int main(int argc, char *argv[]) { return -1; } + ccflags.push_back("-lm"); + wabt::Errors errors; - if (!Succeeded(main_(infile, outfile, init, errors))) { + if (!Succeeded(main_(infile, outfile, init, cc, ccflags, errors))) { FormatErrorsToFile(errors, wabt::Location::Type::Binary); return -1; }