加入 Gitee
与超过 1200万 开发者一起发现、参与优秀开源项目,私有仓库也完全免费 :)
免费加入
文件
克隆/下载
build.py 11.18 KB
一键复制 编辑 原始数据 按行查看 历史
hiaifoundation 提交于 2022-01-26 14:22 . init
#!/usr/bin/env python
# encoding: utf-8
# Copyright © Huawei Technologies Co., Ltd. 2021-2021. All rights reserved.
# Description: build.py
# This program is free software; you can redistribute it and/or modify
# it under the terms of the Apache License Version 2.0.You may not use this file except in compliance with the License.
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# Apache License for more details at
# http://www.apache.org/licenses/LICENSE-2.0
from six.moves import urllib
import os
import sys
import zipfile
import tarfile
import stat
import platform
import shutil
config_file = "build.conf"
config_dict = dict()
prj_root_path = os.getcwd()
output_dir = os.path.join(prj_root_path, "..", "hiai_ddk", "libs")
# Tools download link
buildtools_link = {
"ANDROID_NDK_PATH":
["https://dl.google.com/android/repository/android-ndk-r20b-linux-x86_64.zip", "android-ndk-r20b"],
"CMAKE_MAKE_PROGRAM":
["https://github.com/Kitware/CMake/releases/download/v3.21.4/cmake-3.21.4-linux-x86_64.tar.gz", "cmake-3.21.4-linux-x86_64"],
"NINJA_PATH":
["https://github.com/ninja-build/ninja/releases/download/v1.10.2/ninja-linux.zip", "ninja"],
}
third_party = {
"LIBC_SEC_PATH":
[os.path.join(prj_root_path, "third_party", "libboundscheck"),
"https://github.com/openeuler-mirror/libboundscheck/archive/refs/tags/v1.1.11.zip",
os.path.join(prj_root_path, "third_party", "libboundscheck-1.1.11"),
],
"PROTOBUF_DIR":
[os.path.join(prj_root_path, "third_party", "protobuf"),
"https://github.com/protocolbuffers/protobuf/releases/download/v3.9.0/protobuf-cpp-3.9.0.tar.gz",
os.path.join(prj_root_path, "third_party", "protobuf-3.9.0"),
],
}
def extractBuildOptions():
if not os.path.exists(config_file):
print("[ERROR] : Building config file not exists!")
return False
config_dict["ANDROID_NDK_PATH"] = ""
config_dict["CMAKE_TOOLCHAIN_FILE"] = ""
config_dict["CMAKE_MAKE_PROGRAM"] = ""
config_dict["NINJA_PATH"] = ""
config_dict["PROTOBUF_DIR"] = ""
config_dict["ABI"] = "both"
with open(config_file) as f:
for line in f.readlines():
if line.strip() == "" or line.strip().startswith("#"):
continue
if len(line.split("=")) != 2:
print("[ERROR] : Config file not valid :")
print(" {}".format(line))
return None
key = str(line.strip().split("=")[0].strip())
value = str(line.strip().split("=")[1].strip())
config_dict[key] = value
protobuf_dir = os.path.join(prj_root_path, "third_party", "protobuf")
if os.path.exists(protobuf_dir):
config_dict["PROTOBUF_DIR"] = protobuf_dir
return True
def fetchFile(download_url, local_file, data_dir):
download_cmd = "wget -O {} -c -t 3 {} --no-check-certificate".format(local_file, download_url)
os.system(download_cmd)
print("Decompressing files...")
if local_file.endswith(".zip"):
with zipfile.ZipFile(local_file, 'r') as z:
z.extractall(data_dir)
print("[INFO] : PASS! {} has decompressed success!".format(local_file))
return True
elif local_file.endswith(".tar.gz"):
with tarfile.open(local_file) as t:
t.extractall(path=data_dir)
print("[INFO] : PASS! {} has decompressed success!".format(local_file))
return True
else:
return False
def CheckBuildTools(floder, tool_path):
if config_dict[tool_path] != "" and \
not os.path.exists(config_dict[tool_path]):
return False
elif config_dict[tool_path] == "":
if not os.path.exists(floder):
os.makedirs(floder)
target_path = os.path.join(prj_root_path, floder, buildtools_link[tool_path][1])
if not os.path.exists(target_path):
download_url = buildtools_link[tool_path][0]
file_name = download_url.split("/")[-1].strip()
local_file = os.path.join(floder, file_name)
fetchFile(download_url, local_file, floder)
config_dict[tool_path] = target_path
if tool_path == "CMAKE_MAKE_PROGRAM":
config_dict[tool_path] = os.path.join(target_path, "bin", "cmake")
if tool_path == "ANDROID_NDK_PATH":
chmod_ndk = "chmod -R u+x " + config_dict["ANDROID_NDK_PATH"]
os.system(chmod_ndk)
if tool_path == "NINJA_PATH":
os.chmod(config_dict[tool_path], stat.S_IRWXU)
return True
def ConfigThirdParty():
if not os.path.exists(os.path.join(prj_root_path, "third_party")):
os.makedirs(os.path.join(prj_root_path, "third_party"))
for item in third_party:
if not os.path.exists(third_party[item][0]):
download_url = third_party[item][1]
file_name = download_url.split("/")[-1].strip()
local_file = os.path.join("third_party", file_name)
fetchFile(download_url, local_file, "third_party")
os.rename(third_party[item][2], third_party[item][0])
def CheckALLBuildTools():
# Check if the cmake file exists
if not CheckBuildTools("buildtools", "CMAKE_MAKE_PROGRAM"):
print("[ERROR] : FAIL! file {} does not exist".format(
config_dict["CMAKE_MAKE_PROGRAM"]))
return False
# Check if the android-ndk file exists
if not CheckBuildTools("buildtools", "ANDROID_NDK_PATH"):
print("[ERROR] : FAIL! folder {} does not exist".format(
config_dict["ANDROID_NDK_PATH"]))
return False
else:
config_dict["CMAKE_TOOLCHAIN_FILE"] = \
os.path.join(config_dict["ANDROID_NDK_PATH"],
"build", "cmake", "android.toolchain.cmake")
# Check if the android.toolchain.cmake file exists
if config_dict["CMAKE_TOOLCHAIN_FILE"] == "" or \
not os.path.exists(config_dict["CMAKE_TOOLCHAIN_FILE"]):
return False
# Check if the ninja file exists
if not CheckBuildTools("buildtools", "NINJA_PATH"):
print("[ERROR] : FAIL! file {} does not exist".format(
config_dict["NINJA_PATH"]))
return False
# Check whether the ABI configuration is correct.
if config_dict["ABI"] != "armeabi-v7a" and \
config_dict["ABI"] != "arm64-v8a" and config_dict["ABI"] != "both":
print("[ERROR] : FAIL! Invalid parameter of ABI: ".format(
config_dict["ABI"]))
return False
elif config_dict["ABI"] == "both":
config_dict["ABI"] = ["armeabi-v7a", "arm64-v8a"]
else:
config_dict["ABI"] = [config_dict["ABI"]]
# Add PATH Environment Variables
cmake_bin_path = config_dict["CMAKE_MAKE_PROGRAM"].strip("cmake")
os.environ["PATH"] += os.pathsep + cmake_bin_path
ninja_path = config_dict["NINJA_PATH"].strip("ninja")
os.environ["PATH"] += os.pathsep + ninja_path
print("[INFO] : PATH: ", os.environ["PATH"])
return True
def build(ABI):
# Create the build directory
if os.path.exists("build"):
shutil.rmtree("build")
os.makedirs("build")
os.chdir("build")
build_cmd = "{} {} " \
"-DCMAKE_TOOLCHAIN_FILE={} " \
"-DANDROID_NDK={} " \
"-DCMAKE_BUILD_TYPE=Release " \
"-DANDROID_ABI={} " \
"-DANDROID_PLATFORM=android-19 " \
"-DLIB_OUTPUT_DIR=build/objs/hiai_ddk " \
"-DCMAKE_GENERATOR=Ninja " \
"-DPROTOBUF_DIR={} ".format(
config_dict["CMAKE_MAKE_PROGRAM"],
os.path.join("..", ""),
config_dict["CMAKE_TOOLCHAIN_FILE"],
config_dict["ANDROID_NDK_PATH"],
ABI,
third_party["PROTOBUF_DIR"][0],
)
ninja_cmd = config_dict["NINJA_PATH"]
print("[INFO] : build_cmd ", build_cmd)
print("[INFO] : ninja_cmd ", ninja_cmd)
res_build = os.system(build_cmd)
res_ninja = os.system(ninja_cmd)
if res_build != 0 or res_ninja != 0:
print("[ERROR] : build failed!")
sys.exit(-1)
os.chdir(os.path.join(os.getcwd(), ".."))
for obj_file in ["libhiai.so", "libhiai_ir.so"]:
obj_path = os.path.join(output_dir, ABI, obj_file)
if not os.path.exists(obj_path):
print("[ERROR] : Target file {} can not be found!".format(obj_path))
sys.exit(-1)
print("[INFO] : PASS! {} has successfully generated!".format(obj_path))
def CheckArgv(argv):
run_test = True
if len(argv) > 2:
errmsg_invalid_para_count = \
"[ERROR]: The number of command parameters more than 2.\n" \
"[INFO] : You can run the following command to obtain more information:\n" \
" 'python build.py --help'"
print(errmsg_invalid_para_count)
sys.exit(-1)
if len(argv) == 2:
if argv[1] == "--help":
helpmessage = \
"usage: [ python | python3 ] build.py [ --help | --only_ddk ]\n"\
"--help : print this help message and exit\n"\
"--only_ddk : run compile so command only.\n"\
"If no option is available, both compile so and run the test code by default."
print(helpmessage)
sys.exit(-1)
elif argv[1] == "--only_ddk":
run_test = False
else:
errmsg_invalid_para = \
"ERROR]: Unknown options and parameters.\n" \
"[INFO] : You can run the following command to obtain more information:\n" \
" 'python build.py --help'"
print(errmsg_invalid_para)
sys.exit(-1)
return run_test
def RunTest():
#Building the testBuild
testBuild = os.path.join(prj_root_path, "tests", "build")
if not os.path.exists(testBuild):
os.makedirs(testBuild)
os.chdir(testBuild)
os.system("cmake {}".format(os.path.join(prj_root_path, "tests")))
if platform.system() == "Linux":
os.system("make -j4")
if not os.path.exists(os.path.join(testBuild, "ut", "graph", "ut_graph")):
print("[ERROR] : Building testcase failed! Test object has not generated!")
sys.exit(-1)
os.system("export LD_LIBRARY_PATH=$LD_LIBRARY_PATH:./gtest/lib/ && ./ut/graph/ut_graph")
if __name__ == '__main__':
run_test = CheckArgv(sys.argv)
# compile ddk
ConfigThirdParty()
# Read configurations from the configuration file
ret = extractBuildOptions()
print("[INFO] : config: ", config_dict)
if not ret:
print("[ERROR] : FAIL! Parse config file failed")
sys.exit(-1)
else:
print("[INFO] : PASS! Parse config file success!")
is_available = CheckALLBuildTools()
if not is_available:
print("[ERROR] : FAIL! Parse configuration failed")
sys.exit(-1)
for ABI in config_dict["ABI"]:
build(ABI)
# build test
if run_test:
RunTest()
马建仓 AI 助手
尝试更多
代码解读
代码找茬
代码优化