-updated ramdisk class so the project is compilable on older qt builds < v6.5. -more fixes to build.py to work with newer versions of qt and less manual steps to take.
271 lines
8.2 KiB
Python
Executable File
271 lines
8.2 KiB
Python
Executable File
#!/usr/bin/python3
|
|
|
|
import os
|
|
import re
|
|
import subprocess
|
|
import shutil
|
|
import sys
|
|
import platform
|
|
import pwd
|
|
|
|
def get_app_target(text):
|
|
return re.search(r'(APP_TARGET) +(\"(.*?)\")', text).group(3)
|
|
|
|
def get_app_ver(text):
|
|
return re.search(r'(APP_VERSION) +(\"(.*?)\")', text).group(3)
|
|
|
|
def get_app_name(text):
|
|
return re.search(r'(APP_NAME) +(\"(.*?)\")', text).group(3)
|
|
|
|
def get_qt_path():
|
|
try:
|
|
if os.path.exists("/usr/lib/qt6/bin"):
|
|
return "/usr/lib/qt6/bin"
|
|
|
|
return str(subprocess.check_output(["qtpaths6", "--binaries-dir"]), 'utf-8').strip()
|
|
|
|
except:
|
|
print("A direct call to 'qtpaths6' 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_lib_path(qt_bin):
|
|
output = str(subprocess.check_output([qt_bin + "/qtpaths6", "--query"]), 'utf-8').strip()
|
|
lines = output.split("\n")
|
|
ret = ""
|
|
|
|
for line in lines:
|
|
if line.startswith("QT_HOST_LIBS:"):
|
|
ret = line[13:]
|
|
|
|
if ret == "":
|
|
print("failed automatic retrieval of the QT lib folder.")
|
|
|
|
return input("Please enter the QT lib path (leave blank to cancel the build): ")
|
|
|
|
else:
|
|
return ret
|
|
|
|
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:
|
|
return current_dir + os.sep + "src" + os.sep + "common.h"
|
|
|
|
def get_nearest_subdir(path, sub_name):
|
|
dir_list = os.listdir(path)
|
|
ret = ""
|
|
|
|
for entry in dir_list:
|
|
if sub_name in entry:
|
|
ret = entry
|
|
|
|
break
|
|
|
|
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
|
|
# the directory but still throws errors if
|
|
# it fails to apply the same file stats as
|
|
# the source. this type of error 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, qt_lib):
|
|
if not os.path.exists("app_dir/lib"):
|
|
os.makedirs("app_dir/lib")
|
|
|
|
verbose_copy("build/" + app_target, "app_dir/" + app_target)
|
|
|
|
shutil.copyfile("build/" + 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
|
|
# 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 and "libc" not in line:
|
|
#if ("libQt" in line) or ("libicu" in line) or ("libGL.so" in line) or ("libpcre16.so" in line) or ("libpcre.so" in line):
|
|
if " (0x0" in line:
|
|
start_index = line.index("> ") + 2
|
|
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/lib/" + file_name)
|
|
|
|
verbose_copy(qt_lib + "/libQt6DBus.so.6", "app_dir/lib/libQt6DBus.so.6")
|
|
|
|
verbose_copy("templates/linux_run_script.sh", "app_dir/" + app_target + ".sh")
|
|
verbose_copy("templates/linux_uninstall.sh", "app_dir/uninstall.sh")
|
|
verbose_copy("templates/linux_service.service", "app_dir/" + app_target + ".service")
|
|
|
|
complete(app_ver, app_target)
|
|
|
|
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 get_like_distro():
|
|
info = platform.freedesktop_os_release()
|
|
ids = [info["ID"]]
|
|
|
|
if "ID_LIKE" in info:
|
|
# ids are space separated and ordered by precedence
|
|
ids.extend(info["ID_LIKE"].split())
|
|
|
|
return ids
|
|
|
|
def list_installed_packages():
|
|
like_distro = get_like_distro()
|
|
|
|
if ("ubuntu" in like_distro) or ("debian" in like_distro) or ("linuxmint" in like_distro):
|
|
return str(subprocess.check_output(["apt", "list", "--installed"]), 'utf-8')
|
|
|
|
elif ("fedora" in like_distro) or ("rhel" in like_distro):
|
|
return str(subprocess.check_output(["dnf", "list", "installed"]), 'utf-8')
|
|
|
|
elif ("arch" in like_distro):
|
|
return str(subprocess.check_output(["pacman", "-Q"]), 'utf-8')
|
|
|
|
else:
|
|
print("Warning: unable to determine a package manager for this platform.")
|
|
|
|
return []
|
|
|
|
|
|
def list_of_words_in_text(list_of_words, text_body):
|
|
for word in list_of_words:
|
|
if not word in text_body:
|
|
return False
|
|
|
|
return True
|
|
|
|
def user_exists(user_name):
|
|
try:
|
|
pwd.getpwnam(user_name)
|
|
|
|
return True
|
|
|
|
except KeyError:
|
|
return False
|
|
|
|
def platform_setup():
|
|
ins_packages = list_installed_packages()
|
|
like_distro = get_like_distro()
|
|
dep_pkgs_a = ["pkg-config", "make", "g++"]
|
|
dep_pkgs_b = ["ffmpeg", "libfuse3-dev", "libfuse-dev", "fuse3", "imagemagick", "qt6-base-dev"]
|
|
|
|
if not list_of_words_in_text(dep_pkgs_a, ins_packages) or not list_of_words_in_text(dep_pkgs_b, ins_packages):
|
|
if ("ubuntu" in like_distro) or ("debian" in like_distro) or ("linuxmint" in like_distro):
|
|
subprocess.run(["sudo", "apt", "update", "-y"])
|
|
subprocess.run(["sudo", "apt", "install", "-y"] + dep_pkgs_a)
|
|
subprocess.run(["sudo", "apt", "install", "-y"] + dep_pkgs_b)
|
|
|
|
elif ("fedora" in like_distro) or ("rhel" in like_distro):
|
|
subprocess.run(["sudo", "dnf", "install", "-y"] + dep_pkgs_a)
|
|
subprocess.run(["sudo", "dnf", "install", "-y"] + dep_pkgs_b)
|
|
|
|
elif ("arch" in like_distro):
|
|
subprocess.run(["sudo", "pacman", "-S", "--noconfirm"] + dep_pkgs_a)
|
|
subprocess.run(["sudo", "pacman", "-S", "--noconfirm"] + dep_pkgs_b)
|
|
|
|
if not user_exists("jmotion"):
|
|
subprocess.run(["sudo", "useradd", "-r", "jmotion"])
|
|
subprocess.run(["sudo", "usermod", "-aG", "video", "jmotion"])
|
|
|
|
def main():
|
|
platform_setup()
|
|
|
|
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()
|
|
|
|
if qt_bin != "":
|
|
qt_lib = get_qt_lib_path(qt_bin)
|
|
|
|
if qt_lib == "":
|
|
exit(1)
|
|
|
|
print("app_target = " + app_target)
|
|
print("app_version = " + app_ver)
|
|
print("app_name = " + app_name)
|
|
print("qt_bin = " + qt_bin)
|
|
print("qt_lib = " + qt_lib)
|
|
|
|
cd()
|
|
|
|
result = subprocess.run([qt_bin + os.sep + "qmake", "-config", "release"])
|
|
|
|
if result.returncode == 0:
|
|
result = subprocess.run(["make"])
|
|
|
|
if result.returncode == 0:
|
|
if os.path.exists("app_dir"):
|
|
shutil.rmtree("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")
|
|
|
|
linux_build_app_dir(app_ver, app_name, app_target, qt_bin, qt_lib)
|
|
|
|
|
|
if __name__ == "__main__":
|
|
main()
|