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

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

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

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

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

$ 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).

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

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

Met deze uitbreiding zal tcl correct geïdentificeerd worden:

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.

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.

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

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:

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

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

Opmerking:
  • zoals vermeld in de voetnoot komen veel van deze programma's met een tekst bestand met meer installatie informatie. Maar in het geval van Alpine bevat het README bestand bevat dit wat betreft het compileren/installeren van de software weinig informatie op dit gebied:
———————————————————————–
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:

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

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:

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.

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).

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

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).

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.

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:

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:
use-agent
 pinentry-mode loopback
En het de bestand vi~/.gnupg/gpg-agent.conf en het volgende toevoegen:
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:

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:

Opmerking:
  • Na enige tijd zoeken blijkt dat het mogelijk is om meerdere “identiteiten” te gebruiken in Alpine, hiervoor moet je een “role” instellen (hoofdmenu S -> R -> R) en na het drukken op C om een nieuwe mail te starten op de R (setRole) te klikken en de identiteit (role) te selecteren.

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.