clang-format¶
clang-format 是一個根據一組規則和啟發式方法格式化 C/C++/... 程式碼的工具。像大多數工具一樣,它不是完美的,也不能涵蓋所有情況,但它足以提供幫助。
clang-format 可以用於以下幾個目的:
快速將程式碼塊重新格式化為核心風格。在移動程式碼和對齊/排序時特別有用。參見 clangformatreformat。
發現您維護的檔案、您審查的補丁、差異等中的樣式錯誤、錯別字和可能的改進。參見 clangformatreview。
幫助您遵循編碼風格規則,對於那些剛接觸核心開發或同時在具有不同編碼風格的多個專案中工作的人來說特別有用。
它的配置檔案是核心樹根目錄中的 .clang-format。其中包含的規則試圖近似最常見的核心編碼風格。它們還嘗試儘可能地遵循 Documentation/process/coding-style.rst。由於並非所有核心都遵循相同的風格,因此您可能想要調整特定子系統或資料夾的預設設定。為此,您可以透過在子資料夾中編寫另一個 .clang-format 檔案來覆蓋預設設定。
該工具本身早已包含在流行的 Linux 發行版的儲存庫中。在您的儲存庫中搜索 clang-format。否則,您可以下載預構建的 LLVM/clang 二進位制檔案或從以下網址構建原始碼:
有關該工具的更多資訊,請參見:
檢查檔案和補丁的編碼風格¶
透過以行內模式執行該工具,您可以檢查整個子系統、資料夾或單個檔案中的程式碼風格錯誤、錯別字或改進。
為此,您可以執行類似以下內容:
# Make sure your working directory is clean!
clang-format -i kernel/*.[ch]
然後檢視 git diff。
計算此類 diff 的行數也有助於改進/調整配置檔案中的樣式選項;以及測試新的 clang-format 功能/版本。
clang-format 還支援讀取統一差異,因此您可以輕鬆地檢視補丁和 git diff。參見以下文件:
要避免 clang-format 格式化檔案的某些部分,您可以執行以下操作:
int formatted_code;
// clang-format off
void unformatted_code ;
// clang-format on
void formatted_code_again;
雖然很想使用它來使檔案始終與 clang-format 同步,特別是如果您正在編寫新檔案或者您是維護者,但請注意,人們可能正在執行不同的 clang-format 版本或者根本沒有該工具。因此,您可能應該避免在核心原始碼中使用它;至少在我們看到 clang-format 變得普遍之前。
重新格式化程式碼塊¶
透過與您的文字編輯器整合,您可以透過一次擊鍵重新格式化任意程式碼塊(選定部分)。這在移動程式碼、處理深度縮排的複雜程式碼、多行宏(和對齊其反斜槓)等方面特別有用。
請記住,在工具沒有做到最佳效果的情況下,您可以隨時在之後調整更改。但作為第一步,它非常有用。
有許多流行的文字編輯器的整合。對於某些編輯器,如 vim、emacs、BBEdit 和 Visual Studio,您可以找到內建支援。有關說明,請閱讀以下網址的相應部分:
對於 Atom、Eclipse、Sublime Text、Visual Studio Code、XCode 和其他編輯器和 IDE,您應該能夠找到即用型外掛。
對於此用例,請考慮使用輔助 .clang-format,以便您可以調整一些選項。參見 clangformatextra。
缺失的支援¶
clang-format 缺少對核心程式碼中常見的一些內容的支援。它們很容易記住,因此如果您經常使用該工具,您將很快學會避免/忽略它們。
特別是,您會注意到一些非常常見的:
對齊的單行
#defines,例如:#define TRACING_MAP_BITS_DEFAULT 11 #define TRACING_MAP_BITS_MAX 17 #define TRACING_MAP_BITS_MIN 7與
#define TRACING_MAP_BITS_DEFAULT 11 #define TRACING_MAP_BITS_MAX 17 #define TRACING_MAP_BITS_MIN 7對齊的指定初始化器,例如:
static const struct file_operations uprobe_events_ops = { .owner = THIS_MODULE, .open = probes_open, .read = seq_read, .llseek = seq_lseek, .release = seq_release, .write = probes_write, };與
static const struct file_operations uprobe_events_ops = { .owner = THIS_MODULE, .open = probes_open, .read = seq_read, .llseek = seq_lseek, .release = seq_release, .write = probes_write, };
額外的特性/選項¶
某些特性/樣式選項預設情況下未在配置檔案中啟用,以最大程度地減少輸出和當前程式碼之間的差異。換句話說,為了使差異儘可能小,從而使審查完整檔案樣式、差異和補丁儘可能容易。
在其他情況下(例如,特定子系統/資料夾/檔案),核心樣式可能不同,並且啟用其中一些選項可能會更好地近似那裡的樣式。
例如:
對齊賦值 (
AlignConsecutiveAssignments)。對齊宣告 (
AlignConsecutiveDeclarations)。重排註釋中的文字 (
ReflowComments)。排序
#includes(SortIncludes)。
它們通常對於塊重新格式化很有用,而不是完整檔案。您可能想要建立另一個 .clang-format 檔案,並從您的編輯器/IDE 中使用該檔案。