十年网站开发经验 + 多家企业客户 + 靠谱的建站团队
量身定制 + 运营维护+专业推广+无忧售后,网站问题一站解决
最近下载同事的 Android 工程代码,协作开发一些 Native 底层功能,需要首先编译底层的一些 JNI 的代码库,由于工程较大,且依赖的第三方库比较多,下载完毕后,通过 ndk-build 进行编译,报了一些个奇怪的错误,并指向了代码文件的最后一行,如下所示:
兴宾ssl适用于网站、小程序/APP、API接口等需要进行数据传输应用场景,ssl证书未来市场广阔!成为创新互联公司的ssl证书销售渠道,可以享受市场价格4-6折优惠!如果有意向欢迎电话联系或者加微信:18980820575(备注:SSL证书合作)期待与您的合作!
fatal error: error writing to -: Invalid argument } ^
此工程源码一直是同事在 MAC 下进行开发维护的,在同事的环境中是正常的,而我是 Windows 平台,刚开始怀疑是文件类型不对,通过 NotePad++ 转换代码文件格式为 UNIX ,编译测试失败;通过 msys 的 VI 编辑器新建文件复制此代码文件内容并保存为新的文件,经测试也是不行,至此判断应该不是文件格式的问题了。
通过 Google 查找此错误信息,资料甚少,只有一个有用的信息,说是文件路径名太长了,改短一点就行了,我们知道 Windows 系统对路径的最大长度限定为 260 字节,但是我查看我们的文件全路径总长度也就才 130 几个字节,尚未查过最大长度,但通过简单的尝试,如仅仅是缩短了文件名长度,进行编译,最后发现还是有些效果的,至少大部分 native 代码文件不会再报此类错误了,但是不幸的,NDK 编译的四个 ABI 架构(armeabi、armeabi-v7a、arm64-v7a、x86),前三个 ABI 都是可以编译成功的,唯独最后一个仍然会报上述错误,而且报错的只会是 LOCAL_SRC_FILES 指向的第一个代码文件,调整代码文件顺序依旧,这就说明了这种编译错误应该是与 Android.mk 文件有关了,而此 mk 文件在同事的 MAC 上运行一切正常,唯独到我的 Windows 上运行出现各种错误,针对此问题,看来还是上述方法中通过简单的缩短代码文件名的方法并没有从根本上解决问题,通过仔细查看 ndk-build 编译过程中输出的日志信息,发现其生成的代码中间文件 *.o 存储在 objs 的很深的目录,是吧我代码文件的全局路又复制了一遍,通过 Windows 的快捷键去复制、粘贴 这样的文件夹,系统就会报错,提示路径长度太长,至此,我似乎看到一丝希望。
原来同事为了保证大家下载编译这个工程目录能够统一,在代码文件前定义了一个宏变量,如:
ENCODER_MODULE_PATH := $(TOP_LOCAL_PATH)/encoder-module
然后在引用指定代码文件列表的时候,加上了此宏变量作为前缀,如:
LOCAL_SRC_FILES += $(ENCODER_MODULE_PATH)/video_encoder.c
这样就相当于给此文件制定了一个绝对路径了,由于代码所在目录本来就很深,这样相当于在 obj 中间文件目录中重复了一遍源文件的目录,导致整体路径长度超过了 260 字节,从而报出此类奇葩的错误,而 Linux 下系统对目录的最大长度限制默认为 4096,怪不得同事的 MAC 系统不报错。好的,原因知道了,修改源文件列表中由绝对路径改为相对路径就可以了,如:
LOCAL_SRC_FILES += ./video_encoder.c
至此,大功告成,编译成功!