2013-10-04 54 views
3

我有一個相當複雜的scons系統,包含多個子目錄,包含許多庫和可執行文件。目前,每個SConscript都有自己的克隆環境,所以我可以在每個SConscript的基礎上輕鬆地更改CFLAGS(或任何其他可修改的),但是我想改變它的每個目標,甚至每個目標文件目標。scons:更改單個源文件的編譯標誌

我創建了一個簡單的示例SConscript和SConstruct來解釋問題,如下所示。

SConstruct:

env = Environment() 
env['CFLAGS'] = '-O2' 
env.SConscript('SConscript', 'env') 

SConscript:

Import('env') 
env=env.Clone() 
env.Program('foo', ['foo.c', 'bar.c']) 

如果我運行scons的,無論是文件foo.c和bar.c具有-02標誌編譯。我可以通過在SConscript中添加env['CFLAGS'] = '...'來輕鬆更改SConscript範圍的標誌,但是讓我們假設我想用-O2編譯foo.c,但是bar.c完全調試,-O0 -g。我該怎麼做(以最簡單的方式)?

該示例使用gcc,但我希望可以與任何編譯器一起使用的東西。

這經常發生在性能敏感的項目中,在沒有優化的情況下編譯所有內容都會導致不可接受的性能,但需要調試一個單獨的文件(或其中的一個子集)。

回答

5

最簡單的一行答案可能只是用這個替換程序行:

env.Program('foo', ['foo.c', env.Object('bar.c', CFLAGS='-g')]) 

因爲程序可能需要爲對象節點以及源文件,並且您可以在任何構建器中覆蓋任何構造變量(這裏,我們在Object builder調用中覆蓋CFLAGS)。如果你想打出來的對象變成自己的線清晰:

debug_objs = env.Object('bar.c', CFLAGS='-g') 
env.Program('foo', ['foo.c', debug_objs]) 

當然採取任何的限制你得到一個系統,如Avatar33上面顯示的和。

+0

Thanks @GaryO,這是最簡單的解決方案,正是我一直在尋找的!對SConscript進行單行更改以添加一些標誌,暫時僅用於調試。不知何故,我無法在scons手冊中找到它,謝謝我馬上試試! – Daniele

+1

經過測試,工作,很簡單,正是我在找的,謝謝! – Daniele

+0

一個更有趣的問題是如何製作一個隨每個目標而變化的選項,例如,如果你想使用/ Fd {fname}選項來命名基於目標名稱的.pdb文件。 –

4

我想這在scons中比在使用調試標誌清理所需目標和重新構建時要困難得多。然後,它會重建一個特定的對象。

您的特定項目的解決方案取決於它的大小以及開發人員準備投入多少努力。 因此,這裏有一個粗略的解決方案,您可以在命令行上指定要使用調試進行編譯的源文件,沒有優化,其餘的將用-O2編譯。

在你SConsctruct一個額外的一線得到我們想從一個命令行選項調試編譯源文件:

env = Environment() 
    env['CFLAGS'] = '-O2' 
    AddOption('--debug-targets', dest='debug-targets', type='string') 
    env.SConscript('SConscript', 'env') 
在SConscript文件

現在:

Import('env') 
    env=env.Clone() 
    debug_env = env.Clone() 
    debug_env['CFLAGS'] = '-g -O0' 

    normal_src = ['foo.c', 'bar.c'] 
    debug_src = [] 

    #Add src specified via the command line to the debug build 
    if GetOption('debug-targets'): 
     for x in GetOption('debug-targets').split(','): 
      if x in normal_src: 
       normal_src.remove(x) 
       debug_src.append(x) 

    normal_obj = env.Object(normal_src) 
    debug_obj = debug_env.Object(debug_src) 
    all_obj = normal_obj + debug_obj 
    env.Program('foo', all_obj) 

運行我們scons與我們的調試目標標誌:

scons -Q  
    gcc -o bar.o -c -O2 bar.c 
    gcc -o foo.o -c -O2 foo.c 
    gcc -o foo foo.o bar.o 

但是現在我們要編譯吧。 c。與調試信息:

scons -Q --debug-targets=bar.c 
    gcc -o bar.o -c -g -O0 bar.c 
    gcc -o foo foo.o bar.o 

這樣增加了一點複雜性來構建系統,但如果你不需要從這樣的命令行指定調試目標,那麼開發人員可以很明顯只是削減和將過去的來自normal_src列表的源文件調試到debug_src。 很可能有許多方法來改進和微調這個特定環境

+2

儘管對於那些瞭解SCons的人來說可能很明顯,但是從命令行展示如何使用此解決方案將會有所幫助。 – Brady

+0

Thanks @ Avatar33,你的解決方案提供了很多想法,但我真的在尋找一些簡單的東西,我可以很容易地向我的同事解釋,那些對scons一無所知,幾乎不知道python(某些),如果他們需要調試特定文件。另外,我們的項目涉及很多庫和可執行文件,有些庫是針對不同的目標平臺(比如native和arm交叉編譯)構建的,所以只需從scons命令行指定一個源是不夠的。 – Daniele