常规方式

  1. 编译过程分四步:
[Preloader] → 环境初始化
     ↓
[Loader]   → 加载产品配置、模块依赖
     ↓
[GN]       → 生成 build.ninja[Ninja]    → 调用编译器/链接器生成镜像
  1. GN阶段时最耗时的,需要解析整个项目的构建配置,虽然只build-target只指定了一个目标,但是他要完成真个项目的构建关系解析,要确保模块依赖的库优先编译。--fast-rebuild 就是跳过build.gn 生成ninja编译文件的过程,所以编译很快。但是第一次编译,还是需要完成整个项目的配置解析,rk3568项目大约10分钟编一个helloworld程序。

  2. 这种方式优点是可以用BUILD.gn添加系统自带的库。

非常规方式:

  1. 利用自带的clang工具链交叉编译,通常gcc的交叉编译工具都是arm-gnu-xxx-gcc这种命名,但是clang只需要指定目标架构即可
  2. 设置clang用到的musl版本的c语言库libc.so/libc.a和工具链构建好的libc++.so库,再配置额makefile就可以完成对项目的编译
  3. 如果需要openharmony中的库,需要优通过--build-target xxx的方式先编译出需要的库,再通过修改头文件定义CINC和库定义CLIB指定依赖库
  4. 需要根据架构修改SRC_PATH、PRODUCT_NAME、 ARCH 三个参数,脚本如下
set -e
echo "build can start... "
export SRC_PATH=/home/app/new_4.1-1.2.0/ # openharmony源码目录
MAKE=make
export PRODUCT_NAME=xhc200
\#export PRODUCT_NAME=rk3568
export ARCH=arm64
export TARGET=arm-linux-ohos
if [ $ARCH = 'arm64' ]; then
    TARGET=aarch64-linux-ohos
elif [ $ARCH = 'arm' ]; then
    TARGET=arm-linux-ohos
else
    echo "只支持arm或者arm64"
    exit 0
fi

# 优先编译musl这个c库
MUSL_LIB=$SRC_PATH/out/$PRODUCT_NAME/obj/third_party/musl/usr/lib/$TARGET/libm.a
echo $MUSL_LIB
if [ ! -f $MUSL_LIB ]; then
    cd $SRC_PATH;
    echo "编译musl库开始-------"
    echo "bash $SRC_PATH/build.sh --product-name $PRODUCT_NAME --build-target musl_all --target-cpu $ARCH --no-prebuilt-sdk"
    bash $SRC_PATH/build.sh --product-name $PRODUCT_NAME --build-target toybox --target-cpu $ARCH --no-prebuilt-sdk --fast-rebuild
    #./build.sh --product-name=xhc200 --build-target musl_all --target-cpu arm64 --no-prebuilt-sdk
    echo "编译musl库完成-------"
    cd -
fi

echo $TARGET
export OHOS_BUILD_HOME=$SRC_PATH
export CLANG_PATH=$SRC_PATH/prebuilts/clang/ohos/linux-x86_64/llvm/bin
export PATH=$CLANG_PATH:$PATH
export SROOT="--target=$TARGET --sysroot=$OHOS_BUILD_HOME/out/$PRODUCT_NAME/obj/third_party/musl"
export CINC="\
-I$OHOS_BUILD_HOME/out/$PRODUCT_NAME/obj/third_party/musl/usr/include/$TARGET \
-I$OHOS_BUILD_HOME/prebuilts/clang/ohos/linux-x86_64/llvm/include/libcxx-ohos/include/c++/v1 \
-I$OHOS_BUILD_HOME/prebuilts/clang/ohos/linux-x86_64/15.0.4/llvm/include/$TARGET/c++/v1"

export CLib="\
-L$OHOS_BUILD_HOME/out/$PRODUCT_NAME/obj/third_party/musl/usr/lib/$TARGET \
-L$OHOS_BUILD_HOME/prebuilts/clang/ohos/linux-x86_64/llvm/lib/$TARGET/ \
-L$OHOS_BUILD_HOME/prebuilts/clang/ohos/linux-x86_64/llvm/lib/clang/15.0.4/lib/$TARGET"

export CDefines="\
-DV8_DEPRECATION_WARNINGS \
-DNO_TCMALLOC \
-D_GNU_SOURCE \
-DHAVE_SYS_UIO_H \
-D__MUSL__ \
-D_LIBCPP_HAS_MUSL_LIBC \
-D__BUILD_LINUX_WITH_CLANG \
-D__STDC_CONSTANT_MACROS \
-D__STDC_FORMAT_MACROS \
-D_FORTIFY_SOURCE=2 \
-DCOMPONENT_BUILD \
-D__GNU_SOURCE=1 \
-DCHROMIUM_CXX_TWEAK_INLINES \
-D__MUSL__ \
-D_LIBCPP_HAS_MUSL_LIBC \
-D__BUILD_LINUX_WITH_CLANG \
-DNDEBUG -DNVALGRIND  \
-DDYNAMIC_ANNOTATIONS_ENABLED=0"

export CFlags="\
-Wno-builtin-macro-redefined \
-D__DATE__= \
-D__TIME__= \
-D__TIMESTAMP__= \
-funwind-tables \
-fcolor-diagnostics \
-fmerge-all-constants \
-Xclang \
-mllvm \
-Xclang \
-instcombine-lower-dbg-declare=0 \
-no-canonical-prefixes \
-ffunction-sections \
-fno-short-enums \
--target=$TARGET \
-mfloat-abi=softfp \
-mfpu=neon \
-Wall \
-Wextra \
-Wthread-safety \
-Wno-missing-field-initializers \
-Wno-unused-parameter \
-Wno-c++11-narrowing \
-Wno-unneeded-internal-declaration \
-Wno-error=c99-designator \
-Wno-error=anon-enum-enum-conversion \
-Wno-error=sizeof-array-div \
-Wno-error=reorder-init-list \
-Wno-error=range-loop-construct \
-Wno-error=deprecated-copy \
-Wno-error=implicit-int-float-conversion \
-Wno-error=inconsistent-dllimport \
-Wno-error=unknown-warning-option \
-Wno-error=abstract-final-class \
-Wno-error=sign-compare \
-Wno-error=int-in-bool-context \
-Wno-error=xor-used-as-pow \
-Wno-error=return-stack-address \
-Wno-error=dangling-gsl \
-Wno-undefined-var-template \
-Wno-nonportable-include-path \
-Wno-user-defined-warnings \
-Wno-unused-lambda-capture \
-Wno-null-pointer-arithmetic \
-Wno-enum-compare-switch \
-O2 \
-fdata-sections \
-fomit-frame-pointer \
-gdwarf-3 \
-g2 \
-ggnu-pubnames \
-fno-common \
-Wheader-hygiene \
-Wstring-conversion \
-Wtautological-overlap-compare \
-fPIE"

export cc="$CLANG_PATH/clang $CDefines $SROOT $CINC $CFlags "
export cxx="$CLANG_PATH/clang++ $CDefines $SROOT $CINC $CFlags "
export readelf=$CLANG_PATH/llvm-readobj
export ar=$CLANG_PATH/llvm-ar
export ld="$CLANG_PATH/clang++ $SROOT $CLib "
export ranlib=$CLANG_PATH/llvm-ranlib
export strip=$CLANG_PATH/llvm-strip
 
export CC=$cc
export CXX=$cxx
export READELF=$readelf
export AR=$ar
export LD=$ld
export RANLIB=$ranlib
export STRIP=$strip
 
alias cc=$cc
alias cxx=$cxx
alias readelf=$readelf
alias ar=$ar
alias ld=$ld
alias ranlib=$ranlib
alias strip=$strip
 
alias CC=$cc
alias CXX=$cxx
alias READELF=$readelf
alias AR=$ar
alias LD=$ld
alias RANLIB=$ranlib
alias STRIP=$stri

${MAKE}  ARCH=${ARCH}

5.  上面shell脚本调用makefile执行编译

all:
    $(cxx) main.cpp -o main 
  1. 编译选项的deepseek解释如下:
  • 链接库
export CLib="\
-L$OHOS_BUILD_HOME/out/$PRODUCT_NAME/obj/third_party/musl/usr/lib/$TARGET \
-L$OHOS_BUILD_HOME/prebuilts/clang/ohos/linux-x86_64/llvm/lib/$TARGET/ \
-L$OHOS_BUILD_HOME/prebuilts/clang/ohos/linux-x86_64/llvm/lib/clang/15.0.4/lib/$TARGET"

export CDefines="\
-DV8_DEPRECATION_WARNINGS \          # 启用 V8 引擎的废弃 API 警告
-DNO_TCMALLOC \                      # 禁用 Google 的 TCMalloc 内存分配器
-D_GNU_SOURCE \                      # 启用 GNU 扩展功能(如某些 glibc 函数)
-DHAVE_SYS_UIO_H \                   # 声明系统支持 <sys/uio.h> 头文件(向量 I/O)
-D__MUSL__ \                         # 标识使用 musl C 库(非 glibc)
-D_LIBCPP_HAS_MUSL_LIBC \            # 告知 libc++ 标准库当前使用 musl
-D__BUILD_LINUX_WITH_CLANG \         # 标识使用 Clang 编译 Linux 相关代码
-D__STDC_CONSTANT_MACROS \           # 启用 C99 标准中的常量宏(如 INT64_C)
-D__STDC_FORMAT_MACROS \             # 启用 C99 标准中的格式化宏(如 PRId64)
-D_FORTIFY_SOURCE=2 \                # 启用编译时缓冲区溢出检查(安全加固)
-DCOMPONENT_BUILD \                  # 标识构建组件化(动态库)而非静态链接
-D__GNU_SOURCE=1 \                   # 同上(重复定义,可能冗余)
-DCHROMIUM_CXX_TWEAK_INLINES \       # Chromium 项目特定的内联优化(可能历史遗留)
-D__MUSL__ \                         # 重复定义(冗余)
-D_LIBCPP_HAS_MUSL_LIBC \            # 重复定义(冗余)
-D__BUILD_LINUX_WITH_CLANG \         # 重复定义(冗余)
-DNDEBUG \                           # 禁用断言(assert),通常用于发布版本
-DNVALGRIND \                        # 禁用 Valgrind 内存检测相关代码
-DDYNAMIC_ANNOTATIONS_ENABLED=0"     # 关闭动态注解(性能优化)


编译选项

export CFlags="\
-Wno-builtin-macro-redefined \       # 忽略内置宏(如 __DATE__)被重定义的警告
-D__DATE__= \                        # 清空 __DATE__ 宏(避免构建时间泄露)
-D__TIME__= \                        # 清空 __TIME__ 宏(同上)
-D__TIMESTAMP__= \                   # 清空 __TIMESTAMP__ 宏(同上)
-funwind-tables \                    # 生成堆栈展开表(用于异常处理和调试)
-fcolor-diagnostics \                # 输出彩色诊断信息(警告/错误)
-fmerge-all-constants \              # 合并重复常量(优化代码体积)
-Xclang \                            # 传递后续参数给 Clang 底层
-mllvm \                             # 传递后续参数给 LLVM 中间层
-Xclang \                            # 再次传递参数给 Clang
-instcombine-lower-dbg-declare=0 \    # 禁用调试声明的 LLVM 优化(保持调试信息)
-no-canonical-prefixes \             # 禁用路径规范化(保持原始路径名)
-ffunction-sections \                # 将每个函数放入独立的 ELF 段(便于链接时优化)
-fno-short-enums \                   # 禁止短枚举(确保枚举大小与 int 相同)
--target=$TARGET \                   # 指定目标平台三元组(如 aarch64-linux-ohos)
-mfloat-abi=softfp \                 # 指定浮点 ABI 为 softfp(兼容性优化)
-mfpu=neon \                         # 启用 NEON 浮点单元指令(ARM 架构优化)
-Wall \                              # 启用所有常规警告
-Wextra \                            # 启用额外警告(等同 -Wextra)
-Wthread-safety \                    # 启用线程安全分析警告
-Wno-missing-field-initializers \    # 忽略结构体缺少字段初始化的警告
-Wno-unused-parameter \              # 忽略未使用的函数参数警告
-Wno-c++11-narrowing \               # 忽略 C++11 中的窄化转换警告
-Wno-unneeded-internal-declaration \ # 忽略不必要的内部声明警告
-Wno-error=c99-designator \          # 不将 C99 指定初始化器警告视为错误
-Wno-error=anon-enum-enum-conversion \ # 不将匿名枚举转换警告视为错误
-Wno-error=sizeof-array-div \        # 不将数组大小除法操作警告视为错误
-Wno-error=reorder-init-list \       # 不将初始化列表顺序警告视为错误
-Wno-error=range-loop-construct \    # 不将范围循环构造警告视为错误
-Wno-error=deprecated-copy \         # 不将弃用的拷贝操作警告视为错误
-Wno-error=implicit-int-float-conversion \ # 不将隐式整型-浮点转换警告视为错误
-Wno-error=inconsistent-dllimport \  # 不将 DLL 导入不一致警告视为错误
-Wno-error=unknown-warning-option \  # 不将未知警告选项视为错误
-Wno-error=abstract-final-class \    # 不将抽象 final 类警告视为错误
-Wno-error=sign-compare \            # 不将有符号/无符号比较警告视为错误
-Wno-error=int-in-bool-context \     # 不将整型在布尔上下文中的使用警告视为错误
-Wno-error=xor-used-as-pow \         # 不将 XOR 误用为幂运算的警告视为错误
-Wno-error=return-stack-address \    # 不将返回栈地址的警告视为错误
-Wno-error=dangling-gsl \            # 不将 GSL(指南支持库)悬垂指针警告视为错误
-Wno-undefined-var-template \        # 忽略未实例化的模板变量警告
-Wno-nonportable-include-path \      # 忽略非便携式包含路径警告
-Wno-user-defined-warnings \         # 忽略用户自定义的警告
-Wno-unused-lambda-capture \         # 忽略未使用的 lambda 捕获警告
-Wno-null-pointer-arithmetic \       # 忽略空指针算术运算警告
-Wno-enum-compare-switch \           # 忽略枚举与 switch 语句比较的警告
-O2 \                                # 启用优化级别 2(平衡优化)
-fdata-sections \                    # 将每个数据放入独立 ELF 段(链接优化)
-fomit-frame-pointer \               # 省略帧指针(提高性能,降低调试难度)
-gdwarf-3 \                          # 生成 DWARF 3 格式调试信息
-g2 \                                # 生成调试信息级别 2
-ggnu-pubnames \                     # 生成 GNU 风格的公共名称调试信息
-fno-common \                        # 禁止将未初始化全局变量放入 COMMON 段
-Wheader-hygiene \                   # 检查头文件包含的卫生性(避免命名污染)
-Wstring-conversion \                # 启用隐式字符串转换警告
-Wtautological-overlap-compare \     # 启用逻辑重叠比较警告
-fPIE"                               # 生成位置无关可执行文件(增强安全性)

Logo

社区规范:仅讨论OpenHarmony相关问题。

更多推荐