ez a blog sorozat bemutatja a clang-tidy segédprogramot a Clang / LLVM projektből, és bemutatja, hogyan kell használni a C++ forráskód automatikus refaktorálására és integrálására a build rendszerrel, valamint hogyan kell használni az eszközt más platformokon, mint az Unices.
- motiváció: a régi kódbázisok öröme
- használja felülírás, valaki?
- Clang-Tidy, hogy a mentő!
- Beállítás
- Bevezetés
- Listing available checkers
- egyetlen fájl Refaktorálása
- néhány megjegyzés
- teljes projekt refaktorálása (CMake-alapú)
- compile_commands generálása.json fájl
- használja script futtatni clang-tidy
- Egyéb Dáma futtatása
- néhány valós példák
- következtetés
- segítségre van szüksége?
motiváció: a régi kódbázisok öröme
a C++11 jelentős mennyiségű új C++ nyelvi funkciót adott hozzá, amelyeket a mai napig nem használnak teljes mértékben. A leglátványosabbak biztosan auto
, override
, Lambda kifejezések, tartomány-alapú for
, egységes inicializálási szintaxis, Nevezd meg. Míg a C++11 már több éves, még mindig sok olyan kódbázis van, amely nem használja az új nyelvi funkciókat, legyen az a menedzsment politikája vagy a tiszta lustaság, hogy elkerülje a fejlesztői oldal portolási erőfeszítéseit. Clang-Tidy a LLVM fordító infrastruktúra projekt van itt, hogy legalább leküzdeni az utóbbi, hogy az automatikus refactoring a forráskód, így használja az új nyelvi funkciók.
használja felülírás, valaki?
most mi történik, ha már fenntart egy meglehetősen nagy kódbázist, amely még mindig C++03 módban áll össze, de a jövőben a C++11 használatát szeretné átfogni, minden hasznos funkcióval? Valószínűleg sok-sok ehhez hasonló kód lesz:
struct Base { virtual void reimplementMe(int a) {}};struct Derived : public Base { virtual void reimplementMe(int a) {}};
eddig természetesen mindig újra végrehajtotta a helyes alaposztályú módszert, mert egységteszteken keresztül alaposan tesztelte kódját! Hát persze, hogy megtetted. Így a kód rendben van, de most szeretne továbblépni. Szeretné hozzáadni a override
specifikátort minden egyes újra implementált módszerhez a kódbázisban, de természetesen anélkül, hogy olyan gyakornokot alkalmazna, aki átmegy a kódsoron, és manuálisan hozzáadja őket.
csak hangsúlyozni, hogy a override
hozzáadása valóban célt szolgál, nemrég javítottuk a hibát a Qt 3D-ben, ahol nem terheltük túl a megfelelő alaposztályú módszert. A korábban hozzáadott specifikátorral azonnal észrevettük volna, az újrafordítás után.
a hiányzó felülbírálási példát tovább fogjuk magyarázni a clang-tidy alapvető használatának magyarázatára.
Clang-Tidy, hogy a mentő!
Clang-Tidy egy clang-alapú C++ linter eszköz, amely egy shell futtatható nevű clang-tidy, mint a fő belépési pont. Bővíthető keretrendszer tipikus programozási hibák vagy stílusproblémák diagnosztizálására-általában bármi, ami a kód statikus elemzése során kimutatható. Az igazi előnye az eszköz, hogy emellett lehetővé teszi, hogy automatikusan refactor a forráskód alkalmazásával fixits minden egyes kérdés nyújthat. Erősen plugin-alapú, és a dobozból egy hasznos plugin-készletet tartalmaz, amelyet a következő bekezdésben fogunk megvitatni.
a Clang-Tidy a Clang/LLVM közösség által kifejlesztett és karbantartott eszköz.
Beállítás
Linux futtatásakor a clang-tidy általában könnyen elérhető a disztribúció csomagkezelőjén keresztül. Például Ubuntu Linuxon a telepítés ugyanolyan egyszerű, mint a következő parancsok futtatása:
% sudo apt-get install clang-tidy
a közelgő blogbejegyzések egyikében megvitatjuk az eszköz telepítését a Linuxon kívüli más platformokra.
Megjegyzés: Javasoljuk, hogy mindig telepítse a legújabb verziót (az írás idején a Clang/LLVM 3.9 alapú verzió ajánlott), mivel a rendelkezésre álló bővítmények/Dáma verzióonként nagymértékben változik és folyamatosan növekszik.
Bevezetés
megjegyzés: ebben a blogbejegyzésben a clang-tidy-3.9-et használták
a parancssori eszköz tipikus meghívása így néz ki:
% clang-tidy test.cpp -- -Imy_project/include -DMY_DEFINES ...
így végrehajtva az eszköz egy csomó figyelmeztetést és jegyzetet nyomtat (ha van ilyen), pontosan ugyanúgy, ahogy a Clang/GCC diagnosztikát is biztosít.
a Clang-Tidy önmagában hasznos statikus elemző eszköz, sok különböző elérhető ellenőrzővel, ez azonban nem a blogbejegyzés középpontjában áll. Inkább szeretnénk kihasználni az eszköz erőteljes refaktorálási képességeit a forráskód korszerűsítése érdekében.
Listing available checkers
az eszköz parancssori paraméterek nélküli futtatása a segédprogram által engedélyezett alapértelmezett ellenőrzőkészletet fogja futtatni. Nézzük meg, milyen más dáma is kínál (átadásával-checks= ‘ * ‘ látni őket), és különösen grep azok számára, modernize a nevüket. Azok Dáma szószólója használata modern nyelvi konstrukciók:
$ clang-tidy --list-checks -checks='*' | grep "modernize" modernize-avoid-bind modernize-deprecated-headers modernize-loop-convert modernize-make-shared modernize-make-unique modernize-pass-by-value modernize-raw-string-literal modernize-redundant-void-arg modernize-replace-auto-ptr modernize-shrink-to-fit modernize-use-auto modernize-use-bool-literals modernize-use-default modernize-use-emplace modernize-use-nullptr modernize-use-override modernize-use-using
már lenyűgöző lehetőségek listája, nem igaz? A Clang-Tidy valóban néhány érdekes dámát szállít a dobozból (a Clang/LLVM 3.9-től), a lista folyamatosan növekszik a kiadástól a kiadásig.
a dáma neve nagyjából magától értetődő (pl. a modernize-use-auto magában foglalja az auto használatát, ahol alkalmazható), de ha meg akarja vizsgálni, hogy mit jelent mindegyik, kérjük, olvassa el a dáma listáját a clang-tidy honlapon:
az eszköz használatának bemutatásához fókuszáljunk a modernize-use-override ellenőrzőre, mivel ez a leginkább alkalmazható és legvitathatatlanabb ellenőrző.
egyetlen fájl Refaktorálása
felülírási példánk ismét:
struct Base { virtual void reimplementMe(int a) {}};struct Derived : public Base { virtual void reimplementMe(int a) {}};
futás clang-tidy a példa (ezúttal a modernize-use-override checker engedélyezve):
% clang-tidy-3.9 -checks='modernize-use-override' test.cpp -- -std=c++111 warning generated./home/kfunk/test.cpp:5:18: warning: prefer using 'override' or (rarely) 'final' instead of 'virtual' virtual void reimplementMe(int a) {} ^ override
rendben. Tehát észrevette, hogy a Derived::reimplementMe(int)
felülír egy alaposztályú módszert, de hiányzik a override
specifikátor! Most is hozzá, hogy kézzel… vagy csak hagyja, hogy az eszköz csinálni nekünk átadásával-fix!
fut a példa (a modernize-use-override checker & fix-its engedélyezve):
% clang-tidy-3.9 -checks='modernize-use-override' -fix test.cpp -- -std=c++111 warning generated./home/kfunk/test.cpp:5:18: warning: prefer using 'override' or (rarely) 'final' instead of 'virtual' virtual void reimplementMe(int a) {} ^ override/home/kfunk/test.cpp:5:5: note: FIX-IT applied suggested code changes virtual void reimplementMe(int a) {} ^/home/kfunk/test.cpp:5:38: note: FIX-IT applied suggested code changes virtual void reimplementMe(int a) {} ^clang-tidy applied 2 of 2 suggested fixes.
a Clang-tidy alkalmazta a fix-it-t, és az override
– et az 5. sorban a metódus deklaráció után illesztette be. Kész!
néhány megjegyzés
néhány dolgot érdemes megemlíteni:
- a clang-tidy nem minden Dáma hordozza a javítást, de a modernizálással kezdődő összes igen.
- használhatja fix-its több ellenőrök ugyanabban az időben (fontolja-ellenőrzések=’modernize-use-override,modernize-use-auto’ -fix)
- Running clang-tidy meghívja a teljes Clang fordító frontend, így kell egy kis idő, hogy teljes
- Refactoring eredmények clang-tidy tökéletesen pontos, annak a ténynek köszönhető, hogy mögött egy teljes értékű C++ elemző
teljes projekt refaktorálása (CMake-alapú)
eddig csak egyetlen, önálló fájlon futtattuk a Clang-tidy programot. Mi történik, ha összetettebb projektbeállítása van, sok fájllal, mindegyik egyedi fordítási zászlókkal? A Clang-tidy mindig egyetlen fájlon, vagy inkább fordítóegységen működik. Segíthetünk az eszköznek, hogy kitalálja a helyes fordítási zászlókat minden egyes fordítási egységhez, amelyet a projektünkben összeállítunk. A legkényelmesebb módja annak, hogy fut egy fordítási parancs adatbázis. CMake automatikusan generál egy, egyszer egy compile_commands.a JSON a helyén van, a clang-tidy működő verziója pedig úton van a teljes kódbázis elemezhető a run-clang-tidy segítségével.py szkript (általában a telepítés részeként szállítják). Ha nem, egyszerűen letöltheti itt.
Megjegyzés: erősen ajánlott használni run-clang-tidy.py a clang-tidy futtatása egy egész projekten, mivel többször párhuzamosan futtatja az eszközt, és biztosítja, hogy az egyidejű végrehajtások ne zavarják egymást (pl.
compile_commands generálása.json fájl
a compile_commands létrehozásához.json fájl egy CMake-alapú projektben, csak futtassa:
% cd my-cmake-based-project% mkdir build% cd build% cmake -DCMAKE_EXPORT_COMPILE_COMMANDS=ON ..
használja script futtatni clang-tidy
most fut az eszköz az alapértelmezett ellenőrzések minden fordítási egység a projektben, egyszerűen hívja a run-clang-tidy script a könyvtárban a compile_commands.json fájl:
% run-clang-tidy.py
mint korábban láttuk, ez eddig nem módosít semmit, mivel a clang-tidy-t csak az alapértelmezett ellenőrzések engedélyezésével futtattuk. Például az összes fordítási egység modernize-use-override ellenőrzésének futtatásához és az összes kód refaktorálásához ez a meghívás szükséges:
% run-clang-tidy.py -header-filter='.*' -checks='-*,modernize-use-override' -fix
ez az. a clang-tidy mostantól a projekt minden fordítóegységén meghívásra kerül, és felülbírálja, ahol hiányzik. A paraméter-header-filter=’.* ‘gondoskodik arról, hogy a clang-tidy ténylegesen refaktorálja a kódot a fordítóegységben felhasznált fejlécekben. A checks=’ -*,… ‘ paraméter biztosítja, hogy az összes alapértelmezett ellenőrzés le van tiltva.
vegye figyelembe, hogy a javításokat csak akkor alkalmazzák, ha a run-clang-tidy befejeződött! A parancsfájl csak a végrehajtandó változtatásokat rögzíti, és a végén egyszerre alkalmazza őket.
Egyéb Dáma futtatása
ismét a modernize-use-override csak egy példa, a clang-tidy-nek sok más Dáma van, amelyek hasznosak. Egy másik szuper hasznos az egyik a modernize-use-nullptr checker, amely átalakítja 0
, vagy például NULL
literals a modern C++11 nullptr
verzió. A projekt régi stílusú literáljainak összes felhasználásának refaktorálásához egyszerűen futtassa:
% run-clang-tidy.py -header-filter='.*' -checks='-*,modernize-use-nullptr' -fix
ez általában egy jó ötlet, hogy végre egy ellenőrző a másik után, elkövetése köztes eredmények (gondoljunk csak a “Port felé C++11 nullptr”, “Port felé C++11 felülírás”,…) be a verzió-ellenőrző rendszer.
néhány valós példák
már személyesen használt clang-tidy egy csomó különböző projektek már, pozitív eredménnyel. Ne feledje, hogy ez az eszköz tökéletesen ismeri a kódot (mivel valójában a Clang compiler frontend-et használja), így refaktorálja a kódot anélkül, hogy valaha is bevezetné a törött kódot.
példák:
- ez a javítás például a KDE összes Keretkönyvtárát a C++11 nullptr felé irányítja, körülbelül 9000 különböző kódhely megérintésével
- ez a javítás a KDE márvány kódbázisát a C++11 felülbírálja, körülbelül 2300 különböző kódhely megérintésével
következtetés
Clang-Tidy egy hatékony eszköz ami a régi kódbázis átvitelét a C++11 felé egy egysoros futtatásának kérdése. Jön egy nagy sor alapértelmezett ellenőrök és a listát a További is folyamatosan növekszik. A modernize-Dáma lehet használni, hogy korszerűsítse / refactor a forráskódot, hogy az új C++ nyelvi funkciók.
a sorozat következő részében megvitatjuk, hogyan kell használni a clang-tidy projektet más építőrendszerekkel.
segítségre van szüksége?
a KDAB számos mérnököt alkalmaz, akik napi szinten dolgoznak a csengő szerszámokkal. Örömmel segítünk Önnek abban az esetben, ha problémái vannak a Clang Tooling használatával a projektben, vagy a legtöbbet szeretné kihozni belőle: azáltal, hogy lehetővé teszi számunkra, hogy projektspecifikus kódellenőrzéseket hajtsunk végre, vagy automatikus refaktoráló eszközöket futtassunk a kódbázison. Segítettünk az ügyfeleknek a nagyon nagy kódbázisok korszerűsítésében a szerszámok használatával-ami nem lett volna megvalósítható számukra költségesen, manuálisan.
lépjen kapcsolatba velünk
kategóriák: C++ / funkcionális biztonság / hogyan kell / KDAB blogok / KDAB a Qt-N / szerszámozás
címkék: automatikus refaktorálás / C++ / C++11 / C++14 / csengés / LLVM