从Android NDK清单文件中引用相对路径资源

3
我目前在包含NDK清单文件中的资源方面遇到了问题,我确定这只是一个快速修复错误。有很多文件在大型库中在项目和操作系统之间共享。因此,为了使文件与其他项目保持最新并避免每次更新时更新每个单独的项目的最新API,需要使用相对路径引用整个批量的本地头文件和源代码文件。

在Eclipse中,我已经通过拖动文件(而不是复制文件,而是使用相对路径)在项目中的本地文件夹结构中跨越所需的当前应用程序的文件。

/projectFolder /jni /externalProjectFiles /src /include

在Eclipse中,使用此文件夹结构,我有一个具有以下结构的Android.mk文件:

LOCAL_PATH := $(call my-dir)

include $(CLEAR_VARS)

LOCAL_MODULE := projectLib

LIBRARY_SRC_FOLDER   := $(wildcard $(LOCAL_PATH)/externalProjectFiles/src/*.cpp)

LOCAL_C_INCLUDES := $(LOCAL_PATH)/externalProjectFiles/include

LOCAL_SRC_FILES :=  projectLibNDK.c
LOCAL_SRC_FILES +=  $(LIBRARY_SRC_FOLDER:$(LOCAL_PATH)/%=%)

LOCAL_LDLIBS    := -L$(SYSROOT)/usr/lib -llog -landroid
LOCAL_CFLAGS    :=  -Wno-multichar -D_ANDROID -DLIBDIR="\"c\"" 
LOCAL_CFLAGS    +=  -DUSE_TCP_LOOPBACK -DMDNS_UDS_SERVERPATH=\"/var/run/mdnsd\" -DIN_LIBRARY -DBUILDING_LIBICONV -DUSE_BONJOUR 
LOCAL_CFLAGS    +=  -DXR_TARGET_ANDROID -DKS_BUILDING_KS -Wno-psabi -Wno-multichar -D_GNU_SOURCE -DHAVE_IPV6=0 -DNOT_HAVE_SA_LEN 
LOCAL_CFLAGS    +=  -DUSES_NETLINK -DHAVE_LINUX -DTARGET_OS_LINUX
LOCAL_CPPFLAGS  :=  -frtti -fexceptions

include $(BUILD_SHARED_LIBRARY)

然而,当我尝试在projectLibNDC.c中包含第一个头文件时,它会打印出“没有这样的文件或目录”的错误信息。 #include "externalFile.h" 我采取的方法是否可行? 我是否需要在Android.mk文件中提供文件的相对路径?这将比引用本地文件夹中的文件更麻烦。 理论上,通过NDK以这种方式创建库似乎是可行的。但是,也许我没有正确设置项目。任何帮助都将有所裨益;JNI有时会让我感到困惑。 编辑:似乎Eclipse(这是一个很棒的IDE)在其项目设置中与链接文件的引用之间没有任何联系。如果我将引用的文件拖入项目中,则不会将任何物理文件放入那些文件夹中,以表示链接文件的存在。显然,这些信息仅存储在项目设置中。这对于Android.mk文件并不有帮助。 这意味着任何脚本或makefile都没有任何参考信息来确定应该包含哪些文件。不幸的是,我必须从makefile本身单独引用文件和文件夹。我可能会在项目中留下引用,以提示其他程序员它们的存在。很遗憾我不能设计成这样,但这是我迄今为止得出的结论。

它在命令行中无法编译,使用“ndk-build”吗?Eclipse不会读取Android.mk文件,所以您可能需要直接将此库包含在Eclipse配置中... - JonasVautherin
它可以在ndk-build中编译。编辑中的评论所指的是,当我将链接资源添加到项目时,并不存在实际的“链接文件”。链接文件所在的文件夹在其物理位置上保持为空。这与XCode不同,例如正在构建类似的项目。实际上,在该位置存在一个物理链接文件。由于没有物理链接文件,因此ndk-build命令不可能从项目文件夹中获取有关这些文件的任何详细信息。 - Jay Snayder
所以你的问题是,你想在Eclipse中创建一个文件夹的引用,但是ndk-build无法编译,对吗?你不能在操作系统级别创建符号链接吗? - JonasVautherin
那是你刚才让我考虑的一个选项,感谢。如果你把它放在下面的回答中,我一定会点赞。然而,如果这样做确实有效,我相信它只能在Mac OSX上运行。如果我创建了链接文件以供引用(假设它确实有效),那么当有人在Windows机器上检出项目时,它很可能无法编译。理想情况下,该项目应该能够在不同的操作系统上编译。 - Jay Snayder
2个回答

2
最终,我决定采取的方法是逐个在 makefile 中包含文件的相对路径。虽然不是最清晰的解决方案,但它能够工作并为后续工作提供了一个良好的环境。
...
LOCAL_C_INCLUDES += $(COMMON_COMPUTATION_PATH)
LOCAL_C_INCLUDES += $(COMMON_DATASET_PATH)
...
LOCAL_SRC_FILES += $(COMMON_COMPUTATION_PATH)/matrixRT.cpp $(COMMON_COMPUTATION_PATH)/multiplRT.cpp
LOCAL_SRC_FILES += $(COMMON_COMPUTATION_PATH)/multiplSqRT.cpp $(COMMON_COMPUTATION_PATH)/multiplSq1978RT.cpp
...

从一个已经在iOS应用程序中链接了文件的先前库开始,我可以将这些资源拖到Eclipse项目中的本地文件夹中。然后从PROJ_LOC选择“链接到文件”。由于两个项目对于我将要使用的所有文件具有相同的相对路径,所以这个方法非常有效,并且使我免于寻找和拖动单个文件。
由于共享文件只是这些目录中所需文件的一部分,我不能仅通过创建一个包含通配符的源文件文件夹引用来完成。但是,我认为最好为移动软件请求一个组织文件夹结构,以便我们确实可以引用移动项目中所需的文件。
所以最终,我无法使用链接文件作为清单文件的引用。如果对您有用,user1368342已经提到可以创建一个操作系统级别的链接文件,并从清单文件中使用它。但是,出于跨多个操作系统平台的可移植性考虑,我决定不走这条路。
至少这种设置方式可以让用户看到正在构建的项目库中包含的链接文件。当文件更改并得到更新时,他们也可以在屏幕和清单中获得更新,并具有处理直接从项目中编译时出现的任何错误的能力。
缺点是当需要引入新文件时,需要将其添加到项目和清单中,而不是一个单独的位置。但是,这对我来说是可以接受的解决方案。希望其他遇到类似问题的人也会发现这种方法有用。

1

如评论中所提到的,我曾经也遇到过Eclipse引用问题。我在操作系统级别上使用了符号链接。

如果您使用符号链接对项目进行版本控制,可能会出现问题(但我认为仍然值得尝试)。在我的情况下,我有一个主要的项目被版本化(包含所有物理文件),而符号链接被用来编译一个没有被版本化的库。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接