Boost C++ Libraries

PrevUpHomeNext

其他

診斷
錯誤與限制
基礎

除了通用的錯誤訊息外,b2 還可能發出以下訊息:

warning: unknown rule X

呼叫了一個沒有使用「actions」或「rule」語句定義的規則。

using N temp target(s)

找到了標記為臨時文件(但仍然存在)的目標。

updating N target(s)

目標已過期,將會更新。

can't find N target(s)

找不到原始碼檔案,也沒有建立它們的操作。

can't make N target(s)

由於找不到原始碼,因此無法建立其他目標。

warning: X depends on itself

目標直接或透過其原始碼檔案依賴自身。

don't know how to make X

目標不存在,也沒有定義建立它的操作。

X skipped for lack of Y

原始碼建置失敗,因此無法建置目標。

warning: using independent target X

使用 $(<)$(>) 引用了不是任何其他目標依賴項的目標。

X removed

B2 在中斷後移除了一個部分建置的目標。

要成功進行平行建置,必須正確地說明檔案之間的依賴關係,因為目標會傾向以最快完成的順序建置。 此外,請注意那些會將固定名稱的檔案放入目前目錄的不可平行化指令,例如 yacc(1)

設定不佳的 $(JAMSHELL) 很可能導致無聲的失敗。

本節源自 Jam 的官方文件,以及使用 Jam 和閱讀 Jambase 規則的經驗。 我們在這裡重複這些資訊,主要是因为它們對於理解和使用 Jam 至關重要,但卻沒有整合在單一位置。 其中一些資訊在官方文件中完全沒有提及。 我們希望這些資訊對任何想熟悉 Jam 和 Boost 建置系統的人有所幫助。

  • Jam 的「rules」(規則)實際上是簡單的程序實體。 可以將它們視為函式。 參數以冒號分隔。
  • Jam 的**目標**是由任意字串識別的抽象實體。 內建的 DEPENDS 規則會在命名目標之間的依賴圖形中建立連結。
  • 請注意,內建 INCLUDES 規則的原始 Jam 文件不正確:INCLUDES targets1 : targets2 會導致依賴 targets1 成員的所有項目都依賴 targets2 的所有成員。 它的執行方式很奇怪,方法是將 targets2 附加到 targets1 中每個項目的依賴列表的特殊尾部區段。 這樣建立循環依賴關係似乎是可以的;事實上,當單一建置操作產生 targets1targets2 時,這似乎是「正確的做法」。
  • 呼叫規則時,如果宣告了與規則名稱相同的 actions(操作),則會將這些操作新增到由規則的第一個參數識別的目標的更新操作中。 如果宣告了對應的操作,則實際上可以呼叫未宣告的規則:該規則會被視為空。
  • 目標 (除了 NOTFILE 目標之外) 會透過一個稱為「綁定」的過程與檔案系統中的路徑關聯。綁定是指根據目標特定的 SEARCHLOCATE 變數的設定,搜尋與目標名稱相同 (不含 grist) 的檔案的過程。
  • 除了全域和區域變數之外,Jam 還允許您在目標 `on` 設定變數。目標特定的變數值通常無法讀取,並且僅在以下情況下生效:

    • 在更新動作中,會先在第一個參數 (正在更新的目標) 命名的目標 `on` 查找變數值。由於 Jam 會在執行動作之前建構整個相依性樹狀結構,因此 Jam 規則會將目標特定的變數設定作為提供參數給對應動作的一種方式。
    • 綁定完全由 SEARCHLOCATE 變數的目標特定設定控制,如下所述。
    • 在用於標頭檔掃描的特殊規則中,會先在規則的第一個參數 (正在掃描的原始程式檔) 命名的目標 `on` 查找變數值。
  • 變數的「綁定值」是與變數命名的目標關聯的路徑。在建構動作中,前兩個參數會自動替換為其綁定值。可以使用 bind 動作修飾符選擇性地將目標特定變數替換為其綁定值。
  • 請注意,Jam 文件中使用的術語「綁定」指的是一個包含三個子階段的處理階段:綁定 (沒錯!)、更新判斷和標頭檔掃描。重複使用術語「綁定」可能會造成一些混淆。特別是,Jam 文件中的「修改綁定」章節可能應該改名為「修改更新判斷」。
  • 「Grist」只是一個格式為 <字元> 的字串前綴。它在 Jam 中用於根據較簡單的名稱建立唯一的目標名稱。例如,檔名「test.exe」可以由不同子專案中的目標使用,或者用於「相同」抽象目標的偵錯和發行變體。每個綁定到名為「test.exe」的檔案的不同目標都有其自己的唯一 grist 前綴。Boost 建構系統也充分利用了 Jam 在 grist 邊界分割字串的能力,有時會在字串的開頭串連多個 grist 元素。使用 grist 而不是使用絕對路徑來識別目標有兩個原因:

    1. 目標的位置並非總是可以僅根據使用者在 Jamfile 中放入的內容推導出來,有時也取決於綁定過程。仍然需要某種機制來區分名稱相同的目標。
    2. Grist 允許我們為每個建構的目標使用統一的抽象識別符號,而不管目標檔案位置如何 (如設定 ALL_LOCATE_TARGET 所允許)。
  • 當使用 $(var:G) 從名稱中提取 grist 時,結果包含前導和尾端的角括號。當使用 $(var:G=expr) 將 grist 新增到名稱時,會先去除現有的 grist。然後,如果 expr 非空,則會在必要時新增前導 < 和尾端 > 以形成格式為 <expr2> 的表達式;然後會預先加上 <expr2>。
  • 當 Jam 被呼叫時,它會將所有環境變數設定匯入到對應的 Jam 變數中,然後是所有命令列 (-s...) 變數設定。名稱以 PATH、Path 或 path 結尾的變數會根據作業系統特定的路徑清單分隔符號邊界 (例如,UNIX 使用 ":",Windows 使用 ";") 分割成字串清單。所有其他變數都根據空格 (" ") 邊界分割。Boost Jam 修改了這種行為,允許變數被引號括起來。
  • 若變數的值是一個空串列,或是僅包含空字串,則其邏輯值為假 (false)。因此,以下程式碼提供了一個合理的非空預設值,使用者可以輕鬆覆蓋它。
    MESSAGE ?\= starting jam... ;
    if $(MESSAGE) { ECHO The message is: $(MESSAGE) ; }
    
    如果使用者想要指定訊息,可以使用 "-sMESSAGE=訊息文字" 呼叫 Jam。如果使用者不想要任何訊息,可以使用 -sMESSAGE= 呼叫 Jam,這樣就不會印出任何東西。
  • Jam 解析命令列選項的方式可能與其他 Unix 程式不太一樣,它接受兩種選項格式:

    1. -x值,以及
    2. -x 值.

PrevUpHomeNext