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

news2024/11/20 18:24:17

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 <lua.h>
#include <lauxlib.h>
#include <lualib.h>

G++使用
#include <lua.hpp>


*/
#include <lua.hpp>
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.结束了>_<

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

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

赞留下>*_<

赞留下>*_<

赞留下>*_<

赞留下>*_<

赞留下>*_<

不定时更新!!!

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

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1912191.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

nvm下载

nvm下载 1.下载nvm安装包2.安装nvm3.修改settings.txt4.安装成功5.继续配置 下载nvm之前,你最好将你电脑上的node卸载掉,直接在winx中卸载就行 1.下载nvm安装包 https://github.com/coreybutler/nvm-windows/releases 2.安装nvm 3.修改settings.txt root: E:\nvm\install\nv…

哦华为仓颉语言

本来我不太想说的&#xff0c;奈何有不少粉丝提问提到了这语言&#xff0c;目前的情况我不透露太多&#xff0c;看过这课程C实现一门计算机编程语言到手撸虚拟机实战的懂的自然懂。 在互联网领域几乎大部分应用软件运行在X86 LINUX上居多&#xff0c;如果你有问题可以先学习这…

红酒的秘密配方:如何调配出个性化的口感?

在红酒的世界里&#xff0c;每一滴都蕴藏着大自然的秘密和酿酒师的匠心。那些令人陶醉的口感、迷人的色泽和香气&#xff0c;都是经过精心调配和时光酝酿的结果。今天&#xff0c;就让我们一起揭开红酒调配的神秘面纱&#xff0c;探索如何调配出个性化的口感&#xff0c;感受雷…

大语言模型垂直化训练技术与应用

在人工智能领域&#xff0c;大语言模型&#xff08;Large Language Models, LLMs&#xff09;已经成为推动技术进步的关键力量&#xff0c;垂直化训练技术逐渐成为研究的热点&#xff0c;它使得大模型能够更精准地服务于特定行业和应用场景。本文结合达观数据的分享&#xff0c…

C++·模板进阶

1. 非类型模板参数 之前我们写的模板参数都设定class类型的&#xff0c;这个模板参数用来给下面的代码中的某些元素定义类型&#xff0c;我们管这种模板参数叫类型形参。非类型模板参数就是用一个常量作为模板的一个参数&#xff0c;在模板中可将该参数当作常量来使用&#xff…

RT2-使用NLP的方式去训练机器人控制器

目标 研究在网络数据上训练的视觉语言模型也可以直接结合到端到端的机器人控制中&#xff0c;提升泛化性以及获得突出的语义推理&#xff1b;使得单个的端到端训练模型可以同时学习从机器人观测到动作的映射&#xff0c;这个过程可以受益于基于网络上的语言和视觉语言数据的预训…

Python函数 之 函数基础

print() 在控制台输出 input() 获取控制台输⼊的内容 type() 获取变量的数据类型 len() 获取容器的⻓度 (元素的个数) range() ⽣成⼀个序列[0, n) 以上都是我们学过的函数&#xff0c;函数可以实现⼀个特定的功能。我们将学习⾃⼰如何定义函数, 实现特定的功能。 1.函数是什么…

C++进阶:继承和多态

文章目录 ❤️继承&#x1fa77;继承与友元&#x1f9e1;继承和静态成员&#x1f49b;菱形继承及菱形虚拟继承&#x1f49a;继承和组合 ❤️多态&#x1fa77;什么是多态&#xff1f;&#x1f9e1;多态的定义以及实现&#x1f49b;虚函数&#x1f49a;虚函数的重写&#x1f499…

如何借助社交媒体影响者的力量,让品牌影响力倍增?

一、引言&#xff1a;为何社交媒体影响者如此关键&#xff1f; 在信息爆炸的今天&#xff0c;社交媒体已成为塑造消费者行为与品牌认知的重要渠道。社交媒体影响者&#xff0c;凭借其在特定领域的专业知识、庞大的粉丝基础及高度的互动性&#xff0c;成为了品牌传播不可忽视的…

JVM原理(二四):JVM虚拟机锁优化

高效并发是从JDK 5升级到JDK 6后一项重要的改进项&#xff0c;HotSpot虛 拟机开发团队在这个版本上花费了大量的资源去实现各种锁优化技术&#xff0c;如适应性自旋( Adaptive Spinning)、锁消除( Lock Elimination)、锁膨胀(Lock Coarsening)、轻量级锁(Lightweight Locking)、…

DeepMind的JEST技术:AI训练速度提升13倍,能效增强10倍,引领绿色AI革命

谷歌旗下的人工智能研究实验室DeepMind发布了一项关于人工智能模型训练的新研究成果&#xff0c;声称其新提出的“联合示例选择”&#xff08;Joint Example Selection&#xff0c;简称JEST&#xff09;技术能够极大地提高训练速度和能源效率&#xff0c;相比其他方法&#xff…

数字信号处理教程(3)——z变换

在连续时间域中的每一种分析方法&#xff0c;在离散时间域中想必也能得到对应一种分析方法。连续傅里叶变换对应着离散傅里叶变换&#xff08;DFT&#xff09;&#xff0c;而在拉普拉斯变换则是对应着z变换。z变换能够将信号表示成离散复指数函数的线性组合。连续傅里叶变换可以…

NAT技术及其应用

网络地址转换&#xff08;NAT&#xff0c;Network Address Translation&#xff09;是一种广泛应用于现代网络中的技术&#xff0c;旨在解决IP地址短缺问题&#xff0c;同时增强网络的安全性和灵活性。本文将详细解释NAT技术的工作原理&#xff0c;并探讨其在家庭及企业网络中的…

华为HCIP Datacom H12-821 卷30

1.单选题 以下关于OSPF协议报文说法错误的是? A、OSPF报文采用UDP报文封装并且端口号是89 B、OSPF所有报文的头部格式相同 C、OSPF协议使用五种报文完成路由信息的传递 D、OSPF所有报文头部都携带了Router-ID字段 正确答案&#xff1a;A 解析&#xff1a; OSPF用IP报…

【大模型LLM面试合集】大语言模型架构_layer_normalization

2.layer_normalization 1.Normalization 1.1 Batch Norm 为什么要进行BN呢&#xff1f; 在深度神经网络训练的过程中&#xff0c;通常以输入网络的每一个mini-batch进行训练&#xff0c;这样每个batch具有不同的分布&#xff0c;使模型训练起来特别困难。Internal Covariat…

最佳 iPhone 解锁软件工具,可免费下载用于电脑操作的

业内专业人士表示&#xff0c;如果您拥有 iPhone&#xff0c;您一定知道忘记锁屏密码会多么令人沮丧。由于 Apple 的安全功能强大&#xff0c;几乎不可能在没有密码或 Apple ID 的情况下访问锁定的 iPhone。 “当我忘记密码时&#xff0c;如何在没有密码的情况下解锁iPhone&am…

来一组爱胜品1133DN PRO打印机的照片

刚拆箱的机器正面照片 打开前盖正准备要安装原装耗材 下图是原装耗材&#xff0c;硒鼓型号是DR2833、碳粉盒型号是TN2833,鼓组件打印页数12000页&#xff0c;TN2833标准容量粉盒打印页数1600页/5%覆盖率&#xff0c;TN2833H大容量粉盒打印页数3000页/5%覆盖率、TN2833L超大容量…

【LLM】三、open-webui+ollama搭建自己的聊天机器人

系列文章目录 往期文章回顾&#xff1a; 【LLM】二、python调用本地的ollama部署的大模型 【LLM】一、利用ollama本地部署大模型 目录 前言 一、open-webui是什么 二、安装 1.docker安装 2.源码安装 三、使用 四、问题汇总 总结 前言 前面的文章&#xff0c;我们已经…

Studying-代码随想录训练营day34| 62.不同路径、63.不同路径II、343.整数拆分、96.不同的二叉搜索树

第34天&#xff0c;动态规划part02&#xff0c;牢记五部曲步骤&#xff0c;编程语言&#xff1a;C 目录 62.不同路径 63.不同路径II 343.整数拆分 96.不同的二叉搜索树 总结 62.不同路径 文档讲解&#xff1a;代码随想录不同路径 视频讲解&#xff1a;手撕不同路径 题目…

红酒知识百科:从入门到精通

红酒&#xff0c;这个深邃而迷人的世界&#xff0c;充满了无尽的知识与奥秘。从葡萄的选择、酿造工艺&#xff0c;到品鉴技巧&#xff0c;每一步都蕴藏着深厚的文化底蕴和精细的技艺。今天&#xff0c;就让我们一起踏上这场红酒知识之旅&#xff0c;从入门开始&#xff0c;逐步…