| @@ -1,9 +1,9 @@ | |||
| SRCS = \ | |||
| src/BBParser.cc src/build.cc src/compdb.cc src/CompileStep.cc src/DepNode.cc \ | |||
| src/BXParser.cc src/build.cc src/compdb.cc src/CompileStep.cc src/DepNode.cc \ | |||
| src/globals.cc src/LinkStep.cc src/logger.cc src/parallel.cc src/sys.cc \ | |||
| src/toolchain.cc src/main.cc | |||
| HDRS = \ | |||
| src/BBParser.h src/build.h src/compdb.h src/CompileStep.h src/DepNode.h \ | |||
| src/BXParser.h src/build.h src/compdb.h src/CompileStep.h src/DepNode.h \ | |||
| src/globals.h src/LinkStep.h src/logger.h src/parallel.h src/sys.h \ | |||
| src/toolchain.h | |||
| BUILD = build | |||
| @@ -15,7 +15,7 @@ $(BUILD)/%.cc.o: %.cc $(HDRS) | |||
| @mkdir -p $(@D) | |||
| $(CXX) $(CFLAGS) -c $< -o $@ | |||
| $(BUILD)/bbbuild: $(OBJS) | |||
| $(BUILD)/box: $(OBJS) | |||
| @mkdir -p $(@D) | |||
| $(CXX) $(LDFLAGS) -o $@ $^ $(LDLIBS) | |||
| @@ -1,40 +1,40 @@ | |||
| # BBBuild: A build system which scales down | |||
| # Boxberry: A build system which scales down | |||
| BBBuild is a build system which aims to be usable for tiny projects, | |||
| Boxberry is a build system which aims to be usable for tiny projects, | |||
| all the way down to single source files. | |||
| Not all projects need a big Makefile or a huge CMakeLists.txt. | |||
| However, almost all projects grow to the size where they need some library, | |||
| or some compiler flag, maybe an optimization option. | |||
| BBBuild aims to make the path from running `cc file.c` to running | |||
| Boxberry aims to make the path from running `cc file.c` to running | |||
| `cc -lpthread file.c` to `cc file.c $(pkg-config --libs --cflags libfoo) -lpthread` | |||
| as easy as possible. | |||
| * Source files are automatically discovered (by default). | |||
| * Dependencies can be specified in the source file: `//#bb pkgs := libfoo` | |||
| * Dependencies can be specified in the source file: `//#bx pkgs := libfoo` | |||
| * Linker and compiler flags can be specified in the source file: | |||
| `//#bb ldlibs := -lpthread ldflags := -fsanitize=address cflags := -fsanitize=address` | |||
| `//#bx ldlibs := -lpthread ldflags := -fsanitize=address cflags := -fsanitize=address` | |||
| * A source file is automatically recompiled if it has changed, or if any | |||
| included header files have changed. | |||
| * If your project grows, you can put global configs in a `build.bb` file. | |||
| Each directory can have a build.bb file, and each directory inherits the | |||
| * If your project grows, you can put global configs in a `build.bx` file. | |||
| Each directory can have a build.bx file, and each directory inherits the | |||
| configuration of its parent. | |||
| * Files can be specified instead of discovered automatically by setting the | |||
| `files` variable in a `build.bb` file. | |||
| `files` variable in a `build.bx` file. | |||
| ## Building | |||
| This project can be built by running either `make` or `bbbuild`. | |||
| This project can be built by running either `make` or `box`. | |||
| The only dependency is `pthreads`. | |||
| ## TODO | |||
| * ~~Add `--print-compile-commands`~~ | |||
| * ~~Consider changing the config file format name from BBB to BB~~ | |||
| * Support different build configurations (requires conditionals in the BBB parser) | |||
| * Support different build configurations (requires conditionals in the parser) | |||
| * Re-work the command-line interface | |||
| * ~~Save build configuration in the output dir~~ | |||
| * ~~Support one "main" build.bb file which specifies things like the target name~~ | |||
| * ~~Support one "main" build.bx file which specifies things like the target name~~ | |||
| * Support creating shared/static libraries too, not just binaries | |||
| * Implement recursive mkdir in C++ instead of shelling out to mkdir | |||
| * Support subprojects | |||
| @@ -1,4 +1,4 @@ | |||
| target := bbbuild | |||
| target := box | |||
| files := src | |||
| warnings := all extra no-unused-parameter | |||
| std := c++14 | |||
| @@ -1,11 +1,11 @@ | |||
| #include "BBParser.h" | |||
| #include "BXParser.h" | |||
| #include <stdlib.h> | |||
| #include <stdio.h> | |||
| #include <string.h> | |||
| #include <errno.h> | |||
| int BBParser::get() { | |||
| int BXParser::get() { | |||
| int ch = stream_.get(); | |||
| if (ch == '\n') { | |||
| line_ += 1; | |||
| @@ -17,7 +17,7 @@ int BBParser::get() { | |||
| return ch; | |||
| } | |||
| BBParser::Operator BBParser::readOperator() { | |||
| BXParser::Operator BXParser::readOperator() { | |||
| int ch2 = peek2(); | |||
| if (peek() == ':' && ch2 == '=') { | |||
| skip(); // ':' | |||
| @@ -36,7 +36,7 @@ BBParser::Operator BBParser::readOperator() { | |||
| return Operator::NONE; | |||
| } | |||
| void BBParser::skip(char expected) { | |||
| void BXParser::skip(char expected) { | |||
| int ch = get(); | |||
| if (ch == EOF) { | |||
| error(std::string("Expected '") + expected + "', got EOF"); | |||
| @@ -45,8 +45,8 @@ void BBParser::skip(char expected) { | |||
| } | |||
| } | |||
| [[noreturn]] void BBParser::error(std::string msg) { | |||
| throw BBParseError(std::to_string(line_) + ":" + std::to_string(ch_) + ": " + msg); | |||
| [[noreturn]] void BXParser::error(std::string msg) { | |||
| throw BXParseError(std::to_string(line_) + ":" + std::to_string(ch_) + ": " + msg); | |||
| } | |||
| static bool isWhitespace(int ch) { | |||
| @@ -55,7 +55,7 @@ static bool isWhitespace(int ch) { | |||
| return false; | |||
| } | |||
| void BBParser::skipWhitespace() { | |||
| void BXParser::skipWhitespace() { | |||
| if (flags_ & FLAG_ONE_LINE) { | |||
| int ch; | |||
| while (isWhitespace(ch = peek()) && ch != '\r' && ch != '\n') | |||
| @@ -66,7 +66,7 @@ void BBParser::skipWhitespace() { | |||
| } | |||
| } | |||
| char BBParser::parseEscape() { | |||
| char BXParser::parseEscape() { | |||
| skip(); // '\' | |||
| int ch; | |||
| switch (ch = get()) { | |||
| @@ -88,7 +88,7 @@ char BBParser::parseEscape() { | |||
| } | |||
| static void appendVariableToString( | |||
| const BBVariables &vars, std::string &name, | |||
| const BXVariables &vars, std::string &name, | |||
| std::string &value) { | |||
| if (name.size() == 0) | |||
| return; | |||
| @@ -110,7 +110,7 @@ static void appendVariableToString( | |||
| } | |||
| static void appendVariableToArray( | |||
| const BBVariables &vars, const std::string &name, | |||
| const BXVariables &vars, const std::string &name, | |||
| std::vector<std::string> &values) { | |||
| if (name.size() == 0) | |||
| return; | |||
| @@ -125,7 +125,7 @@ static void appendVariableToArray( | |||
| } | |||
| } | |||
| void BBParser::parseExpansion(const BBVariables &vars, std::vector<std::string> &values) { | |||
| void BXParser::parseExpansion(const BXVariables &vars, std::vector<std::string> &values) { | |||
| skip(); // '$' | |||
| std::string str; | |||
| @@ -147,7 +147,7 @@ void BBParser::parseExpansion(const BBVariables &vars, std::vector<std::string> | |||
| } | |||
| } | |||
| void BBParser::parseQuotedExpansion(const BBVariables &vars, std::string &content) { | |||
| void BXParser::parseQuotedExpansion(const BXVariables &vars, std::string &content) { | |||
| skip(); // '$' | |||
| std::string str; | |||
| @@ -169,7 +169,7 @@ void BBParser::parseQuotedExpansion(const BBVariables &vars, std::string &conten | |||
| } | |||
| } | |||
| void BBParser::parseQuotedString(const BBVariables &vars, std::string &content) { | |||
| void BXParser::parseQuotedString(const BXVariables &vars, std::string &content) { | |||
| skip(); // '"' | |||
| int ch; | |||
| @@ -197,7 +197,7 @@ void BBParser::parseQuotedString(const BBVariables &vars, std::string &content) | |||
| } | |||
| } | |||
| bool BBParser::parseString(const BBVariables &vars, std::string &content, int sep) { | |||
| bool BXParser::parseString(const BXVariables &vars, std::string &content, int sep) { | |||
| bool success = false; | |||
| int ch; | |||
| while (1) { | |||
| @@ -236,7 +236,7 @@ bool BBParser::parseString(const BBVariables &vars, std::string &content, int se | |||
| } | |||
| } | |||
| bool BBParser::parseIdentifier(std::string &content) { | |||
| bool BXParser::parseIdentifier(std::string &content) { | |||
| int ch = peek(); | |||
| if (!( | |||
| (ch >= 'a' && ch <= 'z') || | |||
| @@ -261,7 +261,7 @@ bool BBParser::parseIdentifier(std::string &content) { | |||
| } | |||
| } | |||
| void BBParser::parse(BBVariables &vars) { | |||
| void BXParser::parse(BXVariables &vars) { | |||
| std::string key, value; | |||
| std::vector<std::string> values; | |||
| @@ -346,7 +346,7 @@ void BBParser::parse(BBVariables &vars) { | |||
| doAssignment(); | |||
| } | |||
| void BBParser::parseList(const BBVariables &vars, std::vector<std::string> &values) { | |||
| void BXParser::parseList(const BXVariables &vars, std::vector<std::string> &values) { | |||
| while (true) { | |||
| skipWhitespace(); | |||
| std::string value; | |||
| @@ -358,23 +358,23 @@ void BBParser::parseList(const BBVariables &vars, std::vector<std::string> &valu | |||
| } | |||
| } | |||
| void BBWriter::put(char ch) { | |||
| void BXWriter::put(char ch) { | |||
| ch_ += 1; | |||
| stream_ << ch; | |||
| } | |||
| void BBWriter::put(const std::string &str) { | |||
| void BXWriter::put(const std::string &str) { | |||
| ch_ += str.size(); | |||
| stream_ << str; | |||
| } | |||
| void BBWriter::newline() { | |||
| void BXWriter::newline() { | |||
| ch_ = 1; | |||
| line_ += 1; | |||
| stream_ << '\n'; | |||
| } | |||
| void BBWriter::escape(const std::string &str) { | |||
| void BXWriter::escape(const std::string &str) { | |||
| put('"'); | |||
| for (char ch: str) { | |||
| if (ch == '$' || ch == '"' || ch == '\\') { | |||
| @@ -385,7 +385,7 @@ void BBWriter::escape(const std::string &str) { | |||
| put('"'); | |||
| } | |||
| void BBWriter::write(const BBVariables &vars) { | |||
| void BXWriter::write(const BXVariables &vars) { | |||
| for (const auto &pair: vars) { | |||
| put(pair.first); | |||
| put(" :="); | |||
| @@ -6,8 +6,8 @@ | |||
| #include <iostream> | |||
| #include <exception> | |||
| struct BBParseError: std::exception { | |||
| BBParseError(std::string msg): message(msg) {} | |||
| struct BXParseError: std::exception { | |||
| BXParseError(std::string msg): message(msg) {} | |||
| std::string message; | |||
| const char *what() const noexcept override { | |||
| @@ -15,18 +15,18 @@ struct BBParseError: std::exception { | |||
| } | |||
| }; | |||
| using BBVariables = std::unordered_map<std::string, std::vector<std::string>>; | |||
| using BXVariables = std::unordered_map<std::string, std::vector<std::string>>; | |||
| class BBParser { | |||
| class BXParser { | |||
| public: | |||
| static const int FLAG_NONE = 0; | |||
| static const int FLAG_ONE_LINE = 1 << 0; | |||
| BBParser(std::istream &stream, int flags, int line = 1, int ch = 1): | |||
| BXParser(std::istream &stream, int flags, int line = 1, int ch = 1): | |||
| flags_(flags), line_(line), ch_(ch), stream_(stream) {} | |||
| void parse(BBVariables &vars); | |||
| void parseList(const BBVariables &vars, std::vector<std::string> &values); | |||
| void parse(BXVariables &vars); | |||
| void parseList(const BXVariables &vars, std::vector<std::string> &values); | |||
| int peek() { return stream_.peek(); } | |||
| int peek2() { stream_.get(); int ch = peek(); stream_.unget(); return ch; } | |||
| @@ -52,10 +52,10 @@ private: | |||
| void skipWhitespace(); | |||
| char parseEscape(); | |||
| void parseExpansion(const BBVariables &vars, std::vector<std::string> &values); | |||
| void parseQuotedExpansion(const BBVariables &vars, std::string &content); | |||
| void parseQuotedString(const BBVariables &vars, std::string &content); | |||
| bool parseString(const BBVariables &vars, std::string &content, int sep = -1); | |||
| void parseExpansion(const BXVariables &vars, std::vector<std::string> &values); | |||
| void parseQuotedExpansion(const BXVariables &vars, std::string &content); | |||
| void parseQuotedString(const BXVariables &vars, std::string &content); | |||
| bool parseString(const BXVariables &vars, std::string &content, int sep = -1); | |||
| bool parseIdentifier(std::string &content); | |||
| int flags_; | |||
| @@ -64,12 +64,12 @@ private: | |||
| std::istream &stream_; | |||
| }; | |||
| class BBWriter { | |||
| class BXWriter { | |||
| public: | |||
| BBWriter(std::ostream &stream, int line = 1, int ch = 1): | |||
| BXWriter(std::ostream &stream, int line = 1, int ch = 1): | |||
| line_(line), ch_(ch), stream_(stream) {} | |||
| void write(const BBVariables &vars); | |||
| void write(const BXVariables &vars); | |||
| private: | |||
| void put(char ch); | |||
| @@ -7,7 +7,7 @@ | |||
| #include "logger.h" | |||
| #include "globals.h" | |||
| static bool startsWith(BBParser &parser, const char *str) { | |||
| static bool startsWith(BXParser &parser, const char *str) { | |||
| for (size_t i = 0; str[i] != '\0'; ++i) { | |||
| if (parser.peek() != str[i]) | |||
| return false; | |||
| @@ -29,18 +29,18 @@ bool CompileStep::checkHasChanged(const std::string &outDir) { | |||
| return true; | |||
| } | |||
| std::string bbPath = this->bbPath(outDir); | |||
| if (!sys::fileExists(bbPath)) { | |||
| std::string confPath = this->confPath(outDir); | |||
| if (!sys::fileExists(confPath)) { | |||
| return true; | |||
| } | |||
| BBVariables cachedVariables; | |||
| BXVariables cachedVariables; | |||
| try { | |||
| std::ifstream f = sys::ifstream(bbPath); | |||
| BBParser parser(f, BBParser::FLAG_NONE); | |||
| std::ifstream f = sys::ifstream(confPath); | |||
| BXParser parser(f, BXParser::FLAG_NONE); | |||
| parser.parse(cachedVariables); | |||
| } catch (BBParseError &err) { | |||
| logger::log(bbPath + ": " + err.what()); | |||
| } catch (BXParseError &err) { | |||
| logger::log(confPath + ": " + err.what()); | |||
| return true; | |||
| } | |||
| @@ -48,7 +48,7 @@ bool CompileStep::checkHasChanged(const std::string &outDir) { | |||
| // the object file hasn't actually changed. | |||
| auto depsIt = cachedVariables.find("deps"); | |||
| if (depsIt == cachedVariables.end()) { | |||
| logger::log(bbPath + ": Missing 'deps' field"); | |||
| logger::log(confPath + ": Missing 'deps' field"); | |||
| return true; | |||
| } | |||
| @@ -67,7 +67,7 @@ bool CompileStep::checkHasChanged(const std::string &outDir) { | |||
| // Maybe the build command has changed? | |||
| auto commandIt = cachedVariables.find("command"); | |||
| if (commandIt == cachedVariables.end()) { | |||
| logger::log(bbPath + ": Missing 'command' field"); | |||
| logger::log(confPath + ": Missing 'command' field"); | |||
| return true; | |||
| } | |||
| @@ -88,15 +88,15 @@ void CompileStep::doBuild(const std::string &outDir) { | |||
| std::string dirPath = sys::dirname(objPath); | |||
| std::vector<std::string> command = compileCommand(outDir); | |||
| BBVariables newCachedVars = { | |||
| BXVariables newCachedVars = { | |||
| { "deps", toolchain::getDependencies(flags(), type_, path_) }, | |||
| { "command", command}, | |||
| }; | |||
| sys::mkdirp(dirPath); | |||
| std::ofstream f = sys::ofstream(bbPath(outDir)); | |||
| BBWriter writer(f); | |||
| std::ofstream f = sys::ofstream(confPath(outDir)); | |||
| BXWriter writer(f); | |||
| writer.write(newCachedVars); | |||
| sys::execute(command, nullptr, verboseCommand); | |||
| @@ -107,14 +107,14 @@ void CompileStep::doWriteCompDB(const std::string &outDir, compdb::Writer &w) { | |||
| } | |||
| std::vector<std::string> CompileStep::getPublicLDFlags(const std::string &outDir) { | |||
| BBVariables &vars = variables(); | |||
| BXVariables &vars = variables(); | |||
| std::vector<std::string> flags; | |||
| toolchain::getLDFlags(vars, flags); | |||
| return flags; | |||
| } | |||
| std::vector<std::string> CompileStep::getPublicLDLibs(const std::string &outDir) { | |||
| BBVariables &vars = variables(); | |||
| BXVariables &vars = variables(); | |||
| std::vector<std::string> libs; | |||
| toolchain::getLDLibs(vars, libs); | |||
| return libs; | |||
| @@ -124,16 +124,16 @@ std::vector<std::string> CompileStep::getPublicObjects(const std::string &outDir | |||
| return std::vector<std::string>{ toolchain::objectFilePath(path_, outDir) }; | |||
| } | |||
| BBVariables &CompileStep::variables() { | |||
| BXVariables &CompileStep::variables() { | |||
| if (hasVariables_) { | |||
| return variables_; | |||
| } | |||
| std::ifstream f = sys::ifstream(path_); | |||
| BBParser parser(f, BBParser::FLAG_ONE_LINE); | |||
| BXParser parser(f, BXParser::FLAG_ONE_LINE); | |||
| while (f.good()) { | |||
| if (startsWith(parser, "//#bb")) { | |||
| if (startsWith(parser, "//#bx")) { | |||
| parser.parse(variables_); | |||
| } else { | |||
| while (f.good() && parser.get() != '\n'); | |||
| @@ -149,7 +149,7 @@ std::vector<std::string> &CompileStep::flags() { | |||
| return flags_; | |||
| } | |||
| BBVariables &vars = variables(); | |||
| BXVariables &vars = variables(); | |||
| toolchain::getFlags(vars, type_, flags_); | |||
| hasFlags_ = true; | |||
| @@ -1,12 +1,12 @@ | |||
| #pragma once | |||
| #include "DepNode.h" | |||
| #include "BBParser.h" | |||
| #include "BXParser.h" | |||
| #include "toolchain.h" | |||
| class CompileStep: public DepNode { | |||
| public: | |||
| CompileStep(std::string path, toolchain::FileType type, BBVariables vars): | |||
| CompileStep(std::string path, toolchain::FileType type, BXVariables vars): | |||
| path_(std::move(path)), type_(type), variables_(std::move(vars)) {} | |||
| private: | |||
| @@ -21,8 +21,8 @@ private: | |||
| std::vector<std::string> getPublicObjects(const std::string &outDir) override; | |||
| bool hasVariables_ = false; | |||
| BBVariables variables_; | |||
| BBVariables &variables(); | |||
| BXVariables variables_; | |||
| BXVariables &variables(); | |||
| bool hasFlags_ = false; | |||
| std::vector<std::string> flags_; | |||
| @@ -32,5 +32,5 @@ private: | |||
| std::vector<std::string> compileCommand_; | |||
| std::vector<std::string> &compileCommand(const std::string &outDir); | |||
| std::string bbPath(const std::string &outDir) { return outDir + '/' + path_ + ".bb"; } | |||
| std::string confPath(const std::string &outDir) { return outDir + '/' + path_ + ".bx"; } | |||
| }; | |||
| @@ -6,7 +6,7 @@ | |||
| #include "sys.h" | |||
| #include "logger.h" | |||
| #include "globals.h" | |||
| #include "BBParser.h" | |||
| #include "BXParser.h" | |||
| bool LinkStep::checkHasChanged(const std::string &outDir) { | |||
| std::string targetPath = toolchain::targetFilePath(type_, path_, outDir); | |||
| @@ -14,24 +14,24 @@ bool LinkStep::checkHasChanged(const std::string &outDir) { | |||
| return true; | |||
| } | |||
| std::string bbPath = this->bbPath(outDir); | |||
| if (!sys::fileExists(bbPath)) { | |||
| std::string confPath = this->confPath(outDir); | |||
| if (!sys::fileExists(confPath)) { | |||
| return true; | |||
| } | |||
| BBVariables cachedVariables; | |||
| BXVariables cachedVariables; | |||
| try { | |||
| std::ifstream f = sys::ifstream(bbPath); | |||
| BBParser parser(f, BBParser::FLAG_NONE); | |||
| std::ifstream f = sys::ifstream(confPath); | |||
| BXParser parser(f, BXParser::FLAG_NONE); | |||
| parser.parse(cachedVariables); | |||
| } catch (BBParseError &err) { | |||
| logger::log(bbPath + ": " + err.what()); | |||
| } catch (BXParseError &err) { | |||
| logger::log(confPath + ": " + err.what()); | |||
| return true; | |||
| } | |||
| auto commandIt = cachedVariables.find("command"); | |||
| if (commandIt == cachedVariables.end()) { | |||
| logger::log(bbPath + ": Missing 'command' field"); | |||
| logger::log(confPath + ": Missing 'command' field"); | |||
| return true; | |||
| } | |||
| @@ -47,12 +47,12 @@ void LinkStep::doBuild(const std::string &outDir) { | |||
| std::vector<std::string> command = linkCommand(outDir); | |||
| std::string dirPath = sys::dirname(outDir + '/' + path_); | |||
| BBVariables newCachedVars = { | |||
| BXVariables newCachedVars = { | |||
| { "command", command}, | |||
| }; | |||
| std::ofstream f = sys::ofstream(bbPath(outDir)); | |||
| BBWriter writer(f); | |||
| std::ofstream f = sys::ofstream(confPath(outDir)); | |||
| BXWriter writer(f); | |||
| writer.write(newCachedVars); | |||
| sys::mkdirp(dirPath); | |||
| @@ -21,5 +21,5 @@ private: | |||
| std::vector<std::string> linkCommand_; | |||
| std::vector<std::string> &linkCommand(const std::string &outDir); | |||
| std::string bbPath(const std::string &outDir) { return outDir + '/' + path_ + ".bb"; } | |||
| std::string confPath(const std::string &outDir) { return outDir + '/' + path_ + ".bx"; } | |||
| }; | |||
| @@ -6,7 +6,7 @@ | |||
| #include <string.h> | |||
| #include "sys.h" | |||
| #include "BBParser.h" | |||
| #include "BXParser.h" | |||
| #include "CompileStep.h" | |||
| #include "LinkStep.h" | |||
| #include "logger.h" | |||
| @@ -23,7 +23,7 @@ static std::string extension(const std::string &path) { | |||
| } | |||
| static void addFile( | |||
| std::string path, BBVariables variables, | |||
| std::string path, BXVariables variables, | |||
| std::vector<std::unique_ptr<DepNode>> &deps) { | |||
| toolchain::FileType type; | |||
| std::string ext = extension(path); | |||
| @@ -40,7 +40,7 @@ static void addFile( | |||
| static void findDeps( | |||
| const std::string &dir, const std::string &name, | |||
| const BBVariables &variables, std::vector<std::unique_ptr<DepNode>> &deps) { | |||
| const BXVariables &variables, std::vector<std::unique_ptr<DepNode>> &deps) { | |||
| std::string path = dir + "/" + name; | |||
| sys::FileInfo info; | |||
| try { | |||
| @@ -52,19 +52,19 @@ static void findDeps( | |||
| if (info.isDir) { | |||
| // May or may not need to copy variables | |||
| BBVariables subvars; | |||
| const BBVariables *varsptr = &variables; | |||
| BXVariables subvars; | |||
| const BXVariables *varsptr = &variables; | |||
| std::vector<std::string> subpaths; | |||
| // There might be a $path/build.bb. If there is, files in that dir | |||
| // needs a new copy of variables, and that $path/build.bb might contain | |||
| // There might be a $path/build.bx. If there is, files in that dir | |||
| // needs a new copy of variables, and that $path/build.bx might contain | |||
| // a files property. | |||
| if (sys::fileExists(path + "/build.bb")) { | |||
| if (sys::fileExists(path + "/build.bx")) { | |||
| subvars = variables; | |||
| varsptr = &subvars; | |||
| std::ifstream stream = sys::ifstream("build.bb"); | |||
| BBParser parser(stream, BBParser::FLAG_NONE); | |||
| std::ifstream stream = sys::ifstream("build.bx"); | |||
| BXParser parser(stream, BXParser::FLAG_NONE); | |||
| parser.parse(subvars); | |||
| auto it = subvars.find("files"); | |||
| @@ -87,7 +87,7 @@ static void findDeps( | |||
| } | |||
| } | |||
| static std::string findTargetName(const BBVariables &variables) { | |||
| static std::string findTargetName(const BXVariables &variables) { | |||
| auto it = variables.find("target"); | |||
| if (it != variables.end() && it->second.size() != 0) { | |||
| return it->second[0]; | |||
| @@ -98,11 +98,11 @@ static std::string findTargetName(const BBVariables &variables) { | |||
| return "target"; | |||
| } | |||
| std::unique_ptr<DepNode> buildDepTree(const std::string &outDir, BBVariables variables) { | |||
| std::unique_ptr<DepNode> buildDepTree(const std::string &outDir, BXVariables variables) { | |||
| // Read config from file | |||
| if (sys::fileExists("build.bb")) { | |||
| std::ifstream stream = sys::ifstream("build.bb"); | |||
| BBParser parser(stream, BBParser::FLAG_NONE); | |||
| if (sys::fileExists("build.bx")) { | |||
| std::ifstream stream = sys::ifstream("build.bx"); | |||
| BXParser parser(stream, BXParser::FLAG_NONE); | |||
| parser.parse(variables); | |||
| } | |||
| @@ -4,6 +4,6 @@ | |||
| #include <memory> | |||
| #include "DepNode.h" | |||
| #include "BBParser.h" | |||
| #include "BXParser.h" | |||
| std::unique_ptr<DepNode> buildDepTree(const std::string &outDir, BBVariables variables); | |||
| std::unique_ptr<DepNode> buildDepTree(const std::string &outDir, BXVariables variables); | |||
| @@ -1,4 +1,4 @@ | |||
| //#bb ldlibs := pthread | |||
| //#bx ldlibs := pthread | |||
| #include <getopt.h> | |||
| #include <string.h> | |||
| @@ -9,7 +9,7 @@ | |||
| #include <utility> | |||
| #include <stdexcept> | |||
| #include "BBParser.h" | |||
| #include "BXParser.h" | |||
| #include "parallel.h" | |||
| #include "toolchain.h" | |||
| #include "globals.h" | |||
| @@ -24,13 +24,13 @@ static void run(std::vector<std::string> args, std::vector<std::pair<std::string | |||
| if (args.size() == 0) { | |||
| op = "build"; | |||
| path = "./bb-out"; | |||
| path = "./bx-out"; | |||
| } else if (args[0][0] == '.' || args[0][0] == '/') { | |||
| op = "build"; | |||
| path = args[0]; | |||
| } else if (args.size() == 1) { | |||
| op = args[0]; | |||
| path = "./bb-out"; | |||
| path = "./bx-out"; | |||
| } else if (args.size() == 2) { | |||
| op = args[0]; | |||
| path = args[1]; | |||
| @@ -41,32 +41,32 @@ static void run(std::vector<std::string> args, std::vector<std::pair<std::string | |||
| sys::mkdirp(path); | |||
| auto buildVariables = [&]() -> BBVariables { | |||
| BBVariables variables; | |||
| if (sys::fileExists(path + "/.config.bb")) { | |||
| std::ifstream f = sys::ifstream(path + "/.config.bb"); | |||
| BBParser parser(f, BBParser::FLAG_NONE); | |||
| auto buildVariables = [&]() -> BXVariables { | |||
| BXVariables variables; | |||
| if (sys::fileExists(path + "/.config.bx")) { | |||
| std::ifstream f = sys::ifstream(path + "/.config.bx"); | |||
| BXParser parser(f, BXParser::FLAG_NONE); | |||
| parser.parse(variables); | |||
| } | |||
| for (auto &pair: kwargs) { | |||
| std::stringstream ss(pair.second); | |||
| BBParser parser(ss, BBParser::FLAG_NONE); | |||
| BXParser parser(ss, BXParser::FLAG_NONE); | |||
| auto &list = variables[pair.first]; | |||
| list.clear(); | |||
| parser.parseList(variables, list); | |||
| } | |||
| if (kwargs.size() > 0) { | |||
| std::ofstream f = sys::ofstream(path + "/.config.bb"); | |||
| BBWriter w(f); | |||
| std::ofstream f = sys::ofstream(path + "/.config.bx"); | |||
| BXWriter w(f); | |||
| w.write(variables); | |||
| } | |||
| return variables; | |||
| }; | |||
| auto buildTree = [&](BBVariables vars) -> std::unique_ptr<DepNode> { | |||
| auto buildTree = [&](BXVariables vars) -> std::unique_ptr<DepNode> { | |||
| return buildDepTree(path, std::move(vars)); | |||
| }; | |||
| @@ -89,9 +89,9 @@ static void run(std::vector<std::string> args, std::vector<std::pair<std::string | |||
| } | |||
| } else if (op == "config") { | |||
| BBVariables variables = buildVariables(); | |||
| BXVariables variables = buildVariables(); | |||
| printf("%s:\n", (path + "/.config.bb").c_str()); | |||
| printf("%s:\n", (path + "/.config.bx").c_str()); | |||
| if (variables.size() == 0) { | |||
| printf("No config options set.\n"); | |||
| } | |||
| @@ -108,13 +108,13 @@ static void run(std::vector<std::string> args, std::vector<std::pair<std::string | |||
| } else if (op == "clean") { | |||
| // TODO: Remove what's needed, instead of removing everything and | |||
| // re-creating .config.bb | |||
| BBVariables variables = buildVariables(); | |||
| // re-creating .config.bx | |||
| BXVariables variables = buildVariables(); | |||
| sys::rmrf(path); | |||
| sys::rmrf("compile_commands.json"); | |||
| sys::mkdirp(path); | |||
| std::ofstream f = sys::ofstream(path + "/.config.bb"); | |||
| BBWriter w(f); | |||
| std::ofstream f = sys::ofstream(path + "/.config.bx"); | |||
| BXWriter w(f); | |||
| w.write(variables); | |||
| } else { | |||
| @@ -123,7 +123,6 @@ static void run(std::vector<std::string> args, std::vector<std::pair<std::string | |||
| } | |||
| int main(int argc, char **argv) { | |||
| std::string outDir = "bbbuild"; | |||
| int jobs = parallel::coreCount() * 1.2 + 2; | |||
| std::string workDir = ""; | |||
| std::string target = ""; | |||
| @@ -138,7 +137,7 @@ int main(int argc, char **argv) { | |||
| }; | |||
| const char usage[] = | |||
| "Usage: bbbuild [options...] [build | config | compile-commands | clean] [path]\n" | |||
| "Usage: %s [options...] [build | config | compile-commands | clean] [path]\n" | |||
| "\n" | |||
| " -h, --help " | |||
| "Show this help text.\n" | |||
| @@ -161,7 +160,7 @@ int main(int argc, char **argv) { | |||
| switch (c) { | |||
| case 'h': | |||
| puts(usage); | |||
| printf(usage, argv[0]); | |||
| return 0; | |||
| case 'v': | |||
| @@ -181,7 +180,8 @@ int main(int argc, char **argv) { | |||
| break; | |||
| default: | |||
| printf("Unknown option: '%c'.\n%s", (char)c, usage); | |||
| printf("Unknown option: '%c'.\n", (char)c); | |||
| printf(usage, argv[0]); | |||
| return 1; | |||
| } | |||
| } | |||
| @@ -122,7 +122,7 @@ std::string targetFilePath( | |||
| abort(); | |||
| } | |||
| void getFlags(const BBVariables &vars, FileType type, std::vector<std::string> &flags) { | |||
| void getFlags(const BXVariables &vars, FileType type, std::vector<std::string> &flags) { | |||
| auto stdver = vars.find("std"); | |||
| if (stdver != vars.end() && stdver->second.size() > 0) { | |||
| flags.push_back("-std=" + stdver->second[0]); | |||
| @@ -175,7 +175,7 @@ void getFlags(const BBVariables &vars, FileType type, std::vector<std::string> & | |||
| } | |||
| } | |||
| void getLDLibs(const BBVariables &vars, std::vector<std::string> &flags) { | |||
| void getLDLibs(const BXVariables &vars, std::vector<std::string> &flags) { | |||
| auto pkgs = vars.find("pkgs"); | |||
| if (pkgs != vars.end()) { | |||
| std::vector<std::string> argv; | |||
| @@ -199,7 +199,7 @@ void getLDLibs(const BBVariables &vars, std::vector<std::string> &flags) { | |||
| } | |||
| } | |||
| void getLDFlags(const BBVariables &vars, std::vector<std::string> &flags) { | |||
| void getLDFlags(const BXVariables &vars, std::vector<std::string> &flags) { | |||
| auto sanitize = vars.find("sanitizers"); | |||
| if (sanitize != vars.end()) { | |||
| for (auto &s: sanitize->second) { | |||
| @@ -3,7 +3,7 @@ | |||
| #include <vector> | |||
| #include <string> | |||
| #include "BBParser.h" | |||
| #include "BXParser.h" | |||
| namespace toolchain { | |||
| @@ -23,9 +23,9 @@ std::string targetFilePath( | |||
| const std::string &path, | |||
| const std::string &outDir); | |||
| void getFlags(const BBVariables &vars, FileType type, std::vector<std::string> &flags); | |||
| void getLDLibs(const BBVariables &vars, std::vector<std::string> &flags); | |||
| void getLDFlags(const BBVariables &vars, std::vector<std::string> &flags); | |||
| void getFlags(const BXVariables &vars, FileType type, std::vector<std::string> &flags); | |||
| void getLDLibs(const BXVariables &vars, std::vector<std::string> &flags); | |||
| void getLDFlags(const BXVariables &vars, std::vector<std::string> &flags); | |||
| std::vector<std::string> getDependencies( | |||
| const std::vector<std::string> &flags, | |||