MAKE

gcc make - Build from source

De naam van dit artikel op onze site was build-from-source, maar om het beter in dit boek te laten passen heb ik het hier make genoemd.

Vandaag gooien we onze CLI Tool van de week eens over een andere boeg. In plaats van een specifieke CLI tool of toepassing te bespreken gaan we een programma compileren vanaf de Linux commando-regel. Met de komst van pakketbeheerder zoals apt, yum, dnf, PACMAN, etc. etc. Komt dit veel minder voor dan in de tijd dat ik met Linux begon, maar dit kan nog steeds nodig zijn als het programma niet beschikbaar is in een softwarebibliotheek (Repository of Repo) van jouw distributie of als je een nieuwere versie van een bepaald programma wil gebruiken dan de versie aangeboden door jouw distributie.

Het programma dat ik ga gebruiken in dit voorbeeld is alpine 2.21, alpine is een console/terminal email en USENET programma gebaseerd op pine. De versie die zowel op mijn Debian Stretch Laptop/Desktop als mijn Raspbian Pi beschikbaar is is alpine 2.20 en de laatste versie die ik momenteel kan downloaden 1 is versie 2.21. Deze patches worden door Alpine beschouwd als “unofficial patches”.

Eén van de redenen waarom ik upgrade van 2.20 naar 2.21 is omdat 2.21 een veiliger wachtwoord bestand gebruikt (S/MIME encryptie) en 2.20 in de configuratie die bij Debian komt vraagt bij het opstarten niet naar een “Master Password” om het wachtwoord bestand te downloaden.

Omdat er voor het installeren van software vanaf broncode veel extra (-dev) pakketten nodig zijn, kan het een tijdje duren voor je de correcte “dependencies” geïdentificeerd en geïnstalleerd hebt.

Voor dit artikel gebruik ik een maagdelijke installatie van Debian GNU/Linux 9.2 (Stretch) zonder desktopomgeving. Hierdoor zal ik dus de meeste “dependencies” nog moeten installeren.

Laten we beginnen:

eerst downloaden we de broncode van alpine 2.21 naar ~/Downloads

$ cd ~/Downloads

$ wget http://alpine.freeiz.com/alpine/release/src/alpine-2.21.tar.xz

Figuur 1. $ wget http://alpine.freeiz.com/alpine/release/src/alpine-2.21.tar.xz

Vervolgens gaan we het bestand uitpakken en gaan we de aangemaakte directory in:

$ tar xf alpine-2.21.tar.xz

$ cd alpine-2.21

$ ls

Figuur 2. $ ls

Omdat we al zeker enkele “build-essentials” nodig hebben gaan we die eerst installeren:

$ sudo apt update && sudo apt install build-essential gcc make tcl8.5-dev tcl8.6-dev -y

Figuur 3. $ sudo apt update && sudo apt install build-essential gcc make tcl8.5-dev tcl8.6-dev -y

Nu gaan we voor de eerste keer ./configure uitvoeren en kijken welke foutmeldingen we krijgen 2, en zo dus proberen te achterhalen wat we nog moeten installeren. Omdat ik mijn “oud” wachtwoord bestand van alpine 2.21 wil kunnen gebruiken ga ik de optie : –with-passfile=.alpine.pwd meegeven, het wachtwoordbestand bij Alpine 2.20 op Debian is .pine-passfile dus ik ga deze moeten kopiëren naar .alpine.pwd. Ik kan ook de oude naam als optie meegeven en deze gebruiken, maar alpine 2.21 zal dit bestand “upgraden” en dus kan ik deze niet meer gebruiken met een oudere versie van Alpine (indien ooit nodig) en nu kan ik zowel alpine 2.20 als alpine 2.21 draaien zonder dat 1 van de 2 het wachtwoord bestand zodanig aanpast dat de andere er problemen mee heeft.

$ ./configure –with-passfile=.alpine.pwd

Figuur 4. $ ./configure –with-passfile=.alpine.pwd

Als we bovenstaande output gaan analyseren zien we dat er een paar dingen ontbreken:

Sommige zullen niet fataal zijn (hunspell is niet gevonden maar aspell wel, en als beiden ontbreken zal de spellingscontrole niet werken) en anderen zijn wel “fataal”, zoals we kunnen zien is termcap niet gevonden en loopt de configuratie daar op vast. dmalloc bijv. is voor “debugging” en niet nodig als je de ontwikkelaar niet wil helpen met het zoeken/oplossen van fouten. Wat ik nu doe is per optie waar no staat kijken of ik een pakket kan vinden dat deze functie bevat en dan installeer ik deze, in de hoop dat dit ervoor zal zorgen dat deze functie wel zal werken in het uiteindelijke gecompileerde alpine 2.21

Figuur 5. $ apt search inews

$ sudo apt install libdmalloc-dev sendmail hunspell-nl libtinfo-dev

Figuur 6. $ sudo apt install libdmalloc-dev sendmail hunspell-nl libtinfo-dev

Hierna voeren we $ ./configure –with-passfile=.alpine.pwd opnieuw uit en kijken we of dit probleem is opgelost en of er nog een andere dependency is die we moeten oplossen (en dit is/zijn er).

Figuur 7. $ ./configure –with-passfile=.alpine.pwd

Het volgende “probleem” is openssl, om het aantal schermafbeeldingen te beperken ga ik hieronder enkel het commando geven om al de nodige pakketten te installeren, het concept zal nu wel duidelijk zijn.

$ sudo apt install openssl tcl-tls inn2-inews hunspell hunspell-nl libssl-dev libpam0g-dev gettext libtclcl-dev lua-ldap-dev libkrb5-dev tcl-dev ruby-tcltk tk8.5-dev tk8.6-dev

Om tcl correct geïdentificeerd te krijgen moeten we (op Debian tenminste) het ./configure commando uitbreiden met : –with-tcl-lib=”tcl8.6″ en –with-tcl-include=/usr/include/tcl8.6

Figuur 8. $ ./configure commando uitbreiden met : –with-tcl-lib=”tcl8.6″ en –wit-tcl-include=/usr/include/tcl8.6

Zonder deze toevoeging geeft het ./configure script de volgende foutmelding:

Figuur 9. $ ./configure –-with-passfile=.alpine.pwd | grep tcl

Met deze uitbreiding zal tcl correct geïdentificeerd worden:

Figuur 10. $ ./configure –-with-passfile=.alpine.pwd –-with-tcl-lib="tcl8.6" –-with-tcl-include=/usr/include/tcl8.6 | grep tcl

De foutmelding i.v.m. libtoolT kunnen we negeren, dit bestand is de eerste keer dat we ./configure uitgevoerd hebben al gewist en kan nu dus niet meer gevonden worden.

Goed, dus na het uitvoeren van het commando: ./configure –with-passfile=.alpine.pwd –with-tcl-lib=”tcl8.6″ –with-tcl-include=/usr/include/tcl8.6 en als de meeste foutmeldingen opgelost zijn, kunnen we verder gaan met het compileren van alpine. Dit doen we met het commando make en ook nu moeten we nog uitkijken naar eventuele foutmeldingen die ervoor kunnen zorgen dat het compileren van de software niet slaagt.

Figuur 11. $ make

Afhankelijk van de grootte van het programma en de snelheid van het systeem kan dit make proces snel klaar zijn of héél lang duren 3. Als je iets fout hebt gedaan en dit proces opnieuw wil/moet uitvoeren moet je eerst het commando make clean gebruiken en daarna make opnieuw uitvoeren. Als make zonder foutmeldingen afsluit is het programma correct gecompileerd en kunnen we het gaan testen.

Figuur 12. $ make

Ik kies ervoor om eerst te testen en daarna het programma pas “system-wide” te installeren. Ga in de alpine directory cd alpine (bij andere programma’s is dit meestal de bin directory). En start het programma op met ./alpine

Figuur 13. $ ./alpine

Na installatie ziet Alpine er zo uit, maar dit is volledig aan te passen aan jouw persoonlijke smaak. Omdat ik al een configuratiebestand (.pinerc) en een wachtwoord bestand (.pine-passfile) van een oudere installatie heb moet ik deze gewoon in mijn $HOME (~) directory plaatsen en het bestand .pine-passfile kopiëren naar .alpine.pwd (zoals boven beschreven). In onderstaande schermafbeelding zien we dat als ik de FOLDER LIST wil openen ik eerst mijn “Master Password” moet ingeven:

Figuur 14. Alpine Main Menu
Figuur 15. Alpine Message Index
Figuur 16. Alpine Binnengekomen Bericht Lezen

Nu alles correct werkt, kunnen we verder gaan met de “system-wide” installatie. Dit doen we simpelweg met $ sudo make install.

Figuur 17. $ sudo make install

Alpine 2.21 is nu volledig geïnstalleerd en klaar voor gebruik door iedere gebruiker van het systeem.

Figuur 18. README
———————————————————————–
BUILD PROCESS
———————————————————————–

The Alpine build process is based on GNU autotools. On most Unix
systems, generating a suitable Alpine binary from the source
distribution should be as simple as typing the commands:

./configure
make

For a list of configuration options and default Alpine settings type:

./configure –help

Note, the included UW IMAP Toolkit used for mailbox access does not
make use of GNU autotools. However, in most cases Alpine’s configure
script should set the appropriate make target and options. The
targetted OS can be set from Alpine’s configure command line, but in
rare cases more significant manual intervention may be required. If
problems are encountered, see imap/README for more details.

The PC-Alpine build is based on the Microsoft C compiler and
libraries. The Alpine Team bases builds on Visual Studio 8 from the
command line using the static build.bat batch and makefiles to
generate suitable binaries.

The Web Alpine application requires a few extra, manual steps to get
all the components built and installed. See web/README for an
explanation of the various components and web/INSTALL for a basic
installation recipe.    

Hopelijk kun je nu in de toekomst indien nodig zelf een programma installeren waarvoor geen installatiepakket of “binary” bestaat. Of misschien wil je wel een distributie waarbij je zo goed als alle software zelf moet compileren gaan gebruiken. Het voordeel hiervan is dat deze software gebouwd is voor jouw specifieke systeem en in theorie beter zou moeten werken dan pre-build biniaries.

Als extra heb ik nog de instructies nodig om Alpine te gebruiken met GnuPG sleutels om emails te ondertekenen en/of te versleutelen.

OI dit te kunnen gebruiken hebben we een extra “plugin” nodig met de naam ez-pine-gpg, deze kan hier gedownload worden. (ez-pine-gpg (tgz) 6K

Nadat we deze gedownload hebben moeten we het natuurlijk nog installeren. Ga hiervoor naar de directory waar je het bestand naar gedownload hebt (meestal ~/Downloads) en pak het bestand uit:

$ cd ~/Downloads

$ tar xf ez-pine-gpg_v0.4h.tgz

Nu gaan we de aangemaakte directory binnen en gaan we ez-pine-gpg installeren: $ cd ez-pine-gpg/

Bij de installatie kunnen we kiezen om een “global” install te doen of enkel voor de huidige gebruiker. voor de “globale” installatie kun je /usr/local/bin gebruiken en voor de huidige gebruiker ~/bin, kies je voor deze optie dan moet je eerst de directory bin aanmaken in ~ (mkdir ~/bin). Ik ga beide commando’s geven dus je moet er hier maar 1 van gebruiken, de eerste is de “globale” install en de tweede is de huidige gebruiker.
  1. $ sudo ./install /usr/local/bin
  2. $ ./install ~/bin

Na de installatie zal het installatiescript aangeven welke aanpassingen je moet maken in Alpine:

Now configure pine filters.
In pine, press: [M]ain [S]etup [C]onfigure
and add these filters:

display-filters = _LEADING(“—–BEGIN PGP”)_ /usr/local/bin/ez-pine-gpg-incoming
sending-filters = /usr/local/bin/ez-pine-gpg-sign-and-encrypt _INCLUDEALLHDRS_ _RECIPIENTS_
/usr/local/bin/ez-pine-gpg-encrypt _RECIPIENTS_
/usr/local/bin/ez-pine-gpg-sign _INCLUDEALLHDRS_            
        
You may also install the ez-pine-gpg-symmetric sending filter. See the README for details.        

Hoewel deze instructies voor pine zijn werken ze ook voor Alpine, maar Alpine start op in het hoofdmenu dus de M van main kun je weglaten. Dus start Alpine en druk op S en dan op C, je krijgt nu een hele lijst met dingen die je kunt instellen en de 2 filter opties staan bijna volledig onderaan deze lijst:

Figuur 19. Alpine Set-up : Display Filters

Geef de gegevens in zoals aangegeven door het installatiescript (dit is afhankelijk van de plaats waar je ez-pine-gpg geïnstalleerd hebt).

Figuur 20. Alpine set-up : Sending Filters

Volgens het installatiescript moeten we bij “Sending Filters” 3 regels ingeven, maar je moet ze ingeven als 1 lange regel gescheiden door een komma (,) :

/usr/local/bin/ze-pine-gpg-sign-and-encrypt _INCLUDEALLHDRS_ _RECIPIENTS_ ,
                /usr/local/bin/ez-pine-gpg-encryptý_RECIPIENTS_ , /usr/local/bin/ze-pine-gpg-sign
                _INCLUDEALLHDRS_

(of voor de mensen die het eboek of PDF bestand hebben: /usr/local/bin/ez-pine-gpg-sign-and-encrypt _INCLUDEALLHDRS_ _RECIPIENTS_ , /usr/local/bin/ez-pine-gpg-encrypt _RECIPIENTS_ , /usr/local/bin/ez-pine-gpg-sign _INCLUDEALLHDRS_

Als je nu op ENTER drukt zul je 3 verschillende regels met een “Sending Filter” te zien krijgen:

Figuur 21. Alpine : Sending Filters : 3 regels

ez-pine-gpg is nu geïnstalleerd en klaar voor gebruik, voorwaarde is wel dat je een GnuPG (GPG) sleutelpaar hebt gemaakt of beschikbaar hebt om te gebruiken. En hiermee komen we op een probleem met ez-pine-gpg en Alpine. Het “email adres” dat ez-pine-gpg gebruikt om te tekenen en te versleutelen is $USER + “User Domain”, het user domain kun je instellen in het configuratiescherm(zie afbeelding hieronder), maar de $USER (gebruikersnaam) is jouw Linux gebruikersnaam, dus als jouw username pkox is en je hebt linuxgebruikers.nl als domain ingesteld dan zal ez-pine-gpg zoeken naar een gpg-sleutel voor email account pkox@linuxgebruikers.nl nu kun je hiervoor wel een sleutel aanmaken, maar als het een niet bestaand email account is kan het wel verdacht overkomen bij de ontvanger van de email.

Figuur 22. Alpine : Setup Configuration

De laatste stap is nu om een versleutelde/getekende email te versturen om te testen of alles goed werkt

Sluit het configuratiescherm weer af met E en denk er deze keer ook weer aan om op te slaan door op Y te drukken. In het hoofdmenu druk je op C (compose) om een nieuwe email te schrijven en dan op N voor nieuwe email (indien jouw configuratie zo is ingesteld dat hierom gevraagd wordt).

Figuur 23. Alpine : Bericht opstellen

Als je email klaar is om te verzenden druk je op ^X (CTRL+X)

Figuur 24. Alpine : Bericht verzenden
Alpine stelt nu de vraag “Send message (unfiltered) ?” en als je nu op Y drukt zal de email zonder handtekening/versleuteling verstuurd worden. klik daarom op ^N (CTRL+N) voor Next Filter en kies de optie die je wil gebruiken. Er zijn 3 mogelijkheden:
  1. send message (filtered thru “ez-pine-gpg-sign-and-encrypt” ) ?
  2. send message (filtered thru “ez-pine-gpg-encrypt” ) ?
  3. send message (filtered thru “ez-pine-gpg-sign” ) ?
  • Optie 1 zal zowel een handtekening zetten als de email versleutelen (alle ontvangers moeten een bekende publieke sleutel hebben!)
  • Optie 2 zal enkel versleutelen, weerom is het noodzakelijk dat je de publieke sleutel hebt van iedere ontvanger van de mail.
  • Optie 3 zal enkel een handtekening zetten, hiervoor heb je geen publieke sleutels van de ontvangers nodig, maar de ontvangers hebben wel een kopie van jouw publieke sleutel nodig om de handtekening te kunnen verifiëren.

Optie 3 zal enkel een handtekening zetten, hiervoor heb je geen publieke sleutels van de ontvangers nodig, maar de ontvangers hebben wel een kopie van jouw publieke sleutel nodig om de handtekening te kunnen verifiëren.

laten we gaan voor optie 1 (je kunt met ^N eindeloos bladeren tussen deze filters, of terug gaan met ^P).

Figuur 25. Alpine : Bericht verzenden via ez-pine-gpg-sign-and-encrypt filter

Nu drukken we op Y om de email te verzenden (ez-pine-gpg zal nu overnemen en de wachtzin van de GPG sleutel vragen). Op dit moment krijg ik op mijn Rapsberry Pi3 met Raspbian Stretch en Alpine 2.21 deze foutmelding. Ik heb een mail gestuurd naar de ontwikkelaar 4 in de hoop dat hij dit probleem kan oplossen.

Figuur 26. Foutmelding op Raspberry Pi 3 met Raspbian

Omdat dit wel werkt met Gnome kan ik geen schermafbeelding maken, want het venster waar ik in de GUI een wachtzin moet ingeven staat dit om veiligheidsredenen niet toe.

Wel heb ik een schermafbeelding van de uiteindelijke email die ik in Alpine heb ontvangen:

Figuur 27. Alpine : Versleuteld bericht ontvangen

Na lang zoeken heb ik hier de oplossing gevonden voor mijn probleem.

Het “probleem” is dat nieuwe versies van GnuPG vanaf 2.1 de loopback-methode om het wachtwoord in te geven niet meer ondersteund, dit is een beveiliging want het pinentry systeem van gnupg is veiliger, maar dat werkt voorlopig niet met deze plugin. dus om dit op te lossen moeten we 2 bestanden aanpassen (of maken).

vi ~/.gnupg/gpg.conf en het volgende toevoegen:
Figuur 28. $ ~/.gnupg/gpg.conf
use-agent
 pinentry-mode loopback
En het de bestand vi~/.gnupg/gpg-agent.conf en het volgende toevoegen:
Figuur 29. $ vi ~/.gnupg/gpg-agent.conf
allow-loopback-pinentry

Nu kun je de computer opnieuw opstarten en Alpine zou nu ook getekende en versleutelde emails kunnen versturen vanaf een computer waarop geen X server draait. Wil je zoals een echte Linux gebruiker niet opnieuw opstarten kun je ook het volgende commando gebruiken: echo RELOADAGENT | gpg-connect-agent

Nu krijg je wel een veld op de wachtzin (of openPGP PIN) in te geven:

Figuur 30. Alpine : openPGP PIN ingeven.

En na het correct ingeven van deze wachtzin/PIN wordt de email versleuteld, getekend en verzonden. Maar in mijn geval pas na het ingeven van het Master Password om verbinding te kunnen maken met mijn SMTP server:

Figuur 31. Alpine : Master Password ingeven.
Figuur 32. Alpine : Bericht versleuteld en verzonden.
Figuur 33. Alpine : Versleuteld bericht lezen.

Meer informatie kun je altijd terugvinden in de manpages of de infopages

1 Bij het verwerken van dit artikel naar een hoofdstuk in dit CLI-Tool van de Week boek blijkt deze website niet meer te bestaan, maar de algemene instructies voor het compileren vanuit broncode blijven hetzelfde voor andere programma's
2 soms staat er in een READ.ME, INSTALL, README.TXT of dergelijk bestand de te volgen installatieprocedures en de nodige "dependencies", dat maakt het dus een stuk makkelijker.
3 Als je een processor hebt met meerdere "cores" dan kun je het make proces verdelen over verschillende cores waardoor het compileren sneller gaat. Hiervoor gebruik je make -J 8 om bijv. 8 processor cores te gebruiken.
4 De ontwikkelaar heeft ondertussen een reactie gestuurd, hij geeft aan dat deze plugin niet meer in "active development" is, dus ik verwacht geen oplossing voor dit probleem.