【问题标题】:Eclipse CDT - how to use an argfile for the linker for a too long command lineEclipse CDT - 如何将 argfile 用于链接器的太长命令行
【发布时间】:2017-08-08 01:20:16
【问题描述】:

我在 Windows 7 上使用 Eclipse CDT 9 Neon 和 GCC 6.3 进行 STM32 项目。

我已经安装了 GNU ARM 插件并使用 sh.exe 进行长命令行管理(来自 Windows 的 cmd.exe 限制为 8192 个字符)来调用 make.exe(GNU Coreutils 日期:04.06.2009)。

我正在做一个大项目。

如果没有构建排除,我的链接器命令行超过 33 000 个字符,并在链接器命令行上生成错误。

通过构建排除和项目的精简版本,我已将链接器命令行减少到 15 600 个字符,编译工作正常,我的二进制文件可以运行。

首先,对于我的项目的完整版本,链接器命令行大于 20 000 个字符,并在 sh.exe 上生成 ACCESS VIOLATION。

使用其他版本的 sh.exe(来自 Microsemi IDE),我在 sh.exe 上不再存在访问违规问题,并且能够链接更多文件。

但是对于我的项目的完整版本,我有一个链接错误: make (e=87): 参数不正确。 此错误来自过长的命令行(超过 32 000 个字符)。

其他 IDE(带有 GCC 的 Winidea)使用一个参数文件,它结合了链接器文件 (.ld) 和 obj 文件列表,以具有非常短的链接器命令行。

如何在 Eclipse 中配置 GCC 以使用链接器的参数文件?

我找到了一个不完美但完全可操作的解决方案。我已经编写了一个 bat 文件来生成 obj 列表文件。 使用说明以实物为准。

我已经编写了文件“gen__link_ld.bat”:

echo off
rem ***************************************************************************
rem Generate script file for the linker to go throuth linker command line too
rem long trouble under windows (32 000 char max)
rem ***************************************************************************
rem Lunch in pre-build step is not advised, this commande is run in paralel
rem with build step that can temporarie supress obj file need to run 
rem compilation a 2nd time to have a script file up to date for the linker.
rem Run in pre-build step generate trouble in debug mode.
rem
rem Use manual lunch with 2 parameters :
rem create a .bat file per build with the folowing commande :
rem gen__link_ld.bat ./project relative path and .ld file name ./project relative build path
rem in linker commande line pattern replace {INPUT}
rem by -Xlinker --script=${ProjDirPath}/${ConfigName}/___link.ld
rem and add manualy librairie after ___link.ld, in this case library include
rem throuth graphical build setting don't work, they may use {INPUT} from the
rem standard commande
rem ***************************************************************************
echo **************************************************************************
echo *****************************                *****************************
echo *****************************     WARNING    *****************************
echo *****************************                *****************************
echo **************************************************************************
echo Generate script file for the linker to go throuth linker command line too
echo long trouble under windows (32 000 char max)
echo 
echo List only existing obj file.
echo The best way is to use manual lunch with one .bat file per build.
echo follow information in r e m above to use it.
echo
echo Run this commande evry time that obj liste is modified.
echo WARNING this function don't delete obj file for file recently exclude
echo frome build.
echo To secure the compilation need a clean to suppress all obj, run a first 
echo build witch compile all file without error (with only linker error) to
echo generate an obj file listing up to date and run a second buid for a 
echo successful linker step. When the OJB file listing is up to date, only 
echo eclipse build commande is needed
echo **************************************************************************
echo Linker file use : %1
echo Build path use : %2
echo **************************************************************************

setlocal ENABLEDELAYEDEXPANSION
set destination=%2
set destination=%destination:/=\%
rem *** Generate obj file listing ***
echo INPUT(>%destination%\___link.ld
dir %destination%\*.o /s /b >>%destination%\___link.ld
echo )>>%destination%\___link.ld

rem *** Concatenat obj file listing with ld file from parameter 1 ***
set str=%1
set str=%str:/=\%
type %str%>>%destination%\___link.ld
echo *** OBJ file listing up to date
echo **************************************************************************
pause

谢谢

【问题讨论】:

  • 显而易见的非解决方案是:与其链接到单个 .o 文件,不如从它们中创建一个静态库并链接到该文件。
  • 我觉得你非常需要需要像makecmake这样的工具。
  • 使用库编译我将失去调试工具。我可以选择我想调试的代码的女巫部分来管理我链接为 .o 的女巫部分和作为库的女巫部分,但它不是那么有用。
  • 您可以通过gcc 链接步骤ld 设置链接器命令文件的参数。然后将实际的链接器命令放在该链接器命令文件中。如果这对您不起作用,gcc 链接器步骤确实允许增量链接,但我对它不是很熟悉。

标签: c windows eclipse gcc linker


【解决方案1】:

这是我为这个问题找到的一个简单的解决方法(使用一个小的 python 脚本),其思路与将对象列表分离到另一个文件中的思路相同 - 请注意,这类文件称为 响应文件 在 GNU 世界中:https://gcc.gnu.org/wiki/Response_Files,它们分隔了整个命令行,而不仅仅是目标文件和库。

假设您使用的是 GNU Make builder+GNU 链接器:

  • 您需要创建一个 python 脚本并将其放置在项目中的某个位置,我假设脚本的路径是 build/link_with_rsp_file.py。将以下内容放入其中。
  • 转到项目属性 -> C/C++ 构建 -> 设置。确保选择了适当的构建配置。您应该在那里找到工具链设置。
  • 选择链接器项。根据您的构建配置,您应该有一个命令/命令行模式对,例如 g++/${COMMAND} ${FLAGS} ${OUTPUT_FLAG} ${OUTPUT_PREFIX}${OUTPUT} ${输入}。我们假设它看起来像这样,并进行相应的调整。
  • 将命令行模式更改为 @$(file >linkcl.rsp,${FLAGS} ${OUTPUT_FLAG} ${OUTPUT_PREFIX}${OUTPUT} ${INPUTS})python ../build/link_with_rsp_file .py linkcl.rsp ${COMMAND}。这有效地告诉 GNU make 获取所有链接器参数,将它们放入响应文件 linkcl.rsp(使用 $(file) 函数),然后使用生成的响应文件运行链接器(${COMMAND})。

Python 脚本:

import sys, subprocess

def cmd_exec(full_cmd):
    print(full_cmd)
    sys.stdout.flush(); sys.stderr.flush()
    p = subprocess.Popen(full_cmd.split(' '))
    p.communicate()
    return p.returncode == 0

rsp_file, cmd = sys.argv[1], sys.argv[2:]
cmd = ' '.join(cmd)

# First replace all '\' with '/' in the response file (bash doesn't deal well with '\')
with open(rsp_file, "r") as f: linkcl = f.read()
linkcl = linkcl.replace('\\', '/')
with open(rsp_file, "w") as f: f.write(linkcl)

# Call the linker
cmd_exec("{cmd} @{rsp_file}".format(cmd=cmd, rsp_file=rsp_file))

【讨论】:

    猜你喜欢
    • 2023-03-28
    • 2011-12-26
    • 2011-01-13
    • 2012-01-13
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2018-11-25
    相关资源
    最近更新 更多