Makefile: 使用pkg-config

前言

我知道我又打錯字了

前些陣子Ubuntu在升級到14.04的過程爆炸了,所以順勢轉移到Arch Linux上面。在搬家的過程中發現,我自己寫好的Makefile居然無法正常編譯,這時候才發現在Arch下面SDL2不需要引用SDL2main這個共用套件庫(Shared Library),同時也發現Makefile需要有更好一些的寫法。

pkg-config解決了這個問題!!

pkg-config做啥用

簡單來說,他會自動去尋找編譯某某套件庫的時候,需要加入哪些編譯器參數。

舉例來說,如果我在終端機內輸入pkg-config --libs sdl2,就會得到下面的回應(當然,出現的結果視環境而定):

$ pkg-config --libs sdl2
-lSDL2 -lpthread

輸入pkg-config --cflags sdl2

$ pkg-config --cflags sdl2
-D_REENTRANT -I/usr/include/SDL2

吐出了一些有趣的東西。

Makefile這麼改

過去我的Makefile跟引入的header是這樣寫的:

*.h
...
#include <SDL2/SDL.h>
...
Makefile
...
#INCLUDE沒寫
LIBS+= -lSDL2 -lSDL2main
...

然後事實就是,換到Arch Linux,換到別的系統下就有機會出錯。我沒辦法確保其他系統的SDL.h標頭檔是否放在/usr/include/SDL2當中,也不能保證該系統SDL2在編譯時有產生SDL2main.so這份靜態鏈接(我猜是Arch官方提供的SDL2太畸形,過去我自己編譯出來都會有),所以可以加入pkg-config來改善,如下:

*.h
...
#include <SDL.h>
...
Makefile
...
INCLUDE+= $(shell pkg-config --cflags sdl2)
LIBS+= $(shell pkg-config --libs sdl2)
...

$(shell CMD)指的就是呼叫外部指令CMD,並傳回其標準輸出的內容。

pkg-config是神嗎

知道標頭檔放哪裏的有三個人,一個是我,一個是pkg-config,另一個我不能說

man pkg-config可以看見相關解說。事實上pkg-config並不是去做搜索整個資料夾或是分析每個檔案的相依,而是去幾個資料夾,像是/uar/lib/pkgconfig等,查看裏面的*.pc檔案(Package Configure),來看看裏面寫了些什麼:

# sdl pkg-config source file                                                                                                                                                                

prefix=/usr
exec_prefix=${prefix}
libdir=${exec_prefix}/lib
includedir=${prefix}/include

Name: sdl2
Description: Simple DirectMedia Layer is a cross-platform multimedia library designed to provide low level access to audio, keyboard, mouse, joystick, 3D hardware via OpenGL, and 2D video framebuffer.
Version: 2.0.3
Requires:
Conflicts:
Libs: -L${libdir}  -lSDL2  -lpthread
Libs.private: -lSDL2  -lpthread  -Wl,--no-undefined -lm -ldl -lpthread -lrt
Cflags: -I${includedir}/SDL2   -D_REENTRANT

寫的大概就是這些了,請自己欣賞

這些*.pc檔案在編譯時幾乎都會一起創造出來(至少SDL會),如果安裝了某某套件卻沒有這份檔案,那就是開發者忽略了,趕緊email給他吧!

雜談

我再也不相信Ubuntu的啥鬼升級了

參考資料

  • man pkg-config

Comments

comments powered by Disqus