CMAKE 在Linux下 构建android 编译、打包、发布环境
2014-03-28 00:00
841 查看
摘要: 最近在做这样的事情,终于在网上七七八八的资料当中完成了,网上的cmake都是简单的工程示例,而且千篇一律,也就是hello world级别的,对于cmake构建大型项目的完整实例,基本上没有。
环境:
2、目录构建好之后,进入project工程的jni目录里面
这里面有andorid 编译用的各个目录。
jni目录上层目录里面的内容:
执行命令
SET(CMAKE_SYSTEM_NAME Android)
SET(CMAKE_CXX_COMPILER "/opt/android-12-toolchain/arm-linux-androideabi/bin/g++") 交叉编译工具
SET(CMAKE_C_COMPILER "/opt/android-12-toolchain/arm-linux-androideabi/bin/gcc")
显示系统信息
设置代码里面的宏定义
ADD_DEFINITIONS(-DANDROID -DLINUX -DUNIX
-D_DISABLE_CXX_EXCEPTION
-DFT2_BUILD_LIBRARY -D__GL_ES_2_
-DAL_BUILD_LIBRARY -DAL_ALEXT_PROTOTYPES
-D_ARM_ASSEM_ -DNDK_DEBUG
-DKTX_OPENGL_ES2=1)
要求cmake的最低版本
CMAKE_MINIMUM_REQUIRED(VERSION 2.8)
设置编译之后的目标生成路径
SET(EXECUTABLE_OUTPUT_PATH ${PROJECT_BINARY_DIR}/../target)
包含编译需要的头文件,
INCLUDE_DIRECTORIES(".")
INCLUDE_DIRECTORIES("./jvm")
INCLUDE_DIRECTORIES("../../../Src/Core/inc")
INCLUDE_DIRECTORIES("../../../Src/OGES2/inc")
INCLUDE_DIRECTORIES("../../../External/freetype/FreeType2/include")
INCLUDE_DIRECTORIES("../../../External/OGLES2")
INCLUDE_DIRECTORIES("../../../External/OGLES2/Include")
INCLUDE_DIRECTORIES("../../../External/OGLES2/Include/GLES2")
INCLUDE_DIRECTORIES("../../OpenAL4Android/include")
INCLUDE_DIRECTORIES("../../OpenAL4Android/OpenAL32/Include")
INCLUDE_DIRECTORIES("../../../External/luatinker/inc")
INCLUDE_DIRECTORIES("../../../MobileProtocol")
INCLUDE_DIRECTORIES("../../../MobileServer/Core/Networkware/msg")
INCLUDE_DIRECTORIES("./jvm")
#INCLUDE_DIRECTORIES("/usr/include/")
#INCLUDE_DIRECTORIES("/usr/include/sys")
FIND_LIBRARY(LIB_CSTD_DIR NAMES stdc++)
找的编译需要的库文件,设置到变量里面,下面连接的时候用
IF(LIB_CSTD_DIR)
MESSAGE(STATUS "LIB_CSTD_DIR: "${LIB_CSTD_DIR})
ENDIF(LIB_CSTD_DIR)
FIND_LIBRARY(LIB_C_DIR NAMES c)
IF(LIB_C_DIR)
MESSAGE(STATUS "LIB_C_DIR: "${LIB_C_DIR})
ENDIF(LIB_C_DIR)
FIND_LIBRARY(LIB_M_DIR NAMES m)
IF(LIB_M_DIR)
MESSAGE(STATUS "LIB_M_DIR: "${LIB_M_DIR})
ENDIF(LIB_M_DIR)
FIND_LIBRARY(LIB_DL_DIR NAMES dl)
IF(LIB_DL_DIR)
MESSAGE(STATUS "LIB_DL_DIR: "${LIB_DL_DIR})
ENDIF(LIB_DL_DIR)
FIND_LIBRARY(LIB_LOG_DIR NAMES log)
IF(LIB_LOG_DIR)
MESSAGE(STATUS "LIB_LOG_DIR: "${LIB_LOG_DIR})
ENDIF(LIB_LOG_DIR)
FIND_LIBRARY(LIB_GLESV2_DIR NAMES GLESv2)
IF(LIB_GLESV2_DIR)
MESSAGE(STATUS "LIB_GLESV2_DIR: "${LIB_GLESV2_DIR})
ENDIF(LIB_GLESV2_DIR)
FIND_FILE(CRTBEGIN_DIR NAMES crtbegin_dynamic.o)
IF(CRTBEGIN_DIR)
MESSAGE(STATUS "CRTBEGIN_DIR:" ${CRTBEGIN_DIR})
ENDIF(CRTBEGIN_DIR)
FIND_FILE(CRTEND_ANDROID_DIR NAMES crtend_android.o)
IF(CRTEND_ANDROID_DIR)
MESSAGE(STATUS "CRTEND_ANDROID_DIR:" ${CRTEND_ANDROID_DIR})
ENDIF(CRTEND_ANDROID_DIR)
编译需要的c、c++文件
也可以直接包含目录“AUX_SOURCE_DIRECTORY("../../../Src/Core/src/" CORE_SRCS)”
SET(PUGIXML_SRCS "../../../External/pugixml/src/pugixml.cpp")
SET(LPNG167_SRCS "../../../External/lpng167/png.c"
"../../../External/lpng167/pngerror.c"
"../../../External/lpng167/pngwutil.c"
)
SET(KTX20_SRCS "../../../External/ktx20/include/errstr.c"
"../../../External/ktx20/include/etcdec.cxx"
"../../../External/ktx20/include/writer.c"
)
SET(OGES2_MOJOSHADER_SRCS "../../../Src/OGES2/mojoshader/mojoshader.cpp"
"../../../Src/OGES2/mojoshader/mojoshader_assembler.cpp"
"../../../Src/OGES2/mojoshader/mojoshader_preprocessor.cpp"
)
SET(OGES2_SRCS "../../../Src/OGES2/src/zOGLESFrameBuffer.cpp"
"../../../Src/OGES2/src/zOGLESMeshBufferResource.cpp"
"../../../Src/OGES2/src/zOGLESTexture.cpp"
"../../../Src/OGES2/src/zOGLShader.cpp"
"../../../Src/OGES2/src/zRenderDeviceOGLES.cpp"
)
SET(GAMEFRAMEWORK_SRCS "../../gameFrameWork/clientConfigFile.cpp"
"../../gameFrameWork/clientEventDevice.cpp"
"../../gameFrameWork/game.cpp"
"../../gameFrameWork/zHeightLayer.cpp"
"../../gameFrameWork/zTrigger.cpp"
)
SET(GAMEFRAMEWORK_MSG_SRCS "../../gameFrameWork/Msg/clientNetFunction.cpp"
"../../gameFrameWork/Msg/convert.cpp"
"../../gameFrameWork/Msg/MsgLuaRegister.cpp"
"../../gameFrameWork/Msg/systemMsgProcess.cpp"
)
SET(GAMEFRAMEWORK_UI_SRCS "../../gameFrameWork/ui/maoXue.cpp"
"../../gameFrameWork/ui/maoXueManager.cpp"
"../../gameFrameWork/ui/ui_window.cpp"
)
SET(GAMEFRAMEWORK_CG_SRCS "../../gameFrameWork/cg/zAnimPath.cpp"
"../../gameFrameWork/cg/zCgAnimation.cpp"
"../../gameFrameWork/cg/zCgLogicSequence.cpp"
)
SET(NETWORK_SRCS "../../network/MD5.cpp"
"../../network/networkAdapter.cpp"
"../../network/networkconnector.cpp"
"../../network/networkwarelzo.cpp"
"../../network/networkwaremessage.cpp"
)
生成目标库
ADD_LIBRARY(game SHARED ${FREETYPE2_BASE_SRCS}
jvm/JniHelper.cpp
jvm/GameHelper.cpp
jni.cpp
cos_game.cpp
glTest.cpp
testCamera.cpp
gametest.cpp
Game/cosApplication.cpp
Game/cos_main.cpp
${NETWORK_SRCS}
${PUGIXML_SRCS}
${ZLIB_SRCS}
${GAMEFRAMEWORK_UI_SRCS}
${GAMEFRAMEWORK_MSG_SRCS})
#)
需要连接的库
TARGET_LINK_LIBRARIES(cos_game ${LIB_CSTD_DIR}
${LIB_C_DIR}
${LIB_M_DIR}
${LIB_DL_DIR}
${LIB_GLESV2_DIR}
${LIB_LOG_DIR})
依赖的crtbegin_dynamic.o 和 crtend_android.o android编译需要这两个文件。
add_dependencies(cos_game ${CRTBEGIN_DIR} ${CRTEND_ANDROID_DIR})
5、编译cmake,外部编译
在jni目录下面建立build目录 mkdir build,进入build目录,执行下面的命令:
环境:
linux :2.6.32-279.el6.x86_64 linux 版本 cmake: http://www.cmake.org/cmake/resources/software.html android: linux版本 sdk:http://developer.android.com/sdk/index.html linux 版本 ndk:http://developer.android.com/tools/sdk/ndk/index.html
项目代码:project 目录,是C++ 、C语言代码 以上版本注意linux系统是32还是64位版本的不同。 我的思路是:用cmake编译project代码为一个.so库,然后java代码调用.so库,最终打包为apk 方法: 1、 将上面的sdk 、ndk以及project解压放在自己的工作目录。例如我是这样的:
[workspace]$ ls adt project [workspace]$ ls adt eclipse ndk sdk
2、目录构建好之后,进入project工程的jni目录里面
cd /home/test/workspace/project/MobileClient/android/jni
这里面有andorid 编译用的各个目录。
[ jni]$ ls AmkList.txt build game.h gametest.h jni.cpp target Android.mk CMakeLists.txt Game glTest.cpp jvm testCamera.cpp Application.mk game.cpp gametest.cpp glTest.h libcode.mk source.mk testCamera.h
jni目录上层目录里面的内容:
[android]$ls AndroidManifest.xml gen res asserts libs bin obj src jni
这些都是android编译环境的标准目录结构,我们的cmake就在jni目录里面构建的。 3、利用ndk编译android的交叉工具链,命令make-standalone-toolchain.sh 进入ndk的tools目录,里面都是一些脚本程序
/home/test/workspace/adt/ndk/build/tools
执行命令
[tools]$ ./make-standalone-toolchain.sh --platform=android-12 --ndk-dir=/home/test/workspace/adt/ndk/ --install-dir=/opt/android-12-toolchain/ --system=linux-x86_64
--platform 平台 --ndk-dir ndk的路径 --install-dir是安装路径 --system是操作系统,如果不写的话,脚本会自动提示你的。 这样命令就安装到了/opt/目录下面了,我们的cmake还用到里面的lib 和头文件。 安装完之后设置环境变量,不设置的话cmake就不会到里面寻找我们需要的库,而是去系统都文件里面找。 命令: export PATH=$PATH:/opt/android-12-toolchain/sysroot/usr/lib/ 4、在jni目录编写CMakeLists.txt文件,我的cmake是要编译出来为so库,CMakeLists.txt的内容为: PROJECT(GAME) 工程名字
SET(CMAKE_SYSTEM_NAME Android)
SET(CMAKE_CXX_COMPILER "/opt/android-12-toolchain/arm-linux-androideabi/bin/g++") 交叉编译工具
SET(CMAKE_C_COMPILER "/opt/android-12-toolchain/arm-linux-androideabi/bin/gcc")
显示系统信息
MESSAGE(STATUS "System Info:" ${CMAKE_SYSTEM}) MESSAGE(STATUS "System Processor:" ${CMAKE_SYSTEM_PROCESSOR}) MESSAGE(STATUS "BUILD TYPE : " ${CMAKE_BUILD_TYPE})
设置代码里面的宏定义
ADD_DEFINITIONS(-DANDROID -DLINUX -DUNIX
-D_DISABLE_CXX_EXCEPTION
-DFT2_BUILD_LIBRARY -D__GL_ES_2_
-DAL_BUILD_LIBRARY -DAL_ALEXT_PROTOTYPES
-D_ARM_ASSEM_ -DNDK_DEBUG
-DKTX_OPENGL_ES2=1)
要求cmake的最低版本
CMAKE_MINIMUM_REQUIRED(VERSION 2.8)
设置编译之后的目标生成路径
SET(EXECUTABLE_OUTPUT_PATH ${PROJECT_BINARY_DIR}/../target)
包含编译需要的头文件,
INCLUDE_DIRECTORIES(".")
INCLUDE_DIRECTORIES("./jvm")
INCLUDE_DIRECTORIES("../../../Src/Core/inc")
INCLUDE_DIRECTORIES("../../../Src/OGES2/inc")
INCLUDE_DIRECTORIES("../../../External/freetype/FreeType2/include")
INCLUDE_DIRECTORIES("../../../External/OGLES2")
INCLUDE_DIRECTORIES("../../../External/OGLES2/Include")
INCLUDE_DIRECTORIES("../../../External/OGLES2/Include/GLES2")
INCLUDE_DIRECTORIES("../../OpenAL4Android/include")
INCLUDE_DIRECTORIES("../../OpenAL4Android/OpenAL32/Include")
INCLUDE_DIRECTORIES("../../../External/luatinker/inc")
INCLUDE_DIRECTORIES("../../../MobileProtocol")
INCLUDE_DIRECTORIES("../../../MobileServer/Core/Networkware/msg")
INCLUDE_DIRECTORIES("./jvm")
#INCLUDE_DIRECTORIES("/usr/include/")
#INCLUDE_DIRECTORIES("/usr/include/sys")
FIND_LIBRARY(LIB_CSTD_DIR NAMES stdc++)
找的编译需要的库文件,设置到变量里面,下面连接的时候用
IF(LIB_CSTD_DIR)
MESSAGE(STATUS "LIB_CSTD_DIR: "${LIB_CSTD_DIR})
ENDIF(LIB_CSTD_DIR)
FIND_LIBRARY(LIB_C_DIR NAMES c)
IF(LIB_C_DIR)
MESSAGE(STATUS "LIB_C_DIR: "${LIB_C_DIR})
ENDIF(LIB_C_DIR)
FIND_LIBRARY(LIB_M_DIR NAMES m)
IF(LIB_M_DIR)
MESSAGE(STATUS "LIB_M_DIR: "${LIB_M_DIR})
ENDIF(LIB_M_DIR)
FIND_LIBRARY(LIB_DL_DIR NAMES dl)
IF(LIB_DL_DIR)
MESSAGE(STATUS "LIB_DL_DIR: "${LIB_DL_DIR})
ENDIF(LIB_DL_DIR)
FIND_LIBRARY(LIB_LOG_DIR NAMES log)
IF(LIB_LOG_DIR)
MESSAGE(STATUS "LIB_LOG_DIR: "${LIB_LOG_DIR})
ENDIF(LIB_LOG_DIR)
FIND_LIBRARY(LIB_GLESV2_DIR NAMES GLESv2)
IF(LIB_GLESV2_DIR)
MESSAGE(STATUS "LIB_GLESV2_DIR: "${LIB_GLESV2_DIR})
ENDIF(LIB_GLESV2_DIR)
FIND_FILE(CRTBEGIN_DIR NAMES crtbegin_dynamic.o)
IF(CRTBEGIN_DIR)
MESSAGE(STATUS "CRTBEGIN_DIR:" ${CRTBEGIN_DIR})
ENDIF(CRTBEGIN_DIR)
FIND_FILE(CRTEND_ANDROID_DIR NAMES crtend_android.o)
IF(CRTEND_ANDROID_DIR)
MESSAGE(STATUS "CRTEND_ANDROID_DIR:" ${CRTEND_ANDROID_DIR})
ENDIF(CRTEND_ANDROID_DIR)
编译需要的c、c++文件
也可以直接包含目录“AUX_SOURCE_DIRECTORY("../../../Src/Core/src/" CORE_SRCS)”
SET(PUGIXML_SRCS "../../../External/pugixml/src/pugixml.cpp")
SET(LPNG167_SRCS "../../../External/lpng167/png.c"
"../../../External/lpng167/pngerror.c"
"../../../External/lpng167/pngwutil.c"
)
SET(KTX20_SRCS "../../../External/ktx20/include/errstr.c"
"../../../External/ktx20/include/etcdec.cxx"
"../../../External/ktx20/include/writer.c"
)
SET(OGES2_MOJOSHADER_SRCS "../../../Src/OGES2/mojoshader/mojoshader.cpp"
"../../../Src/OGES2/mojoshader/mojoshader_assembler.cpp"
"../../../Src/OGES2/mojoshader/mojoshader_preprocessor.cpp"
)
SET(OGES2_SRCS "../../../Src/OGES2/src/zOGLESFrameBuffer.cpp"
"../../../Src/OGES2/src/zOGLESMeshBufferResource.cpp"
"../../../Src/OGES2/src/zOGLESTexture.cpp"
"../../../Src/OGES2/src/zOGLShader.cpp"
"../../../Src/OGES2/src/zRenderDeviceOGLES.cpp"
)
SET(GAMEFRAMEWORK_SRCS "../../gameFrameWork/clientConfigFile.cpp"
"../../gameFrameWork/clientEventDevice.cpp"
"../../gameFrameWork/game.cpp"
"../../gameFrameWork/zHeightLayer.cpp"
"../../gameFrameWork/zTrigger.cpp"
)
SET(GAMEFRAMEWORK_MSG_SRCS "../../gameFrameWork/Msg/clientNetFunction.cpp"
"../../gameFrameWork/Msg/convert.cpp"
"../../gameFrameWork/Msg/MsgLuaRegister.cpp"
"../../gameFrameWork/Msg/systemMsgProcess.cpp"
)
SET(GAMEFRAMEWORK_UI_SRCS "../../gameFrameWork/ui/maoXue.cpp"
"../../gameFrameWork/ui/maoXueManager.cpp"
"../../gameFrameWork/ui/ui_window.cpp"
)
SET(GAMEFRAMEWORK_CG_SRCS "../../gameFrameWork/cg/zAnimPath.cpp"
"../../gameFrameWork/cg/zCgAnimation.cpp"
"../../gameFrameWork/cg/zCgLogicSequence.cpp"
)
SET(NETWORK_SRCS "../../network/MD5.cpp"
"../../network/networkAdapter.cpp"
"../../network/networkconnector.cpp"
"../../network/networkwarelzo.cpp"
"../../network/networkwaremessage.cpp"
)
生成目标库
ADD_LIBRARY(game SHARED ${FREETYPE2_BASE_SRCS}
jvm/JniHelper.cpp
jvm/GameHelper.cpp
jni.cpp
cos_game.cpp
glTest.cpp
testCamera.cpp
gametest.cpp
Game/cosApplication.cpp
Game/cos_main.cpp
${NETWORK_SRCS}
${PUGIXML_SRCS}
${ZLIB_SRCS}
${GAMEFRAMEWORK_UI_SRCS}
${GAMEFRAMEWORK_MSG_SRCS})
#)
需要连接的库
TARGET_LINK_LIBRARIES(cos_game ${LIB_CSTD_DIR}
${LIB_C_DIR}
${LIB_M_DIR}
${LIB_DL_DIR}
${LIB_GLESV2_DIR}
${LIB_LOG_DIR})
依赖的crtbegin_dynamic.o 和 crtend_android.o android编译需要这两个文件。
add_dependencies(cos_game ${CRTBEGIN_DIR} ${CRTEND_ANDROID_DIR})
5、编译cmake,外部编译
在jni目录下面建立build目录 mkdir build,进入build目录,执行下面的命令:
cmake .. -G "Unix Makefiles" -DCMAKE_BUILD_TYPE=Debug
生成libgame.so库,然后copy到android目录的libs目录下面,一定要copy到libs目录的armeabi目录下面 6、回到android目录下面,生成apk文件,生成apk文件需要好几步我写了一个sh脚本,一起执行,脚本如下:
#!/bin/bash export PATH=$PATH:../../../adt/sdk/build-tools/19.0.3/ export PATH=$PATH:../../../adt/sdk/tools/ export PATH=$PATH:./jdk1.6.0_45/bin/ 这个jdk需要下载,安装, aapt package -f -m -J gen -S res -I ../../../adt/sdk/platforms/android-19/android.jar -M AndroidManifest.xml javac -target 1.5 -bootclasspath ../../../adt/sdk/platforms/android-19/android.jar -d bin src/com/cos/game/*.java gen/com/cos/game/R.java dx --dex --output=bin/classes.dex bin aapt package -f -M AndroidManifest.xml -S res -A asserts -I ../../../adt/sdk/platforms/android-19/android.jar -F bin/byreadreader #如果apk要包含图片、声音,就放到asserts目录下面 apkbuilder byreadreader.apk -v -u -z bin/byreadreader -f bin/classes.dex -rf src -rj libs -nf libs #libs目录就是我们生成的库 keytool -genkey -alias demo.keystore -keyalg RSA -validity 40000 -keystore demo.keystore jarsigner -verbose -keystore demo.keystore -signedjar test.apk byreadreader.apk demo.keystore
主意:这些命令啥意思网上都有,可以查看一下。上面脚本里面用到的目录,都要和我写的一摸一样,否则可能出错,单是没有提示。
相关文章推荐
- Cocos2D-X 项目发布到Android平台(三)编译打包Cocos2D-X项目生成apk安装包
- linux下eclipse构建并编译android一个简单jni项目
- Linux From Scratch 构建临时编译环境(一)
- fedora linux下android源码编译环境的搭建
- Linux下配置Jenkins+Android+Ant自动化构建环境(一)
- 深入浅出 - Android系统移植与平台开发(四)- 搭建Linux编译环境
- Ant自动编译打包&发布 android项目
- Ant自动编译打包&发布 android项目
- 全志A33开发板的android环境搭建及编译、打包
- cmake 配置arm-linux-gcc 交叉编译环境
- Linux平台下构建android环境
- Linux下交叉编译环境构建
- Jenkins + Unity + Android构建基于Unity的自动编译环境
- unity3d-配置Android环境,打包发布Apk流程详解
- Android系统移植1--创建ARM-Linux交叉编译环境
- linux(以ubuntu为例)下Android利用ant自动编译、修改配置文件、批量多渠道,打包生成apk文件
- Android,程序反编译后的打包发布
- Ant自动编译打包&发布 android项目
- [Android] i.MX6 Android源码中分离U-Boot和Linux-Kernel独立编译环境
- linux下eclipse构建并编译android一个简单jni项目