2013-03-06 45 views
3

others我有超过Windows的CMD线限制的链接线scons的链接时,使用响应文件。对于大多数情况,我们通过用对象文件的子集构建中间档案库(也称为静态库)并用这些档案执行最终链接来解决问题。但是,在Google Test中使用此策略会导致找不到测试,尤其是在归档的对象文件中定义的测试。链接命令行太长:如何在Windows

更新:This is why。我可能会使用这种解决方法,但我仍然想了解如何使响应文件在scons下工作。

LongCmdLinesOnWin32解决方法是有问题的。我们有一个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 

我使用scons的v2.1.0.r5357,VS 2008和python 2.7在Windows 7-64

我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规则足以导致悲伤。

+0

您能否提供SCons的完整输出。 – Brady 2013-03-07 07:37:55

+0

嗯,这是巨大的,我不认为它比我上面给出的片段更具信息性 - 只是有一长串的对象名称。 – TheDuke 2013-03-08 02:09:25

回答

1

我试图用gcc重现这个在Linux和跨不同的问题,其解决方案可以帮助来了。

本来,我用这个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()函数。

+0

是的,我也遇到了这个问题,但解决方法不同 - 抱歉,应该提到它。我不是使用源文件作为响应文件的输入,而是首先生成一个对象列表(如在obj_list = env.Object(src_list)中)。env.Object将依赖关系公开给scons并确保它们生成。 – TheDuke 2013-03-08 02:04:00

+0

有趣:gcc似乎没有问题。 – TheDuke 2013-03-08 06:57:07