正如标题所示我试图将本地.so
链接到android工作室项目。我已经浏览了android开发者网站上的文档以及更多文章,但是在将.so
文件与项目连接时失败了。
每当我尝试运行代码时,都会出现以下错误
CMake错误:此项目中使用了以下变量,但是 它们设置为NOTFOUND。请设置它们或确保它们已设置 并在CMake文件中正确测试:testlib
这是我的CMake文件
cmake_minimum_required(VERSION 3.4.1)
add_library( # Sets the name of the library.
native-lib
# Sets the library as a shared library.
SHARED
# Provides a relative path to your source file(s).
src/main/cpp/native-lib.cpp )
find_library( # Sets the name of the path variable.
log-lib
# Specifies the name of the NDK library that
# you want CMake to locate.
log )
add_library(testlib SHARED IMPORTED)
set_property(TARGET testlib PROPERTY IMPORTED_LOCATION "E:/project/Remote_Native/remote_attempt_1/app/libs/armeabi-v7a/libremotedesktop_client.so")
#find_path(testlib E:/project/Remote_Native/remote_attempt_1/app/libs/armeabi-v7a/RemoteDesktop.h)
find_library(testlib E:/project/Remote_Native/remote_attempt_1/app/libs/armeabi-v7a/libremotedesktop_client.so)
#add_library(remote SHARED IMPORTED)
#set_target_properties(remote PROPERTIES IMPORTED_LOCATION libs/${ANDROID_ABI}/libremotedesktop_client.so )
# Specifies libraries CMake should link to your target library. You
# can link multiple libraries, such as libraries you define in this
# build script, prebuilt third-party libraries, or system libraries.
target_link_libraries( # Specifies the target library.
native-lib
# Links the target library to the log library
# included in the NDK.
${log-lib}
${testlib})
target_include_directories()
我有四个.so
文件,分别用于arm64,armeabi,armeabi-v7a,x86。我已经在路径中对armeabi-v7a lib进行了编码,当我这样做时,android studio会抛出上述错误。我的实际目标是根据手机中的芯片动态加载库。我很确定我目前的代码没有实现这一点。
以下是我的查询
如何解决我得到的错误?我试过给出相对路径和绝对路径,但无济于事我得到同样的错误。
如何将.so
和.h
文件添加到本机android工作室项目中?这有基于代码运行的芯片的变化?
当我直接将.h
文件添加到本机文件夹时,我可以在我的C代码中引用该标头中的类和函数,但我无法运行代码。我在getInstance()
文件中有.h
方法。每当我打电话给
getInstance()
函数显示undefined refernce to getInstance()
。我从中理解的是'.h'文件已正确链接,但实际存在于.h
文件中的.so
文件的功能定义未链接。如果回答问题1和问题2,我相信这将得到解决。
所有原生Android项目都必须有.mk文件吗?我没有在我的项目中添加一个,并认为这可能是我得到错误的原因之一。
答案 0 :(得分:1)
1-2)。首先,在CMakeLists.txt的开头添加set(CMAKE_FIND_ROOT_PATH_MODE_LIBRARY BOTH)
(在cmake_minimum_required(...)
之后)以允许库的其他搜索路径。在此之后,您可以使用标准find_library
找到lib:
find_library(FOO_LIBRARY
foo # Lib's full name in this case - libfoo.so
PATHS path/to/lib/)
if (NOT FOO_LIBRARY)
message(FATAL_ERROR "Foo lib not found!")
endif()
如果带有以这种方式组织的库的目录,您可以使用变量ANDROID_ABI
来获取特定的库版本:
- path/to/lib
- armeabi-v7a
- libfoo.so
- arm64-v8a
- libfoo.so
- x86
- libfoo.so
- x86_64
- libfoo.so
因此,在这种情况下,搜索路径为:path/to/lib/${ANDROID_ABI}/
要在项目中包含标题,请使用include_directories
:
include_directories(path/to/headers)
4)。 .mk文件仅在您使用ndk-build
时才需要(因此您不需要)
答案 1 :(得分:0)
在您的情况下,您不需要cmake_minimum_required(VERSION 3.4.1)
add_library( # Sets the name of the library.
native-lib
# Sets the library as a shared library.
SHARED
# Provides a relative path to your source file(s).
src/main/cpp/native-lib.cpp )
add_library(remote SHARED IMPORTED)
set_property(TARGET remote PROPERTY IMPORTED_LOCATION "E:/project/Remote_Native/remote_attempt_1/app/libs/${ANDROID_ABI}/libremotedesktop_client.so")
# Specifies libraries CMake should link to your target library. You
# can link multiple libraries, such as libraries you define in this
# build script, prebuilt third-party libraries, or system libraries.
target_link_libraries( # Specifies the target library.
native-lib
# Links the target library to the log library
# included in the NDK.
log
remote)
。对于日志,NDK会为您解析库;对于 libremotedesktop_client.so ,您知道确切的路径。
以下是适合您的 CMakeLists.txt :
${CMAKE_CURRENT_SOURCE_DIR}
请注意,在CMake脚本中使用完整路径( E:/ project ... )不是最佳做法;您可能会以某种方式表达相对于 CMakeLists.txt 路径的此库的路径,即const { client } = require('nightwatch-cucumber')
const { defineSupportCode } = require('cucumber')
const globals = require('../../config/globals.js')
var emailEntry = (`input[name='administrator[email]']`)
var passwordEntry = (`input[name='administrator[password]']`)
var existingGtmKey = ("GTM-123456")
var newGtmKey = ("GTM-654321")
var gtmKey = (`//div/input[@value='${existingGtmKey}']`)
var saveButton = (`input[type=submit][value='Save']`)
defineSupportCode(({ Given, Then, When }) => {
Given(/^I've logged into Winit cms$/, () => {
return client
.url('http://winit-stage.bauerpublishing.com/admin/sign_in')
.waitForElementVisible('body', 5000)
// Enter winit email address
.moveToElement(`form#new_administrator ${emailEntry}`, 1,1)
.click(`form#new_administrator ${emailEntry}`)
.setValue(`${emailEntry}`, "*****.*****@*****.co.uk")
// Enter winit password
.moveToElement(`form#new_administrator ${passwordEntry}`, 1,1)
.click(`form#new_administrator ${passwordEntry}`)
.setValue(`${passwordEntry}`, "******")
// Click on the 'Sign in' button
.click("form#new_administrator input[type=submit][value='Sign in']")
})
Then (/^I'm able to change the gtm tag for that site (.*?)$/,
(siteedit) => {
return client
// Click on the 'sites' link
.useXpath()
.click("//a[normalize-space(text())='Sites']")
// Click on Edit button
.click(siteedit)
.click(`${gtmKey}`)
.clearValue(`${gtmKey}`)
// Set new gtm key value
.setValue(`${gtmKey}`, `${newGtmKey}`)
// Click save
.useCss()
.click(`${saveButton}`)
})
})
。