由于截断文件名 and/or 无法找到定义,MinGW C++ 链接器无法找到文件
MinGW C++ Linker unable to find file due to truncating filename and/or unable to find definitions
我遇到了一个非常奇怪的 linker 问题,它在不同的场景中以不同的方式表现出来。不幸的是,我不能分享任何来源,所以这是一个有点远的目标,但我缺乏追踪它的想法。
我正在尝试为我们的项目构建单元测试,该项目将 运行 在 Windows 环境中(因此不包括硬件相关功能)。我们还构建相同的单元测试,以便它们将 运行 在我们的目标 (Renesas PK-S5D9) 上,因此使用不同的编译器,并且它是成功的。请注意,我们使用的是 gtest,它作为源而不是库包含在内。此构建中没有涉及库,只有源代码。
场景:
- 一个分支正在处理工作。 Develop 已更新,因此开发人员合并到新的 HEAD 中。这样做后,一个不相关的测试开始失败 link;我们将测试称为 ATest.cpp 并将产品来源称为 A.cpp/h。 linker 抱怨在 A.h 中声明并由 ATest.cpp 使用的函数未定义,但是,A.cpp 的构建成功,.o 存在于预期位置, .o 列在 linking 命令中。
- 我接管了分支的负责人并排除了合并从 develop 带来的文件(一个 class 和一个测试)并得到了一个不同的错误。前一行的末尾包含文件“./product/adapters/ActionableProvider.o”,当 g++ 尝试访问它时,它看起来会被 t运行 处理:
- 我从分支中获取了开发和零碎添加的内容(一些更改和一个新的 class 测试)。当我快完成时,我得到了与场景2中列出的类似的错误。我尝试注释掉class中实现的功能的所有内容,并且t运行cation减少了:
增加怪异的东西:
当 运行ning 使用相同的工具集但在我们的构建服务器上(略有不同 Windows 10 构建并且也没有重反时,开发人员观察到失败的提交不会失败-病毒,因为它在我们的内部网络中被隔离了)。
欢迎提出更多尝试拼凑这个谜团的想法!
顿悟了。这是一个命令长度限制问题。显然 Windows 只能处理命令中的 8192 个字符,因此文件名被截断了。这是一个参考:https://mcuoneclipse.com/2015/03/29/solving-the-8192-character-command-line-limit-on-windows/
我们最终的解决方案是修改我们在 e2studio (eclipse) 中的链接器命令:
${COMMAND} ${FLAGS} ${OUTPUT_FLAG} ${OUTPUT_PREFIX}${OUTPUT} ${INPUTS}
至:
@$(file >link_cmd.in,${FLAGS} ${OUTPUT_FLAG} ${OUTPUT_PREFIX}${OUTPUT} ${INPUTS}) ${COMMAND} @"link_cmd.in"
旅程中的步骤包括列出可能的解决方案(如果我们能弄清楚如何实施它们就好了:)):
- 缩短路径
- 建立图书馆
- 弄清楚如何让 eclipse 在另一个没有这个问题的 shell 中构建 test_desktop
- 弄清楚如何让 eclipse 使链接器命令使用文件(请参阅 https://linux.die.net/man/1/g++ 中的@file 选项)
我们赞成最后一个解决方案,但我们只是意识到它是因为我们的目标特定单元测试就是这样规避问题的。通过一些搜索,我们找到了 https://www.eclipse.org/forums/index.php/t/369721/ where the last post was someone indicating they posted a workaround to the bug https://bugs.eclipse.org/bugs/show_bug.cgi?id=72965。非常感谢 Corneliu Zuzu!!
经过一些初步评估,我们意识到我们只需要使用类似的机制将命令转储到一个文件(似乎 Corneliu Zuzu 有一个更具挑战性的问题,包括反斜杠?)。因此,上述解决方案。
我遇到了一个非常奇怪的 linker 问题,它在不同的场景中以不同的方式表现出来。不幸的是,我不能分享任何来源,所以这是一个有点远的目标,但我缺乏追踪它的想法。
我正在尝试为我们的项目构建单元测试,该项目将 运行 在 Windows 环境中(因此不包括硬件相关功能)。我们还构建相同的单元测试,以便它们将 运行 在我们的目标 (Renesas PK-S5D9) 上,因此使用不同的编译器,并且它是成功的。请注意,我们使用的是 gtest,它作为源而不是库包含在内。此构建中没有涉及库,只有源代码。
场景:
- 一个分支正在处理工作。 Develop 已更新,因此开发人员合并到新的 HEAD 中。这样做后,一个不相关的测试开始失败 link;我们将测试称为 ATest.cpp 并将产品来源称为 A.cpp/h。 linker 抱怨在 A.h 中声明并由 ATest.cpp 使用的函数未定义,但是,A.cpp 的构建成功,.o 存在于预期位置, .o 列在 linking 命令中。
- 我接管了分支的负责人并排除了合并从 develop 带来的文件(一个 class 和一个测试)并得到了一个不同的错误。前一行的末尾包含文件“./product/adapters/ActionableProvider.o”,当 g++ 尝试访问它时,它看起来会被 t运行 处理:
- 我从分支中获取了开发和零碎添加的内容(一些更改和一个新的 class 测试)。当我快完成时,我得到了与场景2中列出的类似的错误。我尝试注释掉class中实现的功能的所有内容,并且t运行cation减少了:
增加怪异的东西:
当 运行ning 使用相同的工具集但在我们的构建服务器上(略有不同 Windows 10 构建并且也没有重反时,开发人员观察到失败的提交不会失败-病毒,因为它在我们的内部网络中被隔离了)。
欢迎提出更多尝试拼凑这个谜团的想法!
顿悟了。这是一个命令长度限制问题。显然 Windows 只能处理命令中的 8192 个字符,因此文件名被截断了。这是一个参考:https://mcuoneclipse.com/2015/03/29/solving-the-8192-character-command-line-limit-on-windows/
我们最终的解决方案是修改我们在 e2studio (eclipse) 中的链接器命令:
${COMMAND} ${FLAGS} ${OUTPUT_FLAG} ${OUTPUT_PREFIX}${OUTPUT} ${INPUTS}
至:
@$(file >link_cmd.in,${FLAGS} ${OUTPUT_FLAG} ${OUTPUT_PREFIX}${OUTPUT} ${INPUTS}) ${COMMAND} @"link_cmd.in"
旅程中的步骤包括列出可能的解决方案(如果我们能弄清楚如何实施它们就好了:)):
- 缩短路径
- 建立图书馆
- 弄清楚如何让 eclipse 在另一个没有这个问题的 shell 中构建 test_desktop
- 弄清楚如何让 eclipse 使链接器命令使用文件(请参阅 https://linux.die.net/man/1/g++ 中的@file 选项)
我们赞成最后一个解决方案,但我们只是意识到它是因为我们的目标特定单元测试就是这样规避问题的。通过一些搜索,我们找到了 https://www.eclipse.org/forums/index.php/t/369721/ where the last post was someone indicating they posted a workaround to the bug https://bugs.eclipse.org/bugs/show_bug.cgi?id=72965。非常感谢 Corneliu Zuzu!! 经过一些初步评估,我们意识到我们只需要使用类似的机制将命令转储到一个文件(似乎 Corneliu Zuzu 有一个更具挑战性的问题,包括反斜杠?)。因此,上述解决方案。