美文网首页
C/C++ 编译器与Makefile

C/C++ 编译器与Makefile

作者: Itachi001 | 来源:发表于2021-09-23 14:54 被阅读0次

    gcc/g++/clang

    clang

    clang 是一个C、C++、Object-C的轻量级编译器。基于LLVM (LLVM是以C++编写而成的构架编译器的框架系统,可以说是一个用于开发编译器相关的库)

    gcc

    GNU C编译器。原本只能处理C语言,很快扩展,变得可处理C++。(GNU计划,又称革奴计划。目标是创建一套完全自由的操作系统)

    g++

    GNU c++编译器

    头文件与库文件指定

    --sysroot=XX
        使用xx作为这一次编译的头文件与库文件的查找目录,查找下面的 usr/include usr/lib 目录
    -isysroot XX
        头文件查找目录,覆盖--sysroot ,查找 XX/usr/include
    -isystem XX
        指定头文件查找路径(直接查找根目录)
    -IXX
        头文件查找目录
    优先级:
        -I -> -isystem -> sysroot
    -LXX
        指定库文件查找目录
    -lxx.so
        指定需要链接的库名
    

    使用示例

    #添加临时环境变量
    export CC=/root/android-ndk-r23/toolchains/llvm/prebuilt/linux-x86_64/bin/armv7a-linux-androideabi16-clang
    export AR=/root/android-ndk-r23/toolchains/llvm/prebuilt/linux-x86_64/bin/llvm-ar
    export AAA="--sysroot=/root/android-ndk-r23/toolchains/llvm/prebuilt/linux-x86_64/sysroot -isystem /root/android-ndk-r23/toolchains/llvm/prebuilt/linux-x86_64/sysroot/usr/include -isystem /root/android-ndk-r23/toolchains/llvm/prebuilt/linux-x86_64/sysroot/usr/include/arm-linux-androideabi/asm"
    #生成可执行文件,pie: 位置无关的可执行程序
    $CC $AAA main.c -pie -o main
    #生成动态库
    $CC $AAA -fPIC -shared test.c -o libTest.so
    #生成静态库
    $CC $AAA -fPIC test.c -o libTest.o
    $AR r libTest.a Test.o
    

    Makefile

    makefile 就是“自动化编译”,告诉make命令如何编译和链接,即make工具的配置脚本。

    Android.mk

    微小 GNU makefile 片段。
    将源文件分组为模块。 模块是静态库、共享库或独立可执行文件。 可在每个 Android.mk 文件中定义一个或多个模块,也可在多个模块中使用同一个源文件。

    #源文件在的位置。宏函数 my-dir 返回当前目录(包含 Android.mk 文件本身的目录)的路径。
    LOCAL_PATH := $(call my-dir)
    #引入其他makefile文件。CLEAR_VARS 变量指向特殊 GNU Makefile,可为您清除许多 LOCAL_XXX 变量
    #不会清理 LOCAL_PATH 变量
    include $(CLEAR_VARS)
    #存储您要构建的模块的名称 每个模块名称必须唯一,且不含任何空格
    #如果模块名称的开头已是 lib,则构建系统不会附加额外的前缀 lib;而是按原样采用模块名称,并添加 .so 扩展名。
    LOCAL_MODULE := hello-jni
    #包含要构建到模块中的 C 和/或 C++ 源文件列表 以空格分开
    LOCAL_SRC_FILES := hello-jni.c
    #构建动态库
    include $(BUILD_SHARED_LIBRARY)
    

    变量和宏
    定义自己的任意变量。在定义变量时请注意,NDK 构建系统会预留以下变量名称:

    • LOCAL_ 开头的名称,例如 LOCAL_MODULE
    • PRIVATE_NDK_APP 开头的名称。构建系统在内部使用这些变量。
    • 小写名称,例如 my-dir。构建系统也是在内部使用这些变量。

    如果为了方便而需要在 Android.mk 文件中定义自己的变量,建议在名称前附加 MY_

    常用内置变量

    变量名 含义 示例
    BUILD_STATIC_LIBRARY 构建静态库的Makefile脚本 include $(BUILD_STATIC_LIBRARY)
    PREBUILT_SHARED_LIBRARY 预编译共享库的Makeifle脚本 include $(PREBUILT_SHARED_LIBRARY)
    PREBUILT_STATIC_LIBRARY 预编译静态库的Makeifle脚本 include $(PREBUILT_STATIC_LIBRARY)
    TARGET_PLATFORM Android API 级别号 TARGET_PLATFORM := android-22
    TARGET_ARCH CUP架构 arm arm64 x86 x86_64
    TARGET_ARCH_ABI CPU架构 armeabi armeabi-v7a arm64-v8a

    模块描述变量

    变量名 描述
    LOCAL_MODULE_FILENAME 覆盖构建系统默认用于其生成的文件的名称 LOCAL_MODULE := foo LOCAL_MODULE_FILENAME := libnewfoo
    LOCAL_CPP_FEATURES 特定 C++ 功能 支持异常:LOCAL_CPP_FEATURES := exceptions
    LOCAL_C_INCLUDES 头文件目录查找路径 LOCAL_C_INCLUDES := $(LOCAL_PATH)/include
    LOCAL_CFLAGS 构建 C C++ 的编译参数
    LOCAL_CPPFLAGS c++
    LOCAL_STATIC_LIBRARIES 当前模块依赖的静态库模块列表
    LOCAL_SHARED_LIBRARIES 当前模块依赖的动态库模块列表
    LOCAL_WHOLE_STATIC_LIBRARIES --whole-archive 将未使用的函数符号也加入编译进入这个模块
    LOCAL_LDLIBS 依赖 系统库 LOCAL_LDLIBS := -lz

    导出给引入模块的模块使用:
    LOCAL_EXPORT_CFLAGS
    LOCAL_EXPORT_CPPFLAGS
    LOCAL_EXPORT_C_INCLUDES
    LOCAL_EXPORT_LDLIBS

    引入其他模块

    #将一个新的路径加入NDK_MODULE_PATH变量
    #NDK_MODULE_PATH 变量是系统环境变量
    
    $(call import-add-path,$(LOCAL_PATH)/platform/third_party/android/prebuilt)
    #包含CocosDenshion/android目录下的mk文件
    $(call import-module,CocosDenshion/android)
    
    #这里即为 我需要引入 CocosDenshion/android 下面的Android.mk
    #CocosDenshion/android 的路径会从 $(LOCAL_PATH)/platform/third_party/android/prebuilt 去查找
    

    Application.mk

    同样是GNU Makefile 片段,在Application.mk中定义一些全局(整个项目)的配置

    APP_OPTIM
    将此可选变量定义为 releasedebug。在构建应用的模块时可使用它来更改优化级别。发行模式是默认模式,可生成高度优化的二进制文件。调试模式会生成未优化的二进制文件,更容易调试。

    APP_CFLAGS
    为任何模块编译任何 C 或 C++ 源代码时传递到编译器的一组 C 编译器标志

    APP_CPPFLAGS
    构建 C++ 源文件时传递到编译器的一组 C++ 编译器标志。

    APP_ABI
    需要生成的cpu架构(ndk r17 只支持:armeabi-v7a, arm64-v8a, x86, x86_64)

    指令集
    基于 ARMv7 的设备上的硬件 FPU 指令 APP_ABI := armeabi-v7a
    ARMv8 AArch64 APP_ABI := arm64-v8a
    IA-32 APP_ABI := x86
    Intel64 APP_ABI := x86_64
    MIPS32 APP_ABI := mips
    MIPS64 (r6) APP_ABI := mips64
    所有支持的指令集 APP_ABI := all

    不同 Android 手机使用不同的 CPU,因此支持不同的指令集。

    armeabi
    此 ABI 适用于基于 ARM、至少支持 ARMv5TE 指令集的 CPU。此 ABI 不支持硬件辅助的浮点计算。 相反,所有浮点运算都使用编译器 libgcc.a 静态库中的软件帮助程序函数。

    armeabi-v7a
    armeabi-v7a ABI 使用 -mfloat-abi=softfp 开关强制实施规则,要求编译器在函数调用时必须传递核心寄存器对中的所有双精度值,而不是专用浮点值。 系统可以使用 FP 寄存器执行所有内部计算。 这样可极大地加速计算。
    如果要以 armeabi-v7a ABI 为目标,则必须设置下列标志:

    CFLAGS= -march=armv7-a -mfloat-abi=softfp -mfpu=vfpv3-d16
    

    arm64-v8a
    此 ABI 适用于基于 ARMv8、支持 AArch64 的 CPU。它还包含 NEON 和 VFPv4 指令集。

    x86
    此 ABI 适用于支持通常称为“x86”或“IA-32”的指令集的 CPU。设置的标志如:

    -march=i686 -mtune=intel -mssse3 -mfpmath=sse -m32
    

    x86_64

    -march=x86-64 -msse4.2 -mpopcnt -m64 -mtune=intel
    

    现在手机主要是armeabi-v7a和arm64-v8a。查看手机cpu:

    adb shell cat /proc/cpuinfo
    adb shell getprop ro.product.cpu.abi
    

    apk在安装的时候,如果手机是armeabi-v7a的,则会首先查看apk中是否存在armeabi-v7a目录,如果没有就会查找armeabi。

    保证cpu目录下so数量一致。
    如果目标是armeabi-v7a,但是拥有一个armeabi的,也可以把它放到armeabi-v7a目录下。但是反过来不行

    ABI(横 so)/CPU(竖 手机) armeabi armeabi-v7a arm64-v8a x86 x86_64
    ARMV5 支持
    ARMV7 支持 支持
    ARMV8 支持 支持 支持
    X86 支持
    X86_64 支持 支持

    APP_PLATFORM
    此变量包含目标 Android 平台的名称。例如,android-3 指定 Android 1.5 系统映像

    APP_STL
    默认情况下,NDK 构建系统为 Android 系统提供的最小 C++ 运行时库 (system/lib/libstdc++.so) 提供 C++ 功能。

    名称 说明 功能
    libstdc++(默认) 默认最小系统 C++ 运行时库。 不适用
    gabi++_static GAbi++ 运行时(静态)。 C++ 异常和 RTTI
    gabi++_shared GAbi++ 运行时(共享)。 C++ 异常和 RTTI
    stlport_static STLport 运行时(静态)。 C++ 异常和 RTTI;标准库
    stlport_shared STLport 运行时(共享)。 C++ 异常和 RTTI;标准库
    gnustl_static GNU STL(静态)。 C++ 异常和 RTTI;标准库
    gnustl_shared GNU STL(共享)。 C++ 异常和 RTTI;标准库
    c++_static LLVM libc++ 运行时(静态)。 C++ 异常和 RTTI;标准库
    c++_shared LLVM libc++ 运行时(共享)。 C++ 异常和 RTTI;标准库

    6.0以下 System.loadLibrary 不会自动为我们加载依赖的动态库
    6.0以上 System.loadLibrary 会自动为我们加载依赖的动态库

    相关文章

      网友评论

          本文标题:C/C++ 编译器与Makefile

          本文链接:https://www.haomeiwen.com/subject/cgkwgltx.html