rt-thread icon indicating copy to clipboard operation
rt-thread copied to clipboard

scons Windows 平台编译报错(文件路径太长)规避办法

Open BreederBai opened this issue 2 years ago • 10 comments

报错内容:

arm-none-eabi-g++: fatal error: cannot execute'c:/programfiles/env-windows-v1.3.2/tools/gnu_gcc/armgcc/mingw/bin/../lib/gcc/arm-none-eabi/10.3.1/collect2.exe: CreateProcess: No such file or directory fbf81c80b8cbfdb8162308603d7d961

原因:

链接时参数(.o文件集合)长度超过windows限制的最大长度。CreateProcess WINAPI函数,它接受参数的最大长度是32767个字符。因为代码保存的路径比较深,编译的文件又比较多,导致在链接的时候长度超过了32767 image

解决办法

  • 缩短文件路径
  • 分模块编译

第一种,比较简单的做法就是给代码库换个存储位置,但这样做不太优雅,而且别人也很容易再遇到相同问题。所以我使用了另一种方式,把编译生成的.o文件统一放到一个文件夹下面来缩短路径。这个方式需要更改的地方并不多,具体如下: image 通过下图可以看出,编译时的路径,明显缩短了很多,而且不再受代码库存储位置的影响。当然这种方式如果文件很多,还是会出现问题,目前对于我的应用(编译二三百个文件)来说是够了。如果这个方法不能满足您的需求,那有可能得用第二种方法了。 image

很抱歉,第二种方法我还没搞明白该怎么弄,,,

BreederBai avatar Oct 28 '22 15:10 BreederBai

分模块编译

@BreederBai 就是把一些功能模块打包成 lib 文件, 链接的时候直接链接 lib 就可以了。

a1012112796 avatar Nov 15 '22 08:11 a1012112796

分模块编译

@BreederBai 就是把一些功能模块打包成 lib 文件, 链接的时候直接链接 lib 就可以了。

RTT中有这样的例子吗?

BreederBai avatar Nov 16 '22 02:11 BreederBai

这些整体上是比较困扰的,有几种方式, ①、编译库方式,可以类似 scons --buildlib=Finsh方式来对一个group进行打包; ②、可以把命令行参数放入到文件中,然后通过@接文件的方式编译。

不过上述两种方式有的时候都会存在一定问题,例如编译成.a后,导出的shell命令会丢失。

BernardXiong avatar Nov 18 '22 08:11 BernardXiong

这些整体上是比较困扰的,有几种方式, ①、编译库方式,可以类似 scons --buildlib=Finsh方式来对一个group进行打包; ②、可以把命令行参数放入到文件中,然后通过@接文件的方式编译。

不过上述两种方式有的时候都会存在一定问题,例如编译成.a后,导出的shell命令会丢失。

shell命令丢失,没有办法解决吗?

BreederBai avatar Nov 19 '22 03:11 BreederBai

@BernardXiong 熊大,scons --buildlib=Finsh会生成一个.a文件,但如何链接这个.a文件呢?我的工程中有几个子模块,使用打包的方式是个不错的选择。有没有什么命令可以自动打包指定的文件,并链接

BreederBai avatar Nov 19 '22 03:11 BreederBai

这个问题可以问论坛 我记着论坛里好像有人问过

mysterywolf avatar Nov 19 '22 05:11 mysterywolf

@BreederBai DefineGroup 有两个可选参数 LIBSLIBPATH 用来指定 lib 名称和lib 所在路径。 https://www.rt-thread.org/document/site/#/development-tools/build-config-system/SCons?id=_56-%e6%b7%bb%e5%8a%a0%e5%ba%93

a1012112796 avatar Nov 20 '22 00:11 a1012112796

以前有生成了.a,后面build的时候就自动使用这个.a,然后大家怕莫名被链接到这个.a,然后就把这个功能给取消掉了 :cry:

BernardXiong avatar Nov 20 '22 01:11 BernardXiong

这些整体上是比较困扰的,有几种方式, ①、编译库方式,可以类似 scons --buildlib=Finsh方式来对一个group进行打包; ②、可以把命令行参数放入到文件中,然后通过@接文件的方式编译。

不过上述两种方式有的时候都会存在一定问题,例如编译成.a后,导出的shell命令会丢失。

据我所知使用 ld -r 命令可以把多个 .o 生成一个 .o。不知道这样是否可以 避免shell命令丢失的问题

yuqingli05 avatar Dec 17 '22 15:12 yuqingli05

这些整体上是比较困扰的,有几种方式, ①、编译库方式,可以类似 scons --buildlib=Finsh方式来对一个group进行打包; ②、可以把命令行参数放入到文件中,然后通过@接文件的方式编译。

不过上述两种方式有的时候都会存在一定问题,例如编译成.a后,导出的shell命令会丢失。

这些整体上是比较困扰的,有几种方式, ①、编译库方式,可以类似 scons --buildlib=Finsh方式来对一个group进行打包; ②、可以把命令行参数放入到文件中,然后通过@接文件的方式编译。 不过上述两种方式有的时候都会存在一定问题,例如编译成.a后,导出的shell命令会丢失。

shell命令丢失,没有办法解决吗?

经过测试 gcc平台 使用 ld -r 命名把多个 .o 合并生成一个 .o 不会导致shell命令丢失。我在 qemu-vexpress-a9 bsp测试通过

测试结果 image

测试源码目录结构 image

测试源码压缩包下载地址 https://github.com/yuqingli05/rt-thread/blob/master/bsp/qemu-vexpress-a9/applications/test.rar

yuqingli05 avatar Dec 17 '22 17:12 yuqingli05

可以参考下这个方法,应该是完美解决方案

https://club.rt-thread.org/ask/article/38b4829d043d3215.html

enkiller avatar May 13 '23 15:05 enkiller

ref https://github.com/SCons/scons/issues/800

a1012112796 avatar May 15 '23 03:05 a1012112796