Boš*_*ber 5 c++ android cmake android-ndk
我正在为Android和iOS开发一个跨平台的C ++库,并且正在使用cmake来准备构建脚本。
项目结构如下所示:
somelib
|
?? .gitignore
|
??? src
? ??? CMakeLists.txt
? ??? Doxyfile.in
| ??? include (Public headers)
? ??? somelib
? ??? somelib.hpp
? ??? somelib
? ??? CMakeLists.txt
? ??? somelib.cpp
? ??? ....hpp, ....cpp
? ??? test
? ??? test_classname.cpp
? ??? libs (source of 3rd party libs)
? ??? 3rd_party_lib_1
? ??? CMakeLists.txt
? ??? ...
? ??? ...
? ??? CMakeLists.txt
? ??? ...
?_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _
|
??? toolchains
? ??? andoid
? ??? android.toolchain.cmake
? ??? ...
? ??? ios
? ??? ios.toolchain.cmake
? ??? ...
?_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _
?
??? build
? ??? build.sh
? ??? Doxyfile
? ??? ...
?_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _
|
??? dist (distribute)
? ??? docs
? ??? index.html
? ??? ...
| ??? include (Public headers)
? ??? somelib.hpp
? ??? local
| ??? somelibtest (executable tests)
? ??? android
? ??? Debug
? ??? armeabi
? ??? armeabi-v7a
? ??? ...
? ??? Release
? ??? armeabi
? ??? armeabi-v7a
? ??? ...
? ??? ios
? ??? Debug
? ??? armv
? ??? armv7
? ??? ...
? ??? Release
? ??? armv
? ??? armv7
? ??? ...
|
Run Code Online (Sandbox Code Playgroud)
我通过执行build.sh从./build/路径运行cmake,在为Android构建的情况下,它看起来像这样:
build.sh:
...
TARGETS="armeabi-v7a armeabi x86 mips arm64-v8a mips64"
mkdir -p "$BUILD_PATH"
for TARGET in $TARGETS
do
cmake -DANDROID_NATIVE_API_LEVEL=${ANDROID_NATIVE_API_LEVEL} -DCMAKE_TOOLCHAIN_FILE=${ANDROID_TOOLCHAIN} -DANDROID_NDK=${ANDROID_NDK} -DCMAKE_BUILD_TYPE=${CMAKE_BUILD_TYPE} -DANDROID_ABI=${TARGET} -DPROJ_HOME=${PROJ_HOME} ../src
make -j32
done
fi
...
Run Code Online (Sandbox Code Playgroud)
如果我要针对一种特定的体系结构进行构建,例如仅将TARGETS设置为“ arm64-v8a”,则该库的构建良好。如果我想一次为多个架构构建一个库,那么它就不能很好地工作,因为cmake专门为每个平台/架构准备了构建脚本。我在生成期间遇到链接器错误,例如“目标不兼容”。
构建针对多个平台和多体系结构的库的最佳实践是什么?
在准备为其他体系结构进行构建之前,如何避免清除构建脚本文件?
感谢您的任何建议!
PS:这是来自src / CmakeLists.txt主文件的几行:
cmake_minimum_required(VERSION 3.6.0 FATAL_ERROR)
include(GNUInstallDirs)
# Set default build type
if(NOT CMAKE_BUILD_TYPE)
set(CMAKE_BUILD_TYPE "Release")
endif()
## Output directories
if (IOS)
set(REL_OUTPUT_DIR "ios/${CMAKE_BUILD_TYPE}/${IOS_ARCH}")
elseif (ANDROID)
set(REL_OUTPUT_DIR "android/${CMAKE_BUILD_TYPE}/${ANDROID_ABI}")
else()
set(REL_OUTPUT_DIR "local")
endif()
set(OUTPUT_DIR ${CMAKE_BINARY_DIR}/../dist/${REL_OUTPUT_DIR})
set(DESTDIR ${CMAKE_BINARY_DIR}/../dist/${REL_OUTPUT_DIR})
set(CMAKE_ARCHIVE_OUTPUT_DIRECTORY "${OUTPUT_DIR}") # Static libraries
set(CMAKE_LIBRARY_OUTPUT_DIRECTORY "${OUTPUT_DIR}") # Dynamic libraries
set(CMAKE_RUNTIME_OUTPUT_DIRECTORY "${OUTPUT_DIR}") # Executables
# Include libraries
add_subdirectory(libs/3rd_party_lib_1)
add_subdirectory(libs/3rd_party_lib_n)
Run Code Online (Sandbox Code Playgroud)
正如我在评论中所忽略的,一种选择是每个目标体系结构使用一个构建目录
...
TARGETS="armeabi-v7a armeabi x86 mips arm64-v8a mips64"
for TARGET in ${TARGETS}
do
# create one build dir per target architecture
mkdir -p ${BUILD_PATH}/${TARGET}
cd ${BUILD_PATH}/${TARGET}
cmake -DANDROID_NATIVE_API_LEVEL=${ANDROID_NATIVE_API_LEVEL} -DCMAKE_TOOLCHAIN_FILE=${ANDROID_TOOLCHAIN} -DANDROID_NDK=${ANDROID_NDK} -DCMAKE_BUILD_TYPE=${CMAKE_BUILD_TYPE} -DANDROID_ABI=${TARGET} -DPROJ_HOME=${PROJ_HOME} ../../src
make -j32
cd -
done
...
Run Code Online (Sandbox Code Playgroud)
这将导致一棵树看起来像下面的样子
project/
+--- src/
+--- build/
+--- armeabi-v7a/
+--- armeabi/
+--- x86/
+--- mips/
+--- arm64-v8a/
+--- mips64/
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
1738 次 |
| 最近记录: |