1# pqiv Makefile 2# 3 4# Default flags, overridden by values in config.make 5CFLAGS?=-O2 -g 6CROSS= 7DESTDIR= 8GTK_VERSION=0 9PQIV_WARNING_FLAGS=-Wall -Wextra -Wfloat-equal -Wpointer-arith -Wcast-align -Wstrict-overflow=1 -Wwrite-strings -Waggregate-return -Wunreachable-code -Wno-unused-parameter 10LDLIBS=-lm 11PREFIX=/usr 12EPREFIX=$(PREFIX) 13LIBDIR=$(PREFIX)/lib 14BINDIR=$(PREFIX)/bin 15MANDIR=$(PREFIX)/share/man 16EXECUTABLE_EXTENSION= 17PKG_CONFIG=$(CROSS)pkg-config 18OBJECTS=pqiv.o lib/strnatcmp.o lib/bostree.o lib/filebuffer.o lib/config_parser.o lib/thumbnailcache.o 19HEADERS=pqiv.h lib/bostree.h lib/filebuffer.h lib/strnatcmp.h 20BACKENDS=gdkpixbuf 21EXTRA_DEFS= 22BACKENDS_BUILD=static 23EXTRA_CFLAGS_SHARED_OBJECTS=-fPIC 24EXTRA_CFLAGS_BINARY= 25EXTRA_LDFLAGS_SHARED_OBJECTS= 26EXTRA_LDFLAGS_BINARY= 27 28# Always look for source code relative to the directory of this makefile 29SOURCEDIR:=$(dir $(abspath $(lastword $(MAKEFILE_LIST)))) 30ifeq ($(SOURCEDIR),$(CURDIR)) 31 SOURCEDIR= 32else 33 HEADERS:=$(patsubst %, $(SOURCEDIR)%, $(HEADERS)) 34endif 35 36# Load config.make (created by configure) 37CONFIG_MAKE_NAME=config.make 38ifeq ($(wildcard $(CONFIG_MAKE_NAME)),$(CONFIG_MAKE_NAME)) 39 include $(CONFIG_MAKE_NAME) 40 HEADERS+=$(CONFIG_MAKE_NAME) 41endif 42 43# First things first: Require at least one backend 44ifeq ($(BACKENDS),) 45$(error Building pqiv without any backends is unsupported.) 46endif 47 48# pkg-config lines for the main program 49LIBS_GENERAL=glib-2.0 >= 2.8 cairo >= 1.6 gio-2.0 50LIBS_GTK3=gtk+-3.0 gdk-3.0 51LIBS_GTK2=gtk+-2.0 >= 2.6 gdk-2.0 >= 2.8 52 53# pkg-config libraries for the backends 54LIBS_gdkpixbuf=gdk-pixbuf-2.0 >= 2.2 55LIBS_poppler=poppler-glib 56LIBS_spectre=libspectre 57LIBS_wand=MagickWand 58LIBS_libav=libavformat libavcodec libswscale libavutil 59LIBS_archive_cbx=libarchive gdk-pixbuf-2.0 >= 2.2 60LIBS_archive=libarchive 61LIBS_webp=libwebp 62 63# This might be required if you use mingw, and is required as of 64# Aug 2014 for mxe, but IMHO shouldn't be required / is a bug in 65# poppler (which does not specify this dependency). If it isn't 66# or throws an error for you, please report this as a bug: 67# 68ifeq ($(EXECUTABLE_EXTENSION),.exe) 69 LDLIBS_poppler+=-llcms2 -lstdc++ 70endif 71 72# If no GTK_VERSION is set, try to auto-determine, with GTK 3 preferred 73ifeq ($(GTK_VERSION), 0) 74 ifeq ($(shell $(PKG_CONFIG) --errors-to-stdout --print-errors "$(LIBS_GTK3)"), ) 75 override GTK_VERSION=3 76 else 77 LIBS=$(LIBS_GTK2) 78 override GTK_VERSION=2 79 endif 80endif 81ifeq ($(GTK_VERSION), 2) 82 LIBS=$(LIBS_GTK2) 83endif 84ifeq ($(GTK_VERSION), 3) 85 LIBS=$(LIBS_GTK3) 86endif 87LIBS+=$(LIBS_GENERAL) 88 89# Add platform specific libraries 90# GIo for stdin loading, 91ifeq ($(EXECUTABLE_EXTENSION), .exe) 92 LIBS+=gio-windows-2.0 93else 94 LIBS+=gio-unix-2.0 95endif 96 97# We need X11 to workaround a bug, see http://stackoverflow.com/questions/18647475 98ifeq ($(filter x11, $(shell $(PKG_CONFIG) --errors-to-stdout --variable=target gtk+-$(GTK_VERSION).0; $(PKG_CONFIG) --errors-to-stdout --variable=targets gtk+-$(GTK_VERSION).0)), x11) 99 LIBS+=x11 100endif 101 102# Add backend-specific libraries and objects 103SHARED_OBJECTS= 104SHARED_BACKENDS= 105HELPER_OBJECTS= 106BACKENDS_INITIALIZER:=backends/initializer 107define handle-backend 108ifneq ($(origin LIBS_$(1)),undefined) 109 ifneq ($(findstring $(1), $(BACKENDS)),) 110 ifeq ($(BACKENDS_BUILD), shared) 111 ifeq ($(shell $(PKG_CONFIG) --errors-to-stdout --print-errors "$(LIBS_$(1))" 2>&1), ) 112 SHARED_OBJECTS+=backends/pqiv-backend-$(1).so 113 HELPER_OBJECTS+=backends/$(1).o 114 BACKENDS_BUILD_CFLAGS_$(1):=$(shell $(PKG_CONFIG) --errors-to-stdout --print-errors --cflags "$(LIBS_$(1))" 2>&1) 115 BACKENDS_BUILD_LDLIBS_$(1):=$(shell $(PKG_CONFIG) --errors-to-stdout --print-errors --libs "$(LIBS_$(1))" 2>&1) 116 SHARED_BACKENDS+="$(1)", 117 endif 118 else 119 LIBS+=$(LIBS_$(1)) 120 OBJECTS+=backends/$(1).o 121 LDLIBS+=$(LDLIBS_$(1)) 122 BACKENDS_INITIALIZER:=$(BACKENDS_INITIALIZER)-$(1) 123 endif 124 endif 125endif 126endef 127$(foreach BACKEND_C, $(wildcard $(SOURCEDIR)backends/*.c), $(eval $(call handle-backend,$(basename $(notdir $(BACKEND_C)))))) 128PIXBUF_FILTER="gdkpixbuf", 129ifeq ($(BACKENDS_BUILD), shared) 130 OBJECTS+=backends/shared-initializer.o 131 BACKENDS_BUILD_CFLAGS_shared-initializer=-DSHARED_BACKENDS='$(filter $(PIXBUF_FILTER), $(SHARED_BACKENDS)) $(filter-out $(PIXBUF_FILTER), $(SHARED_BACKENDS))' -DSEARCH_PATHS='"backends", "../$(subst $(PREFIX),,$(LIBDIR))/pqiv", "$(LIBDIR)/pqiv",' 132 LIBS+=gmodule-2.0 133else 134 OBJECTS+=$(BACKENDS_INITIALIZER).o 135endif 136 137# MagickWand changed their directory structure with version 7, pass the version 138# to the build 139ifneq ($(findstring wand, $(BACKENDS)),) 140backends/wand.o: CFLAGS_REAL+=-DWAND_VERSION=$(shell $(PKG_CONFIG) --modversion MagickWand | awk 'BEGIN { FS="." } { print $$1 }') 141endif 142 143# Add version information to builds from git 144PQIV_VERSION_STRING=$(shell [ -d $(SOURCEDIR).git ] && (which git 2>&1 >/dev/null) && git -C "$(SOURCEDIR)" describe --dirty --tags 2>/dev/null) 145ifneq ($(PQIV_VERSION_STRING),) 146 PQIV_VERSION_FLAG=-DPQIV_VERSION=\"$(PQIV_VERSION_STRING)\" 147endif 148ifdef DEBUG 149 DEBUG_CFLAGS=-DDEBUG 150else 151 DEBUG_CFLAGS=-DNDEBUG 152endif 153 154# Less verbose output 155ifndef VERBOSE 156 SILENT_CC=@echo " CC " $@; 157 SILENT_CCLD=@echo " CCLD" $@; 158 SILENT_GEN=@echo " GEN " $@; 159endif 160 161# Assemble final compiler flags 162CFLAGS_REAL=-std=gnu99 $(PQIV_WARNING_FLAGS) $(PQIV_VERSION_FLAG) $(CFLAGS) $(DEBUG_CFLAGS) $(EXTRA_DEFS) $(shell $(PKG_CONFIG) --cflags "$(LIBS)") 163LDLIBS_REAL=$(shell $(PKG_CONFIG) --libs "$(LIBS)") $(LDLIBS) 164LDFLAGS_REAL=$(LDFLAGS) 165 166all: pqiv$(EXECUTABLE_EXTENSION) pqiv.desktop $(SHARED_OBJECTS) 167.PHONY: get_libs get_available_backends _build_variables clean distclean install uninstall all 168.SECONDARY: 169 170pqiv$(EXECUTABLE_EXTENSION): $(OBJECTS) 171 $(SILENT_CCLD) $(CROSS)$(CC) $(CPPFLAGS) $(EXTRA_CFLAGS_BINARY) -o $@ $+ $(LDLIBS_REAL) $(LDFLAGS_REAL) $(EXTRA_LDFLAGS_BINARY) 172 173ifeq ($(BACKENDS_BUILD), shared) 174backends/%.o: CFLAGS_REAL+=$(BACKENDS_BUILD_CFLAGS_$(notdir $*)) $(EXTRA_CFLAGS_SHARED_OBJECTS) 175 176$(SHARED_OBJECTS): backends/pqiv-backend-%.so: backends/%.o 177 @[ -d backends ] || mkdir -p backends || true 178 $(SILENT_CCLD) $(CROSS)$(CC) $(CPPFLAGS) $(EXTRA_CFLAGS_SHARED_OBJECTS) -o $@ $+ $(LDLIBS_REAL) $(LDFLAGS_REAL) $(BACKENDS_BUILD_LDLIBS_$*) $(EXTRA_LDFLAGS_SHARED_OBJECTS) -shared 179endif 180 181$(filter-out $(BACKENDS_INITIALIZER).o, $(OBJECTS)) $(HELPER_OBJECTS): %.o: $(SOURCEDIR)%.c $(HEADERS) 182 @[ -d $(dir $@) ] || mkdir -p $(dir $@) || true 183 $(SILENT_CC) $(CROSS)$(CC) $(CPPFLAGS) -c -o $@ $(CFLAGS_REAL) $< 184 185$(BACKENDS_INITIALIZER).o: $(BACKENDS_INITIALIZER).c $(HEADERS) 186 @[ -d $(dir $@) ] || mkdir -p $(dir $@) || true 187 $(SILENT_CC) $(CROSS)$(CC) $(CPPFLAGS) -I"$(SOURCEDIR)/lib" -c -o $@ $(CFLAGS_REAL) $< 188 189$(BACKENDS_INITIALIZER).c: 190 @[ -d $(dir $(BACKENDS_INITIALIZER)) ] || mkdir -p $(dir $(BACKENDS_INITIALIZER)) || true 191 @$(foreach BACKEND, $(sort $(BACKENDS)), [ -e $(SOURCEDIR)backends/$(BACKEND).c ] || { echo; echo "Backend $(BACKEND) not found!" >&2; exit 1; };) 192 $(SILENT_GEN) ( \ 193 echo '/* Auto-Generated file by Make. */'; \ 194 echo '#include "../pqiv.h"'; \ 195 echo "file_type_handler_t file_type_handlers[$(words $(BACKENDS)) + 1];"; \ 196 $(foreach BACKEND, $(sort $(BACKENDS)), echo "void file_type_$(BACKEND)_initializer(file_type_handler_t *info);";) \ 197 echo "void initialize_file_type_handlers(const gchar * const * disabled_backends) {"; \ 198 echo " int i = 0;"; \ 199 $(foreach BACKEND, $(filter gdkpixbuf, $(BACKENDS)), echo " if(!strv_contains(disabled_backends, \"$(BACKEND)\")) file_type_$(BACKEND)_initializer(&file_type_handlers[i++]);";) \ 200 $(foreach BACKEND, $(sort $(filter-out gdkpixbuf, $(BACKENDS))), echo " if(!strv_contains(disabled_backends, \"$(BACKEND)\")) file_type_$(BACKEND)_initializer(&file_type_handlers[i++]);";) \ 201 echo "}" \ 202 ) > $@ 203 204pqiv.desktop: $(HEADERS) 205 $(SILENT_GEN) ( \ 206 echo "[Desktop Entry]"; \ 207 echo "Version=1.0"; \ 208 echo "Type=Application"; \ 209 echo "Comment=Powerful quick image viewer"; \ 210 echo "Name=pqiv"; \ 211 echo "NoDisplay=true"; \ 212 echo "Icon=emblem-photos"; \ 213 echo "TryExec=$(PREFIX)/bin/pqiv"; \ 214 echo "Exec=$(PREFIX)/bin/pqiv %F"; \ 215 echo "MimeType=$(shell cat $(foreach BACKEND, $(sort $(BACKENDS)), $(SOURCEDIR)backends/$(BACKEND).mime) /dev/null | sort | uniq | awk 'ORS=";"')"; \ 216 echo "Categories=Graphics;"; \ 217 echo "Keywords=Viewer;" \ 218 ) > $@ 219 220install: all 221 mkdir -p $(DESTDIR)$(BINDIR) 222 install pqiv$(EXECUTABLE_EXTENSION) $(DESTDIR)$(BINDIR)/pqiv$(EXECUTABLE_EXTENSION) 223 -mkdir -p $(DESTDIR)$(MANDIR)/man1 224 -install -m 644 $(SOURCEDIR)pqiv.1 $(DESTDIR)$(MANDIR)/man1/pqiv.1 225 -mkdir -p $(DESTDIR)$(PREFIX)/share/applications 226 -install -m 644 pqiv.desktop $(DESTDIR)$(PREFIX)/share/applications/pqiv.desktop 227ifeq ($(BACKENDS_BUILD), shared) 228 mkdir -p $(DESTDIR)$(LIBDIR)/pqiv 229 install $(SHARED_OBJECTS) $(DESTDIR)$(LIBDIR)/pqiv/ 230endif 231 232uninstall: 233 rm -f $(DESTDIR)$(PREFIX)/bin/pqiv$(EXECUTABLE_EXTENSION) 234 rm -f $(DESTDIR)$(MANDIR)/man1/pqiv.1 235 rm -f $(DESTDIR)$(PREFIX)/share/applications/pqiv.desktop 236ifeq ($(BACKENDS_BUILD), shared) 237 rm -f $(foreach SO_FILE, $(SHARED_OBJECTS), $(DESTDIR)$(LIBDIR)/pqiv/$(notdir $(SO_FILE))) 238 rmdir $(DESTDIR)$(LIBDIR)/pqiv 239endif 240 241# Rudimentary MacOS bundling 242# Only really useful for opening pqiv using "open pqiv.app --args ..." from the 243# command line right now, but that already has the benefit that the application 244# window will be visible right away 245pqiv.app: pqiv.app.tmp 246 rm -f ../$@ 247 cd pqiv.app.tmp && zip -9r ../$@ . 248 249pqiv.app.tmp: pqiv.app.tmp/Contents/MacOS/pqiv pqiv.app.tmp/Contents/Info.plist pqiv.app.tmp/Contents/PkgInfo 250 251pqiv.app.tmp/Contents/MacOS/pqiv: 252 -mkdir -p pqiv.app.tmp/Contents/MacOS 253 install pqiv$(EXECUTABLE_EXTENSION) $@ 254 255pqiv.app.tmp/Contents/PkgInfo: 256 -mkdir -p pqiv.app.tmp/Contents 257 $(SILENT_GEN) ( \ 258 echo -n "APPL????"; \ 259 ) > $@ 260 261pqiv.app.tmp/Contents/Info.plist: $(HEADERS) 262 -mkdir -p pqiv.app.tmp/Contents 263 $(SILENT_GEN) ( \ 264 echo '<?xml version="1.0" encoding="UTF-8"?><!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">'; \ 265 echo '<plist version="1.0"><dict><key>CFBundleName</key><string>pqiv</string><key>CFBundleDisplayName</key><string>pqiv</string>'; \ 266 echo '<key>CFBundleIdentifier</key><string>com.pberndt.pqiv</string><key>CFBundleVersion</key><string>$(PQIV_VERSION_STRING)</string>'; \ 267 echo '<key>CFBundlePackageType</key><string>APPL</string><key>CFBundleExecutable</key><string>pqiv</string><key>LSMinimumSystemVersion</key>'; \ 268 echo '<string>10.4</string><key>CFBundleDocumentTypes</key><array><dict><key>CFBundleTypeMIMETypes</key><array>'; \ 269 cat $(foreach BACKEND, $(sort $(BACKENDS)), $(SOURCEDIR)backends/$(BACKEND).mime) /dev/null | sort | uniq | awk '{print "<string>" $$0 "</string>"}'; \ 270 echo '</array></dict></array></dict></plist>'; \ 271 ) > $@ 272 273clean: 274 rm -f pqiv$(EXECUTABLE_EXTENSION) *.o backends/*.o backends/*.so lib/*.o backends/initializer-*.c pqiv.desktop 275 276distclean: clean 277 rm -f config.make 278 279get_libs: 280 $(info LIBS: $(LIBS)) 281 @true 282 283get_available_backends: 284 @OUT=; $(foreach BACKEND_C, $(wildcard $(SOURCEDIR)backends/*.c), \ 285 [ "$(DISABLE_AUTOMATED_BUILD_$(basename $(notdir $(BACKEND_C))))" != "yes" ] && \ 286 [ -n "$(LIBS_$(basename $(notdir $(BACKEND_C))))" ] && \ 287 $(PKG_CONFIG) --exists "$(LIBS_$(basename $(notdir $(BACKEND_C))))" \ 288 && OUT="$$OUT $(basename $(notdir $(BACKEND_C))) ";) echo BACKENDS: $$OUT 289 @true 290