第 16 章 原生碼編譯 (ocamlopt)

本章描述 OCaml 高效能原生碼編譯器 ocamlopt,它將 OCaml 原始碼檔案編譯為原生碼物件檔案,並連結這些物件檔案以產生獨立的可執行檔。

原生碼編譯器僅在某些平台上可用。它產生的程式碼執行速度比 ocamlc 產生的位元組碼快,但代價是編譯時間和可執行程式碼大小增加。與位元組碼編譯器的相容性非常高:當使用 ocamlcocamlopt 編譯時,相同的原始碼應該以相同的方式執行。

無法將 ocamlopt 產生的原生碼物件檔案與 ocamlc 產生的位元組碼物件檔案混合使用:程式必須完全使用 ocamlopt 或完全使用 ocamlc 編譯。ocamlopt 產生的原生碼物件檔案無法載入頂層系統 ocaml

1 編譯器概觀

ocamlopt 命令的命令列介面與 ocamlc 非常接近。它接受相同類型的引數,並在處理完所有選項後依序處理它們。

連結階段的輸出是常規的 Unix 或 Windows 可執行檔。它不需要 ocamlrun 即可執行。

編譯器能夠發出關於其內部階段的一些資訊

2 選項

ocamlopt 可識別下列命令列選項。選項 -pack-a-shared-c-output-obj-output-complete-obj 是互斥的。

-a
使用命令列上給定的物件檔案(.cmx.o/.obj 檔案)建置函式庫(.cmxa.a/.lib 檔案),而不是將它們連結到可執行檔案中。函式庫的名稱必須使用 -o 選項設定。

如果在命令列上傳遞了 -cclib-ccopt 選項,這些選項會儲存在產生的 .cmxa 函式庫中。然後,連結此函式庫會自動新增 -cclib-ccopt 選項,就像它們在命令列上提供一樣,除非給定 -noautolink 選項。

-absname
強制錯誤訊息顯示檔案名稱的絕對路徑。
-no-absname
請勿嘗試在錯誤訊息中顯示絕對檔案名稱。
-annot
自 OCaml 4.11 版起已過時。請改用 -bin-annot
-args filename
filename 讀取其他以換行符號結尾的命令列引數。
-args0 filename
filename 讀取其他以空字元結尾的命令列引數。
-bin-annot
以二進位格式傾印有關編譯的詳細資訊(類型、繫結、尾呼叫等)。檔案 src.ml(或 src.mli)的資訊會放入檔案 src.cmt(或 src.cmti)。如果發生類型錯誤,請在錯誤之前傾印類型檢查器推斷的所有資訊。-bin-annot 產生的 *.cmt*.cmti 檔案比 -annot 產生的檔案包含更多資訊,而且更精簡。
-c
僅編譯。抑制編譯的連結階段。原始碼檔案會被轉換為編譯後的檔案,但不產生可執行檔。此選項對於分別編譯模組非常有用。
-cc ccomp
使用 ccomp 作為 C 連結器,用於建置最終可執行檔,並作為 C 編譯器,用於編譯 .c 原始碼檔案。當連結由 C++ 編譯器(例如 g++clang++)產生的目標檔案時,建議使用 -cc c++
-cclib -llibname
-llibname 選項傳遞給連結器。這會導致給定的 C 函式庫與程式連結。
-ccopt option
將給定的選項傳遞給 C 編譯器和連結器。例如,-ccopt -Ldir 會導致 C 連結器在目錄 dir 中搜尋 C 函式庫。
-cmi-file filename
使用給定的介面檔案來類型檢查要編譯的 ML 原始碼檔案。如果未指定此選項,編譯器會尋找與它正在編譯的實作具有相同基本名稱且位於相同目錄中的 .mli 檔案。如果找到此類檔案,編譯器會在包含的目錄中尋找對應的 .cmi 檔案,如果找不到,則會報告錯誤。
-color mode
啟用或停用編譯器訊息中的色彩(尤其是警告和錯誤)。支援以下模式
auto
僅當輸出支援色彩時,才使用啟發式方法啟用色彩(ANSI 相容的 tty 終端機);
always
無條件啟用色彩;
never
停用色彩輸出。

如果未提供 -color,則會考慮環境變數 OCAML_COLOR。其值如上,為 auto/always/never。

如果未提供 -colorOCAML_COLOR 未設定且設定了環境變數 NO_COLOR,則會停用色彩輸出。否則,預設設定為「auto」,且目前的啟發式方法會檢查 TERM 環境變數是否存在且不為空或 dumb,並且「isatty(stderr)」成立。

-error-style mode
控制錯誤訊息和警告的列印方式。支援以下模式
short
僅列印錯誤及其位置;
contextual
short 類似,但也會顯示對應於錯誤位置的原始碼片段。
預設設定為 contextual

如果未提供 -error-style,則會考慮環境變數 OCAML_ERROR_STYLE。其值如上,為 short/contextual。

-compact
針對空間而非時間最佳化產生的程式碼。這會產生稍微小但稍微慢的程式。預設為針對速度進行最佳化。
-config
列印 ocamlopt 的版本號碼及其組態的詳細摘要,然後結束。
-config-var var
列印來自 -config 輸出的特定組態變數的值,然後結束。如果變數不存在,則結束代碼為非零。此選項僅自 OCaml 4.08 起可用,因此指令碼作者應為較舊版本提供後備選項。
-depend ocamldep-args
計算相依性,如同 ocamldep 命令所做的那樣。其餘引數會被解讀為如同它們已提供給 ocamldep 命令。
-for-pack module-path
產生一個目標檔案(.cmx.o/.obj 檔案),該檔案稍後可以作為使用 -pack 建構的編譯單元的子模組(具有給定的存取路徑)包含在內。例如,ocamlopt -for-pack P -c A.ml 將產生 a..cmxa.o 檔案,這些檔案稍後可以與 ocamlopt -pack -o P.cmx a.cmx 一起使用。注意:您仍然可以打包一個在沒有 -for-pack 的情況下編譯的模組,但在這種情況下,例外情況將會印出錯誤的名稱。
-g
在編譯和連結時新增偵錯資訊。當程式因未捕捉到的例外情況而終止時,此選項是產生堆疊回溯所必需的(請參閱第 15.2 節)。
-no-g
不記錄偵錯資訊(預設)。
-i
使編譯器在編譯實作檔案(.ml 檔案)時列印所有已定義的名稱(及其推斷的類型或定義)。不產生編譯後的檔案(.cmo.cmi 檔案)。這對於檢查編譯器推斷的類型非常有用。此外,由於輸出遵循介面的語法,它可以協助為檔案撰寫明確的介面(.mli 檔案):只需將編譯器的標準輸出重新導向到 .mli 檔案,並編輯該檔案以移除所有未匯出的名稱宣告。
-I directory
將給定的目錄新增至搜尋已編譯介面檔案(.cmi)、已編譯目標程式碼檔案(.cmx)和函式庫(.cmxa)的目錄清單。依預設,首先會搜尋目前目錄,然後是標準函式庫目錄。使用 -I 新增的目錄會在目前目錄之後搜尋,依它們在命令列上給定的順序搜尋,但在標準函式庫目錄之前搜尋。另請參閱選項 -nostdlib

如果給定的目錄以 + 開頭,則會將其視為相對於標準函式庫目錄。例如,-I +unix 會將標準函式庫的子目錄 unix 新增至搜尋路徑。

-H directory
其行為與 -I 相同,但 (a) 程式可能不會直接參考以此方式新增至搜尋路徑的模組,以及 (b) 這些目錄會在任何 -I 目錄之後搜尋。這使得能夠為編譯器提供目前程式的傳遞相依性(其相依性的相依性)的已編譯介面和目標程式碼檔案,而不會讓它們悄悄地變成直接相依性。
-impl filename
將檔案 filename 編譯為實作檔案,即使其副檔名不是 .ml
-inline n
將內嵌的積極性設定為 n,其中 n 為正整數。指定 -inline 0 會防止所有函式被內嵌,除非它們的主體小於呼叫位置。因此,內嵌不會導致程式碼大小擴充。預設積極性 -inline 1 允許內嵌稍大的函式,從而導致程式碼大小稍微擴充。較高的 -inline 選項值會導致越來越大的函式成為內嵌的候選者,但可能會導致程式碼大小嚴重增加。
-intf filename
將檔案 filename 編譯為介面檔案,即使其副檔名不是 .mli
-intf-suffix string
將以 string 結尾的檔案名稱識別為介面檔案(而非預設的 .mli)。
-labels
標籤在類型中不會被忽略,標籤可以在應用程式中使用,且帶標籤的參數可以按任何順序給定。這是預設設定。
-linkall
強制將函式庫中包含的所有模組連結進來。如果未提供此旗標,則不會連結未參考的模組。當建置函式庫(選項 -a)時,設定 -linkall 選項會強制所有後續連結涉及該函式庫的程式連結函式庫中包含的所有模組。當編譯模組(選項 -c)時,設定 -linkall 選項可確保如果將此模組放入函式庫且連結了該函式庫,則始終會連結此模組。
-linscan
使用線性掃描暫存器配置。使用此配置器進行編譯比使用通常的圖形著色配置器更快,對於長函式和模組來說,速度有時會明顯快很多。另一方面,產生的程式碼可能會稍微慢一些。
-match-context-rows
設定在模式匹配編譯期間用於最佳化的上下文列數。預設值為 32。較低的值會導致更快的編譯速度,但程式碼最佳化程度較低。此進階選項適用於模式匹配繁重的程式導致編譯時間顯著增加的情況。
-no-alias-deps
不記錄模組別名的依賴關係。請參閱第 12.8 節以取得更多資訊。
-no-app-funct
停用函子的應用行為。使用此選項時,每個函子應用都會在其結果中產生新的類型,並且將同一個函子兩次應用於相同參數會產生兩個不相容的結構。
-no-float-const-prop
停用浮點運算的常數傳播。如果程式在其執行期間變更浮點捨入模式,則應給定此選項。
-noassert
不編譯斷言檢查。請注意,特殊形式 assert false 總是會被編譯,因為它是經過特殊類型化的。此標誌在連結已編譯的檔案時無效。
-noautolink
在連結 .cmxa 程式庫時,忽略程式庫中可能包含的 -cclib-ccopt 選項(如果這些選項是在建置程式庫時給定的)。如果程式庫包含 C 程式庫或 C 選項的不正確規格,這可能會很有用;在這種情況下,在連結期間,設定 -noautolink 並在命令列上傳遞正確的 C 程式庫和選項。
-nodynlink
允許編譯器使用僅對靜態連結的程式碼有效的某些最佳化,以產生不可重定位的可執行檔。產生的程式碼不能連結以產生共享程式庫或與位置無關的可執行檔 (PIE)。許多作業系統預設會產生 PIE,這會在連結使用 -nodynlink 編譯的程式碼時導致錯誤。請勿使用 -nodynlink 或在連結時傳遞選項 -ccopt -no-pie
-nolabels
忽略類型中非選用的標籤。標籤不能在應用程式中使用,並且參數順序會變得嚴格。
-nostdlib
不要自動將標準程式庫目錄新增至搜尋已編譯介面檔案 (.cmi)、已編譯物件程式碼檔案 (.cmx) 和程式庫 (.cmxa) 的目錄清單中。另請參閱選項 -I
-o output-file
指定要產生的輸出檔案名稱。對於可執行檔,預設輸出名稱在 Unix 下為 a.out,在 Windows 下為 camlprog.exe。如果給定 -a 選項,則指定產生的程式庫名稱。如果給定 -pack 選項,則指定產生的壓縮物件檔案名稱。如果給定 -output-obj-output-complete-obj 選項,則指定產生的物件檔案名稱。如果給定 -shared 選項,則指定產生的外掛程式檔案名稱。
-opaque
當原生編譯器編譯實作時,預設會產生一個 .cmx 檔案,其中包含跨模組最佳化的資訊。它還期望目前編譯的原始碼的相依性存在 .cmx 檔案,並將它們用於最佳化。自 OCaml 4.03 起,如果編譯器無法找到其中一個相依性的 .cmx 檔案,則會發出警告。

自 4.04 起提供的 -opaque 選項會停用目前編譯單元的跨模組最佳化資訊。在編譯 .mli 介面時,使用 -opaque 會將編譯的 .cmi 介面標記為,使其後續編譯依賴於它的模組不會依賴於對應的 .cmx 檔案,如果它不存在,也不會發出警告。當原生編譯器編譯 .ml 實作時,使用 -opaque 會產生一個不包含任何跨模組最佳化資訊的 .cmx

使用此選項可能會降低產生的程式碼品質,但它會減少編譯時間,無論是在乾淨或增量建置時。實際上,對於原生編譯器,當編譯單元的實作變更時,所有依賴於它的單元可能都需要重新編譯 – 因為跨模組資訊可能已變更。如果實作變更的編譯單元是使用 -opaque 編譯的,則不需要進行此類重新編譯。因此,此選項可用於例如更快地取得編輯-編譯-測試回饋迴圈。

-open Module
在處理介面或實作檔案之前,開啟給定的模組。如果給定多個 -open 選項,則會依序處理它們,就像語句 open! Module1;; ... open! ModuleN;; 新增至每個檔案的頂端一樣。
-output-obj
使連結器產生 C 物件檔案而不是可執行檔。這對於將 OCaml 程式碼包裝為可從任何 C 程式呼叫的 C 程式庫很有用。請參閱第 22 章,第 22.7.5 節。輸出物件檔案的名稱必須使用 -o 選項設定。此選項還可用於產生編譯的共享/動態程式庫(.so 副檔名,在 Windows 下為 .dll)。
-output-complete-obj
-output-obj 選項相同,只是產生的物件檔案包含執行階段和自動連結程式庫。
-pack
建置一個物件檔案 (.cmx.o/.obj 檔案) 及其相關聯的已編譯介面 (.cmi),它會組合命令列上給定的 .cmx 物件檔案,使其顯示為輸出 .cmx 檔案的子模組。輸出 .cmx 檔案的名稱必須使用 -o 選項給定。例如,
        ocamlopt -pack -o P.cmx A.cmx B.cmx C.cmx
產生已編譯的檔案 P.cmxP.oP.cmi,描述一個具有三個子模組 ABC 的編譯單元,對應於物件檔案 A.cmxB.cmxC.cmx 的內容。這些內容可以在程式的其餘部分中參照為 P.AP.BP.C

正在組合的 .cmx 物件檔案必須已使用適當的 -for-pack 選項編譯。在上面的範例中,A.cmxB.cmxC.cmx 必須已使用 ocamlopt -for-pack P 編譯。

可以透過將 -pack-for-pack 結合來實現多個層級的壓縮。請考量以下範例

        ocamlopt -for-pack P.Q -c A.ml
        ocamlopt -pack -o Q.cmx -for-pack P A.cmx
        ocamlopt -for-pack P -c B.ml
        ocamlopt -pack -o P.cmx Q.cmx B.cmx

產生的 P.cmx 物件檔案具有子模組 P.QP.Q.AP.B

-pp command
使編譯器將給定的 command 作為每個原始檔的預處理器呼叫。 command 的輸出會重新導向至中繼檔案,然後對其進行編譯。如果沒有編譯錯誤,則稍後會刪除中繼檔案。
-ppx command
在剖析後,透過預處理器 command 傳送抽象語法樹。在第 30 章中描述的模組 Ast_mapper Ast_mapper 實作了預處理器的外部介面。
-principal
在類型檢查期間檢查資訊路徑,以確保所有類型都以主要方式衍生。使用標籤參數和/或多型方法時,需要此標誌來確保編譯器的未來版本能夠正確推斷類型,即使內部演算法變更也一樣。在 -principal 模式中接受的所有程式也會在預設模式中以等效的類型接受,但二進位簽章不同,這可能會減慢類型檢查速度;然而,在發佈原始碼之前使用一次是一個好主意。
-rectypes
允許在類型檢查期間使用任意遞迴類型。預設情況下,僅支援遞迴透過物件類型的遞迴類型。請注意,一旦您使用此標誌建立介面,您必須再次將它用於所有相依性。
-runtime-variant suffix
suffix 字串新增至程式使用的執行階段程式庫的名稱。目前,僅支援一個此類字尾:d,並且僅當 OCaml 編譯器使用選項 -with-debug-runtime 設定時。此字尾提供執行階段的偵錯版本,這對於偵錯低階程式碼(例如 C 樁)中的指標問題很有用。
-S
保留編譯期間產生的組譯碼。原始檔案 x.ml 的組譯碼會儲存在檔案 x.s 中。
-safe-string
強制 stringbytes 類型之間的區隔,從而使字串成為唯讀。這是預設設定,自 OCaml 5.0 起強制執行。
-safer-matching
不使用類型資訊來最佳化模式匹配。即使錯誤地假設模式匹配是詳盡的,這也允許偵測到匹配失敗。這僅影響 GADT 和多型變體編譯。
-save-ir-after pass
在給定的編譯階段之後,將中繼表示儲存到檔案。目前支援的階段和對應的檔案副檔名為:scheduling (.cmir-linear)。

此實驗性功能使外部工具能夠使用 compiler-libs 程式庫檢查和操作編譯器的程式中繼表示(請參閱第 30 章和 Compiler_libs )。

-shared
建立一個外掛程式(通常是 .cmxs),可以使用 Dynlink 模組動態載入。外掛程式的名稱必須使用 -o 選項設定。一個外掛程式可以包含數個 OCaml 模組和函式庫,以及額外的原生物件(.o.obj.a.lib 檔案)。只有在某些作業系統上支援建立原生外掛程式。在某些系統下(目前僅限 Linux AMD 64),連結到外掛程式中的所有 OCaml 程式碼都必須在編譯時沒有使用 -nodynlink 旗標。對於額外原生物件的編譯方式也可能有一些限制(在 Linux AMD 64 下,它們必須僅包含位置無關的程式碼)。
-short-paths
當一個型別在多個模組路徑下可見時,在推斷介面以及錯誤和警告訊息中列印該型別名稱時,使用最短的路徑。以底線 _ 開頭或包含雙底線 __ 的識別符號名稱,在計算長度時會額外加上 10 的懲罰值。
-stop-after pass
在指定的編譯階段後停止編譯。目前支援的階段有:parsingtypingschedulingemit
-strict-sequence
強制每個序列的左側部分都必須具有 unit 型別。
-strict-formats
拒絕傳統格式實作中接受的無效格式。您應該使用此旗標來偵測並修正這些無效格式,因為它們將在未來的 OCaml 版本中被拒絕。
-unboxed-types
當一個型別可取消裝箱時(即只有一個參數的記錄或只有一個單參數建構子的具體資料型別),除非標記了 [@@ocaml.boxed],否則它將會被取消裝箱。
-no-unboxed-types
當一個型別可取消裝箱時,除非標記了 [@@ocaml.unboxed],否則它將會被裝箱。這是預設行為。
-unsafe
關閉陣列和字串存取的邊界檢查(v.(i)s.[i] 結構)。使用 -unsafe 編譯的程式速度較快,但不安全:如果程式存取超出其邊界的陣列或字串,可能會發生任何事情。此外,關閉整數除法和模數運算中除數為零的檢查。使用 -unsafe,整數除法(或模數)除以零可能會使程式停止或繼續執行並產生未指定結果,而不是引發 Division_by_zero 例外。
-unsafe-string
識別 stringbytes 型別,使字串可寫入。這是為了與舊的原始程式碼相容,不應在新軟體中使用。從 OCaml 5.0 開始,此選項會無條件引發錯誤。
-v
列印編譯器的版本號碼和標準函式庫目錄的位置,然後結束。
-verbose
在執行所有外部命令之前列印它們,特別是組譯器、C 編譯器和連結器的調用。有助於除錯 C 函式庫問題。
-version-vnum
以簡短形式(例如 3.11.0)列印編譯器的版本號碼,然後結束。
-w warning-list
啟用、停用或將 warning-list 參數指定的警告標記為致命。每個警告都可以啟用停用,每個警告都可以是致命非致命的。如果警告被停用,它不會被顯示,也不會以任何方式影響編譯(即使它是致命的)。如果警告被啟用,當原始程式碼觸發時,它會由編譯器正常顯示。如果它被啟用且是致命的,編譯器也會在顯示後停止並產生錯誤。

warning-list 參數是一系列警告指定符,它們之間沒有分隔符號。警告指定符是以下其中一種

+num
啟用警告號碼 num
-num
停用警告號碼 num
@num
啟用並將警告號碼 num 標記為致命。
+num1..num2
啟用指定範圍內的警告。
-num1..num2
停用指定範圍內的警告。
@num1..num2
啟用並將指定範圍內的警告標記為致命。
+letter
啟用對應於 letter 的警告集合。字母可以是大小寫。
-letter
停用對應於 letter 的警告集合。字母可以是大小寫。
@letter
啟用並將對應於 letter 的警告集合標記為致命。字母可以是大小寫。
uppercase-letter
啟用對應於 uppercase-letter 的警告集合。
lowercase-letter
停用對應於 lowercase-letter 的警告集合。

或者,warning-list 可以使用其助記名稱(如下所示)來指定單個警告,如下所示

+name
啟用警告 name
-name
停用警告 name
@name
啟用並將警告 name 標記為致命。

目前未定義的警告號碼、字母和名稱將被忽略。警告如下(每個號碼後面的名稱指定該警告的助記符)。

1 comment-start
看起來可疑的註解開始標記。
2 comment-not-end
看起來可疑的註解結束標記。
3
已棄用的「deprecated」警示的同義詞。
4 fragile-match
脆弱的模式匹配:即使在匹配的變體型別之一中新增了其他建構子,也仍將保持完整的匹配。
5 ignored-partial-application
部分應用函式:結果具有函式型別且被忽略的運算式。
6 labels-omitted
在函式應用中省略了標籤。
7 method-override
覆寫的方法。
8 partial-match
部分匹配:模式匹配中缺少的情況。
9 missing-record-field-pattern
記錄模式中缺少欄位。
10 non-unit-statement
序列左側的運算式不具有 unit 型別(且不是函式,請參閱警告號碼 5)。
11 redundant-case
模式匹配中的冗餘情況(未使用的匹配情況)。
12 redundant-subpat
模式匹配中的冗餘子模式。
13 instance-variable-override
覆寫的實例變數。
14 illegal-backslash
字串常數中不合法的反斜線跳脫字元。
15 implicit-public-methods
隱式公開的私有方法。
16 unerasable-optional-argument
無法消除的可選參數。
17 undeclared-virtual-method
未宣告的虛擬方法。
18 not-principal
非主要型別。
19 non-principal-labels
沒有主要性的型別。
20 ignored-extra-argument
未使用的函式參數。
21 nonreturning-statement
不返回的陳述式。
22 preprocessor
前處理器警告。
23 useless-record-with
無用的記錄 with 子句。
24 bad-module-name
不正確的模組名稱:原始檔案名稱不是有效的 OCaml 模組名稱。
25
已忽略:現在是警告 8 的一部分。
26 unused-var
可疑的未使用變數:使用 letas 綁定的未使用變數,且不以底線 (_) 字元開頭。
27 unused-var-strict
無害的未使用變數:未使用變數,未使用 letas 綁定,且不以底線 (_) 字元開頭。
28 wildcard-arg-to-constant-constr
萬用字元模式作為常數建構子的引數給定。
29 eol-in-string
字串常數中未跳脫的行尾符號(不可移植的程式碼)。
30 duplicate-definitions
在兩個相互遞迴的型別中,定義了兩個同名的標籤或建構子。
31 module-linked-twice
同一個可執行檔中連結了兩次模組。
I
已忽略:現在是硬性錯誤(自 5.1 起)。
32 unused-value-declaration
未使用的值宣告。(自 4.00 起)
33 unused-open
未使用的 open 陳述式。(自 4.00 起)
34 unused-type-declaration
未使用的型別宣告。(自 4.00 起)
35 unused-for-index
未使用的 for 迴圈索引。(自 4.00 起)
36 unused-ancestor
未使用的祖先變數。(自 4.00 起)
37 unused-constructor
未使用的建構子。(自 4.00 起)
38 unused-extension
未使用的擴充建構子。(自 4.00 起)
39 unused-rec-flag
未使用的 rec 標誌。(自 4.00 起)
40 name-out-of-scope
建構子或標籤名稱超出範圍使用。(自 4.01 起)
41 ambiguous-name
不明確的建構子或標籤名稱。(自 4.01 起)
42 disambiguated-name
已消除歧義的建構子或標籤名稱 (相容性警告)。(自 4.01 起)
43 nonoptional-label
非可選標籤被當作可選標籤應用。(自 4.01 起)
44 open-shadow-identifier
Open 陳述式遮蔽了已定義的識別符。(自 4.01 起)
45 open-shadow-label-constructor
Open 陳述式遮蔽了已定義的標籤或建構子。(自 4.01 起)
46 bad-env-variable
環境變數錯誤。(自 4.01 起)
47 attribute-payload
不合法的屬性有效負載。(自 4.02 起)
48 eliminated-optional-arguments
隱式消除可選參數。(自 4.02 起)
49 no-cmi-file
查找模組別名時缺少 cmi 檔案。(自 4.02 起)
50 unexpected-docstring
意外的文件註解。(自 4.03 起)
51 wrong-tailcall-expectation
使用不正確的 @tailcall 屬性註解的函數調用。(自 4.03 起)
52 fragile-literal-pattern (參見 13.5.3)
脆弱的常數模式。(自 4.03 起)
53 misplaced-attribute
屬性不能出現在此上下文中。(自 4.03 起)
54 duplicated-attribute
屬性在一個表達式中使用了多次。(自 4.03 起)
55 inlining-impossible
無法內聯。(自 4.03 起)
56 unreachable-case
模式匹配中無法到達的情況 (基於類型資訊)。(自 4.03 起)
57 ambiguous-var-in-pattern-guard (參見 13.5.4)
在守衛條件下的不明確的或模式變數。(自 4.03 起)
58 no-cmx-file
缺少 cmx 檔案。(自 4.03 起)
59 flambda-assignment-to-non-mutable-value
賦值給不可變的值。(自 4.03 起)
60 unused-module
未使用的模組宣告。(自 4.04 起)
61 unboxable-type-in-prim-decl
原始宣告中無法裝箱的類型。(自 4.04 起)
62 constraint-on-gadt
GADT 類型宣告上的類型約束。(自 4.06 起)
63 erroneous-printed-signature
錯誤的列印簽名。(自 4.08 起)
64 unsafe-array-syntax-without-parsing
搭配使用 -unsafe 與返回語法樹的預處理器。(自 4.08 起)
65 redefining-unit
類型宣告定義了一個新的 '()' 建構子。(自 4.08 起)
66 unused-open-bang
未使用的 open! 陳述式。(自 4.08 起)
67 unused-functor-parameter
未使用的函子參數。(自 4.10 起)
68 match-on-mutable-state-prevent-uncurry
依賴於可變狀態的模式匹配會阻止剩餘參數被取消柯里化。(自 4.12 起)
69 unused-field
未使用的記錄欄位。(自 4.13 起)
70 missing-mli
缺少介面檔案。(自 4.13 起)
71 unused-tmc-attribute
未使用的 @tail_mod_cons 屬性。(自 4.14 起)
72 tmc-breaks-tailcall
尾調用被 @tail_mod_cons 轉換變成了非尾調用。(自 4.14 起)
73 generative-application-expects-unit
生成函子應用於空結構 (struct end) 而不是 ()。(自 5.1 起)
A
所有警告
C
警告 1、2。
D
警告 3 的別名。
E
警告 4 的別名。
F
警告 5 的別名。
K
警告 32、33、34、35、36、37、38、39。
L
警告 6 的別名。
M
警告 7 的別名。
P
警告 8 的別名。
R
警告 9 的別名。
S
警告 10 的別名。
U
警告 11、12。
V
警告 13 的別名。
X
警告 14、15、16、17、18、19、20、21、22、23、24、30。
Y
警告 26 的別名。
Z
警告 27 的別名。

預設設定為 -w +a-4-6-7-9-27-29-32..42-44-45-48-50-60。它由 ocamlopt -help 顯示。請注意,警告 5 和 10 並非總是觸發,這取決於類型檢查器的內部機制。

-warn-error 警告列表
將參數 警告列表 中指定的警告標記為致命。當發出這些警告之一時,編譯器將停止並顯示錯誤。警告列表 的含義與 -w 選項相同:+ 號(或大寫字母)將對應的警告標記為致命,- 號(或小寫字母)將它們變回非致命警告,而 @ 號則同時啟用並將對應的警告標記為致命。

注意:不建議在生產程式碼中使用警告集(即字母)作為 -warn-error 的參數,因為當未來版本的 OCaml 新增一些新警告時,可能會中斷您的建置。

預設設定為 -warn-error -a(沒有警告是致命的)。

-warn-help
顯示所有可用警告號碼的描述。
-where
列印標準程式庫的位置,然後退出。
-with-runtime
在產生的程式中包含執行階段系統。這是預設值。
-without-runtime
編譯器不包含執行階段系統(也不包含對它的引用)在產生的程式中;必須單獨提供。
- 檔案
檔案 作為檔案名稱處理,即使它以連字符號 (-) 字元開頭。
-help--help
顯示簡短的使用摘要並退出。
針對 64 位元 x86 架構的選項

針對 Intel/AMD x86 處理器的 64 位元程式碼產生器(amd64 架構)支援以下額外選項

-fPIC
產生與位置無關的機器程式碼。這是預設值。
-fno-PIC
產生與位置相關的機器程式碼。
命令列選項的上下文控制

可以使用以下機制「從外部」修改編譯器命令列。這些是實驗性的,可能會變更。它們應僅用於實驗和開發工作,而不應在發布的套件中使用。

OCAMLPARAM (環境變數)
一組將插入到命令列參數之前或之後的參數。參數以逗號分隔的 name=value 對列表指定。_ 用於指定命令列參數的位置,例如 a=x,_,b=y 表示 a=x 應在解析參數之前執行,而 b=y 應在之後執行。最後,可以在字串的第一個字元中指定一個替代分隔符,該字元位於集合 :|; , 中。
ocaml_compiler_internal_params (stdlib 目錄中的檔案)
檔案名稱到將新增到命令列(和 OCAMLPARAM)參數的參數列表的對應。

3 常見錯誤

錯誤訊息幾乎與 ocamlc 的錯誤訊息相同。請參閱第 13.4 節。

4 執行 ocamlopt 產生的可執行檔

ocamlopt 產生的可執行檔是原生的、獨立的可執行檔案,可以直接調用。它們不依賴於 ocamlrun 位元組碼執行階段系統,也不依賴於動態載入的 C/OCaml stub 程式庫。

在執行 ocamlopt 產生的可執行檔期間,也會查詢以下環境變數

OCAMLRUNPARAM
用法與 ocamlrun 中相同(請參閱第 15.2 節),只是選項 l 會被忽略(改為使用作業系統的堆疊大小限制)。
CAMLRUNPARAM
如果在環境中找不到 OCAMLRUNPARAM,則將改為使用 CAMLRUNPARAM。如果找不到 CAMLRUNPARAM,則將使用預設值。

5 與位元組碼編譯器的相容性

本節列出了位元組碼編譯器和原生程式碼編譯器之間已知的 不相容之處。除了這些點之外,兩個編譯器應該產生行為相同的程式碼。