Elaztek Developer Hub
Blamite Game Engine - Tool (Library)
A command-line utility that aids in the creation of Blamite Cache (.map) Files.
BuildCommand.hpp
Go to the documentation of this file.
1 #pragma once
2 
3 #include <Strings/components/logger/logger.h>
4 #include <Strings/components/utils/io/io.h>
5 #include <Strings/components/utils/string/string.h>
6 #include <Strings/components/utils/list/list.h>
7 #include <Strings/components/3rdparty/rapidxml/rapidxml.hpp>
8 #include <Strings/components/classes/map/map.h>
9 #include <Strings/components/utils/converters/converters.h>
10 #include <HEKGuerilla/components/projects/projects.h>
11 
12 #include "../ToolCommand.hpp"
13 #include "../console.h"
14 #include "components/utils/utils.h"
15 
16 #ifdef TOOL_LIB_EXPORTS
17 #define TOOL_LIB_API __declspec(dllexport)
18 #else
19 #define TOOL_LIB_API __declspec(dllimport)
20 #endif
21 
28 {
29 private:
30  bool verbose = false;
31  bool rebuild_scripts = false;
32  bool package = false;
33 
34  std::vector<std::string> PreprocessArgs(std::vector<std::string> args)
35  {
36  std::vector<std::string> processed_args = std::vector<std::string>();
37 
38  for (int i = 0; i < args.size(); i++)
39  {
40  if (args[i] == "-verbose")
41  {
42  verbose = true;
43  }
44  else if (args[i] == "-rebuild-scripts")
45  {
46  rebuild_scripts = true;
47  }
48  else if (args[i] == "-package")
49  {
50  package = true;
51  }
52  else
53  {
54  processed_args.push_back(args[i]);
55  }
56  }
57 
58  return processed_args;
59  }
60 
61 public:
63  {
64  command = "build";
65  syntax = "build <configuration> <platform> [project filename] [game vcxproj filepath] [-verbose] [-rebuild-scripts] [-package]";
66  description = "builds the current project into a playable game executable";
67  }
68 
69  int execute(std::vector<std::string> args)
70  {
71  args = PreprocessArgs(args);
72 
73  if (args.size() < 2)
74  {
75  BlamStrings::Logger::LogEvent("failed to build executable: you must supply a configuration and platform", WSV_ERROR);
76  BlamStrings::Logger::LogEvent("syntax: " + syntax, WSV_ERROR);
77  return -1;
78  }
79 
80  std::string project_root = BlamTool::Utils::GetProjectRoot();
81  std::string project_filename = BlamStrings::Utils::IO::GetFileNameWithoutExtension(project_root) + ".blam";
82 
83  if (args.size() > 2)
84  {
85  project_filename = args[2];
86  }
87 
88  BlamProject* project_info = Guerilla::Projects::LoadProject(project_root + project_filename);
89 
90  if (!project_info->IsLoaded())
91  {
92  BlamStrings::Logger::LogEvent("failed to create stub project: could not load project info (tried to "
93  "read from file path: " + project_root + project_filename + ")", WSV_ERROR);
94 
95  if (args.size() == 0)
96  {
97  BlamStrings::Logger::LogEvent("project path was assumed from directory path - if your .blam file "
98  "has a different name, use " + syntax + " to specify the filename", WSV_WARNING);
99  }
100 
101  delete project_info;
102  return -1;
103  }
104 
105  std::string game_vcx_dir = project_root + "_build/_internal/game/";
106  std::string game_vcx_path = game_vcx_dir + "game.vcxproj";
107 
108  if (args.size() > 3)
109  {
110  game_vcx_path = args[3];
111  }
112 
113  if (project_info->cpp_script_info.pre_build_commands.length() > 0)
114  {
115  BlamStrings::Logger::LogEvent("running pre-build commands");
116 
117  std::string input = str_replace(project_info->cpp_script_info.pre_build_commands, "\r\n", "\n");
118 
119  for (std::string line : BlamStrings::Utils::String::Split(input, "\n"))
120  {
121  system(line.c_str());
122  }
123  }
124 
125  int build_result = 0;
126 
127  // Build game library
128  if (rebuild_scripts)
129  {
130  std::string msbuild_path_base = "\"" + project_info->GetMSBuildPath() + "\" \"" + project_info->GetVcxprojPath() + "\" ";
131  std::string cmd = "\"" + msbuild_path_base + "/p:Configuration=\"" + args[0] + "\" /p:Platform=\"" + args[1] + "\"" + "\"";
132 
133  if (verbose) BlamStrings::Logger::LogEvent("running system command :: " + cmd);
134  build_result = system(cmd.c_str());
135  }
136 
137  // Build game executable
138  if (build_result >= 0)
139  {
140  if (!GenerateProjectInfoSourceFile(project_info, game_vcx_dir + "gameinfo.cpp", !package,
141  BlamStrings::Utils::IO::GetAbsolutePathFromRelative(project_root)))
142  {
143  BlamStrings::Logger::LogEvent("failed to generate embedded game info file - CreateNewFile returned false", WSV_ERROR);
144  delete project_info;
145  return -1;
146  }
147 
148  std::string msbuild_path_base = "\"" + project_info->GetMSBuildPath() + "\" \"" + game_vcx_path + "\" ";
149  std::string cmd = "\"" + msbuild_path_base + "/p:Configuration=\"" + args[0] + "\" /p:Platform=\"" + args[1] + "\"" + "\"";
150 
151  if (verbose) BlamStrings::Logger::LogEvent("running system command :: " + cmd);
152  build_result = system(cmd.c_str());
153  }
154 
155  if (build_result < 0)
156  {
157  BlamStrings::Logger::LogEvent("build failed with code " + std::to_string(build_result) + " - see log for details", WSV_ERROR);
158  delete project_info;
159  return build_result;
160  }
161 
162  if (project_info->cpp_script_info.post_build_commands.length() > 0)
163  {
164  BlamStrings::Logger::LogEvent("running post-build commands");
165 
166  std::string input = str_replace(project_info->cpp_script_info.post_build_commands, "\r\n", "\n");
167 
168  for (std::string line : BlamStrings::Utils::String::Split(input, "\n"))
169  {
170  system(line.c_str());
171  }
172  }
173 
174  BlamStrings::Logger::LogEvent("finished");
175 
176  delete project_info;
177  return 0;
178  }
179 
180  bool GenerateProjectInfoSourceFile(BlamProject* project_info, std::string output_file, bool use_project_dirs, std::string project_root)
181  {
182  std::string template_file = BlamStrings::Utils::IO::GetFileContentsAsString("./content/blam/default_stub_project/gameinfo.cpp.template");
183 
184  BlamMap<std::string, std::string> replacements = BlamMap<std::string, std::string>();
185  {
186  replacements.Add("{project_name}", project_info->project_name);
187  //replacements.Add("{project_root}", project_info->project_root);
188  replacements.Add("{game_info.title}", project_info->game_info.title);
189  replacements.Add("{game_info.codename}", project_info->game_info.codename);
190  replacements.Add("{game_info.publisher}", project_info->game_info.publisher);
191  replacements.Add("{game_info.developer}", project_info->game_info.developer);
192  replacements.Add("{game_info.affiliates}", project_info->game_info.affiliates);
193  replacements.Add("{game_info.copyright}", project_info->game_info.copyright);
194  replacements.Add("{game_info.website}", project_info->game_info.website);
195  replacements.Add("{game_info.version}", project_info->game_info.version);
196  replacements.Add("{game_info.icon}", project_info->game_info.icon);
197  replacements.Add("{cpp_script_info.uses_cpp_script}", BlamStrings::Converters::BoolToString(project_info->cpp_script_info.uses_cpp_script));
198  replacements.Add("{cpp_script_info.vcxproj_path}", project_info->cpp_script_info.vcxproj_path);
199  replacements.Add("{cpp_script_info.engine_dependencies_path}", project_info->cpp_script_info.engine_dependencies_path);
200  replacements.Add("{cpp_script_info.msbuild_path}", project_info->cpp_script_info.msbuild_path);
201  replacements.Add("{cpp_script_info.msbuild_extra_args}", project_info->cpp_script_info.msbuild_extra_args);
202  replacements.Add("{cpp_script_info.pre_build_commands}", project_info->cpp_script_info.pre_build_commands);
203  replacements.Add("{cpp_script_info.post_build_commands}", project_info->cpp_script_info.post_build_commands);
204  replacements.Add("{engine_settings.user_data_folder}", project_info->engine_settings.user_data_folder);
205  replacements.Add("{engine_settings.default_cache}", project_info->engine_settings.default_cache);
206  replacements.Add("{engine_settings.campaign_info}", project_info->engine_settings.campaign_info);
207  replacements.Add("{engine_settings.startup_movie}", project_info->engine_settings.startup_movie);
208  replacements.Add("{engine_settings.content_root}", project_info->engine_settings.content_root);
209  replacements.Add("{engine_settings.tags_dir}", project_info->engine_settings.tags_dir);
210  replacements.Add("{engine_settings.movies_dir}", project_info->engine_settings.movies_dir);
211  replacements.Add("{engine_settings.data_dir}", project_info->engine_settings.data_dir);
212  replacements.Add("{engine_settings.cache_dir}", project_info->engine_settings.cache_dir);
213  replacements.Add("{engine_settings.plugins_dir}", project_info->engine_settings.plugins_dir);
214  replacements.Add("{engine_settings.fonts_dir}", project_info->engine_settings.fonts_dir);
215  replacements.Add("{engine_settings.allow_user_tag_overrides}", BlamStrings::Converters::BoolToString(project_info->engine_settings.allow_user_tag_overrides));
216  }
217 
218  if (use_project_dirs)
219  {
220  if (!project_root.ends_with("/"))
221  {
222  project_root += "/";
223  }
224 
225  replacements.Add("{engine_settings.tags_dir}", project_root + project_info->engine_settings.tags_dir);
226  replacements.Add("{engine_settings.movies_dir}", project_root + project_info->engine_settings.movies_dir);
227  replacements.Add("{engine_settings.plugins_dir}", project_root + project_info->engine_settings.plugins_dir);
228  replacements.Add("{engine_settings.fonts_dir}", project_root + project_info->engine_settings.fonts_dir);
229  }
230 
231  for (std::string key : replacements.KeySet())
232  {
233  std::string value = replacements.At(key);
234 
235  value = str_replace(value, "\\", "\\\\");
236  value = str_replace(value, "\r\n", "\n");
237  value = str_replace(value, "\n", "\\n");
238  value = str_replace(value, "\"", "\\\"");
239 
240  template_file = str_replace(template_file, key, value);
241  }
242 
243  return BlamStrings::Utils::IO::CreateNewFile(output_file, template_file);
244  }
245 };
TOOL_LIB_API
#define TOOL_LIB_API
Definition: BuildCommand.hpp:19
BuildCommand::execute
int execute(std::vector< std::string > args)
Executes the command.
Definition: BuildCommand.hpp:69
utils.h
BuildCommand::GenerateProjectInfoSourceFile
bool GenerateProjectInfoSourceFile(BlamProject *project_info, std::string output_file, bool use_project_dirs, std::string project_root)
Definition: BuildCommand.hpp:180
BuildCommand::BuildCommand
BuildCommand()
Definition: BuildCommand.hpp:62
BuildCommand
Class for the build command.
Definition: BuildCommand.hpp:27
ToolCommand
Base class representing a Tool command.
Definition: ToolCommand.hpp:15
BlamTool::Utils::GetProjectRoot
TOOL_LIB_API std::string GetProjectRoot()
Retrieves the current project root.
Definition: utils.cpp:6