惯性聚合 高效追踪和阅读你感兴趣的博客、新闻、科技资讯
阅读原文 在惯性聚合中打开

推荐订阅源

Application and Cybersecurity Blog
Application and Cybersecurity Blog
博客园 - Franky
博客园 - 叶小钗
阮一峰的网络日志
阮一峰的网络日志
Y
Y Combinator Blog
The GitHub Blog
The GitHub Blog
J
Java Code Geeks
F
Full Disclosure
V
V2EX
The Register - Security
The Register - Security
罗磊的独立博客
OSCHINA 社区最新新闻
OSCHINA 社区最新新闻
云风的 BLOG
云风的 BLOG
T
Troy Hunt's Blog
Microsoft Security Blog
Microsoft Security Blog
Help Net Security
Help Net Security
P
Privacy & Cybersecurity Law Blog
K
Kaspersky official blog
博客园 - 聂微东
Recorded Future
Recorded Future
I
Intezer
S
Schneier on Security
cs.CV updates on arXiv.org
cs.CV updates on arXiv.org
H
Hacker News: Front Page
SecWiki News
SecWiki News
M
MIT News - Artificial intelligence
Security Latest
Security Latest
Attack and Defense Labs
Attack and Defense Labs
A
About on SuperTechFans
aimingoo的专栏
aimingoo的专栏
宝玉的分享
宝玉的分享
T
Tenable Blog
B
Blog
N
News | PayPal Newsroom
P
Proofpoint News Feed
D
Docker
奇客Solidot–传递最新科技情报
奇客Solidot–传递最新科技情报
MyScale Blog
MyScale Blog
C
Cisco Blogs
A
Arctic Wolf
T
Threat Research - Cisco Blogs
I
InfoQ
Stack Overflow Blog
Stack Overflow Blog
CTFtime.org: upcoming CTF events
CTFtime.org: upcoming CTF events
GbyAI
GbyAI
P
Palo Alto Networks Blog
Engineering at Meta
Engineering at Meta
Hugging Face - Blog
Hugging Face - Blog
Latest news
Latest news
Project Zero
Project Zero

I'm OWenT

国产大模型(GLM 5.1、Kimi K2.6)真实场景效果和 Coding Plan 额度测试 新版本libatapp的连接管理——从etcd服务发现到拓扑驱动的自动重连 新版本libatbus的设计变更——从树形路由到拓扑驱动 Protobuf又一坑 - C++标准和ABI兼容性 AI真好用-给Blog主题统一加mermaid,chart.js,excalidraw,draw.io的多种引入方式支持 给内网部署Squid-通用HTTP下载缓存 UE使用CodeChecker和clang-tidy生成静态分析报告 找出UE的循环依赖 C++小协程栈和临时变量及作用域的栈溢出问题分析 游戏服务的可观测性能力建设(C++生态) 指标上报的多线程优化和多拉取源点优化 协程(libcopp)的Channel功能和CPU命中率优化 通用RPC代码生成器 实现strong_rc_ptr(比shared_ptr更快的引用计数智能指针) 手夯一个STL allocator和对象内存分析组件 std::condition_variable 的信号丢失问题 踩坑一处(GCC)STL std::async 实现BUG导致的crash问题 GCC 14的一个warning to error BUG 给xresloader(Excel导表工具)增强UE读表支持(包含蓝图,Blueprint) Opentelemetry社区在gRPC的几个链接问题(静态库和动态库混用,musl工具链,符号裁剪) Excel转表工具(xresloader)的新验证器(验证外部Excel和文本数据,唯一性和自定义规则) protobuf v22和gRPC v1.55版本升级的依赖变化和upb适配 关于protobuf近期版本(v20/v3.20+)和 gRPC v1.54版本在某些编译环境下的一些链接和编译问题 xresloader-Excel导表工具链的近期变更汇总 打通游戏服务端框架的C++20协程改造的最后一环 Opentelemetry-cpp的Logs模块标准更新(涉及近期版本:1.8-1.9的BREAK CHANGES) 给cmake-toolset和工具链(curl等)加HTTP/2和HTTP/3支持 又开新坑之 coredns 插件: nftables和filter 关于opentelemetry-cpp社区对于C++ Head Only组件单例和符号可见性的讨论小记 填个转表工具 xresloader 去年的坑(数组尾部裁剪) 集成 upb 和 lua binding 的踩坑小记 libcopp对C++20协程的接入和接口设计 游戏服务的分布式事务优化(二)- 事务管理 游戏服务的分布式事务优化(一)- Write Ahead Log(WAL) 模块 记录一些bazel适配用编译选项 测试现代化硬件C++浮点数性能和一致性 适配Boringssl和OpenSSL 3.0 近期cmake-toolset的一些适配问题 C++20 Text Formatting/fmtlib 适配问题小记 再次重构LLVM+Clang+libcxx+libc++abi+其他相关工具的构建流程 重构基于CMake的构建工具链 新版GCC和LLVM+Clang终于Release啦 折腾一下nftables下的双拨 [C++20] Module partitions和符号交叉引用(声明和实现分离) [Rust] 实现一个线程安全且迭代器可以保存的链表 基于protobuf的代码生成 几个使用protobuf中C++接口的Arena的坑 Amazon Aurora DB存储引擎论文阅读小记 近期对libatapp的一些优化调整(增加服务发现和连接管理,支持yaml等) xresloader转表工具链增加了一些新功能(map,oneof支持,输出矩阵,基于模板引擎的加载代码生成等) 在游戏服务器中使用分布式事务 libcopp接入C++20 Coroutine和一些过渡期的设计 libatbus 的大幅优化 nftables初体验 容器配置开发环境小计 PALM Tree - 适合多核并发架构的B+树 - 论文阅读小记 跨平台协程库 - libcopp 简介 C++20 Coroutine 性能测试 (附带和libcopp/libco/libgo/goroutine/linux ucontext对比) 尝鲜Github Action 一些xresloader(转表工具)的改进 protobuf、flatbuffer、msgpack 针对小数据包的简单对比 协程框架(libcopp) 小幅优化 Excel转表工具(xresloader) 增加protobuf插件功能和集成 UnrealEngine 支持 Anna(支持任意扩展和超高性能的KV数据库系统)阅读笔记 C++20 Coroutine libcopp merge boost.context 1.69.0 Google去中心化分布式系统论文三件套(Percolator、Spanner、F1)读后感 Rust玩具-企业微信机器人通用服务 使用ELK辅助监控开发测试环境服务质量和问题定位 2018年的新通用伪随机数算法(xoshiro / xoroshiro)的C++(head only)实现 Webpack+vue+boostrap+ejs构建Web版GM工具 Rust的第二次接触-写个小服务器程序 理解和适配AEAD加密套件 atsf4g-co的进化:协程框架v2、对象路由系统和一些其他细节优化 协程框架(libcopp)v2优化、自适应栈池和同类库的Benchmark对比 可执行文件压缩 初识Rust 使用restructedtext编写xresloader文档 atframework的etcd模块化重构 C++的backtrace ECDH椭圆双曲线(比DH快10倍的密钥交换)算法简介和封装 protobuf-net的动态Message实现 pbc的proto3接入 atgateway内置协议流程优化-加密、算法协商和ECDH 整理一波软件源镜像同步工具+DevOps工具 Blog切换到Hugo libcopp v2的第一波优化完成 libcopp(v2) vs goroutine性能测试 libcopp的线程安全、栈池和merge boost.context 1.64.0 GCC 7和LLVM+Clang+libc++abi 4.0的构建脚本 libatbus的几个藏得很深的bug 用cmake交叉编译到iOS和Android 开源项目得一些小维护 atapp的c binding和c#适配 对象路由系统设计 2016年总结 近期的一个协程流程BUG 重写了llvm+clang+libc++和libc++abi的构建脚本 atsf4g完整游戏工程示例|I'm OWenT atframework基本框架已经完成|I'm OWenT
再度优化GCC、LLVM、Clang、libc++、libc++abi等套件的构建脚本
owent · 2022-04-18 · via I'm OWenT

blog-website

前言

一直以来,我都维护了完整的 GCC 工具链构建工具LLVM,Clang,libc++,libc++abi工具链构建工具 。 一方面是为了测试和体验新版本编译器的功能和利用一些更现代化的工具检查代码中的风险,另一方面也是为了给我得很多开源仓库做多版本适配。 其中所有的编译期依赖项(不包括 tar,awk等可执行程序的工具)都是自己构建的,这样也能管理好某些新版本组件需要的新版本依赖项,并且做到跨发行版兼容。同时很多发行版自带的 LLVM+Clang 套件都缺斤少两,有的缺少 clang-analyzer ,有的缺少 clang-format ,也有的缺少 libc++libc++abi 或者缺少sanitizer组件。我也是根据自己的需要编译并输出了大多数开发工具,甚至还有一些开发库以便二次开发(比如用libclang写工具来复用libcang的AST功能)。

我一直而在陆陆续续更新和增加这两组工具中的组件和版本,然后对流程上进行一些优化。这两天把 LLVM+Clang+libc++abi+libc++工具链构建工具 升级到了最新的Release 14.0.1 版本,然后发现很多配置都过时了,所以大规模重构了以下。并且顺带记录一下近期这两组构建工具的变化。

GNU/GCC

  • 增加压缩库
    • zlib: zstd依赖项
    • zstd: GCC 10以后的版本支持使用zstd压缩调试符号了
    • lz4: 顺带加的
  • 增加常见的工具库
    • m4: 我们发现有些开源库要求的此工具的版本已经高于CentOS 7自带的版本了
    • autoconf: 同上
    • automake: 同上
    • pkg-config: 同上
    • libtool: 有些开发工具包默认不带,为了方便加的
    • libexpat
    • libxcrypt
    • libffi
    • gdbm
  • 默认关闭 libssp

    大多数发行版默认也是关闭的,如果开启的话,有些组件链接时要手动加 -lssp ,编译时要手动加 -fstack-protector-strong。 而很多软件编译的时候并不会自己适配这个,所以为了方便默认还是关掉了。

  • openssl 升级到 3.0

    openssl 3.0 版本有个比较大的变化是64位系统的库文件输出目录变成了 <PREFIX>/lib64 ,之前是 <PREFIX>/lib 。 而有些工具是写死 lib 目录的,比如cmake的 FindOpenSSL.cmake 和 Python (至少到 3.9之前都是这样)。 所以为了适配这些兼容性不好的系统,我把 <PREFIX>/lib64 里的 pkgconfig,库文件,engine和ossl-modules链接到了 <PREFIX>/lib 目录。

  • Python升级到 3.9而不是最新的 3.10,因为distcc(目前最新版本是3.4)不支持Python3.10
  • 允许通过环境变量 REPOSITORY_MIRROR_URL_GNU 来执行GNU软件包的下载源。

    如: export REPOSITORY_MIRROR_URL_GNU=http://mirrors.tencent.com/gnu

  • 增加了用于生成RPM包的配置

LLVM,Clang,libc++,libc++abi工具链构建工具 经历过多次改版。主要原因是早期这一套工具的的构建系统健壮性欠佳,又没啥标准化安装的文档。只能看着已有的文档,结合别人的分享经验还有官方源代码搞。而编译这玩意儿又局耗内存和慢。 我得编译策略是先尽可能采用多核编译,如果编译失败了,可能是OOM,再降低并发数再试。直到 -j1 还失败,那才是真的失败。而这一轮下载,到最后 -j1 的时候就特别慢,调试起来特别费劲。

最早我试自己写的自举编译,老是会碰到某些组件,这个版本自举能编出来,下个版本不能的情况。非常恶心。 而从LLVM 12.0开始,我转向使用 LLVM 自带的 All In One的工程 - llvm-project 了,这样就有了官方的自举构建流程。 但是这种编译方式,仍然没有完善的文档。那么我只好常考他们一些Test和脚本里的写法。所幸找到了官方的一个参考: https://github.com/llvm/llvm-project/tree/main/clang/cmake/caches 。这里面的 Fuchsia 的配置试最为完善的,所以就参考这里面的设置写了自己的生成配置。当时还写了个简单的总结 《再次重构LLVM+Clang+libcxx+libc++abi+其他相关工具的构建流程》

但是其实 Fuchsia 的组件也是缺斤少两的(比如没有 lldb ,没发布 scan-build 等),并且在Linux上的一些环境检测还有问题。所以我也根据自己的需要增加了不少发布组件,改了不少适配。 当时是基于 llvm-project 12.0 的版本改的,后来升级到 13.0 的时候没做太大变化,只是常规地升级了版本。 知道最近升级 14.0 后发现有些组件又有问题了,我就整体看了一下。好家伙变化真大。

所以我重新基于14.0版本里 Fuchsia 的配置重新梳理了一遍,顺便把改动的内容记录下来以便后面更新的时候照葫芦画瓢。

目前已经看到的又一个变化是 Fuchsia 里main分支已经包含bolt了,但是14.0里还没有。 以后肯定还是会再Merge的。

首先我们和 GCC 工具链构建工具 一样,我们也给 LLVM,Clang,libc++,libc++abi工具链构建工具 增加了用于生成RPM包的配置。,然后基于 Fuchsia 的配置修改的内容如下:

  • LLVM_TARGETS_TO_BUILD 改为 Native : 目前没有交叉编译需求,有了再说吧。只编译Native可以加快编译速度。
  • 注释掉所有的set(*LIBCXX_ABI_VERSION 2*) : ABI 2还未稳定
  • ~distribution-stage2.cmakeLLVM_INSTALL_TOOLCHAIN_ONLY 改为 OFF : 我们需要开发包,这个ON的情况不能发布开发包。~
  • [distribution-stage1.cmake][11] 的 BOOTSTRAP_CMAKE_SYSTEM_NAME 内和 [distribution-stage2.cmake][12]
    • *LIBCXXABI_INSTALL_LIBRARY 改为 ON
    • *LIBUNWIND_INSTALL_LIBRARY 改为 ON
  • distribution-stage1.cmakeCLANG_BOOTSTRAP_CMAKE_ARGS 改为以下脚本: 只是为了更灵活一点
if(STAGE2_CACHE_FILE)
  set(CLANG_BOOTSTRAP_CMAKE_ARGS -C ${STAGE2_CACHE_FILE} CACHE STRING "")
else()
  set(CLANG_BOOTSTRAP_CMAKE_ARGS -C ${CMAKE_CURRENT_LIST_DIR}/distribution-stage2.cmake CACHE STRING "")
endif()
  • LLVM_ENABLE_PROJECTS 增加 lldb;libclc;mlir;pstl

    注意顺序要参考 [llvm/CMakeLists.txt][10] 内的 LLVM_ALL_PROJECTS

  • distribution-stage2.cmakeforeach(target *-linux-*) 后的 if(LINUX_${target}_SYSROOT) 改为 if(LINUX_${target}_SYSROOT OR target STREQUAL "${LINUX_NATIVE_TARGET}") ,并在前面插入适配脚本
# Intel JIT API support
if(CMAKE_HOST_SYSTEM_NAME MATCHES "Linux|Windows")
  set(LLVM_USE_INTEL_JITEVENTS ON CACHE BOOL "")
endif()
# Cross compiling
if("${LLVM_TARGETS_TO_BUILD}" MATCHES "Native|X86")
  if(CMAKE_HOST_SYSTEM_NAME STREQUAL "Linux")
    cmake_host_system_information(RESULT LINUX_NATIVE_IS_64BIT QUERY IS_64BIT)
    if(CMAKE_HOST_SYSTEM_PROCESSOR MATCHES "x86_64" OR ("${CMAKE_HOST_SYSTEM_PROCESSOR}" STREQUAL ""
                                                        AND LINUX_NATIVE_IS_64BIT))
      set(LINUX_NATIVE_TARGET x86_64-unknown-linux-gnu)
    elseif(CMAKE_HOST_SYSTEM_PROCESSOR MATCHES "i386|i686|x86" OR "${CMAKE_HOST_SYSTEM_PROCESSOR}" STREQUAL "")
      set(LINUX_NATIVE_TARGET i386-unknown-linux-gnu)
    endif()
  endif()
endif()
message(STATUS "Stage2: CMAKE_HOST_SYSTEM_NAME=${CMAKE_HOST_SYSTEM_NAME}")
message(STATUS "Stage2: CMAKE_HOST_SYSTEM_PROCESSOR=${CMAKE_HOST_SYSTEM_PROCESSOR}")
message(STATUS "Stage2: CMAKE_HOST_SYSTEM_VERSION=${CMAKE_HOST_SYSTEM_VERSION}")
message(STATUS "Stage2: LLVM_TARGETS_TO_BUILD=${LLVM_TARGETS_TO_BUILD}")
message(STATUS "Stage2: LINUX_NATIVE_IS_64BIT=${LINUX_NATIVE_IS_64BIT}")
message(STATUS "Stage2: LINUX_NATIVE_TARGET=${LINUX_NATIVE_TARGET}")

首先JIT功能的选项是直接参考构建系统里的设置的,它只支持Linux和Windows。 然后这里对目标平台构建时要设置很多子组件。脚本原先是为在Fuchsia下跑的,编译到Linux的时候要指定SYSROOT。 而且我们直接在Linux里编译Native版本是没有SYSROOT设置的,所以这里要把和自己当前架构一致的设置目标平台特设置了。

这个Cache文件是在cmake启动工程之前加载的,这时候 CMAKE_SYSTEM_NAME 还不可用。所以我们只能用 CMAKE_HOST_SYSTEM_NAME

  • distribution-stage2.cmakeLLVM_TOOLCHAIN_TOOLS 改名为非Cache的 LLVM_TOOLCHAIN_TOOLS_SELECT, 增加注释 # See <llvm-project>/llvm/test/CMakeLists.txt ,同时组件变更如下:
    • 移除:
      • llvm-ifs
      • llvm-lipo
      • llvm-libtool-darwin
      • llvm-otool
    • 增加
      • llc
      • lli
      • llvm-addr2line
      • llvm-as
      • llvm-config
      • llvm-cxxdump
      • llvm-cxxmap
      • llvm-install-name-tool
      • llvm-jitlink
      • llvm-jitlistener
      • llvm-link
      • llvm-mc
      • llvm-ml
      • llvm-strings
      • llvm-lto
      • llvm-lto2
      • scan-build
      • scan-view
    • 最后添加
      if(APPLE)
        list(
          APPEND
          LLVM_TOOLCHAIN_TOOLS_SELECT
          llvm-bitcode-strip
          llvm-ifs
          llvm-lipo
          llvm-libtool-darwin
          llvm-otool)
      endif()
      if(CMAKE_HOST_SYSTEM_NAME MATCHES "Linux|Windows")
        list(APPEND LLVM_TOOLCHAIN_TOOLS_SELECT llvm-jitlink llvm-jitlistener)
      endif()
      set(LLVM_TOOLCHAIN_TOOLS ${LLVM_TOOLCHAIN_TOOLS_SELECT} CACHE STRING "")
      

JIT组件的开关同上。

  • distribution-stage2.cmakeLLVM_DISTRIBUTION_COMPONENTS 增加 ${LLVM_DISTRIBUTION_ADDTIONAL_COMPONENTS}
set(LLVM_DISTRIBUTION_ADDTIONAL_COMPONENTS
    # add_lldb_library(...) in <llvm-project>/lldb
    liblldb
    # add_lldb_tool(...) in <llvm-project>/lldb
    lldb
    lldb-server
    lldb-instr
    lldb-vscode
    # add_llvm_install_targets(xxx) in <llvm-project>/clang
    libclang-headers
    libclang-python-bindings
    libclang
    # add_clang_tool(xxx) in <llvm-project>/clang
    clang-change-namespace
    clang-check
    clang-extdef-mapping
    clang-rename
    clang-repl
    diagtool
    modularize
    pp-trace
    opt-viewer
    # unwind, cxx, cxxabi are already included in runtimes
    # From <llvm-project>/clang/cmake/caches/Apple-stage2.cmake
    Remarks
    # From <llvm-project>/clang/cmake/caches/MultiDistributionExample.cmake . These targets are development targets, and
    # them will only available when LLVM_INSTALL_TOOLCHAIN_ONLY=OFF
    cmake-exports
    llvm-headers
    llvm-libraries
    clang-cmake-exports
    clang-headers
    clang-libraries)
#[[
# clang-cpp is a development library, and linking it will cost alot memory, we ignore it.
if(UNIX OR (MINGW AND LLVM_LINK_LLVM_DYLIB))
  list(APPEND LLVM_DISTRIBUTION_ADDTIONAL_COMPONENTS clang-cpp)
endif()
]]
if(NOT WIN32)
  list(APPEND LLVM_DISTRIBUTION_ADDTIONAL_COMPONENTS lldb-python-scripts)
endif()

set(LLVM_DISTRIBUTION_COMPONENTS
    # ============ Additional tools begin ============
    ${LLVM_DISTRIBUTION_ADDTIONAL_COMPONENTS}
    # ============ Additional tools end ============
)    

目前就到此为止,可以看到。我们还是增加了不少发布组件的。 以后更新版本就按这里的流程来一遍就可以了,当然还需要人工去重一下,以防官方发布的组件又增加了什么我们已经添加的部分。 总体来说还不是特别费事儿。以上脚本我在我们公司内部的CentOS 7和Cent OS 8环境都测试过没问题了。其他发行版应该也没啥问题,但是我没试。

最后

欢迎有兴趣的小伙伴交流分享。