Úvod do modulárneho programovania
nástroj make, konfiguračný súbor Makefile,
statická analýza kódu, formátovanie kódu
Video pre cvičenie
Motivácia
V prvom zadaní, do ktorého sa tento týždeň pustíte, budete mať okrem
iného za úlohu vytvoriť dva samostatné moduly. Aby ste ich zvládli
vytvoriť a správne manažovať, naučíte sa na tomto cvičení konfigurovať
nástroj make pomocou jeho konfiguračného súboru
Makefile. Táto znalosť vám v budúcnosti pomôže pri práci na
rozsiahlejších projektoch, ktoré sa budú skladať z viacerých
samostatných modulov.
Ciele
- Naučiť sa vytvoriť vlastný konfiguračný súbor
Makefile. - Naučiť sa vytvárať vlastné ciele (targets) v súbore
Makefile. - Naučiť sa základy práce s nástrojom
cppcheck. - Naučiť sa základy práce s nástrojom .
- Porozumieť významu modulárneho programovania.
Postup
Funkcia
reverse()
Aby sme nepracovali s prázdnym kódom, urobíme v tomto kroku naivnú
implementáciu funkcie reverse(), ktorá patrí do modulu
bmp. Jej implementáciu umiestnime do súboru
bmp.c a odskúšame ju v súbore main.c.
Úloha
V súbore bmp.c vytvorte implementáciu funkcie
reverse().
Pre jednoduchosť vytvoríme veľmi naivnú implementáciu tejto funkcie. Naša implementácia bude vyzerať takto:
char* reverse(const char* text){
// returns reversed string "Hello world!"
return "!DLROW OLLEH";
}Poznámka
Ak už máte vytvorenú vlastnú implementáciu funkcie
reverse(), nemusíte v tomto kroku robiť nič. Budete
pracovať s ňou.
Úloha
Otestujte vytvorenú funkciu reverse() v hlavnej funkcii
main() v súbore main.c.
Pre otestovanie môžete použiť napr. fragment kódu, ktorý sa nachádza
v opise funkcie reverse() v špecifikácii zadania:
#include <stdio.h>
#include "bmp.h"
int main(){
char* reversed = reverse("Hello world!");
printf("%s\n", reversed);
// "!DLROW OLLEH"
}Úloha
Preložte a spustite projekt.
Program sa pokúste preložiť pomocou prekladača gcc spolu
so zoznamom všetkých prepínačov, ktoré sú uvedené na stránke zadania Top Secret. Výsledný
spustiteľný súbor nech sa volá jednoducho ps1.
Úloha
Aktualizujte svoj projekt na GitLab-e.
Okrem aktualizovania lokálneho repozitára nezabudnite váš projekt odoslať aj do vzdialeného repozitára.
Konfiguračný súbor
Makefile
V tomto kroku si vytvoríte svoj vlastný súbor Makefile,
ktorý povie nástroju make čo má robiť. Súbor
Makefile sa skladá zo zoznamu pravidiel, pomocou ktorých
nástroj make preloží a zostaví výsledný program. Tento
súbor sa používa hlavne vtedy, ak pracujete na projekte, ktorého kód je
uložený vo viacerých súboroch, ako len v jednom.
Úloha
Vytvorte v súbore Makefile pravidlo s názvom cieľa
ps1, pomocou ktorého bude možné preložiť celý program.
Každé pravidlo v súbore Makefile má nasledovnú
štruktúru:
target: dependencies
command
...
commandVýznam jednotlivých častí pravidla je nasledovný:
target- Predstavuje názov pravidla (z angl. cieľa). Týmto názvom môže byť názov súboru, ktorý sa má vytvoriť (napr. výsledná spustiteľná binárka alebo objektový súbor), ale rovnako to môže byť len názov úlohy alebo akcie, ktorá sa má vykonať (napr. spustením úlohy s názvomcleansa zmažú všetky preložené súbory). V prípade nášho prekladu pomocou prekladačagccto môže byť napr. názov výsledného spustiteľného programu, ktorým jeps1.dependencies- Zoznam súborov, na ktorých závisí zostavenie cieľa (alebo vykonanie pravidla). Tieto súbory musia existovať predtým, ako sa začnú vykonávať jednotlivé príkazy. V prípade nášho prekladu pomocou prekladačagccbude zoznam závislostí tvorený všetkými zdrojovými súbormi (s príponou.c).commands- Zoznam príkazov, ktoré sa vykonajú na zostavenie daného cieľa. V prípade nášho prekladu pomocou prekladačagccbude zoznam príkazov tvorený len jediným príkazom na preloženie a zostavenie výsledného spustiteľného súboru.
Poznámka
Existujú pravidlá, kde je zoznam príkazov prázdny. V našom prípade to
bude pravidlo s cieľom all, ktoré si vytvoríme neskôr počas
cvičenia.
Upozornenie
Je veľmi dôležité, aby prvý znak pred každým príkazom (tzv.
oddeľovač, z angl. separator) bol znak tabulátor. Ak
sa tam bude nachádzať znak medzera, súbor Makefile nebude
valídny a nástroj make skončí s chybou.
Ak pre programovanie používate editor vim a v jeho
konfigurácii je explicitne uvedená voľba set expandtab na
nahradenie znaku tabulátor uvedeným počtom medzier, potrebujete
ju vypnúť. Pre otvorený súbor môžete túto voľbu potlačiť napísaním
príkazu v príkazovom režime:
:set noexpandtab
Výsledné pravidlo v súbore Makefile bude vyzerať
nasledovne:
ps1: bmp.c main.c playfair.c
gcc -std=c11 -Wall -Werror -g playfair.c bmp.c main.c -lm -o ps1Úloha
Overte funkčnosť vytvoreného cieľa.
Funkčnosť overíte spustením príkazu make nasledovne:
$ make TARGETkde TARGET je názov cieľa, ktorý chcete spustiť.
Ak ste postupovali správne, po spustení príkazu make
dôjde k preloženiu programu a vytvoreniu spustiteľného súboru
ps1.
Poznámka
Ak pri spúšťaní príkazu make neuvediete žiadny cieľ,
spustí sa prvé pravidlo v poradí, ktoré sa v súbore
Makefile nachádza.
Ak spustíte príkaz make viackrát za sebou, môžete si
všimnúť, že nedôjde k opätovnému zostaveniu cieľa, pretože nedošlo k
zmene v závislostiach. Ak však v niektorom zo súborov so zdrojovým kódom
urobíte zmenu (stačí použiť len príkaz touch), dôjde k
opätovnému prekladu.
$ touch main.c
$ make ps1Moduly a objektové súbory
Aktuálne nám vytvorené pravidlo umožňuje preložiť celý program naraz.
Pravidlo závisí na troch zdrojových súboroch, čo znamená, že výsledný
program je možné rozdeliť do troch modulov: main,
playfair a bmp.
Každý z týchto modulov je možné preložiť samostatne, čím sa vždy vytvorí tzv. objektový súbor. Spojením objektových súborov a prilinkovaním potrebných knižníc nakoniec dôjde k vytvoreniu spustiteľného súboru.
Vytvoríme teda tri nové pravidlá s názvami main.o,
playfair.o a bmp.o, kde v každom jednom
vytvoríme objektový súbor konkrétneho modulu programu. Pre vytvorenie
objektového súboru použijeme pri preklade prepínač -c.
Poznámka
Prepínač -c umožňuje preložiť program bez spojenia
(zlinkovania) zdrojových súborov. Výstupom takéhoto prekladu je
objektový súbor. To znamená, že pri vytváraní objektového súboru nie je
potrebné pridávať zoznam knižníc pre linkovanie.
Úloha
Vytvorte v súbore Makefile pravidlá pre zostavenie
objektových súborov main.o, playfair.o a
bmp.o.
Ako bolo uvedené, pre vytvorenie objektového súboru použijeme pri
preklade prepínač -c a nebudeme linkovať žiadnu knižnicu.
Pravidlo pre zostavenie modulu bmp.o bude vyzerať
takto:
bmp.o: bmp.c gcc -std=c11 -Wall -Werror -g -c bmp.c -o bmp.o
Podobným spôsobom zostavte zostávajúce pravidlá.
Poznámka
Pri vytváraní objektových súborov si dajte pozor, aby ste ich
zbytočne nepridávali do vášho Git projektu. Aby ste sa tomu
vyhli, odporúčame vám vytvoriť si samostatný súbor
.gitignore v koreňovom priečinku vášho projektu (to je ten
priečinok, v ktorom sa nachádza priečinok .git/). Do tohto
súboru je následne možné pridať zoznam súborov a priečinkov, ktoré sa do
Git repozitára nedostanú. V našom prípade môže tento súbor
vyzerať takto:
# content of .gitignore
*.o
Úloha
Overte funkčnosť vytvorených pravidiel.
Ak ste postupovali správne, po spustení akéhokoľvek pravidla príkazom
make dôjde k vytvorenie príslušného objektového súboru.
Poznámka
Ak pracujete v príkazovom riadku OS Linux, môžete využiť
kláves TAB. Po napísaní príkazu make a
stlačení klávesy TAB sa vám zobrazí zoznam pravidiel, ktoré
sú zadefinované v súbore Makefile:
$ make <TAB>
ps1 payfair.o bmp.o main.oRovnako funguje aj automatické dopĺňanie ich názvov pri písaní pravidla.
Úloha
Upravte a overte cieľ ps1 tak, aby do spustiteľného
súboru spojil (zlinkoval) aj vzniknuté objektové súbory.
Pri zostavovaní spustiteľného súboru sú zatiaľ vstupom pre preklad všetky zdrojové súbory. Teraz ich nahradíme vytvorenými objektovými súbormi.
Úloha
Vytvorte samostatné pravidlo pre zostavenie cieľa all,
ktoré bude závisieť len na existencii výstupného spustiteľného
súboru.
Pravidlo all zrejme nájdete vo vačšine projektov, ktoré
pre zostavenie výsledného programu používajú nástroj make a
súbor Makefile. Toto pravidlo vykoná všetko potrebné pre
zostavenie požadovaného výstupu.
Toto pravidlo bude jednoduché - bude obsahovať len názov cieľa a
zoznam závislostí, ktorý bude tvorený len spustiteľným súboro
ps1. Toto pravidlo nebude maž žiaden príkaz.
Úloha
Overte funkčnosť vytvoreného pravidla all.
Ak ste postupovali správne, k prekladu by malo dôjsť iba vtedy, ak
došlo k zmene v niektorom zo súborov uvedených v závislostiach.
Aktualizovať ktorúkoľvek z nich môžete jednoducho spustením príkazu
touch.
Premenné v súbore
Makefile
Vytvorený súbor Makefile aktuálne obsahuje množstvo
opakujúcich sa častí. Napríklad sa neustále opakuje rovnaký zoznam
volieb prekladača gcc. V súbore Makefile
môžeme tieto zápisy zjednodušiť použitím vlastných premenných. Tým
zjednodušíme prípadnú aktualizáciu týchto volieb v budúcnosti. Alebo aj
prípadnú výmenu prekladača gcc za iný.
Úloha
Pomocou premenných nahraďte v príkazoch realizujúcich preklad meno prekladača, zoznam jeho prepínačov a zoznam potrebných knižníc.
Vytvorenie premennej v súbore Makefile vyzerá podobne
ako v jazyku C, akurát nie je potrebné uvádzať jej typ:
VARIABLE=VALUENa mieste, kde budete chcieť hodnotu premennej použiť, zapíšete túto premennú v tvare:
$(VARIABLE)V súbore Makefile vytvorte tieto premenné:
CC- názov, resp. absolútna cesta k prekladačuCFLAGS- zoznam prepínačov pre prekladačLDLIBS- zoznam knižníc potrebných pre prekladTARGET- názov výsledného spustiteľného súboru
Poznámka
V súbore Makefile je možné rovnako používať aj
komentáre. Makefile podporuje len jednoriadkové komentáre.
Časť riadku, ktorá sa nachádza za znakom '#' bude
ignorovaná. V prípade, ak sa znak '#' nachádza na začiatku
riadku, bude ignorovaný celý riadok.
Úloha
Overte funkčnosť upraveného súboru Makefile.
Ak ste postupovali správne, použitie súboru Makefile je
bez zmien.
Úloha
V súbore Makefile použite automatické premenné, ktoré
nástroj make pozná.
Okrem používateľom definovaných premenných je možné v súbore
Makefile použiť aj tzv. automatické premenné. Ich
kompletný zoznam nájdete v dokumentácii
k nástroju make.
Pre potreby tejto úlohy si vystačíme s týmito automatickými premennými:
$@- názov vytváraného cieľa daného pravidla$^- zoznam všetkých závislostí (vstupných súborov)
Použitím uvedených premenných je možné upraviť napr. pravidlo pre
zostavenie objektového súboru playfair.o takto:
playfair.o: playfair.c
$(CC) $(CFLAGS) -c $^ -o $@Poznámka
V prípade, že má pravidlo len jeden vstupný súbor, na prístup k nemu
sa používa premenná $<. Najčastejšie sa používa v tzv.
implicitných pravidlách alebo v pravidlách, kde je len
jeden vstupný súbor.
Úloha
Overte funkčnosť aktualizovaných pravidiel.
Pokiaľ ste postupovali správne, funkcionalita zostane nezmenená.
Implicitné pravidlá
Aktuálny zoznam pravidiel obsahuje tri pravidlá na zostavenie troch rôznych modulov. Jednotlivé pravidlá sa však od seba odlišujú len názvami vstupných a výstupných súborov. Ak by sme takýmto spôsobom mali organizovať projekt s 1000+ súbormi, nebolo by to veľmi praktické.
V súbore Makefile je však možné vytvoriť aj tzv.
implicitné pravidlá. Tieto pravidlá dokážu automaticky
spracovať určité typy súborov bez toho, aby sme museli pre ne písať
vlastné pravidlá. My si takéto implicitné pravidlo vytvoríme pre
zostavenie objektových súborov.
Úloha
Vytvorte implicitné pravidlo pre zostavenie objektových súborov zo všetkých zdrojových súborov.
Pri tvorbe implicitných pravidiel sa používa zástupný znak
(z angl. wildcard) %, ktorý nahrádza názov súboru
bez prípony. Implicitné pravidlo pre zostavenie objektových
súborov zo zodpovedajúcich zdrojových súborov bude vyzerať
nasledovne:
%.o: %.c
$(CC) $(CFLAGS) -c $< -o $@Úloha
Overte funkčnosť vytvoreného pravidla.
Aby bolo možné implicitné pravidlo overiť, ostatné pravidlá,
ktoré doteraz slúžili na vytváranie objektových súborov buď
zakomentujte alebo rovno zmažte. Funkcionalita samotného súboru
Makefile zostane nezmenená, ale jeho obsah sa výrazne
zmenší.
Zostavenie projektu od začiatku po spustenie
Pomocou súboru Makefile je možné vytvoriť tzv.
build pipeline. Jedná sa o postupnosť krokov, pomocou
ktorej je možné zostaviť celý projekt - od čistého stavu, cez jeho
preklad, testovanie až po jeho spustenie, prípadne nasadenie. Tieto
kroky môžeme vytvoriť pomocou pravidiel v súbore Makefile a
zreťazíme ich pri volaní príkazu make. V tomto kroku
vytvoríme tieto pravidlá:
clean- Zmaže priebežne vytvorené súbory, ktoré vznikli pri preklade.build- Preloží a zostaví výsledný projekt.run- Spustí projekt.
Po vytvorení budeme vedieť spustiť celú postupnosť zadaním príkazu:
$ make clean build runÚloha
Premenujte pravidlo na zostavenie výsledného spustiteľného súboru na
build a otestujte ho.
Súbor Makefile obsahuje pravidlo na zostavenie
výsledného spustiteľného súboru, ktorého názov sa nachádza v premennej
$(TARGET). Aby sme však zostavenie výsledného spustiteľného
súboru zovšeobecnili, premenujeme toto pravidlo na
build:
build: playfair.o bmp.o main.o
$(CC) $(CFLAGS) $^ $(LDLIBS) -o $(TARGET)Poznámka
Nezabudnite aktualizovať aj pravidlo all:
all: buildÚloha
Vytvorte pravidlo run, ktoré spustí vytvorený program a
otestujte ho.
Po zavolaní pravidla build bude vytvorený spustiteľný
súbor ps1. Vytvoríme preto jednoduché pravidlo s názvom
run, ktoré tento súbor spustí.
Upozornenie
Závislosťou tohto pravidla nebude súbor ps1, ako by sa
mohlo zdať, ale pravidlo build! Ak by totiž závislosťou bol
súbor ps1 a tento súbor by ešte neexistoval, príkaz
make by skončil chybou:
make: *** No rule to make target 'ps1', needed by 'run'. Stop.
Aby sa zostavenie a následné spustenie vykonali správne, muselo by v
súbore Makefile existovať pravidlo s názvom
ps1, ktoré by tento súbor vedelo vytvoriť. Preto je
vhodnejšie ako závislosť uviesť celé pravidlo build, ktoré
zabezpečuje vytvorenie výsledného súboru. Tým sa zaručí, že pred
spustením programu prebehne jeho kompletné zostavenie.
run: build
./$(TARGET)Úloha
Vytvorte pravidlo s názvom cieľa clean, pomocou ktorého
zmažete z disku vytvorený spustiteľný súbor a všetky ostatné objektové
súbory .o a otestujte ho.
Upozornenie
Dajte si pozor, aby ste nesprávnym zápisom tohto cieľa nezmazali všetky súbory nachádzajúce sa vo vašom projekte!
Toto pravidlo nebude mať žiadne závislosti a môže vyzerať napríklad takto:
clean:
rm -rf $(TARGET) *.oÚloha
Otestujte vytvorené pravidlá spustením celej build pipeline.
Ak ste postupovali správne, celú build pipeline môžete otestovať spustením príkazu:
$ make clean build runÚloha
Definujte pravidlo pre cieľ .PHONY a uveďte v ňom všetky
ciele, ktoré nepredstavujú skutočné súbory.
Cieľ .PHONY je špeciálny cieľ v súbore
Makefile, ktorým označujeme tzv. falošné
(ne-súborové) ciele. Ciele uvedené ako závislosti pravidla
.PHONY sa vykonajú vždy, bez ohľadu na to, či existuje
súbor s rovnakým názvom. Tým sa predchádza neželanému správaniu pri
kontrole časových pečiatok súborov.
Používa sa na označenie pravidiel, ktoré nevytvárajú žiadny súbor,
ale vykonávajú určitú činnosť, ako napr. clean,
run alebo help.
Pravidlo definujúce špeciálny cieľ .PHONY sa v súbore
Makefile obyčajne umiestňuje pred prvé pravidlo. V našom
prípade bude vyzerať takto:
.PHONY: all build clean runExtending Tasks with Additional Commands
Vytvorené pravidlá v súbore Makefile aktuálne obsahujú
len jeden príkaz na preklad a vytvorenie objektového súboru. V tomto
kroku do procesu zostavovania výsledného projektu pridáme nástroj
cppcheck, ktorý zabezpečí statickú analýzu kódu, a nástroj
uncrustify, ktorý zabezpečí preformátovanie kódu.
Výhodou bude, že ak niektorý zo zdrojových súborov neprejde statickou analýzou kódu, preklad a zostavovanie programu sa zastaví.
Úloha
Každé pravidlo začnite výpisom informácie o spúšťanom pravidle.
Každé pravidlo môže byť tvorené zoznamom príkazov spustiteľných v
príkazovom riadku. Ak chceme v príkazovom riadku vypísať reťazec na
obrazovku, použijeme na to príkaz printf v tvare:
$ printf "Hello, world!\n"Implicitné pravidlo pre zostavenie objektových súborov bude vyzerať takto:
%.o: %.c
printf "Building object file $@\n"
$(CC) $(CFLAGS) -c $< -o $@Poznámka
Miesto príkazu printf je možné použiť aj príkaz
echo. Tento príkaz však nie je úplne prenositeľný medzi
rozličnými shell-mi. Obecne je viac odporúčané používať príkaz
printf, pretože je bezpečnejší, spoľahlivejší a viac
prenositeľný. Ďalšie dôvody, prečo používať printf miesto
echo nájdete napr. na tomto
odkaze.
Úloha
Potlačte výpis príkazov, ktoré sa majú vykonať.
Predtým, ako sa ľubovoľný príkaz v zozname príkazov pravidla vykoná,
ho príkaz make vypíše na obrazovku. To však môže pôsobiť
veľmi rušivo a v prípade príkazu printf aj zbytočne.
Ak chceme potlačiť vypísanie príkazu na obrazovku, tak pred príkaz
pridáme znak '@'. Potlačíme však len vypísanie príkazu
printf a príkaz pre preklad si naopak vypísať necháme, aby
sme videli jeho tvar pre prípadné neskoršie ladenie.
Implicitné pravidlo pre zostavovanie objektových súborov bude vyzerať takto:
%.o: %.c
@printf "Building object file $@\n"
$(CC) $(CFLAGS) -c $< -o $@Úloha
Zabezpečte, aby sa pred spustením prekladu vykonala statická analýza
kódu pomocou nástroja cppcheck.
Ako bolo uvedené vyššie, v jednom pravidle sa môže nachádzať aj viac príkazov ako len jeden. Ak sa tak stane, tak v prípade, že dôjde pri vykonávaní niektorého z nich ku chybe (návratový kód príkazu bude iný ako 0), žiadne ďalšie príkazy sa nebudú vykonávať. Túto vlastnosť je možné s výhodou využiť v procese vytvorenia spustiteľného programu, kedy pred samotným prekladom spustíme statickú analýzu kódu. V prípade, že táto analýza zlyhá, proces vytvárenia programu sa okamžite skončí.
Nástroj cppcheck slúži
na statickú analýzu kódu. Pri kontrole zadaní sa cppcheck
bude používať nasledovne:
$ cppcheck --enable=performance,unusedFunction --error-exitcode=1 *.cMiesto toho, aby sme však tento príkaz zakaždým písali so všetkými
voľbami, ho budeme používať pomocou premennej CPPCHECK. Tým
vieme jednoducho upravovať zoznam jeho volieb podľa potrieb:
CPPCHECK = cppcheck --enable=performance --error-exitcode=1Implicitné pravidlo pre zostavovanie objektových súborov bude so statickou analýzou kódu vyzerať takto:
%.o: %.c
@printf "Building object file $@\n"
@$(CPPCHECK) $<
$(CC) $(CFLAGS) -c $< -o $@Úloha
Zabezpečte, aby sa pred spustením prekladu vykonalo formátovanie kódu.
Ak pracujete s veľkými vývojovými prostrediami, obyčajne obsahujú aj možnosť preformátovať kód. Túto operáciu je možné vykonať automaticky (napr. pri ukladaní súboru) alebo ručne.
Aj napriek tomu, že editor Vim vie tiež formátovať kód,
formátovanie kódu spustíme pri vykonávaní príkazov konkrétneho pravidla
v súbore Makefile. Na formátovanie budeme používať nástroj
uncrustify.
Jeho ukážkovú konfiguráciu nájdete v súbore uncrustify.cfg.
Opäť si môžeme najprv vytvoriť samostatnú premennú so všetkými voľbami pre formátovanie kódu:
FORMAT_CODE = uncrustify --no-backup --replace -qImplicitné pravidlo pre zostavovanie objektových súborov bude s formátovaním kódu vyzerať takto:
%.o: %.c
@printf "Building object file $@\n"
@$(FORMAT_CODE) $<
@$(CPPCHECK) $<
$(CC) $(CFLAGS) -c $< -o $@Ďalšie pravidlá a tipy
Na záver si ukážeme ešte niekoľko tipov, ako je možné s nástrojom
make a so súborom Makefile pracovať
efektívnejšie.
Úloha
Upravte výpisy správ v jednotlivých pravidlách pomocou príkazu
printf tak, aby používali farby.
Predvolený výstup v príkazovom riadku je zvyčajne iba čiernobiely, resp. dvojfarebný (farba pozadia a farba popredia). Moderné terminály však podporujú tzv. ANSI escape sekvencie, ktoré umožňujú meniť farbu textu, pozadia aj štýl písma (napr. tučné alebo podčiarknuté). Vložením týchto riadiacich sekvencií do výstupu je možné zobrazovať správy farebne, čím bude výstup prehľadnejší. Táto technika sa často používa v skriptoch na zvýraznenie chýb, upozornení alebo stavových hlásení.
Princíp použitia je možné vidieť v nasledujúcom výpise, ktorého výsledkom bude tučný podčiarknutý text vypísaný červenou farbou:
$ printf "\e[1;4;31mHello world!\e[0m\n"Význam jednotlivých častí je nasledovný:
\e[- začiatok ANSI sekvencie1;4;31- tučný text (1), podčiarknutý text (4), červená farba textu (31)m- koniec sekvencie\e[0m- reset farieb (ak by sme text neukončili touto sekvenciou, červenou farbou by bol vypisovaný každý ďalší text) (samotná escape sekvencia je pritom len0)
Prehľad základných farieb, ktoré môžete použiť na farbu textu a pozadia, sa nachádza v nasledujúcej tabuľke:
| color | black | red | green | yellow | blue | magenta | cyan | white |
|---|---|---|---|---|---|---|---|---|
| text | 30 |
31 |
32 |
33 |
34 |
35 |
36 |
37 |
| background | 40 |
41 |
42 |
43 |
44 |
45 |
46 |
47 |
Okrem toho je možné použiť ďalšie kódy pre zmenu štýlu. Ich prehľad sa nachádza v nasledujúcej tabuľke:
| názov | ANSI kód | opis |
|---|---|---|
| reset | 0 |
návrat do predvoleného nastavenia textu |
| bold | 1 |
tučné písmo |
| faint/dim | 2 |
zníži intenzitu textu (nie je podporované v každom termináli) |
| italic | 3 |
kurzíva (nie je podporované v každom termináli) |
| underline | 4 |
podčiarknuté |
Kompletný zoznam sekvencií je možné nájsť napríklad v giste Bash Colors.
Pre zjednodušenie vytvárania ANSI escape sekvencií pre formátovanie textu však môžete využiť ANSI Color Code Generator, kde si príslušnú sekvenciu môžete vytvoriť pomocou webového prehliadača.
Do súboru Makefile môžeme teda pridať premenné, ktoré
budú reprezentovať základné farby:
COLOR_RED = \e[31m
COLOR_GREEN = \e[32m
COLOR_YELLOW = \e[33m
COLOR_BLUE = \e[34m
COLOR_MAGENTA = \e[35m
COLOR_RESET = \e[0mNásledne ich môžeme použiť v jednotlivých pravidlách napr. takto:
%.o: %.c
@printf "$(COLOR_MAGENTA)Building object file $@$(COLOR_RESET)\n"
@$(FORMAT_CODE) $<
@$(CPPCHECK) $<
@$(CC) $(CFLAGS) -c $< -o $@Odteraz bude sprievodný text pri zostavovaní objektového súboru vypisovaný fialovou farbou.
Úloha
Rozšírte svoj súbor Makefile o pravidlo/target
help, pomocou ktorého vypíšete zoznam všetkých pravidiel aj
s dokumentáciou pravidiel samotných.
Nástroj make neobsahuje voľbu, pomocou ktorej by bolo
možné jednoducho zobraziť zoznam všetkých pravidiel. Práve na tento účel
si je možné vytvoriť vlastné pravidlo help, ktoré túto
funkcionalitu zabezpečí. Obyčajne sa jedná o jednoduchý skript, ktorý sa
pozrie do obsahu súboru Makefile a vyextrahuje z neho
pravidlá.
Pravidlo help teda nepotrebujeme vytvárať sami, ale
môžeme si pomôcť s už existujúcimi implementáciami, ako je napríklad tá,
ktorá sa nachádza v tomto
článku. Upravená a čitateľnejšia podoba tohto pravidla môže vyzerať
napríklad takto:
help: ## Show this help.
@awk ' \
BEGIN { \
FS = ":.*##"; \
printf "\nUsage:\n make \033[36m<target>\033[0m\n" \
} \
/^[a-zA-Z0-9_-]+:.*##/ { \
printf " \033[36m%-15s\033[0m %s\n", $$1, $$2 \
} \
/^##@/ { \
printf "\n\033[1m%s\033[0m\n", substr($$0, 5) \
} \
' $(MAKEFILE_LIST)Toto pravidlo vložte do svojho súboru Makefile na
koniec, aby sme zachovali konvenciu, že prvé pravidlo, ktoré sa spustí
bez uvedenia názvu pravidla, bude pravidlo all.
Upozornenie
Nezabudnite na to, že príkaz pravidla (awk) musí byť
odsadený znakom TAB!
Vďaka príkazu awk je možné k pravidlám pridávať aj
dokumentáciu, prípadne robiť aj skupiny pravidiel:
Dokumentácia pravidla - Stačí, ak za pravidlo pridáte komentár cez
##, napr.:all: build ## Build all.Skupiny pravidiel - Stačí pridať samostatný riadok, ktorý začne trojicou znakov
##@, čím bude vytvorená skupina, napr.:##@ Build
Ak pravidlo help spustíte, zobrazí sa vám zoznam
pravidiel spolu s komentárom pre ich použitie:
$ make help
Usage:
make <target>
all Build all
build Compile project
clean Clean the mess
run Run project
help Show this helpĎalšie zdroje
Znenie zadania č. 1 - Top Secret
GNU Make - dokumentácia k nástroju
make(a súboruMakefile)Beautiful Makefile help messages with awk - ako vytvoriť pravidlo
help, ktoré vypíše pomocníkaGitHubGist pre pravidlo
help- množstvo ďalších príkladov, ako spraviť pomocníka pravidlohelpuncrustify- formátovač kóducppcheck- nástroj na statickú analýzu C/C++ kóduastyle- A Free, Fast, and Small Automatic Formatter for C, C++, C++/CLI, Objective-C, C#, JS, GSC, and Java Source CodeANSI Escape Code - ANSI escape sequences are a standard for in-band signaling to control cursor location, color, font styling, and other options on video text terminals and terminal emulators.
Bash Colors - The entire table of ANSI color codes.