fixed some grammar issues in the README. also moved it back to root

directory for better repository support.

fixed Qt6 support in the build.py file. (missing files)
This commit is contained in:
Maurice ONeal 2022-07-09 19:24:43 -04:00
parent d268fcb2ee
commit 27b03885df
2 changed files with 62 additions and 61 deletions

View File

@ -4,7 +4,7 @@ Cmdr is a command line terminal emulator client for MRCI host using text input/o
### Usage ###
Cmdr have it's own terminal display so there is no command line switches to pass on start up. Instead, all commands are parsed and processed within it's own terminal interface. Any commands not seen as an internal command for the client itself is passed through to the MRCI host if connected. The client will add a numeric identifer to the end of all host command names that clash with the client commands so there is no chance a client and host command can conflict with each other.
Cmdr have it's own terminal display so there is no command line switches to pass on start up. Instead, all commands are parsed and processed within it's own terminal interface. Any commands not seen as an internal command for the client itself is passed through to the MRCI host if connected. The client will add a numeric identifier to the end of all host command names that clash with the client commands so there is no chance a client and host command can conflict with each other.
### Versioning System ###
@ -35,11 +35,11 @@ payload - variable - the actual data to be processed.
notes:
* A full description of the type id's can be found in the [Type_IDs.md](type_ids.md) document.
* A full description of the type id's can be found in the [Type_IDs.md](docs/type_ids.md) document.
* This client call commands by name but the host will assign unique command ids for it's command names and will require the client to use the command id on calling. To track this command id to command name relationship for the host commands, this client will rely on the [ASYNC_ADD_CMD](async.md) and [ASYNC_RM_CMD](async.md) async commands.
* This client call commands by name but the host will assign unique command ids for it's command names and will require the client to use the command id on calling. To track this command id to command name relationship for the host commands, this client will rely on the [ASYNC_ADD_CMD](docs/async.md) and [ASYNC_RM_CMD](docs/async.md) async commands.
* The branch id is an id that can be used to run muliple instances of the same command on the host. Commands sent by a certain branch id will result in data sent back with that same branch id. For now, this client does not do branching; instead all commands sent to the host using branch id 0 only.
* The branch id is an id that can be used to run multiple instances of the same command on the host. Commands sent by a certain branch id will result in data sent back with that same branch id. For now, this client does not do branching; instead all commands sent to the host using branch id 0 only.
### Client Header (This Application) ###
@ -58,7 +58,7 @@ notes:
* **appName** is the name of the client application that is connected to the host. It can also contain the client's app version if needed because it doesn't follow any particular standard. This string is accessable to all modules so the commands themselves can be made aware of what app the user is currently using.
* **modInst** is an additional set of command lines that can be passed onto to all module processes when they are intialized. This can be used by certain clients that want to intruct certain modules that might be installed in the host to do certain actions during intialization. This remains constant for as long as the session is active and cannot be changed at any point.
* **modInst** is an additional set of command lines that can be passed onto to all module processes when they are initialized. This can be used by certain clients that want to instruct certain modules that might be installed in the host to do certain actions during initialization. This remains constant for as long as the session is active and cannot be changed at any point.
### Host Header ###
@ -77,7 +77,7 @@ sesId - 28bytes - 224bit sha3 hash
notes:
* **reply** is a numeric value that the host returns in it's header to communicate to the client if SSL need to initated or not.
* **reply** is a numeric value that the host returns in it's header to communicate to the client if SSL need to imitated or not.
* reply = 1, means SSL is not required so the client doesn't need to take any further action.
* reply = 2, means SSL is required to continue so the client needs to send a STARTLS signal.
@ -86,7 +86,7 @@ notes:
### Async Commands ###
Async commands are 'virtual commands' that this application can encounter at any time while connected to the host. More information about this can be found in the [Async.md](Async.md) document. This application does act on some of the data carried by the async commands but not all of them.
Async commands are 'virtual commands' that this application can encounter at any time while connected to the host. More information about this can be found in the [Async.md](docs/async.md) document. This application does act on some of the data carried by the async commands but not all of them.
### Build Setup ###
@ -116,7 +116,7 @@ while running the install script, it will ask you to input 1 of 3 options:
***local machine*** - This option will install the built application onto the local machine without creating an installer.
***create installer*** - This option creates an installer that can be distributed to other machines to installation. The resulting installer is just a regular .py script file that the target machine can run if it has Python3 insalled. Only Python3 needs to be installed and an internet connection is not required.
***create installer*** - This option creates an installer that can be distributed to other machines to installation. The resulting installer is just a regular .py script file that the target machine can run if it has Python3 installed. Only Python3 needs to be installed and an internet connection is not required.
***exit*** - Cancel the installation.

107
build.py
View File

@ -19,28 +19,28 @@ def get_app_name(text):
def get_qt_path():
try:
return str(subprocess.check_output(["qtpaths", "--binaries-dir"]), 'utf-8').strip()
except:
print("A direct call to 'qtpaths' has failed so automatic retrieval of the QT bin folder is not possible.")
return input("Please enter the QT bin path (leave blank to cancel the build): ")
def get_qt_from_cli():
for arg in sys.argv:
if arg == "-qt_dir":
index = sys.argv.index(arg)
try:
return sys.argv[index + 1]
except:
return ""
return ""
def get_ver_header():
current_dir = os.path.dirname(__file__)
if current_dir == "":
return "src" + os.sep + "common.h"
else:
@ -63,7 +63,7 @@ def get_maker(qt_path):
if platform.system() == "Linux":
ret = "make"
elif platform.system() == "Windows":
path = os.path.abspath(qt_path + "\\..")
name = os.path.basename(path)
@ -76,9 +76,9 @@ def get_maker(qt_path):
if not os.environ['PATH'].endswith(";"):
os.environ['PATH'] = os.environ['PATH'] + ";"
os.environ['PATH'] = os.environ['PATH'] + mingw_tool_path
ret = "mingw32-make"
elif "msvc" in name:
@ -90,28 +90,28 @@ def get_maker(qt_path):
if ans == 'y' or ans == 'Y':
ret = "nmake"
else:
exit()
else:
print("The system platform is unknown. Output from platform.system() = " + platform.system())
return ret
return ret
def cd():
current_dir = os.path.dirname(__file__)
if current_dir != "":
os.chdir(current_dir)
def verbose_copy(src, dst):
print("cpy: " + src + " --> " + dst)
if os.path.isdir(src):
if os.path.exists(dst) and os.path.isdir(dst):
shutil.rmtree(dst)
try:
# ignore errors thrown by shutil.copytree()
# it's likely not actually failing to copy
@ -120,47 +120,47 @@ def verbose_copy(src, dst):
# the source. this type of errors can be
# ignored.
shutil.copytree(src, dst)
except:
pass
elif os.path.exists(src):
shutil.copyfile(src, dst)
else:
print("wrn: " + src + " does not exists. skipping.")
def linux_build_app_dir(app_ver, app_name, app_target, qt_bin):
if not os.path.exists("app_dir/linux/platforms"):
os.makedirs("app_dir/linux/platforms")
if not os.path.exists("app_dir/linux/xcbglintegrations"):
os.makedirs("app_dir/linux/xcbglintegrations")
if not os.path.exists("app_dir/linux/lib"):
os.makedirs("app_dir/linux/lib")
if not os.path.exists("app_dir/icons"):
os.makedirs("app_dir/icons")
verbose_copy(qt_bin + "/../plugins/platforms/libqxcb.so", "app_dir/linux/platforms/libqxcb.so")
verbose_copy(qt_bin + "/../plugins/xcbglintegrations/libqxcb-egl-integration.so", "app_dir/linux/xcbglintegrations/libqxcb-egl-integration.so")
verbose_copy(qt_bin + "/../plugins/xcbglintegrations/libqxcb-glx-integration.so", "app_dir/linux/xcbglintegrations/libqxcb-glx-integration.so")
verbose_copy("build/linux/" + app_target, "app_dir/linux/" + app_target)
verbose_copy("icons", "app_dir/icons")
shutil.copyfile("build/linux/" + app_target, "/tmp/" + app_target)
# copying the executable file from the build folder to
# temp bypasses any -noexe retrictions a linux file
# system may have. there is a chance temp is also
# restricted in this way but that kind of config is
# rare. ldd will not run correctly with -noexe
# rare. ldd will not run correctly with -noexe
# enabled.
lines = str(subprocess.check_output(["ldd", "/tmp/" + app_target]), 'utf-8').split("\n")
os.remove("/tmp/" + app_target)
for line in lines:
if " => " in line:
if ("libQt" in line) or ("libicu" in line) or ("libssl" in line) or ("libcrypto" in line) or ("libGL.so" in line) or ("libpcre16.so" in line) or ("libpcre.so" in line):
@ -169,25 +169,26 @@ def linux_build_app_dir(app_ver, app_name, app_target, qt_bin):
end_index = line.index(" (0x0")
src_file = line[start_index:end_index]
file_name = os.path.basename(src_file)
verbose_copy(src_file, "app_dir/linux/lib/" + file_name)
if "/usr/lib/x86_64-linux-gnu/qt5/bin" == qt_bin:
verbose_copy(qt_bin + "/../../libQt5DBus.so.5", "app_dir/linux/lib/libQt5DBus.so.5")
verbose_copy(qt_bin + "/../../libQt5XcbQpa.so.5", "app_dir/linux/lib/libQt5XcbQpa.so.5")
verbose_copy(qt_bin + "/../../libQt6DBus.so.6", "app_dir/linux/lib/libQt6DBus.so.6")
verbose_copy(qt_bin + "/../../libQt6XcbQpa.so.6", "app_dir/linux/lib/libQt6XcbQpa.so.6")
else:
verbose_copy(qt_bin + "/../lib/libQt5DBus.so.5", "app_dir/linux/lib/libQt5DBus.so.5")
verbose_copy(qt_bin + "/../lib/libQt5XcbQpa.so.5", "app_dir/linux/lib/libQt5XcbQpa.so.5")
verbose_copy(qt_bin + "/../lib/libQt6DBus.so.6", "app_dir/linux/lib/libQt6DBus.so.6")
verbose_copy(qt_bin + "/../lib/libQt6XcbQpa.so.6", "app_dir/linux/lib/libQt5XcbQpa.so.6")
verbose_copy(qt_bin + "/../lib/libQt6XcbQpa.so.6", "app_dir/linux/lib/libQt6XcbQpa.so.6")
verbose_copy(qt_bin + "/../lib/libQt6OpenGL.so.6", "app_dir/linux/lib/libQt6OpenGL.so.6")
verbose_copy("templates/linux_run_script.sh", "app_dir/linux/" + app_target + ".sh")
verbose_copy("templates/linux_uninstall.sh", "app_dir/linux/uninstall.sh")
verbose_copy("templates/linux_icon.desktop", "app_dir/linux/" + app_target + ".desktop")
complete(app_ver, app_target)
def windows_build_app_dir(app_ver, app_name, app_target, qt_bin):
@ -199,15 +200,15 @@ def windows_build_app_dir(app_ver, app_name, app_target, qt_bin):
if not os.path.exists("app_dir\\windows"):
os.makedirs("app_dir\\windows")
if not os.path.exists("app_dir\\icons"):
os.makedirs("app_dir\\icons")
verbose_copy("icons", "app_dir\\icons")
verbose_copy("build\\windows\\" + app_target + ".exe", "app_dir\\windows\\" + app_target + ".exe")
verbose_copy("templates\\windows_uninstall.bat", "app_dir\\windows\\uninstall.bat")
verbose_copy("templates\\win_icon.vbs", "app_dir\\windows\\icon.vbs")
os.chdir("app_dir\\windows\\")
result = subprocess.run([qt_bin + "\\" + "windeployqt", app_target + ".exe"])
@ -216,7 +217,7 @@ def windows_build_app_dir(app_ver, app_name, app_target, qt_bin):
if result.returncode == 0:
complete(app_ver, app_target)
def complete(app_ver, app_target):
if os.path.exists("Makefile"):
os.remove("Makefile")
@ -235,21 +236,21 @@ def complete(app_ver, app_target):
print("Build complete for version: " + app_ver)
print("You can now run the install.py script to install onto this machine or create an installer.")
def main():
with open(get_ver_header()) as file:
text = file.read()
app_target = get_app_target(text)
app_ver = get_app_ver(text)
app_name = get_app_name(text)
qt_bin = get_qt_from_cli()
if qt_bin == "":
qt_bin = get_qt_path()
maker = get_maker(qt_bin)
if qt_bin != "":
print("app_target = " + app_target)
print("app_version = " + app_ver)
@ -262,38 +263,38 @@ def main():
else:
cd()
if platform.system() == "Linux":
if os.path.exists("build/linux"):
shutil.rmtree("build/linux")
elif platform.system() == "Windows":
if os.path.exists("build/windows"):
shutil.rmtree("build/windows")
result = subprocess.run([qt_bin + os.sep + "qmake", "-config", "release"])
if result.returncode == 0:
result = subprocess.run([maker])
if result.returncode == 0:
if not os.path.exists("app_dir"):
os.makedirs("app_dir")
with open("app_dir" + os.sep + "info.txt", "w") as info_file:
info_file.write(app_target + "\n")
info_file.write(app_ver + "\n")
info_file.write(app_name + "\n")
if platform.system() == "Linux":
linux_build_app_dir(app_ver, app_name, app_target, qt_bin)
elif platform.system() == "Windows":
windows_build_app_dir(app_ver, app_name, app_target, qt_bin)
else:
print("The platform you are running in is not compatible with the app_dir build out procedure.")
print(" output from platform.system() = " + platform.system())
if __name__ == "__main__":
main()
main()