如何获得ndk-build使用的全套编译器和链接器标志?

时间:2017-10-02 16:58:21

标签: android-ndk

是否有直接的方法来获取NDK构建使用的完整编译和链接器标志集?现在,我们通过查看将C ++添加到Android Studio项目时创建的cmake文件来解决问题。

问题在于,我们绝大多数时间都在构建许多现有的第三方项目,每个项目都有自己的构建系统。重写构建系统以使用Android工具(cmake和ndk-build系统)将是疯狂的;我们需要使用现有的make系统,绝大多数时候这意味着我们需要为配置脚本提供CFLAGS,CXX_FLAGS,CPPFLAGS,LDFLAGS等内容。除了通过观看原生Android ndk构建的输出之外,这些标志都没有记录在我找到的任何地方。

更新:我认为我并不清楚我想要的是什么。

我们有一些讨厌的脚本设法使用cmake从现有构建中吸取正确的标志集。 (其中一个项目你说它会带你二十分钟,而且你可笑得很糟糕。)这些脚本打破了r16 beta 1.我真的不需要编写令人讨厌的不稳定脚本来拉出标记,因为他们可能会打破下一个ndk版本。

(这是我们脚本的最后一个输出,如果您想看到我正在谈论的标志:https://gist.github.com/banshee/15f1a5fbce0c71af6498656bb02ebc67

3 个答案:

答案 0 :(得分:1)

尝试检查

{SDK_PATH}/ndk-bundle/build/core/toolchains/arm-linux-androideabi-4.9/setup.mk

或不同的工具链(取决于你正在建造什么)。定义了交叉编译所需的标志。

修改

我做了一些挖掘。

如果您编辑文件:

{SDK_PATH}/ndk-bundle/build/core/definitions.mk

并找到一行define ev-compile-cpp-source。或者更好define ev-build-file

你可以添加

$(info $_FLAGS is [${_FLAGS}])
$$eval之前

现在,如果你建造一些东西,你会看到旗帜。

答案 1 :(得分:1)

对于自定义构建系统,您应使用standalone toolchain。这将处理所有基本标志正确定位Android。它不会处理最好留给构建系统的任何决策,例如优化级别,调试标志等。

编辑:

不幸的是,您当前的解决方案是暂时可以获得的。最终,工具链配置将被移动到$NDK/meta中的JSON文件中,就像已经拥有的一些(微不足道的)一样,所以我们可以在ndk-build和CMake之间共享该信息,但这不会很快发生。

答案 2 :(得分:0)

使用cmake驱动configure,或者以您需要的任何格式写出值。

例如,这是一个配置和编译expat项目的CMakeLists.txt文件。它期望expat的源已经在系统上。可能大多数你想要的是在standard_configure_env宏中;它是您想要的修改后的CFLAGS等。

cmake_minimum_required(VERSION 3.6)

project (expat)

macro(standard_configure_env output)
set(${output}
    CC=${ANDROID_C_COMPILER}
    CXX=${ANDROID_CXX_COMPILER}
    CFLAGS=--target=${CMAKE_C_COMPILER_TARGET}\ --sysroot=${ANDROID_SYSROOT}\ \ --gcc-toolchain=${ANDROID_TOOLCHAIN_ROOT}\ ${ANDROID_COMPILER_FLAGS}
    CXXFLAGS=${ANDROID_COMPILER_FLAGS_CXX}
    AR=${ANDROID_AR} 
    RANLIB=${ANDROID_RANLIB}  
    LD=${CMAKE_LINKER}  
    LDFLAGS=${ANDROID_LINKER_FLAGS}
)
endmacro()

include(ProcessorCount)
ProcessorCount(nCpus)

set(expat_output_dir ${CMAKE_CURRENT_BINARY_DIR}/expat)
set(expat_build_dir ${expat_output_dir}/expat_bin)
set(expat_install_dir ${expat_output_dir}/install)
set(expat_src_dir /Users/james/yourpathgoeshere/cmake/expat/src/expat-2.1.0)

set(markers_dir ${expat_output_dir}/markers)
file(MAKE_DIRECTORY ${markers_dir})

set(expat_copied ${markers_dir}/copied)
set(expat_configured ${markers_dir}/configured)

set(expat_final_lib ${expat_install_dir}/lib/libexpat.a)

file(MAKE_DIRECTORY ${expat_install_dir}/include)

standard_configure_env(configure_env)

set(configure_host ${ANDROID_HEADER_TRIPLE})
# expat doesn't understand these Android architectures, so set them by hand to what expat can
# use
if(${configure_host} STREQUAL aarch64-linux-android)
set(configure_host arm-linux-android64v8a)
elseif(${configure_host} STREQUAL armv7-linux-androideabi)
set(configure_host arm-linux-androideabiv7a)
endif()

set(configure_args
    --host=${configure_host}
    --disable-shared
    --prefix=${expat_output_dir}/install
    --exec-prefix=${expat_output_dir}/install
    )

add_custom_command(
    OUTPUT ${expat_configured}
    COMMAND ${configure_env} ./configure ${configure_args} && touch ${expat_configured}
    DEPENDS ${expat_copied}
    WORKING_DIRECTORY ${expat_build_dir}
    )

add_custom_command(
    OUTPUT ${expat_copied}
    COMMAND ${CMAKE_COMMAND} -E copy_directory ${expat_src_dir} ${expat_build_dir}
    COMMAND touch ${expat_copied}
    )

add_custom_command(
    OUTPUT ${expat_final_lib}
    COMMAND make -j${nCpus} installlib && touch ${expat_final_lib}
    WORKING_DIRECTORY ${expat_build_dir}
    DEPENDS ${expat_configured}
    )

add_custom_target(expat_build DEPENDS ${expat_final_lib})
add_library(expat STATIC IMPORTED GLOBAL)
add_dependencies(expat expat_build)

set_target_properties(expat
  PROPERTIES
  LINKER_LANGUAGE CXX
  IMPORTED_LOCATION ${expat_install_dir}/lib/libexpat.a
  INTERFACE_INCLUDE_DIRECTORIES ${expat_install_dir}/include)

感谢@DanAlbert和@JakubPiskorz指出我确实想从cmake获得这个。