diff --git a/build_scripts/win/__pycache__/common.cpython-37.pyc b/build_scripts/win/__pycache__/common.cpython-37.pyc deleted file mode 100644 index 4061d4f..0000000 Binary files a/build_scripts/win/__pycache__/common.cpython-37.pyc and /dev/null differ diff --git a/build_scripts/win/build.py b/build_scripts/win/build.py index 78070f8..a1d8a21 100644 --- a/build_scripts/win/build.py +++ b/build_scripts/win/build.py @@ -1,9 +1,58 @@ +""" +Build script to compile OpenVR Advanced Settings on Windows. + +The entire purpose of the script is to locate the correct install locations +for seven different applications: + +1. Qt Framework, used for compiling. +2. Visual Studio, used for setting up the variables needed to compile with Qt. +3. jom.exe, a part of Qt, basically a multi core nmake. +4. 7zip. Used for creating the portable versions of the app. +5. NSIS. Used for creating the installer versions of the app. +6. LLVM. Used for clang-format and clang-cl. +7. Qmake, a part of Qt, used for creating the makefiles. + +The script does error checking on environmental variables before outputting +a simple Windows batch file that will be called by other batch scripts. + +The reason that a batch file is created and run outside of python is that if +you don't do it like that, you have these options + +1) Run applications one by one in python. + + This is not viable because the build() function requires that a batch file + be run to set up environmental variables for QMAKE and nmake, and all environmental + variables and settings are lost between sessions. + +2) Batch all applications together and run them in python. + + This is still a viable way of doing things, but creating an actual file + makes debugging and experimentation a lot easier by less experienced people. + Furthermore the stdout and stderr output wouldn't be real time without adding + unnecessary complexity. + +3) Write the entire thing in another language (like Powershell). + + This was tried and even though Powershell has decent stdlib functionality like + testing paths and replacing chars in strings, it is still lacking in some areas + like actually running .exe files without resorting to weird tricks and cmd line hacks. + In addition, Powershell has some weird tendencies compared to other "real" + programming languages that would add unnecessary complexity. + +Writing this script in pure Windows batch file language is definitely possible, +but the large amounts of replication and low amounts of abstraction possibilities +will make development and extension a chore. +""" + import os from sys import argv import inspect from common import * def package(): + """ + Runs 7zip and NSIS to create portable and installer versions. + """ set_current_activity("PACKAGE") set_dirs() @@ -16,6 +65,7 @@ def package(): ZIP_NAME = "AdvancedSettings-" + VERSION_STRING + ".7z" add_line_to_run_bat_file("@ECHO Starting 7zip:") + # -t7z means to output a 7zip file. add_line_to_run_bat_file('"' + ZIP_LOC + '"' + " a -t7z " + get_project_dir() + "\\bin\\win64\\" + ZIP_NAME + " " + get_deploy_dir() + "\\*") add_error_handling_line_to_bat_file() add_line_to_run_bat_file("@ECHO 7zip done.") @@ -33,6 +83,9 @@ def package(): def deploy(): + """ + Runs windeployqt and copies necessary files. + """ set_current_activity("DEPLOY") set_dirs() @@ -89,6 +142,12 @@ def deploy(): def build(): + """ + Runs: + 'vcvarsall.bat', a Visual Studio file to set up the environment for QMAKE. + QMAKE, creates the makefiles. + jom/nmake, builds the makefiles. + """ set_current_activity("BUILD") set_dirs() diff --git a/build_scripts/win/common.py b/build_scripts/win/common.py index a33a0b0..8bac5ba 100644 --- a/build_scripts/win/common.py +++ b/build_scripts/win/common.py @@ -9,6 +9,8 @@ import shutil import distutils.dir_util #Const globals +#Version string must be bumped every release. +#TODO: See developer documentation. VERSION_STRING = "2-8-0" EXIT_CODE_SUCCESS = 0 @@ -46,34 +48,66 @@ current_activity = "" bat_file_contents = "" def set_current_activity(activity: str): + """ + Wrapper around the current_activity global var to make it usable in other files. + """ global current_activity current_activity = activity def say(message: str): + """ + Prints a message to the console prepended by the current activity, like: + BUILD: Building things. + DEPLOY: Deploying things. + """ global current_activity print(current_activity + ": " + message) def say_error(message: str): + """ + Prints an error message to the console. + + Not currently different from say, but put in incase somebody wanted to + do something fancy with outputting to stderr or something instead. + """ global current_activity print(current_activity + ": " + message) def is_env_var_set(env_var_name: str): + """ + Returns whether or not an environment variable is set. + """ var = os.getenv(env_var_name) if var is None: return False return True def add_line_to_run_bat_file(line: str): + """ + Adds a line ended by a newline to the batch file. + """ global bat_file_contents bat_file_contents += line + "\n" def add_error_handling_line_to_bat_file(): + """ + Adds an error handling line to the batch file. + + This is because some applications don't cause the script to error out + even if they exit with an error. + """ global bat_file_contents bat_file_contents += "IF ERRORLEVEL 1 EXIT /B " + str(EXIT_CODE_FAILURE_BUILD_APP) + "\n" def get_required_env_var_path(env_var_name: str, default_env_var_value: str): + """ + Easy function for getting *_LOC values, complete with testing for path validity and + outputting status to console. + """ if not is_env_var_set(env_var_name): say(f"{env_var_name} not defined. Using default value.") + #Sanitize quotes because we'll add them later and they might mess up + #how we put together strings. path = default_env_var_value.replace('"', '') else: path = os.getenv(env_var_name).replace('"', '') @@ -85,14 +119,23 @@ def get_required_env_var_path(env_var_name: str, default_env_var_value: str): return path def create_batch_file(): + """ + Creates a batch file in the dir. Must be called by another outside batch file. + """ file = open(get_project_dir() + "\\build_scripts\\win\\test.bat", "w+") file.write(bat_file_contents) file.close() def exit_on_error(error_number): + """Wrapper around sys.exit.""" sys.exit(error_number) def set_dirs(): + """ + Sets up the directories. + + We know that the project dir will always be two dirs up from the dir the file is in. + """ global ORIGINAL_DIR global PROJECT_DIR global DEPLOY_DIR @@ -112,11 +155,13 @@ def get_deploy_dir(): return DEPLOY_DIR def copy_file(src, dest): + """Copies a file and outputs status to console.""" say(f"Copying {src} to {dest}") shutil.copy(src, dest) say(f"{src} to {dest} copied.") def copy_folder(src, dest): + """Copies a folder and outputs status to console.""" say(f"Copying {src} to {dest}") distutils.dir_util.copy_tree(src, dest) say(f"{src} to {dest} copied.")