3

他のと同様に、Windows コマンド行の制限を超えるリンク行があります。ほとんどの場合、オブジェクト ファイルのサブセットを使用して中間アーカイブ (別名静的ライブラリ) を構築し、それらのアーカイブとの最終的なリンクを実行することで問題を解決しました。ただし、Google Test でこの戦略を使用すると、テスト、特にアーカイブされたオブジェクト ファイルで定義されたテストが見つからなくなります。

更新:これが理由です。おそらくこの回避策を使用しますが、scons の下で応答ファイルを機能させる方法を理解したいと思っています。

LongCmdLinesOnWin32の修正には問題があります。cygwin 環境とスペースを含むパス名があるため、一部のコンパイラの絶対パスには引用符が含まれます。最初に、LongCmdLinesOnWin32 のスクリプトを拡張して、埋め込まれた引用符とスペースの両方を処理する必要があります (そうしないと、単一のパス名の個別のトークンが作成されます)。さらに深刻なことに、MS Visual Studio を使用している場合、コンパイラ コマンドは単に 'cl' であり、パス名が含まれていません。これは PATH 環境では使用できません。LongCmdLinesOnWin32 スクリプトへの cmdline 引数を作成するときに、(何らかの方法で) 動的に設定され、表示されないように見えます。しかし、私は脱線します....

はるかに単純な (そして私の目には適切な) 解決策があるようです: response filesgcc でサポートされています。

オブジェクト名のリストを取得し、それらを 1 行に 1 つずつテキスト ファイルに出力する、次のような小さな関数を作成しました。

"""
  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 ファイルに貼り付けました。(VS 2008コマンドライン環境から)batファイルを実行したとき、リンクは魅力的に機能したので、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 ルールは、何らかの形で、悲しみを引き起こすほど異なっていると思います。

4

1 に答える 1

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) 、コンパイラによって読み取られました。私が遭遇した問題は、SCons が応答ファイルにリストされているオブジェクトとの依存関係を認識していないように見えるため、コンパイルされていないことでした。結果は次のとおりです。testClass.htestClass.o/some/path/testClass.otestClass.o

# 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()関数を使用する必要があります。

于 2013-03-07T07:36:58.987 に答える