project.h 2.2 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283
  1. #pragma once
  2. // Because Apple refuses to update libc++ in a timely manner
  3. // In exchange, this in C++11 compatible...
  4. #include <string>
  5. #include <vector>
  6. #include "command_builder.h"
  7. #include "types.h"
  8. #define CXX "clang++"
  9. namespace build {
  10. class project {
  11. private:
  12. version vers_{version::none};
  13. std::string name_;
  14. std::vector<source_file> source_files_;
  15. public:
  16. project(int argc, char const * const * const argv);
  17. project & set_version(version vers);
  18. project & set_name(std::string const & name);
  19. project & set_source_file(fs::path const & file);
  20. int generate() const;
  21. private:
  22. std::pair<std::vector<object_file>, int> generate_objects() const;
  23. };
  24. // TODO(samjaffe): Are there actually any arguments that belong here?
  25. project::project(int argc, char const * const * const argv) {}
  26. project & project::set_version(version vers) {
  27. vers_ = vers;
  28. return *this;
  29. }
  30. project & project::set_name(std::string const & name) {
  31. name_ = name;
  32. return *this;
  33. }
  34. project & project::set_source_file(fs::path const & file) {
  35. if (!fs::is_regular_file(file)) {
  36. throw std::logic_error(file.string() + " is not a regular file");
  37. }
  38. source_files_.emplace_back(file);
  39. return *this;
  40. }
  41. std::pair<std::vector<object_file>, int> project::generate_objects() const {
  42. fs::path obj_dir(".obj");
  43. fs::create_directory(obj_dir);
  44. std::vector<object_file> objects;
  45. for (auto const & file : source_files_) {
  46. output_file const outfile =
  47. obj_dir / file.get().filename().replace_extension(".o");
  48. auto cmd = command_builder(CXX, 1) << vers_ << file << outfile;
  49. if (int rc = cmd.execute()) { return {{}, rc}; }
  50. objects.emplace_back(outfile);
  51. }
  52. return {objects, 0};
  53. }
  54. int project::generate() const {
  55. std::cout << "Generating Project: " << name_ << std::endl;
  56. // Step 1: Compile Object files
  57. auto [objects, rc] = generate_objects();
  58. if (rc) { return rc; }
  59. // Step 2: Generate Executable
  60. fs::path bin_dir(".bin");
  61. fs::create_directory(bin_dir);
  62. output_file const outfile = bin_dir / name_;
  63. auto cmd = command_builder(CXX, 1) << vers_ << outfile << objects;
  64. return cmd.execute();
  65. }
  66. }