gpt4 book ai didi

android - cmake - 一次针对多个架构,无需在构建之间手动清理

转载 作者:太空狗 更新时间:2023-10-29 20:34:40 28 4
gpt4 key购买 nike

我正在为 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
│ └── ...
|

我通过执行 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
...

如果我正在为一种特定的架构构建,例如仅将 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)

最佳答案

正如我在评论中所回避的那样,一种选择是为每个目标架构使用一个构建目录

...

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

...

这将导致一棵树看起来有点像下面这样

project/
+--- src/
+--- build/
+--- armeabi-v7a/
+--- armeabi/
+--- x86/
+--- mips/
+--- arm64-v8a/
+--- mips64/

关于android - cmake - 一次针对多个架构,无需在构建之间手动清理,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/47146262/

28 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com