class SeparatedListByCommaAction(argparse.Action):
# 把类当做一个方法使用
# 参考用例:https://zhuanlan.zhihu.com/p/165245990
def __call__(self, parser, namespace, vals, option_string):
for val in vals.split(','):
if val in known_platforms:
continue
else:
error = '\'{}\' invalid. Choose from {}'.format(val, known_platforms)
raise argparse.ArgumentError(self, error)
setattr(namespace, self.dest, vals.split(','))
```python
def check_create_dir(self, path):
if not os.path.exists(path):
"""Proxy for os.makedirs with logging and dry-run support."""
self.logger().info('makedirs %s', path)
os.makedirs(path)
```
##### 2.2.3.9 `check_rm_tree`方法解析
递归删除目录
```python
def check_rm_tree(self, tree_dir):
"""Removes directory tree."""
def chmod_and_retry(func, path, _):
if not os.access(path, os.W_OK):
os.chmod(path, stat.S_IWUSR)
return func(path)
raise IOError("rmtree on %s failed" % path)
if os.path.exists(tree_dir):
self.logger().info('shutil rmtree %s', tree_dir)
shutil.rmtree(tree_dir, onerror=chmod_and_retry)
```
##### 2.2.3.10 `check_copy_tree`方法解析
拷贝目录
```python
def check_copy_tree(self, src_dir, dst_dir):
self.check_rm_tree(dst_dir)
"""Proxy for shutil.copytree with logging and dry-run support."""
self.logger().info('copytree %s %s', src_dir, dst_dir)
shutil.copytree(src_dir, dst_dir, symlinks=True)
```
##### 2.2.3.11 `check_copy_file`方法解析
拷贝文件
```python
def check_copy_file(self, src_file, dst_file):
if os.path.exists(src_file):
"""Proxy for shutil.copy2 with logging and dry-run support."""
self.logger().info('copy %s %s', src_file, dst_file)
shutil.copy2(src_file, dst_file)
```
```python
def rm_cmake_cache(self, cache_dir):
os.walk()主要用来扫描某个指定目录下所包含的子目录和文件
for dirpath, dirs, files in os.walk(cache_dir):
if 'CMakeCache.txt' in files:
self.logger().info('rm CMakeCache.txt on %s', cache_dir)
os.remove(os.path.join(dirpath, 'CMakeCache.txt'))
if 'CMakeFiles' in dirs:
self.logger().info('rm CMakeFiles on %s', cache_dir)
self.check_rm_tree(os.path.join(dirpath, 'CMakeFiles'))
```
##### 2.2.3.17 `find_program`方法解析
返回命令的路径
```python
@staticmethod
def find_program(name):
# FIXME: Do we need Windows support here?
return os.popen('which ' + name).read().strip()
```
# Write a NATIVE.cmake in windows_path that contains the compilers used
# to build native tools such as llvm-tblgen and llvm-config. This is
# used below via the CMake variable CROSS_TOOLCHAIN_FLAGS_NATIVE.
cc = os.path.join(windowstool_path, 'bin', 'clang')
cxx = os.path.join(windowstool_path, 'bin', 'clang++')
# Extra cmake defines to use while building for Windows
windows_defines = {}
self.llvm_compile_windows_defines(windows_defines, cc, cxx, windows_sysroot)
# Set CMake path, toolchain file for native compilation (to build tablegen
# etc). Also disable libfuzzer build during native compilation.
# OHOS.cmake already exsit on cmake prebuilts,
# but it didn't contain these two lines, so we still need OHOS.cmake.
ohos_cmake = 'OHOS.cmake'
# 这个目录路径是 prebuilts/cmake/linux-x86/share/cmake-3.16/Modules/Platform
dst_dir = self.merge_out_path(
'../prebuilts/cmake/%s/share/cmake-3.16/Modules/Platform' % self.platform_prefix())
# 这个文件路径是 toolchain/llvm-project/llvm-build/OHOS.cmake
src_file = '%s/%s' % (self.build_config.LLVM_BUILD_DIR, ohos_cmake)
if os.path.exists(os.path.join(dst_dir, ohos_cmake)):
os.remove(os.path.join(dst_dir, ohos_cmake))
shutil.copy2(src_file, dst_dir)
```
if llvm_triple in arch_list:
if need_lldb_server and has_lldb_server and llvm_triple not in seen_arch_list:
self.build_lldb_server(llvm_install, llvm_path, arch, llvm_triple, cflags, ldflags,
defines)
seen_arch_list.append(llvm_triple)
continue
self.build_libomp(llvm_install, arch, llvm_triple, cflags, ldflags, multilib_suffix, defines)
self.build_libz(arch, llvm_triple, cflags, ldflags, defines)
if need_lldb_server and has_lldb_server and llvm_triple not in seen_arch_list:
self.build_lldb_server(llvm_install, llvm_path, arch, llvm_triple, cflags, ldflags, defines)
seen_arch_list.append(llvm_triple)
```
crt_extra_flags = []
if not self.build_config.debug:
# Remove absolute paths from compiler-rt debug info emitted with -gline-tables-only
crt_extra_flags = ['-ffile-prefix-map=%s=.' % self.build_config.REPOROOT_DIR]
if os.path.exists(libcxx_ndk_install):
for headerfile in os.listdir(libcxx_ndk_install_include):
if not headerfile =='__config':
if os.path.isdir(os.path.join(libcxx_ndk_install_include, headerfile)):
shutil.rmtree(os.path.join(libcxx_ndk_install_include, headerfile))
else:
os.remove(os.path.join(libcxx_ndk_install_include, headerfile))
# Remove unnecessary Windows lib files.
windows_necessary_lib_files = ['libc++.a', 'libc++abi.a']
for lib_file in lib_files:
if lib_file.endswith('.a') and lib_file not in windows_necessary_lib_files:
static_library = os.path.join(lib_dir, lib_file)
os.remove(static_library)
for necessary_lib_file in windows_necessary_lib_files:
if not os.path.isfile(os.path.join(lib_dir, necessary_lib_file)):
raise RuntimeError('Did not find %s under %s' % (necessary_lib_file, lib_dir))
self.install_mingw_python(install_dir)
```
##### 2.2.8.8 `darwin_stripped_xargs`方法解析
`darwin`系统相关,不介绍
```python
def darwin_stripped_xargs(self, bin_dir, necessary_bin_files, script_bins, need_x_bins_darwin):
for bin_filename in os.listdir(bin_dir):
binary = os.path.join(bin_dir, bin_filename)
if not os.path.isfile(binary):
continue
if bin_filename not in necessary_bin_files:
os.remove(binary)
elif bin_filename not in script_bins and self.build_config.strip:
if bin_filename not in need_x_bins_darwin and self.host_is_darwin():
self.check_call(['strip', '-x', binary])
else:
self.check_call(['strip', binary])
```
if not host.startswith('linux') or not os.path.exists(clang_version_bin_dir) or not self.build_config.strip:
return
llvm_strip = os.path.join(install_dir, 'bin', 'llvm-strip')
# os.listdir 返回指定路径下的目录和文件列表
for llvm_triple_dir in os.listdir(clang_version_bin_dir):
llvm_triple_bin_dir = os.path.join(clang_version_bin_dir, llvm_triple_dir)
if not os.path.isdir(llvm_triple_bin_dir):
continue
for bin_filename in os.listdir(llvm_triple_bin_dir):
binary = os.path.join(llvm_triple_bin_dir, bin_filename)
if os.path.isfile(binary):
self.check_call([llvm_strip, binary])
```
# Fetch all the LICENSE.* files under our projects and append them into a
# Single NOTICE file for the resulting prebuilts.
notices = []
for project in projects:
license_pattern = os.path.abspath(os.path.join(self.build_config.LLVM_PROJECT_DIR, project, 'LICENSE.*'))
# glob.glob 查找符合特定规则的文件路径名
for license_file in glob.glob(license_pattern):
with open(license_file) as notice_file:
notices.append(notice_file.read())
zlib_license_file = os.path.abspath(os.path.join(self.build_config.REPOROOT_DIR, 'third_party/zlib/LICENSE'))
with open(zlib_license_file) as notice_file:
notices.append(notice_file.read())
if host.startswith('windows'):
mingw_license_file = os.path.abspath(os.path.join(self.build_config.REPOROOT_DIR,
'third_party/mingw-w64/COPYING'))
with open(mingw_license_file) as notice_file:
notices.append(notice_file.read())
with open(os.path.join(install_dir, 'NOTICE'), 'w') as notice_file:
notice_file.write('\n'.join(notices))
```
# Scripts that should not be stripped
script_bins = ['git-clang-format', 'scan-build', 'scan-view']
need_x_bins_darwin = ['clang', 'clang++', 'clang-9', 'clang-cl', 'clang-cpp']
# Bin file in the list should be stripped with -x args when host=darwin
self.darwin_stripped_xargs(bin_dir, necessary_bin_files, script_bins, need_x_bins_darwin)
for necessary_bin_file in necessary_bin_files:
if not os.path.isfile(os.path.join(bin_dir, necessary_bin_file)):
print('Did not find %s in %s' % (necessary_bin_file, bin_dir))
raise RuntimeError('Did not find %s in %s' % (necessary_bin_file, bin_dir))
args = build_config.parse_args()
need_host = build_utils.host_is_darwin() or ('linux' not in args.no_build)
need_windows = build_utils.host_is_linux() and \
('windows' not in args.no_build)
configs = []
if not build_config.no_build_arm:
configs.append(('arm', build_utils.liteos_triple('arm')))
configs.append(('arm', build_utils.open_ohos_triple('arm')))
if not build_config.no_build_aarch64:
configs.append(('arm64', build_utils.open_ohos_triple('aarch64')))
if not build_config.no_build_riscv64:
configs.append(('riscv', build_utils.open_ohos_triple('riscv64')))
if not build_config.no_build_mipsel:
configs.append(('mipsel', build_utils.open_ohos_triple('mipsel')))
if not build_config.no_build_x86_64:
configs.append(('x86_64', build_utils.open_ohos_triple('x86_64')))
if build_config.do_build and need_host:
llvm_core.llvm_compile(
build_config.build_name,
llvm_install,
build_config.debug,
build_config.no_lto,
build_config.build_instrumented,
build_config.xunit_xml_output)
llvm_core.set_clang_version(llvm_install)
if build_config.do_build and build_utils.host_is_linux():
sysroot_composer.setup_cmake_platform(llvm_install)
llvm_libs.build_crt_libs(configs, llvm_install, build_config.need_lldb_server)
if build_config.need_libs:
for (arch, target) in configs:
llvm_libs.build_libs(build_config.need_lldb_server, llvm_install, target)
if build_config.do_build and need_windows:
mingw.main(build_config.VERSION)
llvm_libs.build_runtimes_for_windows(build_config.enable_assertions)
llvm_core.llvm_compile_for_windows(build_config.TARGETS,
build_config.enable_assertions,
build_config.build_name)
if build_config.need_lldb_mi:
lldb_mi.build_lldb_mi_for_windows()
if build_config.do_build and build_config.need_lldb_mi and need_host:
lldb_mi.build_lldb_mi(llvm_install)
if build_config.do_package:
if build_utils.host_is_linux():
llvm_package.package_libcxx()
llvm_package.package_operation(llvm_install, build_utils.use_platform())
if build_config.do_package and need_windows:
llvm_package.package_operation(windows64_install, 'windows-x86_64')
```
```cmake
-- check-shadowcallstack does nothing.
-- Configuring done
-- Generating done
CMake Warning:
Manually-specified variables were not used by the project:
LLVM_BUILD_TOOLS
-- Build files have been written to: /home/wen_fei/OpenHarmony/llvm/out/llvm_make/runtimes/runtimes-bins
[2892/3455] Performing build step for 'runtimes'
[819/1056] Building C object compiler-rt/lib/profile/CMakeFiles/clang_rt.profile-i386.dir/GCDAProfiling.c.o
FAILED: compiler-rt/lib/profile/CMakeFiles/clang_rt.profile-i386.dir/GCDAProfiling.c.o
/home/wen_fei/OpenHarmony/llvm/out/llvm_make/./bin/clang --target=x86_64-unknown-linux-gnu -D__STDC_CONSTANT_MACROS -D__STDC_FORMAT_MACROS -D__STDC_LIMIT_MACROS -I/home/wen_fei/OpenHarmony/llvm/toolchain/llvm-project/compiler-rt/lib/profile/.. -I/home/wen_fei/OpenHarmony/llvm/toolchain/llvm-project/compiler-rt/lib/profile/../../include -fPIC -fno-semantic-interposition -Werror=date-time -Werror=unguarded-availability-new -Wall -Wextra -Wno-unused-parameter -Wwrite-strings -Wmissing-field-initializers -Wimplicit-fallthrough -Wcovered-switch-default -Wno-comment -Wstring-conversion -Wmisleading-indentation -fdiagnostics-color -ffunction-sections -fdata-sections -Wall -Wno-unused-parameter -O3 -DNDEBUG -m32 -fno-lto -fPIC -Wno-pedantic -DCOMPILER_RT_HAS_ATOMICS=1 -DCOMPILER_RT_HAS_FCNTL_LCK=1 -DCOMPILER_RT_HAS_UNAME=1 -nostdinc++ -MD -MT compiler-rt/lib/profile/CMakeFiles/clang_rt.profile-i386.dir/GCDAProfiling.c.o -MF compiler-rt/lib/profile/CMakeFiles/clang_rt.profile-i386.dir/GCDAProfiling.c.o.d -o compiler-rt/lib/profile/CMakeFiles/clang_rt.profile-i386.dir/GCDAProfiling.c.o -c /home/wen_fei/OpenHarmony/llvm/toolchain/llvm-project/compiler-rt/lib/profile/GCDAProfiling.c
In file included from /home/wen_fei/OpenHarmony/llvm/toolchain/llvm-project/compiler-rt/lib/profile/GCDAProfiling.c:24:
In file included from /usr/include/errno.h:28:
In file included from /usr/include/bits/errno.h:26:
/usr/include/linux/errno.h:1:10: fatal error: 'asm/errno.h' file not found
#include <asm/errno.h>
^~~~~~~~~~~~~
1 error generated.
```