2014-07-22 51 views
0

我有一個生成一些包的別名,名爲'build_packages'。但是,除非在其之前構建了特定的代碼轉換器庫,否則該別名不會生成:'transcoderLib''transcoderLib'也是一個別名,它本身就很好。我試圖指定我的別名依賴像這樣:如何指定scons別名依賴關係?

env.Alias('transcoderLib') 
... 
Default(env.Alias('build_packages')) 
Depends('build_packages', 'transcoderLib') 

如果我再建'build_packages''transcoderLib'完全不建成並構建失敗,因爲'build_packages'依賴於它。爲什麼scons不會提取依賴關係?

更多信息:在我聲明這兩個別名的時候,他們都沒有任何目標,它們只是空的別名,後來由SConscript填充。我預計Depends('build_packages', 'transcoderLib')定義從'build_packages''transcoderLib'的依賴關係,以便首先構建'transcoderLib',然後構建'build_packages'

編輯:添加到這個困惑,我發現,當我用scons --tree=derived,prune,它打印出'build_packages'所有正確的依賴關係!如果它看到依賴關係,爲什麼不構建它們?這裏是構建樹本身(修剪當然,新發展區和這樣):

+-build_packages 
    +-Build\Config\Package_1 
    | +-Package_1_Dependencies... 
    +-Build\Config\Package_2 
    | +-Package_2_Dependencies... 
    ...etc... for 16+ packages... 
    +-transcoderLib 
    +-Build\Transcoder.dll 
    | +-DLL dependencies... 
    +-Build\Transcoder.lib 
    | +-LIB dependencies 
    +-Build\Transcoder.exp 
    | +-EXP depdendencies 
    +-Lib\Python\Transcoder.pyd 
     +-[Build\Transcoder.dll] 
     +-[Build\Transcoder.lib] 
     +-[Build\Transcoder.exp] 

編輯3:爲客戶提供更完整的示例,我已經安排了簡單的SConstruct是模擬了我相當出色的情況(我刪除編輯2中的前一個例子以避免混淆)。真正的問題是一個Python文件正在導入'transcoderLib'目標,所以scons甚至不知道它需要在構建軟件包之前構建庫。我試圖告訴scons這是必要的。下面是簡單的例子:

import SCons 
import shutil 
import os 

env = Environment(tools=['default', 'textfile']) 

def package_builder(target, source, env): 
    cmdLine = 'python test.py' 
    return os.system(cmdLine) 

def copy(env, target, source): 
    shutil.copy(source[0].path, target[0].path) 
env.Append(BUILDERS = { 'copybuilder' : Builder(action = Action(copy, ' COPY $SOURCE -> $TARGET')) }) 
env.Append(BUILDERS = { 'package' : Builder(action = Action(package_builder, ' PACKAGE $SOURCES -> $TARGET'), suffix='.zip') }) 

env.Textfile(target='foo.txt', source='hello, world\n') 

config = int(ARGUMENTS.get('config', 0)) 
if config == 1: 
    Default(env.Alias('build_packages')) 
    Depends(env.Alias('build_packages'), env.Alias('transcoderLib')) 

env.Alias('transcoderLib', 'foo.txt') 
copyTarget = env.copybuilder('bar.txt', 'foo.txt') 
env.Alias('transcoderLib', copyTarget) 

package = env.package('#Test', []) 
env.Alias('build_packages', package) 

當然test.py,這是一個非常簡單的腳本,取決於跳回到bar.txt,「transcoderLib」的目標和:

import os 
if not os.path.exists('bar.txt'): 
    raise Exception("bar.txt wasn't created yet!") 

和輸出:


scons: warning: Support for pre-2.7.0 Python version (2.6.2) is deprecated. 
    If this will cause hardship, contact [email protected] 
File "C:\Python26\Scripts\scons.py", line 192, in 
scons: Building targets ... 
PACKAGE -> Test.zip 
Traceback (most recent call last): 
    File "test.py", line 3, in 
    raise Exception("bar.txt wasn't created yet!") 
Exception: bar.txt wasn't created yet! 
scons: *** [Test.zip] Error 1 

當然,如果我scons的transcoderLib「第一,它建立 '跳回到bar.txt' 就好了,我可以運行沒有錯誤 'scons的配置= 1'。對於那些想知道爲什麼我使用沒有任何源代碼或目標的構建器的人來說,這是爲了讓我的示例儘可能簡單。 '包'構建器應該運行'test.py'(實際上,它也構建了包,但包的依賴與'transcoderLib'完全隔離)。

+0

你能提供一個簡短的,完整的SConstruct失敗的例子嗎? [我的嘗試](http://ideone.com/jFREtj)完全按照您的預期工作。請參閱http://stackoverflow.com/help/mcve –

+0

@Robᵩ我已經爲SConstruct發佈了上面的代碼,但仍然失敗。我想你的例子也會失敗,如果你真的在'build_packages'別名中構建了一些東西。最終,'transcoderLib'會以我複雜的示例構建,但重點是需要首先構建它。 – Darkhydro

+0

您的示例具有誤導性,因爲您沒有定義/用於實際創建目標「build_packages」的Builder。請注意,在SCons中,隱式依賴(如foo.h頭文件)被添加到構建的目標(在這種情況下爲foo.o)。只是簡單地定義一個別名,而不是一個依賴項,就不會這樣做......如果你關心從庫中構建的簡單模塊和程序(=你的包?),你所要做的就是指定那些libnames和-paths通過LIBS和LIBPATH變量(檢查SCons出色的UserGuide)正確運行,而且應該可以立即使用。 – dirkbaechle

回答

3

你設置錯誤的依賴關係,如果我正確理解你想要實現的。我試圖修改從上面編輯3您SConstruct,具體如下:

import SCons 
import shutil 
import os 

env = Environment(tools=['default', 'textfile']) 

def package_builder(target, source, env): 
    cmdLine = 'python test.py' 
    return os.system(cmdLine) 

def copy(env, target, source): 
    shutil.copy(source[0].path, target[0].path) 
env.Append(BUILDERS = { 'copybuilder' : Builder(action = Action(copy, ' COPY $SOURCE -> $TARGET')) }) 
env.Append(BUILDERS = { 'package' : Builder(action = Action(package_builder, ' PACKAGE $SOURCES -> $TARGET'), suffix='.zip') }) 

env.Textfile(target='foo.txt', source='hello, world\n') 

# 
# Here the changes start 
# 

# The following line is not needed, SCons picks up the 
# dependency bar.txt -> foo.txt automatically 
#tclib = env.Alias('transcoderLib', 'foo.txt') 
copyTarget = env.copybuilder('bar.txt', 'foo.txt') 
# Defining Alias for later reference... 
# important: don't create new Alias()es all over 
#   the place, but pass a single reference around 
tclib = env.Alias('transcoderLib', copyTarget) 

# Main change: Your initial dependencies were wrong, it's 
# the package (='python test.py') that depends on your 
# transcoderLib (='bar.txt')... 
package = env.package('#Test', []) 
env.Depends(package, tclib) 

# Create an Alias for the packages, you can pass 
# a list of all your packages too here... 
bp = env.Alias('build_packages', package) 

# Finally, set the package Alias() as default target if 
# requested by the config parameter... 
config = int(ARGUMENTS.get('config', 0)) 
if config == 1: 
    env.Default(bp) 

它正確地建立「跳回到bar.txt」第一,試圖運行「一攬子」步驟之前。請注意,在更新中,'包'構建器被一次又一次地調用,因爲指定的目標「#Test」永遠不會被創建......所以它總是被認爲是過期的。

我希望這可以幫助你進一步,或者至少給你一些新的想法,如果這不是你一直在尋找的解決方案。

最後的備註:只需將所需的依賴項集體添加到包含您的包的別名中,即可將所有包集體添加到所有包中。你的別名被認爲是一個不同的目標,所以如果你打電話給「scons package_1」來構建一個單獨的包......依賴不會被引入。你必須明確並且添加依賴到每個包,因爲這就是你的構建結構看起來像。

+0

事實證明,我用if語句阻止了所需文件的生成......你的回答是完全正確的。 *拍自己* – Darkhydro

1

顯然env.Alias()設置依賴關係,而不是等同。所以當你說build_packages取決於transcoderLib時,你是而不是,說bar.txt也取決於transcoderLib。

考慮您簡單的例子產生的樹:

$ scons -n -Q --tree=all -f ex.sc config=1 
scons: `build_packages' is up to date. 
+-build_packages 
    +-bar.txt 
    | +-hello, world 

    +-transcoderLib 
    +-foo.txt 
     +-hello, world 

正如你所看到的,build_packages取決於bar.txt由於env.Alias()通話。 build_packages也取決於transcoderLib,由於Depends()調用。但bar.txttranscoderLib之間沒有關係。

如果bar.txt取決於transcoderLib,那麼這種關係需要來表示:

Depends('bar.txt', env.Alias('transcoderLib')) 

如果該行被添加到您的例子,結果樹是:

$ scons -Q --tree=all -f ex1.sc config=1 
scons: `build_packages' is up to date. 
+-build_packages 
    +-bar.txt 
    | +-hello, world 

    | +-transcoderLib 
    | +-foo.txt 
    |  +-hello, world 

    +-transcoderLib 
    +-foo.txt 
     +-hello, world 
+0

這是有啓發性的。我很樂意聽到可以用於分組目標的替代路線,因爲Alias似乎不起作用。我正在構建的各種軟件包都在單獨的SConscript中,因此通過每個軟件包並取決於'transcoderLib'是可行的,但令人討厭。你知道有什麼方法將這些包目標分組在一起,這樣我就可以在整個組上設置一個依賴關係了嗎? – Darkhydro

+0

這沒有奏效。現在,每個包下都會顯示依賴關係,但它不會正確構建「transcoderLib」 - 即,如果我剛剛運行別名「transcoderLib」,它將以不同的方式構建它。 – Darkhydro

+0

我發佈了一個更精確的SConstruct,高於 – Darkhydro