ImageMagick für Perl kompilieren

PerlMagick, das Perl-Binding für ImageMagick zu kompilieren, ist eine gruselige Angelegenheit, denn es funktioniert so gut wie nie auf Anhieb. Entdecke in diesem Blogbeitrag eine mühelose Lösung für diese mühselige Aufgabe. Sag auf Wiedersehen zu manuellem Herumfummeln und Compiler-Fehlern und Hallo zu use Image::Magick!

Table Of Contents

Quelltext auf GitHub

Das begleitende Sourcecode-Repository gibt es auf GitHub: https://github.com/gflohr/perlmagick-hint. Ich werde versuchen, es immer auf dem neuesten Stand zu halten.

Voraussetzungen

ImageMagick muss installiert sein, ganz gleich ob als vorkompiliertes Binärpaket oder selbst kompiliert. Bei vorkompilierten Binärpaketen muss darauf geachtet werden, dass die C-Header-Dateien auch installiert sind. Auf RedHat-basierten Systemen muss zum Beispiel auch das Paket ImageMagick-devel und nicht nur ImageMagick installiert werden.

Verifizieren lässt sich das mit diesem Kommando:

$ MagickCore-config --version

Das sollte die Version von ImageMagick plus einige Extra-Informationen ausgeben. Siehe den Abschnitt Problembehebung weiter unten, falls das Kommando nicht gefunden wird, oder eine andere Version als erwartet ausgibt.

Das Perl-Binding für ImageMagick wird natürlich auch benötigt. Dieses kann man von https://metacpan.org/dist/Image-Magick herunterladen.

Kompilieren

Vorbereiten der Sourcen

Der Tarball für ImageMagick/PerlMagick kann in einem beliebigen Verzeichnis abgelegt werden. Dann:

$ tar xzf ImageMagick-VERSION.tar.gz
$ cd ImageMagick-VERSION

Dabei muss VERSION mit der Version von ImageMagick für Perl, die heruntergeladen wurde, ersetzt werden.

Das Hilfsskript herunterladen

Die benötigte Datei kann von https://github.com/gflohr/perlmagick-hint/blob/main/hint.pl heruntergeladen werden. Es muss in ein Verzeichnis hints in der ausgepackten Distribution von PerlMagick kopiert werden.

$ mkdir hints
$ cp ~/Downloads/hint.pl hints

Das Hilfsskript umbenennen

Das Hilfsskript muss einer bestimmten Namenskonvention folgen. Der Name muss aus dem Perl-Identifier für das Betriebssystem und der üblichen Endung .pl bestehen. Den Perl-Identifier für das Betriebssystem kann man mit diesem Kommando herausbekommen:

$ perl -e 'print $^O'
darwin

Die Ausgabe darwin, die man auf macos sieht, ist nur ein Beispiel. Das Skript muss jetzt entsprechend umbenannt werden:

$ mv hints/hint.pl hints/darwin.pl

Alternativ kann man auch einfach das Skript ausführen. Es findet selber heraus, wenn es nicht in einem Verzeichnis hints liegt, oder noch den falschen Namen hat, und gibt dann einen Fehler aus:

$ perl hints/hint.pl
Error: Create a directory 'hints' in an unpacked ImageMagick distribution and
store this file as 'hints/darwin.pl'! Then run 'perl Makefile.PL && make &&
make install'!

Auf anderen Systemen würde man statt hints/darwin.pl natürlich etwas anderes wie hints/DEIN-SYSTEM.pl sehen.

Wurde das Skript korrekt umbenannt, gibt es jetzt die modifizierte Konfiguration aus:

$ perl hints/darwin.pl # Mit dem korrekten Namen ersetzen!
Patch configuration:
    CCFLAGS = -DMAGICKCORE_HDRI_ENABLE=0 -DMAGICKCORE_QUANTUM_DEPTH=16 -I/opt/local/include/ImageMagick-6
    INC = 
    LDDLFLAGS = -L/opt/local/lib -lMagickCore-6.Q16
    LDFLAGS = -L/opt/local/lib -lMagickCore-6.Q16
    LIBS = -L/opt/local/lib -lMagickCore-6.Q16 -L/Users/me/perl5/perlbrew/perls/perl-5.34.0/lib/5.34.0/darwin-2level/CORE -L/Users/me/perl5/perlbrew/perls/perl-5.34.0/lib/5.34.0/darwin-2level/CORE

Jetzt ist alles bereit, um die Erweiterung zu konfigurieren:

$ perl Makefile.PL
Getting ImageMagick configuration from hints.
Generating a Unix-style Makefile
Writing Makefile for Image::Magick
Writing MYMETA.yml and MYMETA.json

Falls die Ausgabe "Getting ImageMagick configuration from hints" nicht erscheint, stimmt etwas nicht.

Falls alles funktioniert, kann jetzt kompiliert und installiert werden:

$ make
$ make install

Wer nicht Perlbrew benutzt, muss mit Superuser-Privilegien installieren: sudo make install.

Problembehebung

ImageMagick 7 von MacPorts

Zur Zeit bietet MacPorts zwei Versionen von ImageMagick. Der Port ImageMagick enthält ImageMagic Version 6. Die neuere Version 7 erhält man mit dem Port ImageMagick7.

Das Problem ist, dass die Programme von ImageMagick7 nicht in $PATH installiert werden. Das kann man auf zwei Arten ändern.

Eine Option ist, die Umgebungs-Variable $PATH in der aktuellen Shell zu erweitern:

$ export PATH="/opt/local/lib/ImageMagick7/bin:$PATH"
$ perl hints/darwin.pl
$ perl Makefile.PL

Die andere Möglichkeit besteht darin, den vollständigen Pfad des Programms MagickCore-config anzugeben:

$ export MAGICKCORE_CONFIG=/opt/local/lib/ImageMagick7/bin/MagickCore-config
$ perl hints/darwin.pl
$ perl Makefile.PL

'MagickCore/MagickCore.h' file not found

Stößt man auf diesen Fehler, wurden die C-Header-Dateien vermutlich nicht installiert. Falls der eigene Vendor separate Development-Versionen von vorkompilierten Software-Paketen bereitstellt, müssen diese ebenfalls installiert sein. In vielen Fällen wird das Development-Paket den Namen des Grundpakets mit der Endung -devel haben, zum Beispiel ImageMagick-devel.

MS-DOS/Windows

Das Makefile.PL das mit ImageMagick ausgeliefert wird, sollte ohne Anpassung funktionieren, und das Hilfsskript wird nicht benötigt.

Hintergrund

Beim Kompilieren des Perl-Bindings von ImageMagick stößt man auf zwei Probleme auf einmal. Das Makefile.PL, das mit dem Perl-Binding ausgeliefert wird, anthält eine hartkodierte Konfiguration, die davon ausgeht, dass ImageMagick mit Default-Parametern aus den Sourcen gebaut und installiert wurde. Diese Konfiguration funktioniert auch mit Homebrew für macos, aber das ist mehr oder weniger Zufall.

Es funktioniert jedoch nicht mehr, wenn ImageMagick mit einem anderen Präfix als /usr/local konfiguriert wurde. Die Konfiguration ist ebenfalls fehlerhaft, wenn ohne HDRI-Support gebaut wurde.

Überraschenderweise ermittelt das Makefile.PL die notwendige Konfiguration auf MS-DOS/MS-Windows automatisch, nicht jedoch auf POSIX-Systemen. Unser Hint-Script springt hier ein, und erkennt die korrekte Konfiguration auf jedem System.

Das andere Problem ist die fehlende Flexibilität und schreckliche Dokumentation von ExtUtils::MakeMaker. Theoretisch könnte man ImageMagick folgendermaßen erfolgreich konfigurieren:

$ perl Makefile.PL INC= \
    LIBS=`MagickCore-config --libs` \
    CCFLAGS=`MagickCore-config --cflags` \
    LDFLAGS=`MagickCore-config --ldflags` \
    LDDLFLAGS=`MagickCore-config --lddlflags`

Aber wer weiß das schon? Wer kann sich das merken? Und wo ist es dokumentiert?

Der Trick mit dem Hint-Skript funktioniert eigentlich für jede Perl-Erweiterung, nicht nur für ImageMagick. Aber weshalb gibt es keinen Standard-Suchpfad für das Hintskript, wenn keine plattformspezifische Version gefunden wurde? Und es funktioniert auch nicht, wenn man nicht-interaktiv konfiguriert, zum Beispiel mit cpanm. Klar. Das ist so, weil der Mechanismus für Autorinnen von Modulen gedacht ist, und nicht für Enduser. Das ist allerdings nur ein schwacher Trost.

Feedback und Bug-Reports

Feedback oder Bug-Reports kann man entweder als GitHub-Issue unter https://github.com/gflohr/perlmagick-hint oder in der Kommentar-Sektion unten loswerden.

Leave a comment
Diese Website verwendet Cookies und ähnliche Technologien, um gewisse Funktionalität zu ermöglichen, die Benutzbarkeit zu erhöhen und Inhalt entsprechend ihren Interessen zu liefern. Über die technisch notwendigen Cookies hinaus können abhängig von ihrem Zweck Analyse- und Marketing-Cookies zum Einsatz kommen. Sie können ihre Zustimmung zu den vorher erwähnten Cookies erklären, indem sie auf "Zustimmen und weiter" klicken. Hier können sie Detaileinstellungen vornehmen oder ihre Zustimmung - auch teilweise - mit Wirkung für die Zukunft zurücknehmen. Für weitere Informationen lesen sie bitte unsere Datenschutzerklärung.