• 2024-7-9 Windows NDK,Clion,C4droid 编译环境配置(基础|使用命令编译,非AndroidStudio),小白(记录)友好型教程


    2024-7-9 Windows NDK,Clion,C4droid 编译环境配置(基础|使用命令编译),小白友好型

    一直想使用NDK编译出lua库,然后进行开发.结果一直不成功,问题Bug出现了一堆(主要还是自己太菜,毕竟咱是编程散修一名>_<)

    NDK之前一直不会配置(直接用命令配置的那种,非AndroidStudio),一直用的Clion,但是结果发现编译lua源码时,搞不定,摸索了两天终于搞定了

    为啥非要编译Lua源码???

    因为想搞一些C/C++的操作,但是纯C写起来很繁琐,就想着,直接搞lua(为了之后大量的简化代码,制作LuaCAPI,在Lua里调用)

    而且通过以上方式可以实现点小动态的操作,而不是C那种静态的操作了

    如果你也有和我一样的需求的话,就来看看吧

    当然这不仅仅局限于lua源码的编译,像很多开源的JNI(可执行/静态库)都可由用这种方式搞定

    以前在手机上使用C4droid编译的lua源码->liblua.so也是可以跑的,但是,要别的架构,就只能NDK了(别的我也不会)

    我将介绍多种操作

    1.C4droid编译Lua配置

    2.Clion编译可执行文件(放到/data/local/tmp)可以直接跑的那种

    3.Clion编译可动态链接库文件(libtest.so)需要通过dlopen加载的那种

    Clion编译Lua我就不演示了,因为不会>_

    4.NDK编译不同架构Lua源码

    最繁琐的其实是Clion(可能我菜,不会方便的配置)

    主要是网上的教程对我来说不太友好(对小白不友好),所以搞出来,就赶紧记录了

    本教程仅用于记录编程配置处理!!!

    本教程仅用于记录编程配置处理!!!

    本教程仅用于记录编程配置处理!!!

    为编程爱好者解决一些问题 >_<

    0.做点初始化准备

    第一步是必须,后面根据自身需求选择
    1.下载Lua源码 (下载你需要的版本)
        https://www.lua.org/ftp/
    2.下载C4droid(手机)
        自行百度
    3.下载NDK(电脑)
    NDK下载镜像站
        https://github.com/android/ndk/wiki/Unsupported-Downloads
    4.下载Clion
        https://www.jetbrains.com.cn/clion/
    

    在这里插入图片描述

    1.C4droid编译Lua配置(一键配置)

    解压lua源码

    在源码下面创建by.sh,复制我写的配置,

    进入C4droid模拟器

    # 切换到你的源码目录
    cd 到你lua源码目录
    # 执行编译
    ./by.sh
    # 等待编译....
    
    # 提示复制头文件啥的,直接扣y
    
    # 配置C4droid GCC,G++参数
    
    # 创建测试的tes.cpp,script.lua
    # 我使用的是G++运行
    # 想要使用GCC运行,可以看tes.cpp前面的注释
    
    # 运行测试
    
    # ok了,你现在就可以用手机编写CLUA了
    

    请添加图片描述
    在这里插入图片描述
    在这里插入图片描述

    在这里插入图片描述
    在这里插入图片描述

    在这里插入图片描述
    在这里插入图片描述
    在这里插入图片描述

    by.sh

    #!/system/bin/sh
    # Lua源码src路径
    cd ./src/
    #清除原编译
    make clean
    #执行静态编译
    make linux
    echo "$.静态编译完成"
    
    
    #转动态
    gcc -shared -fPIC -Wl,--whole-archive liblua.a -Wl,--no-whole-archive -Wl,-soname,liblua.so -o liblua.so -lm -ldl
    echo "$.动态liblua.so编译完成"
    
    #!/bin/sh
    
    # 源文件路径
    src_dir="./"
    
    # 目标目录路径
    dest_lib_so="/data/user/0/com.n0n3m4.droidc/files/gcc/lib64/"
    dest_include="/data/user/0/com.n0n3m4.droidc/files/gcc/aarch64-linux-android/include/"
    
    # 是否复制相应文件到指定目录下? (y/n)
    echo "是否复制liblua.so和必要h文件到lib64和include目录下? (y/n)"
    read input
    
    case "$input" in
        y | Y)
            echo "Continuing..."
            # 复制liblua.so
            src_lua_so="$src_dir/liblua.a"
            cp "$src_lua_so" "$dest_include../lib/"
            chmod 700 "$dest_include../lib/liblua.a"
            echo "liblua.a copied successfully."
            
            # 复制头文件
            cp "$src_dir/lauxlib.h" "$dest_include"
            chmod 777 "$dest_include/lauxlib.h"
            echo "lauxlib.h copied successfully."
    
            cp "$src_dir/lua.h" "$dest_include"
            chmod 777 "$dest_include/lua.h"
            echo "lua.h copied successfully."
    
            cp "$src_dir/lua.hpp" "$dest_include"
            chmod 777 "$dest_include/lua.hpp"
            echo "lua.hpp copied successfully."
    
            cp "$src_dir/luaconf.h" "$dest_include"
            chmod 777 "$dest_include/luaconf.h"
            echo "luaconf.h copied successfully."
    
            cp "$src_dir/lualib.h" "$dest_include"
            chmod 777 "$dest_include/lualib.h"
            echo "lualib.h copied successfully."
            ;;
        n | N)
            echo "Exiting..."
            # 执行退出操作,例如:
            # exit 1
            ;;
        *)
            echo "Invalid input. Please enter 'y' or 'n'."
            ;;
    esac
    

    tes.cpp

    /*
    GCC 使用以下头文件
    #include 
    #include 
    #include 
    
    G++使用
    #include 
    
    
    */
    #include 
    int main() {
        // 初始化Lua环境
        lua_State* L = luaL_newstate();
        luaL_openlibs(L);
     
        // 加载并运行Lua脚本
        if (luaL_dofile(L, "script.lua")){
        	
        	perror("脚本加载失败");
        	return 0;
        }
     
        // 调用Lua函数
        lua_getglobal(L, "add");
        lua_pushnumber(L, 10);
        lua_pushnumber(L, 20);
        lua_pcall(L, 2, 1, 0);
     
        // 获取函数返回值并输出
        int result = (int)lua_tonumber(L, -1);
        printf("Result = %d\n", result);
        
        // 释放Lua环境
        lua_close(L);
     
        return 0;
    }
    

    script

    function add(a,b)
    print("Lua.函数add调用成功!")
    return a+b
    end
    
    --add(1,5)
    

    C4droid配置结束

    2.解压NDK(这是后面的前提)

    3.Clion编译操作

    1.配置Clion,配置后别忘记点应用>_

    在这里插入图片描述
    在这里插入图片描述

    参数模板

    -G Ninja
    -DCMAKE_TOOLCHAIN_FILE="你NDK路径\build\cmake\android.toolchain.cmake"
    -DCMAKE_SYSTEM_NAME=Android
    -DANDROID_ABI=编译的架构,一次好像只能写一个
    -DCMAKE_ANDROID_NDK="你NDK路径"
    -DCMAKE_SYSTEM_VERSION=19 
    -DCMAKE_C_FLAGS="" 
    -DCMAKE_CXX_FLAGS="" 
    -DCMAKE_ANDROID_NDK_TOOLCHAIN_VERSION=clang++ 
    -llog
    

    这里只能一次配置一个架构,自己研究吧,我就不深究了

    我的是,编译arm64-v8a架构的

    -G Ninja
    -DCMAKE_TOOLCHAIN_FILE="D:\NDK\android-ndk-r21e\build\cmake\android.toolchain.cmake"
    -DCMAKE_SYSTEM_NAME=Android
    -DANDROID_ABI=arm64-v8a
    -DCMAKE_ANDROID_NDK="D:\NDK\android-ndk-r21e\" 
    -DCMAKE_SYSTEM_VERSION=19 -DCMAKE_C_FLAGS="" 
    -DCMAKE_CXX_FLAGS="" 
    -DCMAKE_ANDROID_NDK_TOOLCHAIN_VERSION=clang++ -llog
    
    2.编译配置(按照自己需求配置)

    修改CMakeLists.txt

    cmake_minimum_required(VERSION 3.23)
    # 工程名字
    set(projectName 你创建的项目名,直接把原CMakeLists.txt里的project里的内容复制过来)
    
    
    # ----------------------------------------[默认通用配置]--------------------------------------
    project(${projectName})
    
    set(CMAKE_CXX_STANDARD 11)
    set(CMAKE_BUILD_TYPE Release)
    
    # 添加头文件
    set(INC_DIR src)
    # 设置第三方库 --- 一般引用liblua.o这种静态库时会用到
    set(LINK_DIR lib)
    include_directories(${INC_DIR})
    link_directories(${LINK_DIR})
    
    
    # 配置多个目标架构 -- 这里配置主要是把生成的文件,放到指定的目录下,便于区分
    set(TARGET_ARCHS "arm64-v8a" "armeabi-v7a" "x86" "x86-64")
    
    
    foreach (arch ${TARGET_ARCHS})
        # 为每个目标架构创建一个单独的目录
        set(ARCH_DIR "${CMAKE_CURRENT_BINARY_DIR}/${arch}")
        file(MAKE_DIRECTORY ${ARCH_DIR})
    
        # 配置交叉编译
        set(CMAKE_SYSTEM_NAME Android)
        set(CMAKE_ANDROID_NDK "${ANDROID_NDK}")
        set(CMAKE_ANDROID_ARCH_ABI ${arch})
        set(CMAKE_ANDROID_NDK_TOOLCHAIN_VERSION clang)
        set(CMAKE_ANDROID_API 19)
        set(CMAKE_ANDROID_STL_TYPE c++_static)
        # set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -fPIC")
        # -fPIC 好像高于Android5.0都需要,不需要改
        set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -std=c++14 -fexceptions -frtti -stdlib=libc++ -fPIC")
        set(CMAKE_SHARED_LINKER_FLAGS "${CMAKE_SHARED_LINKER_FLAGS} -lc++_shared")
        set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -Wall -Wextra -Wfatal-errors")
        
        # ----------------------------------------[结束]--------------------------------------
    
    
    
        # ----------------------------------------[优化大小]--------------------------------------
        # 这里是因为,有时候编译出来比较臃肿
        # 比如C4droid,HelloWord 编译出来可能就6-8KB大小
        # 但是Clion编译出来可能 几 MB
        # 这一块就是为了优化大小 
        # 优化大小
        add_compile_options(-Os)
        # 将每个函数放在自己的节中
        add_compile_options(-ffunction-sections -fdata-sections)
        # 移除未使用的节
        set(CMAKE_SHARED_LINKER_FLAGS "${CMAKE_SHARED_LINKER_FLAGS}" -WI,--gc-sections )
        # 省略帧指针
        add_compile_options(-fomit-frame-pointer)
        
       # ----------------------------------------[结束]--------------------------------------
       
       
        set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -s")
        set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -s")
        set(CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} -s")
        
        
        # ======= 添加要编译的文件 ======
        # ---------------------------------------[可执行文件配置]-------------------------------------------
        # 生成二进制文件 add_executable 编译可执行文件
        add_executable(${projectName}${arch}
                main.cpp
        )
    
        set_target_properties(${projectName}${arch} PROPERTIES OUTPUT_NAME "${projectName}")
        set_target_properties(${projectName}${arch} PROPERTIES RUNTIME_OUTPUT_DIRECTORY ${ARCH_DIR})
        # ----------------------------------------[结束]--------------------------------------
        
        # ---------------------------------------[链接静态库配置]-------------------------------------------
        #target_link_libraries(${projectName}${arch}  ${PROJECT_SOURCE_DIR}/lib/${arch}/liblua.a)
        # ----------------------------------------[结束]--------------------------------------
        
        
        # __________________________分类________________________________
        
        
        # ---------------------------------------[动态链接库编译配置]-------------------------------------------
            # 编译动态链接库文件
        # add_library(${projectName}${arch} SHARED ...cpp)
        # set_target_properties(${projectName}${arch} PROPERTIES LIBRARY_OUTPUT_DIRECTORY ${ARCH_DIR})
        # ----------------------------------------[结束]--------------------------------------
        
    endforeach ()
    
    
    3.第三方静态库目录配置

    .a静态库配置路径

    在这里插入图片描述

    库对应的.c .cpp .h .hpp…文件
    在这里插入图片描述

    4.直接编译

    在这里插入图片描述

    5.运行肯定报错,你是Windows编译的安卓可执行文件,肯定不能运行
    6.可以像我这样配置一下(这里看自己需求)

    $$$ 记得先ADB连接手机,需要ROOT,模拟器也行(MuMu支持ARM64部分),其他的模拟器都是x86/x86-64的,我直接用的VMOS(嘻嘻*_<),自己捣鼓吧

    adb push 你生成的文件 /data/local/tmp

    在这里插入图片描述

    在项目目录下创建a.bat

    @echo off
    :: 切换UTF-8字符
    chcp 65001 > nul
    cls
    echo 开始传输
    adb push cmake-build-debug/arm64-v8a/lua_test /data/local/tmp
    echo 传输结束
    echo.
    echo.
    echo.
    echo =======================================================
    echo 开始给予777权限
    @REM 这里修改名字 adb shell chmod 777 /data/local/tmp/你push的进去的名字
    adb shell chmod 777 /data/local/tmp/lua_test
    echo ====================[开始执行]===========================
    echo.
    @REM 运行 adb shell su -c /data/local/tmp/你push的进去的名字
    adb shell su -c /data/local/tmp/lua_test
    echo.
    echo =======================================================
    
    

    4.NDK编译Lua源码(所有架构配置)

    1.环境搭建

    NDK下载镜像站
        https://github.com/android/ndk/wiki/Unsupported-Downloads
    

    2.环境变量配置

    添加 NDK_HOME -> 你的NDK路径
    添加 %NDK_HOME%\prebuilt\windows-x86_64\bin
        %NDK_HOME%
    

    在这里插入图片描述

    3.配置Android.mk

    LOCAL_PATH := $(call my-dir)
    
    include $(CLEAR_VARS)
    LOCAL_MODULE    := lua
    LOCAL_SRC_FILES := lapi.c lauxlib.c lbaselib.c lcode.c ldblib.c ldebug.c ldo.c ldump.c lfunc.c lgc.c linit.c liolib.c llex.c lmathlib.c lmem.c loadlib.c lobject.c lopcodes.c loslib.c lparser.c lstate.c lstring.c lstrlib.c ltable.c ltablib.c ltm.c lundump.c lvm.c lzio.c
    LOCAL_LDLIBS    := -ld -lm
    
    include $(BUILD_STATIC_LIBRARY)
    

    4.配置Application.mk

    APP_ABI := armeabi-v7a arm64-v8a x86 x86_64
    APP_PLATFORM := android-14
    

    5.把lua源码里的src名字改成jni

    在这里插入图片描述

    6.把Android.mk和Application.mk放到jni下

    外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

    7.编译

    cd D:\lua-5.4.6\
    ndk-build
    

    在这里插入图片描述

    在这里插入图片描述

    在这里插入图片描述

    在这里插入图片描述

    在这里插入图片描述

    8.结束了>_<

    你都看到这里了,咱也不是收费的,

    给个大大的赞再走呗>*_<

    赞留下>*_<

    赞留下>*_<

    赞留下>*_<

    赞留下>*_<

    赞留下>*_<

    不定时更新!!!

    可能含金量不高,但是绝对实用

  • 相关阅读:
    LVGL---标签(lv_label)
    硅芯思见:UDP是干什么的?
    redis的eval命令
    postman在ubuntu下报gpu-disable
    C++类和对象(二)构造函数、析构函数、拷贝构造函数
    「学习笔记」字符串基础:Hash,KMP与Trie
    chatgpt赋能python:如何升级你的Python到最新版本
    【库函数】复习小结
    2023-9-12 阿里健康2024秋招后端开发-体检及泛医疗二面
    Linux CentOS 8(MariaDB的数据类型)
  • 原文地址:https://blog.csdn.net/qq_37567841/article/details/140295142