解决JNI在Windows环境下因长路径导致编译失败问题

Posted 杰嗒嗒的阿杰

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了解决JNI在Windows环境下因长路径导致编译失败问题相关的知识,希望对你有一定的参考价值。

之前听一个朋友反馈LuaScriptoCore在Windows下编译会报错,今天特意跑到Windows环境下测试了一番,果然是存在问题。得到了下面的编译报错信息:

Build command failed.
Error while executing process C:\\Users\\vimfung\\AppData\\Local\\android\\Sdk\\ndk-bundle\\ndk-build.cmd with arguments NDK_PROJECT_PATH=null APP_BUILD_SCRIPT=C:\\Users\\vimfung\\Documents\\LuaScriptCore\\Source\\Unity3D\\Android\\luascriptcore-unity-android\\src\\main\\jni\\Android.mk APP_ABI=arm64-v8a NDK_ALL_ABIS=arm64-v8a NDK_DEBUG=1 APP_PLATFORM=android-21 NDK_OUT=C:/Users/vimfung/Documents/LuaScriptCore/Source/Unity3D/Android/luascriptcore-unity-android/build/intermediates/ndkBuild/debug/obj NDK_LIBS_OUT=C:\\Users\\vimfung\\Documents\\LuaScriptCore\\Source\\Unity3D\\Android\\luascriptcore-unity-android\\build\\intermediates\\ndkBuild\\debug\\lib APP_CPPFLAGS+=-frtti APP_CPPFLAGS+=-fexceptions APP_CPPFLAGS+=-std=gnu++11 APP_CPPFLAGS+=-Wno-format-contains-nul APP_CPPFLAGS+=-g APP_CPPFLAGS+=-Wno-deprecated-declarations APP_CPPFLAGS+=-fpermissive APP_STL=gnustl_static NDK_DEBUG=1 APP_PLATFORM=android-14 NDK_TOOLCHAIN_VERSION=4.9 C:/Users/vimfung/Documents/LuaScriptCore/Source/Unity3D/Android/luascriptcore-unity-android/build/intermediates/ndkBuild/debug/obj/local/arm64-v8a/libLuaScriptCore-Unity-Android.so
Android NDK: WARNING: Unsupported source file extensions in C:\\Users\\vimfung\\Documents\\LuaScriptCore\\Source\\Unity3D\\Android\\luascriptcore-unity-android\\src\\main\\jni\\Android.mk for module LuaScriptCore-Unity-Android
Android NDK: …/…/…/…/…/…/lua-core/src/lua.hpp
[arm64-v8a] Compile++ : LuaScriptCore-Unity-Android <= LuaScriptCoreForUnity.cpp
C:/Users/vimfung/Documents/LuaScriptCore/Source/Unity3D/Android/luascriptcore-unity-android/src/main/jni/…/…/…/…/…/UnityCommon/LuaScriptCoreForUnity.cpp:616:1: fatal error: opening dependency file C:/Users/vimfung/Documents/LuaScriptCore/Source/Unity3D/Android/luascriptcore-unity-android/build/intermediates/ndkBuild/debug/obj/local/arm64-v8a/objs-debug/LuaScriptCore-Unity-Android/C_/Users/vimfung/Documents/LuaScriptCore/Source/Unity3D/Android/luascriptcore-unity-android/src/main/jni//////UnityCommon/LuaScriptCoreForUnity.o.d: No such file or directory

^
compilation terminated.
make: *** [C:/Users/vimfung/Documents/LuaScriptCore/Source/Unity3D/Android/luascriptcore-unity-android/build/intermediates/ndkBuild/debug/obj/local/arm64-v8a/objs-debug/LuaScriptCore-Unity-Android/C_/Users/vimfung/Documents/LuaScriptCore/Source/Unity3D/Android/luascriptcore-unity-android/src/main/jni/
/////UnityCommon/LuaScriptCoreForUnity.o] Error 1

其中最重要的信息就是这段描述:

fatal error: opening dependency file C:/Users/vimfung/Documents/LuaScriptCore/Source/Unity3D/Android/luascriptcore-unity-android/build/intermediates/ndkBuild/debug/obj/local/arm64-v8a/objs-debug/LuaScriptCore-Unity-Android/C_/Users/vimfung/Documents/LuaScriptCore/Source/Unity3D/Android/luascriptcore-unity-android/src/main/jni/////__/UnityCommon/LuaScriptCoreForUnity.o.d: No such file or directory

意思是说没有找到对应的LuaScriptCoreForUnity.o.d文件。后来经过查找资料发现是因为Windows下如果你的路径超长,其实会导致编译失败,无法生成.o文件,因此就会出现无法找到的提示。

对于出现这种情况,可以尝试下面三种方案:

方案一:修改长路径文件

手动调整项目中的文件路径和文件名称来缩短编译的文件路径,让它在限制的长度以内。

不过这种方式不太适用于我的项目,主要因为我的项目是一款SDK,不能太随意地调整文件名称和目录结构。

方案二:Gradle编译设置

打开项目的build.gradle文件,在allprojects项下添加下面设置:

allprojects 

    if(org.gradle.internal.os.OperatingSystem.current().isWindows())
    
        //Windows下由于路径问题会导致编译报错,这里重新设置build路径
        buildDir = "C:/tmp/$rootProject.name/$project.name"
    

    repositories 
        jcenter()
        google()
    

该设置主要是判断当前环境是否为Windows,如果是则将编译目录设置到C:/tmp目录下。

这种方式跟方案一类似,但是不会调整编译文件的名字,但是能够改变编译输出的路径。经过尝试能够解决部分项目编译问题,但是对于一些项目路径较深的项目依然不适用。

方案三:调整Android.mk文件

该方式主要针对使用mk文件进行编译的项目,如果你的mk文件中设置的LOCAL_SRC_FILES项中每个编译文件都带有$(LOCAL_PATH)环境变量,那么可以将这个变量给移除调,再进行编译。

估计是因为JNI编译问题,编译产生的文件会根据你在mk文件中指定的路径来创建,如果你在mk文件中配置了$(LOCAL_PATH)/cpp/Test.cpp,那么,它会先对这个编译路径进行解析,假设文件就放在C:/project/sample/下,那么转换出来的路径就是C:/project/sample/cpp/Test.cpp,最终输出文件路径就会是C:/tmp/buildDir/C/project/sample/cpp/Test.o。这样无形中增加了三级目录,而这目录正是$(LOCAL_PATH)带来的。

所以移除后这个环境变量后项目就会以相对路径来查找编译文件,不会影响编译,同时也能够去除掉由于$(LOCAL_PATH)产生的多余目录路径。我的项目正好是使用Android.mk进行编译的,调整后编译正常,问题解决!

以上是关于解决JNI在Windows环境下因长路径导致编译失败问题的主要内容,如果未能解决你的问题,请参考以下文章

ADT+NDK搭建jni编译环境

clion编译jni,找不到jni.h的解决办法

java jni 怎么在windows环境中编译成linux下的so文件

未定义对“JNI_CreateJavaVM”窗口的引用

JNI_3

JNI调用之本地库文件的安装