赞others我有一个超过 Windows cmd 行限制的链接行。对于大多数情况,我们已经通过使用目标文件的子集构建中间文件(又名静态库)并与这些文件执行最终链接来解决问题。然而,将此策略与 Google Test 一起使用会导致找不到测试,特别是在存档的目标文件中定义的测试。
更新:This is why .我可能会使用这个解决方法,但我仍然想了解如何使响应文件在 scons 下工作。
LongCmdLinesOnWin32 fix 是有问题的。我们有一个 cygwin 环境和包含空格的路径名,因此一些编译器绝对路径包含引号。 LongCmdLinesOnWin32 中的脚本首先需要扩展以处理嵌入的引号和空格(否则它会创建单个路径名的单独标记)。更严重的是,当使用 MS Visual Studio 时,编译器命令只是“cl”,即不包含路径名。这在 PATH 环境中不可用——它似乎是动态设置的(以某种方式)并且在构造 LongCmdLinesOnWin32 脚本的 cmdline 参数时不可见。但我离题了....
似乎有一个更简单(并且在我看来合适)的解决方案:response files , 这也是 supported by gcc .
我写了一个小函数来获取对象名称列表并将它们打印到一个文本文件中,一个到一行,例如:
"""
In place for generating response files
"""
def gen_response_file(filename,file_list):
with open(filename,"w") as f:
for obj_name in file_list:
f.write ('%s\n' %os.path.abspath(str(obj_name)).replace('\\','/'))
return filename
然后我尝试在文件名前加上“@”字符并将其添加到选项列表中。
回显的命令行是:
link /nologo /MACHINE:x86 /DEBUG @E:\dev\pcoip_view_client\soft_test.rsp /OUT:blah_client\blah_client_tests.exe /LIBPATH:\\sterbkp03\qt\4.8.2\lib ....
如果我只是将文件命名为“soft_test”,那么 scons 会添加后缀“.obj”,而链接器找不到它,因此我尝试添加后缀“.rsp”。现在,链接器提示找不到该文件,但它存在。我捕获了 scons 的输出并将其粘贴到一个 bat 文件中。当我运行 bat 文件(从 VS 2008 命令行 env)时,链接就像一个魅力,所以看起来 scons 在某种程度上导致了查找文件的问题
我尝试更改路径,使用绝对路径 (@C:\blah\soft_test.rsp)、相对路径 (@.\soft_test.rsp) 和 @soft_test.rsp,但均无效。
LINK : fatal error LNK1104: cannot open file '@E:\dev\swift.dev\blah_client\soft_test.rsp'
scons: *** [blah_client\blah_client_tests.exe] Error 1104
我在 Windows 7-64 下使用 scons v2.1.0.r5357、VS 2008 和 python 2.7
我的 scons 文件如下所示:
test_objects = tenv.Object(test_sources)
xx = gen_response_file('soft_test.rsp',test_objects)
tenv.Append( LINKFLAGS = [ '@%s' % os.path.abspath(xx)]) #
test_exe = tenv.Program(target = 'blah_client_tests', source = objects + moc_objects + qrc_objects )
非常感谢任何建议。
更新:我尝试使用 gcc,没有问题。我的猜测是,与 Visual Studio 工具关联的 scons 规则在某种程度上是不同的,足以引起悲伤。
最佳答案
我尝试在 Linux 中使用 gcc 重现此问题,但遇到了一个不同的问题,其解决方案可能会有所帮助。
最初,我使用这个 SConscript:
import os
"""
In place for generating response files
"""
def gen_response_file(filename,file_list):
with open(filename,"w") as f:
for obj_name in file_list:
f.write ('%s\n' %os.path.abspath(str(obj_name)).replace('\\','/'))
return filename
env = Environment()
test_objects = env.Object(target = 'testClass', source = 'testClass.cc')
resp_file = gen_response_file('response_file.rsp', test_objects)
env.Append(LINKFLAGS = [ '@%s' % os.path.abspath(resp_file)])
env.Program(target = 'helloWorld', source = 'helloWorld.cc')
下面是我使用的相关源文件:
# tree .
.
|-- SConstruct
|-- helloWorld.cc
|-- testClass.cc
`-- testClass.h
其中helloWorld.cc
是主程序。 helloWorld.cc
包括 testClass.h
和 testClass.o
中的链接 当我尝试编译它时,正确生成了响应文件(仅包含/some/path/testClass.o
) 并由编译器读取。我遇到的问题是 testClass.o
没有编译,因为 SCons 似乎无法识别响应文件中列出的对象的依赖关系。这是结果:
# scons
scons: Reading SConscript files ...
scons: done reading SConscript files.
scons: Building targets ...
g++ -o helloWorld.o -c helloWorld.cc
g++ -o helloWorld @/some/path/response_file.rsp helloWorld.o
g++: /some/path/testClass.o: No such file or directory
scons: *** [helloWorld] Error 1
scons: building terminated because of errors.
这似乎是 SCons 中的一个失败,因为它没有分析响应文件。为了解决这个问题,我不得不使用 Depends()
函数,如下摘录:
...
bin = env.Program(target = 'helloWorld', source = 'helloWorld.cc')
env.Depends(bin, test_objects)
这有效并给了我以下内容:
# scons
scons: Reading SConscript files ...
scons: done reading SConscript files.
scons: Building targets ...
g++ -o helloWorld.o -c helloWorld.cc
g++ -o testClass.o -c testClass.cc
g++ -o helloWorld @/some/path/response_file.rsp helloWorld.o
scons: done building targets.
我知道这并没有回答关于为什么找不到响应文件的原始问题,但是一旦你解决了这个问题,你很可能会遇到上面提到的问题,并且必须使用 Depends()
函数。
关于windows - 链接命令行太长 : how to use response files when linking in scons on windows,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/15242177/