Warning: file_get_contents(/data/phpspider/zhask/data//catemap/3/android/219.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
配置CMake以根据当前Android构建类型添加_库_Android_Cmake_Java Native Interface_Native - Fatal编程技术网

配置CMake以根据当前Android构建类型添加_库

配置CMake以根据当前Android构建类型添加_库,android,cmake,java-native-interface,native,Android,Cmake,Java Native Interface,Native,我将我的凭证密钥存储在cpp本机文件中,并使用CMake构建,然后将其链接到我的应用程序: 当前代码: src | - CMakeLists.txt | | - debug/cpp | - CMakeLists.txt | - credentials-debug.cpp | | - main/cpp | - CMakeLists.txt | - credentials-release.cpp | | - staging/cpp | - CMakeLists.txt | -

我将我的凭证密钥存储在
cpp
本机文件中,并使用CMake构建,然后将其链接到我的应用程序:

当前代码:

src
| - CMakeLists.txt
|
| - debug/cpp
  | - CMakeLists.txt
  | - credentials-debug.cpp
|
| - main/cpp
  | - CMakeLists.txt
  | - credentials-release.cpp
|
| - staging/cpp
  | - CMakeLists.txt
  | - credentials-staging.cpp
cmake_minimum_required(VERSION 3.4.1)

add_subdirectory(debug/cpp)

add_subdirectory(staging/cpp)

add_subdirectory(main/cpp)
add_library(
    credentials-debug
    SHARED
    credentials-debug.cpp)
我的
src/main/cpp/credentials-provider-dev.cpp
文件:

JNIEXPORT jobject JNICALL
Java_com_{package}_CredentialsProvider_extractApiCredentials(JNIEnv *env, jobject instance) {
    jclass cls = env -> FindClass("com/{path}/models/ApiCredentials");
    jmethodID methodId = env -> GetMethodID(cls, "<init>",
    "(Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;)V");

    return env -> NewObject(cls, methodId,
                            env->NewStringUTF("key"),
                            env->NewStringUTF("other key"),
                            env->NewStringUTF("another key"),
                            env->NewStringUTF("key again"),
                            NULL, NULL
    );
}
externalNativeBuild {
    cmake {
        path 'src/main/cpp/CMakeLists.txt'
    }
}
cmake_minimum_required(VERSION 3.4.1)

add_library(
    credentials-provider-dev
    SHARED
    credentials-provider-dev.cpp)
我的
src/main/cpp/CMakeLists.txt
文件:

JNIEXPORT jobject JNICALL
Java_com_{package}_CredentialsProvider_extractApiCredentials(JNIEnv *env, jobject instance) {
    jclass cls = env -> FindClass("com/{path}/models/ApiCredentials");
    jmethodID methodId = env -> GetMethodID(cls, "<init>",
    "(Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;)V");

    return env -> NewObject(cls, methodId,
                            env->NewStringUTF("key"),
                            env->NewStringUTF("other key"),
                            env->NewStringUTF("another key"),
                            env->NewStringUTF("key again"),
                            NULL, NULL
    );
}
externalNativeBuild {
    cmake {
        path 'src/main/cpp/CMakeLists.txt'
    }
}
cmake_minimum_required(VERSION 3.4.1)

add_library(
    credentials-provider-dev
    SHARED
    credentials-provider-dev.cpp)
credentials provider dev
文件仅定义我的开发环境凭据,当我在调试类型中构建时,此代码可以正常工作

问题:

src
| - CMakeLists.txt
|
| - debug/cpp
  | - CMakeLists.txt
  | - credentials-debug.cpp
|
| - main/cpp
  | - CMakeLists.txt
  | - credentials-release.cpp
|
| - staging/cpp
  | - CMakeLists.txt
  | - credentials-staging.cpp
cmake_minimum_required(VERSION 3.4.1)

add_subdirectory(debug/cpp)

add_subdirectory(staging/cpp)

add_subdirectory(main/cpp)
add_library(
    credentials-debug
    SHARED
    credentials-debug.cpp)
我还有登台和发布版本,我想为每种版本类型使用不同的
凭证提供程序-{dev/staging/production}.cpp
文件:

debug {
    ext.alwaysUpdateBuildId = false
    applicationIdSuffix ".debug"
}

staging {
    initWith debug
    debuggable true
}

release {
    minifyEnabled true
    proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules-app.pro'
    signingConfig signingConfigs.release
}
尝试:

src
| - CMakeLists.txt
|
| - debug/cpp
  | - CMakeLists.txt
  | - credentials-debug.cpp
|
| - main/cpp
  | - CMakeLists.txt
  | - credentials-release.cpp
|
| - staging/cpp
  | - CMakeLists.txt
  | - credentials-staging.cpp
cmake_minimum_required(VERSION 3.4.1)

add_subdirectory(debug/cpp)

add_subdirectory(staging/cpp)

add_subdirectory(main/cpp)
add_library(
    credentials-debug
    SHARED
    credentials-debug.cpp)
由于更好的密钥保护,我使用本机代码来存储这些密钥。我不想将所有的构建密钥合并到一个文件中,因为repo安全性。只有负责访问生产版本的人员才能拥有
凭据提供程序production.cpp
文件并能够生成版本。因此,我的队友只能使用
dev
文件和构建调试模式

在像这样调用
add\u library
之前,我尝试使用
find\u library
检查staging
cpp
文件是否存在,但不起作用,库仍然没有添加:

find_file(
    STAGING_KEY_LIB
    PATHS main/cpp/credentials-provider-staging.cpp)
if (STAGING_KEY_LIB)
    add_library(
        credentials-provider-staging
        SHARED
        main/cpp/credentials-provider-staging.cpp)
endif()
我还尝试了发送到
CMakeLists.txt
CMAKE\u BUILD\u TYPE
参数,如下所示。但基于:
有效值是Release和Debug
。我也希望有一个临时构建,所以这个方法不起作用

add_library(
    credentials-provider-${CMAKE_BUILD_TYPE}
    SHARED
    credentials-provider-${CMAKE_BUILD_TYPE}.cpp)
总之:

使用本机代码:如何将密钥文件分离为不同的基于构建类型的文件?任何有这方面经验的人请帮助。
谢谢

这是我目前的解决方案:

项目结构:

src
| - CMakeLists.txt
|
| - debug/cpp
  | - CMakeLists.txt
  | - credentials-debug.cpp
|
| - main/cpp
  | - CMakeLists.txt
  | - credentials-release.cpp
|
| - staging/cpp
  | - CMakeLists.txt
  | - credentials-staging.cpp
cmake_minimum_required(VERSION 3.4.1)

add_subdirectory(debug/cpp)

add_subdirectory(staging/cpp)

add_subdirectory(main/cpp)
add_library(
    credentials-debug
    SHARED
    credentials-debug.cpp)
src/CMakeLists.txt:

src
| - CMakeLists.txt
|
| - debug/cpp
  | - CMakeLists.txt
  | - credentials-debug.cpp
|
| - main/cpp
  | - CMakeLists.txt
  | - credentials-release.cpp
|
| - staging/cpp
  | - CMakeLists.txt
  | - credentials-staging.cpp
cmake_minimum_required(VERSION 3.4.1)

add_subdirectory(debug/cpp)

add_subdirectory(staging/cpp)

add_subdirectory(main/cpp)
add_library(
    credentials-debug
    SHARED
    credentials-debug.cpp)
src/debug/cpp/CMakeLists.txt:

src
| - CMakeLists.txt
|
| - debug/cpp
  | - CMakeLists.txt
  | - credentials-debug.cpp
|
| - main/cpp
  | - CMakeLists.txt
  | - credentials-release.cpp
|
| - staging/cpp
  | - CMakeLists.txt
  | - credentials-staging.cpp
cmake_minimum_required(VERSION 3.4.1)

add_subdirectory(debug/cpp)

add_subdirectory(staging/cpp)

add_subdirectory(main/cpp)
add_library(
    credentials-debug
    SHARED
    credentials-debug.cpp)
src/main/cpp/CMakeLists.txt:(在.gitignore中被忽略&在其他计算机上将为空)

src/staging/cpp/CMakeLists.txt:(在.gitignore中被忽略&将在其他计算机上为空)

因此,每个子文件
CMakeLists.txt
都会加载不同的cpp文件

  • 在我的本地计算机上,我将拥有所有3个(CMakeLists+cpp)文件

  • 在其他没有建立暂存或发布权限的队友上。他们没有登台+发布cpp文件,只有一个占位符空
    CMakeList
    文件

  • 在Kotlin代码中:我可以提取debug/staging/release构建类型以决定加载正确的库

优点:

src
| - CMakeLists.txt
|
| - debug/cpp
  | - CMakeLists.txt
  | - credentials-debug.cpp
|
| - main/cpp
  | - CMakeLists.txt
  | - credentials-release.cpp
|
| - staging/cpp
  | - CMakeLists.txt
  | - credentials-staging.cpp
cmake_minimum_required(VERSION 3.4.1)

add_subdirectory(debug/cpp)

add_subdirectory(staging/cpp)

add_subdirectory(main/cpp)
add_library(
    credentials-debug
    SHARED
    credentials-debug.cpp)
  • 更改构建类型是一个单步骤的过程,只需从AndroidStudio更改构建变量,代码就会自动选择正确的本机库进行导入
  • 从repo忽略重要凭据文件
缺点:

src
| - CMakeLists.txt
|
| - debug/cpp
  | - CMakeLists.txt
  | - credentials-debug.cpp
|
| - main/cpp
  | - CMakeLists.txt
  | - credentials-release.cpp
|
| - staging/cpp
  | - CMakeLists.txt
  | - credentials-staging.cpp
cmake_minimum_required(VERSION 3.4.1)

add_subdirectory(debug/cpp)

add_subdirectory(staging/cpp)

add_subdirectory(main/cpp)
add_library(
    credentials-debug
    SHARED
    credentials-debug.cpp)
  • 在我的机器上,3种构建类型的所有可用cpp文件都是从一开始构建的,但只使用了其中的1种
  • 当有人提取项目时,他们必须在main/cpp和staging/cpp文件夹中手动创建空的
    CMakeLists
    ,这样
    add\u子目录就不会抛出错误

我使用的是Android传递给CMAKE的
CMAKE\u BUILD\u类型。在我的例子中,我想使用一个特定的库版本,但这种方法也可以与CMake
IF
一起使用,以定义不同的流

string(TOLOWER ${CMAKE_BUILD_TYPE} BUILD_TYPE)
target_link_libraries(Bar  ${PROJECT_SOURCE_DIR}/../../Foo/lib/build/intermediates/library_and_local_jars_jni/${BUILD_TYPE}/jni/arm64-v8a/libFoo.so)

为什么不使用环境变量呢?像BUILD_ENV一样,使用环境的值,比如Dev、Prod和Stagging,然后使用这个变量选择合适的文件?我理解。您应该能够使用环境传递一些var。然后,如果定义了,您可以使用ENV{VAR_NAME}访问它。我看不到更好的方法,除非您直接在CMake列表中计算BUILD_ENV感谢
$ENV
部分,但这会导致一个问题。每次更改构建变量时,我都必须手动更改环境变量。我仍在研究一种自动化这个过程的方法。例如,当更改构建变量时,将自动设置env var,代码将使用正确的fileHum,我建议使用一个内部变量,在调试构建时设置为Dev,在发布时设置为Staging,在CI生成代码时,它应该将env var设置为prod,这样您就可以使用local_build_env=dev,如果debug local_build_env=staging,如果release local_build_env=env_build_env,那么env_build_env在您的CI上设置为prod,或者如果您有一个特殊的构建,则使用staging,否则设置为dev。我真的不明白,为什么不能声明一个CMake变量并使用它来代替CMake\u BUILD\u类型。只要您能够在CMake contexte中捕获环境变量,就不需要传递另一个变量。(构建类型,至少如果您想使用它的话)作为最后一次尝试,我写了一个要点,使用一个env变量并使用适当的凭证文件创建适当的库。