wtorek, 4 kwietnia 2017

Hardcore - Kompilacja programu pod własny procesor, cz.2 - makepkg.conf

Zasadniczym plikiem, który w Archu (bądź szerzej w dystrybucjach pacmanowych) przekazuje informacje sterujące procesem kompilowania jest makepkg.conf wykorzystywany przez program makepkg. Dla niezaznajomionych, to on jest wykorzystywany przez różne AUR-helpery dla budowania programów z AUR. Z niego korzystamy również kompilując lokalnie program.
Pośród opcji tego pliku znajdziemy również dwie, które powodują, że kompilator języka C/C++ stara się zoptymalizować kod programu pod procesor, jaki tam został zadeklarowany. Są to zmienne: CFLAGS, CXXFLAGS oraz CPPFLAGS.
Standardowo (tj. bezpośrednio po zainstalowaniu pacmana) wyglądają one tak (dla procesorów 64bitowych):
CFLAGS="-march=x86-64 -mtune=generic -O2 -pipe -fstack-protector-strong"
CXXFLAGS="-march=x86-64 -mtune=generic -O2 -pipe -fstack-protector-strong"
Interesujące będą dla nas dwie: march i mtune. W powyższym przykładzie (czyli standardowo), zbudowany z użyciem skryptu makepkg program będzie dostosowany do każdego procesora 64bitowego. Możemy to prosto zmienić, edytując plik /etc/makepkg.conf. Możemy się zdecydować na to, by sam kompilator "odgadł" jakie flagi kompilacyjne winien zastosować. Wówczas w miejscu x86-64 oraz generic wpisujemy native.
Możemy jednak nie wierzyć automatowi i spróbować dokładniej określić jakie flagi winny tu zostać użyte, tak by na pewno odpowiadały naszemu procesorowi. Wpierw musimy jednak poznać te flagi. Wydajemy w tym celu polecenie:
gcc -march=native -E -v - </dev/null 2>&1 | sed -n 's/.* -v - //p'
Teraz pozostaje nam odnalezienie odpowiednich pozycji po słowach march i mtune oraz ich wpisanie jako zmiennych w pliku /etc/makepkg.conf.
W moim przypadku (mam procesor AMD serii Piledriver) może to wyglądać tak:
CFLAGS="-march=native -mtune=native -O2 -pipe -fstack-protector-strong"
CXXFLAGS="-march=native -mtune=native -O2 -pipe -fstack-protector-strong"
lub
CFLAGS="-march=bdver2 -mtune=bdver2 -O2 -pipe -fstack-protector-strong"
CXXFLAGS="-march=bdver2 -mtune=bdver2 -O2 -pipe -fstack-protector-strong"
Niestety te zmienne nie działają dla programów używających cmake bądź qmake (zob. poradnik, choć niebawem jego uproszczenie) przy kompilacji.
Musimy również pamiętać, że tak zbudowany program może w ogóle nie zadziałać na innym procesorze (np. po jego wymianie). Nie będzie też "przenośny" w tym sensie, że zbudowany z takimi flagami program może nie pracować na innym komputerze, działającym na innym procesorze.