Clang-Tidy, 1. rész: modernizálja a forráskódot a C++11/C++14automatizált refactoring a forráskód segítségével erőteljes nyílt forráskódú Szerszámok

16.03.2017 Kevin Funk

 Facebook  Twitter  LinkedIn  e-mail

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

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.

LLVM logo -- home of clang-tidy

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

Facebook Twitter  LinkedIn  e-mail

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

Kevin Funk vezető szoftvermérnök

Vélemény, hozzászólás?

Az e-mail-címet nem tesszük közzé.