2013-03-06 46 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