我正在尝试将本机C ++ DLL移植为Android上的共享库。对于构建,我使用的是VSCode,而不是Visual Studio。下载了Android NDK r18b。我的项目基于CMake,当我尝试使用“ NMake Mmakefiles”生成器生成该项目时,总是会收到此错误:
CMAKE_SYSTEM_NAME is 'Android' but 'NVIDIA Nsight Tegra Visual Studio Edition' is not installed.
我创建了一个小项目来对此进行测试。
main.cpp
int foo( int a, int b ) { return a + b; }
CMakeLists.txt
cmake_minimum_required( VERSION 3.11.0 )
add_library( Engine SHARED main.cpp )
我使用以下命令行(CMake 3.11.4)运行它:
cmake -g "NMake Makefiles" .. -DCMAKE_TOOLCHAIN_FILE=%NDK_ROOT%\build\cmake\android.toolchain.cmake -DANDROID_NDK=%NDK_ROOT%
有了这个,我仍然得到错误:
CMake Error in CMakeLists.txt:
CMAKE_SYSTEM_NAME is 'Android' but 'NVIDIA Nsight Tegra Visual Studio Edition' is not installed.
有人可以帮我把这个小main.cpp制作成Android .so吗?我不想使用Android Studio或其他IDE。寻找创建make文件并将其添加到我的VSCode版本中。
谢谢。
答案 0 :(得分:0)
如果您愿意使用Gradle来配置cmake ...
我使用Gradle Wrapper,在安装gradle之后,您可以在目录中调用gradle wrapper
,它将安装本地副本。此副本可以设置为特定版本,也可以为upgraded。
Android Gradle插件使用ninja构建系统来配置cmake和目标ABI。以下脚本将为所有受支持的平台类型生成ABI,但是很容易删除您不想创建的任何ABI。
VSCode有一个gradle plugin可以从IDE生成,或者您可以创建仅调用gradlew命令行的构建类型。
首先,我先使用gradle wrapper
然后使用gradlew init
来创建gradle项目。
然后,我添加了用于构建Android库的构建脚本。
build.gradle
/*
* This file was generated by the Gradle 'init' task.
*
* This is a general purpose Gradle build.
* Learn how to create Gradle builds at https://guides.gradle.org/creating-new-gradle-builds/
*/
buildscript {
repositories {
jcenter()
google()
}
dependencies {
classpath 'com.android.tools.build:gradle:3.2.1'
// NOTE: Do not place your application dependencies here; they belong
// in the individual module build.gradle files
}
}
allprojects {
repositories {
jcenter()
google()
}
}
apply plugin: 'com.android.library'
android {
compileSdkVersion 28 // Change this to the SDK version you have installed
buildToolsVersion '28.0.3' // Change this to the SDK build tools you have installed
defaultConfig {
minSdkVersion 16 // Cannot be less than 16
targetSdkVersion 28 // Same as CompileSdkVersion
versionCode 1
versionName "1.0"
sourceSets {
main {
manifest.srcFile 'AndroidManifest.xml'
}
}
ndk {
abiFilters = []
abiFilters.addAll(ABI_FILTERS.split(';').collect { it as String })
}
externalNativeBuild {
cmake {
arguments '-DANDROID_PLATFORM=android-16',
'-DANDROID_TOOLCHAIN=clang', '-DANDROID_STL=c++_static',
'-DANDROID_CPP_FEATURES=rtti exceptions'
}
}
}
externalNativeBuild {
cmake {
path './CMakeLists.txt'
}
}
buildTypes {
release {
minifyEnabled false
}
debug {
debuggable true
jniDebuggable true
minifyEnabled false
}
}
}
此构建文件包括一个虚拟 AndroidManifest.xml 文件:
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.example"
android:versionCode="1"
android:versionName="1.0" >
<uses-sdk android:minSdkVersion="16" />
<application/>
</manifest>
我需要旧版本的CMake,我使用3.4而不是3.11
CMakeLists.txt
cmake_minimum_required( VERSION 3.4.0 )
add_library( Engine SHARED main.cpp )
local.properties
# This file must *NOT* be checked into Version Control Systems,
# as it contains information specific to your local configuration.
#
# Location of the SDK. This is only used by Gradle.
# For customization when using a Version Control System, please read the
# header note.
ndk.dir=d\:\\android\\ndk
sdk.dir=d\:\\android\\sdk
gradle.properties
# Project-wide Gradle settings.
# IDE (e.g. Android Studio) users:
# Gradle settings configured through the IDE *will override*
# any settings specified in this file.
# For more details on how to configure your build environment visit
# http://www.gradle.org/docs/current/userguide/build_environment.html
# Specifies the JVM arguments used for the daemon process.
# The setting is particularly useful for tweaking memory settings.
org.gradle.jvmargs=-Xmx1536m
# When configured, Gradle will run in incubating parallel mode.
# This option should only be used with decoupled projects. More details, visit
# http://www.gradle.org/docs/current/userguide/multi_project_builds.html#sec:decoupled_projects
# org.gradle.parallel=true
# EDIT THIS LINE to change the Target ABIs
ABI_FILTERS=x86;x86_64;armeabi-v7a;arm64-v8a
org.gradle.java.home=D:\\Program Files\\Java\\jdk8
distributionUrl=\
https\://services.gradle.org/distributions/gradle-4.1-all.zip
# When set to true the Gradle daemon is used to run the build. For local developer builds this is our favorite property.
# The developer environment is optimized for speed and feedback so we nearly always run Gradle jobs with the daemon.
org.gradle.daemon=true
最后,要构建,我只需运行:
.\gradlew :externalNativeBuildDebug
或
.\gradlew :externalNativeBuildRelease
它会在build\intermediates\cmake
目录中生成库。
答案 1 :(得分:0)
我将其留在这里,是因为很难找到并完成有关Android Gradle实际操作方式的詹姆斯回答。
CMake arguments created the Gradle
ProcessInfoBuilder builder = new ProcessInfoBuilder();
// CMake requires a folder. Trim the filename off.
File cmakeListsFolder = getMakefile().getParentFile();
builder.setExecutable(getCmakeExecutable());
builder.addArgs(String.format("-H%s", cmakeListsFolder));
builder.addArgs(String.format("-B%s", outputJson.getParentFile()));
builder.addArgs("-GAndroid Gradle - Ninja");
builder.addArgs(String.format("-DANDROID_ABI=%s", abi));
builder.addArgs(String.format("-DANDROID_NDK=%s", getNdkFolder()));
builder.addArgs(
String.format("-DCMAKE_LIBRARY_OUTPUT_DIRECTORY=%s",
new File(getObjFolder(), abi)));
builder.addArgs(
String.format("-DCMAKE_BUILD_TYPE=%s", isDebuggable() ? "Debug" : "Release"));
builder.addArgs(String.format("-DCMAKE_MAKE_PROGRAM=%s",
getNinjaExecutable().getAbsolutePath()));
builder.addArgs(String.format("-DCMAKE_TOOLCHAIN_FILE=%s",
getToolChainFile().getAbsolutePath()));
builder.addArgs(String.format("-DANDROID_NATIVE_API_LEVEL=%s", abiPlatformVersion));
if (!getcFlags().isEmpty()) {
builder.addArgs(String.format("-DCMAKE_C_FLAGS=%s", Joiner.on(" ").join(getcFlags())));
}
if (!getCppFlags().isEmpty()) {
builder.addArgs(String.format("-DCMAKE_CXX_FLAGS=%s",
Joiner.on(" ").join(getCppFlags())));
}
for (String argument : getBuildArguments()) {
builder.addArgs(argument);
}