DepperDan/build_deps.py

232 lines
8.0 KiB
Python

#!/usr/bin/env python3
# (c) 2025 by Stephan Menzel
# Licensed under the Apache License, Version 2.0.
# See attached file LICENSE for full details
import argparse
import json
import os
import datetime
import logging as log
import importlib
from build_functions.build_abseil import build_abseil
from build_functions.build_asio import build_asio
from build_functions.build_boost import build_boost
from build_functions.build_cares import build_cares
from build_functions.build_ceres import build_ceres
from build_functions.build_curl import build_curl
from build_functions.build_cppzmq import build_cppzmq
from build_functions.build_eigen import build_eigen
from build_functions.build_fineftp import build_fineftp
from build_functions.build_glog import build_glog
from build_functions.build_googletest import build_googletest
from build_functions.build_grpc import build_grpc
from build_functions.build_hdf5 import build_hdf5
from build_functions.build_jpeg import build_jpeg
from build_functions.build_libzmq import build_libzmq
from build_functions.build_matplot import build_matplot
from build_functions.build_onetbb import build_onetbb
from build_functions.build_opencv import build_opencv
from build_functions.build_openssl import build_openssl
from build_functions.build_opensubdiv import build_opensubdiv
from build_functions.build_openusd import build_openusd
from build_functions.build_protobuf import build_protobuf
from build_functions.build_qt5 import build_qt5
from build_functions.build_qt6 import build_qt6
from build_functions.build_qwt import build_qwt
from build_functions.build_recycle import build_recycle
from build_functions.build_spdlog import build_spdlog
from build_functions.build_tclap import build_tclap
from build_functions.build_re2 import build_re2
from build_functions.build_tcp_pubsub import build_tcp_pubsub
from build_functions.build_termcolor import build_termcolor
from build_functions.build_tinyxml2 import build_tinyxml2
from build_functions.build_yaml_cpp import build_yaml_cpp
from build_functions.build_zlib import build_zlib
import common.settings
from package.package_info import PackageInfo, get_package_info, build_package_tree
import sys
from pathlib import Path
from common.errors import DependencyInfoError
from build_functions.build_utils import print_banner, file_and_console_log, logfile
# Iterate over all Python files in the `build_functions` folder and import them
module_path = Path(__file__).parent / "build_functions"
for file in module_path.glob("*.py"):
module_name = f"build_functions.{file.stem}"
module = importlib.import_module(module_name)
# If the module has a `build` function, call it
if hasattr(module, "build"):
module.build()
# Plenty of warnings raising out of protobuf when using c++23
os.environ["CXXFLAGS"] = "-D_SILENCE_ALL_CXX23_DEPRECATION_WARNINGS"
def build_all(prefix: Path | str) -> dict:
"""Build all known dependencies
:return The merged (partial) SBOM
:raise DependencyInfoError
"""
sbom = {}
file_and_console_log(f"Build script running in python {sys.version}")
file_and_console_log(f"Installing to: {prefix}")
# First those without any dependencies
build_asio(prefix, sbom)
build_tclap(prefix, sbom)
build_spdlog(prefix, sbom)
build_boost(prefix, sbom)
build_zlib(prefix, sbom)
build_glog(prefix, sbom)
build_abseil(prefix, sbom)
build_eigen(prefix, sbom)
build_libzmq(prefix, sbom)
build_jpeg(prefix, sbom)
build_onetbb(prefix, sbom)
build_cares(prefix, sbom)
build_recycle(prefix, sbom)
build_termcolor(prefix, sbom)
build_tinyxml2(prefix, sbom)
build_yaml_cpp(prefix, sbom)
# Conditional. This could depend on abseil but I'll try to build without
build_googletest(prefix, sbom)
# Then the ones that depend on any of those above
# Note that this doesn't constitute a dependency tree yet
build_curl(prefix, sbom)
build_fineftp(prefix, sbom)
build_re2(prefix, sbom)
build_cppzmq(prefix, sbom)
build_protobuf(prefix, sbom)
build_ceres(prefix, sbom)
build_opencv(prefix, sbom)
build_matplot(prefix, sbom)
build_openssl(prefix, sbom)
build_opensubdiv(prefix, sbom)
build_openusd(prefix, sbom)
build_hdf5(prefix, sbom)
build_tcp_pubsub(prefix, sbom)
# This one gets a special place as it depends on many of the above
build_grpc(prefix, sbom)
build_qt5(prefix, sbom)
build_qt6(prefix, sbom)
build_qwt(prefix, sbom)
return sbom
build_functions = {
"abseil-cpp": build_abseil,
"asio": build_asio,
"boost": build_boost,
"curl": build_curl,
"glog": build_glog,
"hdf5": build_hdf5,
"protobuf": build_protobuf,
"eigen": build_eigen,
"ceres-solver": build_ceres,
"libzmq": build_libzmq,
"cppzmq": build_cppzmq,
"fineftp": build_fineftp,
"googletest": build_googletest,
"libjpeg-turbo": build_jpeg,
"opencv": build_opencv,
"matplotplusplus": build_matplot,
"openssl": build_openssl,
"opensubdiv": build_opensubdiv,
"openusd": build_openusd,
"onetbb": build_onetbb,
"re2": build_re2,
"recycle": build_recycle,
"spdlog": build_spdlog,
"tclap": build_tclap,
"c-ares": build_cares,
"grpc": build_grpc,
"qt5": build_qt5,
"qt6": build_qt6,
"qwt": build_qwt,
"termcolor": build_termcolor,
"tcp_pubsub": build_tcp_pubsub,
"tinyxml2": build_tinyxml2,
"yaml-cpp": build_yaml_cpp,
"zlib": build_zlib,
}
if __name__ == '__main__':
try:
with open(logfile, 'w') as f:
f.write(str(datetime.datetime.now()) + f' - started {__file__}\n')
parser = argparse.ArgumentParser()
parser.add_argument("--install-dir", "-i", type=str, required=True, help="install into this directory")
parser.add_argument("--package", "-p", type=str, default="all", help="build specific package or 'all'")
parser.add_argument("--rebuild", action="store_true", help="always delete build dir")
parser.add_argument("--sbom", "-s", type=str, default="sbom.json",
help="Append to this SBOM in CycloneDX format. If all packages are being built (-p=all) "
"a previously existing sbom file gets deleted and overwritten")
parser.add_argument("--build-dir", "-b", type=Path, default=Path("raw"), help="use this directory to build in")
args = parser.parse_args()
global_prefix = Path(args.install_dir)
if not global_prefix.is_absolute():
script_dir = Path(__file__).parent.resolve().absolute()
global_prefix = script_dir / global_prefix
common.settings.set_global_build_dir(args.build_dir)
common.settings.set_global_install_prefix(args.install_dir)
common.settings.set_global_rebuild(args.rebuild)
package = args.package
sbomfile = args.sbom
build_package_tree()
if package == "all":
# Build all packages
sbom = build_all(prefix=global_prefix)
# (Over)write CycloneDX SBOM
with open(sbomfile, "w") as f:
json.dump(sbom, f)
else:
if package not in build_functions:
raise DependencyInfoError(f"Don't know how to build {package}")
sbom = {}
# Build the package, amend SBOM with package info
build_functions[package](prefix=global_prefix, sbom=sbom)
# The partial SBOM gets written into the install dir so we can later combine it.
# We cannot merge them into one file right here as in the pipeline there may be multiple tasks in parallel
package_info = get_package_info(package)
partial_sbom_filename = package_info.install_location() / "partial_sbom.json"
with open(partial_sbom_filename, "w") as f:
json.dump(sbom, f)
print_banner("Done")
exit(0)
except ValueError as ve:
print(f"Cannot read or write SBOM: {str(ve)}")
except DependencyInfoError as die:
print(f"Dependency info error: {str(die)}")
exit(-1)