forked from ninja-build/ninja
-
Notifications
You must be signed in to change notification settings - Fork 0
Team 2 - Converter #21
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Open
mayank-ramnani
wants to merge
17
commits into
nyuoss:team2-homework1
Choose a base branch
from
mayank-ramnani:team2-hw2
base: team2-homework1
Could not load branches
Branch not found: {{ refName }}
Loading
Could not load tags
Nothing to show
Loading
Are you sure you want to change the base?
Some commits from the old base branch may be removed from the timeline,
and old review comments may become outdated.
Open
Changes from 14 commits
Commits
Show all changes
17 commits
Select commit
Hold shift + click to select a range
760226a
Add manifest and test files for converter
mayank-ramnani d71da44
Make testing build.ninja and build.ninja.cc consistent
mayank-ramnani d09f9e0
Start implementing converter in Python
mayank-ramnani 92c5603
Move Python converter to archive - will use cpp to do the conversion …
mayank-ramnani 1e73da6
Start changing ninja code itself to behave as a converter instead of …
mayank-ramnani dde456b
Add converter usage instructions in readme
mayank-ramnani b04bb73
Handle rules for converter
mayank-ramnani 4753b56
Handle let statements for converter
mayank-ramnani 8ae9f15
Handle edges (build statements) for converter
mayank-ramnani 62ddf32
Handle default statements for converter
mayank-ramnani d27564b
Fix bug with converting let statements (to prevent extra statements f…
mayank-ramnani 76602c8
Formatting improvements for output file - tab characters
mayank-ramnani 30d3550
Change converter output to match Team 5 output
mayank-ramnani 2017874
Add zlib build.ninja and compiled files
mayank-ramnani 8493480
Remove unnecessary files, move others
mayank-ramnani 3804bac
Create test suite
mayank-ramnani 559c9a4
Update readme
mayank-ramnani File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -1,100 +1,19 @@ | ||
| # Ninja | ||
|
|
||
| Ninja is a small build system with a focus on speed. | ||
| https://ninja-build.org/ | ||
|
|
||
| See [the manual](https://ninja-build.org/manual.html) or | ||
| `doc/manual.asciidoc` included in the distribution for background | ||
| and more details. | ||
|
|
||
| Binaries for Linux, Mac and Windows are available on | ||
| [GitHub](https://github.com/ninja-build/ninja/releases). | ||
| Run `./ninja -h` for Ninja help. | ||
|
|
||
| Installation is not necessary because the only required file is the | ||
| resulting ninja binary. However, to enable features like Bash | ||
| completion and Emacs and Vim editing modes, some files in misc/ must be | ||
| copied to appropriate locations. | ||
|
|
||
| If you're interested in making changes to Ninja, read | ||
| [CONTRIBUTING.md](CONTRIBUTING.md) first. | ||
|
|
||
| ## Building Ninja itself | ||
|
|
||
| You can either build Ninja via the custom generator script written in Python or | ||
| via CMake. For more details see | ||
| [the wiki](https://github.com/ninja-build/ninja/wiki). | ||
|
|
||
| ### Python | ||
|
|
||
| ``` | ||
| ./configure.py --bootstrap | ||
| # Shadowdash Converter | ||
|
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. if that is a part of the ninja like here, I believe rewriting the stock ninja readme is kinda wrong in this case |
||
| ## Build | ||
| ```sh | ||
| ./build.sh | ||
| ``` | ||
| This will create the converter in the `debug-build` directory with debug symbols. | ||
|
|
||
| This will generate the `ninja` binary and a `build.ninja` file you can now use | ||
| to build Ninja with itself. | ||
|
|
||
| If you have a GoogleTest source directory, you can build the tests | ||
| by passing its path with `--gtest-source-dir=PATH` option, or the | ||
| `GTEST_SOURCE_DIR` environment variable, e.g.: | ||
|
|
||
| ``` | ||
| ./configure.py --bootstrap --gtest-source-dir=/path/to/googletest | ||
| ./ninja all # build ninja_test and other auxiliary binaries | ||
| ./ninja_test` # run the unit-test suite. | ||
| ``` | ||
|
|
||
| Use the CMake build below if you want to use a preinstalled binary | ||
| version of the library. | ||
|
|
||
| ### CMake | ||
|
|
||
| ``` | ||
| cmake -Bbuild-cmake | ||
| cmake --build build-cmake | ||
| ## Run | ||
| ```sh | ||
| ./debug-build/ninja | ||
| ``` | ||
| Run the above in a directory where a `build.ninja` file is present | ||
|
|
||
| The `ninja` binary will now be inside the `build-cmake` directory (you can | ||
| choose any other name you like). | ||
|
|
||
| To run the unit tests: | ||
|
|
||
| ## Testing | ||
| ```sh | ||
| cd converter/testing/ | ||
| ../../debug-build/ninja | ||
| ``` | ||
| ./build-cmake/ninja_test | ||
| ``` | ||
|
|
||
| ## Generating documentation | ||
|
|
||
| ### Ninja Manual | ||
|
|
||
| You must have `asciidoc` and `xsltproc` in your PATH, then do: | ||
|
|
||
| ``` | ||
| ./configure.py | ||
| ninja manual doc/manual.pdf | ||
| ``` | ||
|
|
||
| Which will generate `doc/manual.html`. | ||
|
|
||
| To generate the PDF version of the manual, you must have `dblatext` in your PATH then do: | ||
|
|
||
| ``` | ||
| ./configure.py # only if you didn't do it previously. | ||
| ninja doc/manual.pdf | ||
| ``` | ||
|
|
||
| Which will generate `doc/manual.pdf`. | ||
|
|
||
| ### Doxygen documentation | ||
|
|
||
| If you have `doxygen` installed, you can build documentation extracted from C++ | ||
| declarations and comments to help you navigate the code. Note that Ninja is a standalone | ||
| executable, not a library, so there is no public API, all details exposed here are | ||
| internal. | ||
|
|
||
| ``` | ||
| ./configure.py # if needed | ||
| ninja doxygen | ||
| ``` | ||
|
|
||
| Then open `doc/doxygen/html/index.html` in a browser to look at it. | ||
| This will run the converter on the hello world example `build.ninja` file and produce `output.cc` as a result. | ||
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,2 @@ | ||
| cmake -DCMAKE_BUILD_TYPE=Debug -B debug-build | ||
| cmake --build debug-build --parallel --config Debug --target ninja |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,98 @@ | ||
| import argparse | ||
|
|
||
| def parse_ninja_file(ninja_file_content): | ||
| rules = {} | ||
| builds = [] | ||
| current_rule = None | ||
| default_target = None | ||
|
|
||
| lines = ninja_file_content.splitlines() | ||
|
|
||
| for line in lines: | ||
| line = line.strip() | ||
| if line.startswith("rule"): | ||
| current_rule = line.split()[1] | ||
| rules[current_rule] = {"command": None, "flags": "-O3"} | ||
| elif line.startswith("command ="): | ||
| if current_rule: | ||
| rules[current_rule]["command"] = line.split("=", 1)[1].strip() | ||
| elif line.startswith("flags ="): | ||
| if current_rule: | ||
| rules[current_rule]["flags"] = line.split("=", 1)[1].strip() | ||
| elif line.startswith("build"): | ||
| parts = line.split() | ||
| output, rule, inputs = parts[1], parts[2], parts[3:] | ||
| builds.append((output, rule, inputs)) | ||
| elif line.startswith("default"): | ||
| default_target = line.split()[1] | ||
|
|
||
| return rules, builds, default_target | ||
|
|
||
| def generate_manifest_cc(rules, builds, default_target): | ||
| cc_code = '#include "../manifest.h"\n\nusing namespace shadowdash;\n\nvoid manifest() {\n' | ||
| cc_code += f' let(flags, "{rules["compile"]["flags"]}");\n\n' | ||
|
|
||
| for rule, details in rules.items(): | ||
| cc_code += f' auto {rule} = rule{{ {{\n' | ||
| command = details["command"].replace("$flags", '"flags"_v').replace("$in", "in").replace("$out", "out") | ||
| cc_code += f' bind(command, {command}), //\n' | ||
| cc_code += f' }} }};\n\n' | ||
|
|
||
| for build in builds: | ||
| output, rule, inputs = build | ||
| inputs_str = ", ".join([f'str{{ "{inp}" }}' for inp in inputs]) | ||
| if rule == "compile" and "flags" in rules["compile"] and rules["compile"]["flags"] != "-O3": | ||
| cc_code += f' build(list{{ str{{ "{output}" }} }}, //\n' | ||
| cc_code += f' {{}}, //\n' | ||
| cc_code += f' {rule}, //\n' | ||
| cc_code += f' list{{ {inputs_str} }}, //\n' | ||
| cc_code += f' {{}}, //\n' | ||
| cc_code += f' {{}}, //\n' | ||
| cc_code += f' {{ bind(flags, "{rules["compile"]["flags"]}") }} //\n' | ||
| cc_code += f' );\n\n' | ||
| else: | ||
| cc_code += f' build(list{{ str{{ "{output}" }} }}, //\n' | ||
| cc_code += f' {{}}, //\n' | ||
| cc_code += f' {rule}, //\n' | ||
| cc_code += f' list{{ {inputs_str} }}, //\n' | ||
| cc_code += f' {{}}, //\n' | ||
| cc_code += f' {{}}, //\n' | ||
| cc_code += f' {{}} //\n' | ||
| cc_code += f' );\n\n' | ||
|
|
||
| cc_code += f' build(list{{ str{{ "{default_target}" }} }}, //\n' | ||
| cc_code += f' {{}}, //\n' | ||
| cc_code += f' link, //\n' | ||
| cc_code += f' list{{ str{{ "{default_target}.o" }} }}, //\n' | ||
| cc_code += f' {{}}, //\n' | ||
| cc_code += f' {{}}, //\n' | ||
| cc_code += f' {{}} //\n' | ||
| cc_code += f' );\n' | ||
|
|
||
| cc_code += '}\n' | ||
| return cc_code | ||
|
|
||
| def main(): | ||
| # argument parser for input and output file names | ||
| parser = argparse.ArgumentParser(description="Convert a build.ninja file to a build.ninja.cc file.") | ||
| parser.add_argument('input_file', help="Path to the input build.ninja file") | ||
| parser.add_argument('output_file', help="Path to the output build.ninja.cc file") | ||
|
|
||
| args = parser.parse_args() | ||
|
|
||
| # read input file | ||
| with open(args.input_file, 'r') as f: | ||
| ninja_file_content = f.read() | ||
|
|
||
| # parse the ninja file | ||
| rules, builds, default_target = parse_ninja_file(ninja_file_content) | ||
|
|
||
| # generate the manifest.cc content | ||
| manifest_cc_content = generate_manifest_cc(rules, builds, default_target) | ||
|
|
||
| # write the output to the file | ||
| with open(args.output_file, 'w') as f: | ||
| f.write(manifest_cc_content) | ||
|
|
||
| if __name__ == "__main__": | ||
| main() |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,21 @@ | ||
|
|
||
| void HandleRule(Rule* rule) | ||
| { | ||
| // output string | ||
| std::string output = "auto " + rule.name_ + " = rule{{bind(command, \"g++\", \"flags\"_v, \"-c\", "; | ||
|
|
||
| // Iterate over the parsed_ vector in the "command" binding | ||
| for (const auto& entry : rule.bindings_["command"].parsed_) { | ||
| if (entry.second == RAW) { | ||
| output += "\"" + entry.first + "\", "; // Add quotes for raw strings | ||
| } else if (entry.second == SPECIAL) { | ||
| output += entry.first + ", "; // No quotes for special variables | ||
| } | ||
| } | ||
|
|
||
| // Finish the string | ||
| output += ")}};"; | ||
|
|
||
| // Print the result | ||
| std::cout << output << std::endl; | ||
| } |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,55 @@ | ||
| #include <iostream> | ||
| #include <string> | ||
| #include <map> | ||
| #include <vector> | ||
|
|
||
| // Assuming you have these constants | ||
| enum EvalStringType { RAW, SPECIAL }; | ||
|
|
||
| // Example structures based on your description | ||
| struct EvalString { | ||
| std::string first; | ||
| EvalStringType second; | ||
| }; | ||
|
|
||
| struct Binding { | ||
| std::vector<EvalString> parsed_; | ||
| }; | ||
|
|
||
| struct Rule { | ||
| std::string name_; | ||
| std::map<std::string, Binding> bindings_; | ||
| }; | ||
|
|
||
| int main() { | ||
| // Simulate your object | ||
| Rule rule; | ||
| rule.name_ = "compile"; | ||
| rule.bindings_["command"].parsed_ = { | ||
| {"g++ -c ", RAW}, | ||
| {"in", SPECIAL}, | ||
| {" -o ", RAW}, | ||
| {"out", SPECIAL}, | ||
| {" ", RAW} | ||
| }; | ||
|
|
||
| // Begin the output string | ||
| std::string output = "auto " + rule.name_ + " = rule{{bind(command, \"g++\", \"flags\"_v, \"-c\", "; | ||
|
|
||
| // Iterate over the parsed_ vector in the "command" binding | ||
| for (const auto& entry : rule.bindings_["command"].parsed_) { | ||
| if (entry.second == RAW) { | ||
| output += "\"" + entry.first + "\", "; // Add quotes for raw strings | ||
| } else if (entry.second == SPECIAL) { | ||
| output += entry.first + ", "; // No quotes for special variables | ||
| } | ||
| } | ||
|
|
||
| // Finish the string | ||
| output += ")}};"; | ||
|
|
||
| // Print the result | ||
| std::cout << output << std::endl; | ||
|
|
||
| return 0; | ||
| } |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,86 @@ | ||
| #pragma once | ||
|
|
||
| #include <initializer_list> | ||
| #include <string_view> | ||
|
|
||
| namespace shadowdash { | ||
|
|
||
| class Token { | ||
| public: | ||
| enum Type { LITERAL, VAR }; | ||
|
|
||
| constexpr Token(Type type, std::string_view value) | ||
| : type_(type), value_(value) {} | ||
|
|
||
| constexpr Token(std::string_view value) : Token(Token::LITERAL, value) {} | ||
|
|
||
| constexpr Token(const char* value) : Token(Token::LITERAL, value) {} | ||
|
|
||
| Type type_; | ||
| std::string_view value_; | ||
| }; | ||
|
|
||
| constexpr Token operator"" _l(const char* value, std::size_t len) { | ||
| return Token(Token::Type::LITERAL, { value, len }); | ||
| } | ||
|
|
||
| constexpr Token operator"" _v(const char* value, std::size_t len) { | ||
| return Token(Token::Type::VAR, { value, len }); | ||
| } | ||
|
|
||
| class str { | ||
| public: | ||
| str(std::initializer_list<Token> tokens) : tokens_(tokens) {} | ||
| std::initializer_list<Token> tokens_; | ||
| }; | ||
|
|
||
| using binding = std::pair<std::string_view, str>; | ||
| using map = std::initializer_list<binding>; | ||
|
|
||
| class list { | ||
| public: | ||
| list(std::initializer_list<str> values) : values_(values) {} | ||
| std::initializer_list<str> values_; | ||
| }; | ||
|
|
||
| class var { | ||
| public: | ||
| var(const char* name, str value) {} | ||
| }; | ||
|
|
||
| class rule { | ||
| public: | ||
| rule(map bindings) {} | ||
| }; | ||
|
|
||
| class build { | ||
| public: | ||
| build( // | ||
| list outputs, // | ||
| list implicit_outputs, // | ||
| rule& rule, // | ||
| list inputs, // | ||
| list implicit_inputs, // | ||
| list order_only_inputs, // | ||
| map bindings) // | ||
| {} | ||
| }; | ||
|
|
||
| static constexpr auto in = "in"_v; | ||
| static constexpr auto out = "out"_v; | ||
|
|
||
| } // namespace shadowdash | ||
|
|
||
| #define let(name, ...) \ | ||
| var name { \ | ||
| #name, str { \ | ||
| __VA_ARGS__ \ | ||
| } \ | ||
| } | ||
|
|
||
| #define bind(name, ...) \ | ||
| { \ | ||
| #name, str { \ | ||
| __VA_ARGS__ \ | ||
| } \ | ||
| } |
Oops, something went wrong.
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
is this replacing the stock ninja readme!?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yes.