連接指定的庫有兩種方式html
如連接LuaJIT庫,能夠用-lluajit-5.1,此時gcc會在庫路徑中查找libluajit-5.1.so或者libluajit-5.1.a。 也能夠用-l llibluajit-5.1.a,第二種只能用在POXIS上,推薦使用第一種方式。並且第二種方式只會在特定的目錄進行搜索,會發生找不到庫的狀況。linux
經過-llibrary連接庫時,可能既有靜態庫如libluajit-5.1.a,也有動態庫如libluajit-5.1.so,這是連接器會優先連接動態庫。c++
若是須要的庫不在系統的庫搜索路徑下,就須要經過-L指定庫的搜索路徑。 如lua解釋器安裝時會把libluajit-5.1.a,和libluajit-5.1.so等放在/usr/local/lib下,而gcc進行連接時默認不會在這個路徑下搜索庫,致使連接失敗。經過-L/usr/local/lib指定庫路徑就能夠解決這個問題。app
~$ gcc main.c -lluajit-5.1 /usr/bin/ld: 找不到 -lluajit-5.1 collect2: error: ld returned 1 exit status ~$ gcc main.c -L/usr/local/lib -lluajit-5.1
有時經過-L指定庫路徑能夠正常連接,運行程序時卻由於找不到庫報錯lua
~ $ ./a.out ./a.out: error while loading shared libraries: libluajit-5.1.so.2: cannot open shared object file: No such file or directory ~ $ ldd ./a.out linux-vdso.so.1 => (0x00007ffc1638e000) libluajit-5.1.so.2 => not found libc.so.6 => /lib/x86_64-linux-gnu/libc.so.6 (0x00007f4c23d48000) /lib64/ld-linux-x86-64.so.2 (0x000055713bf16000)
使用ldd命令能夠看到運行時找不到libluajit-5.1.so.2,沒法運行,對此能夠經過-Wl,-rpath指定運行時庫的搜索路徑3d
kenan@kenan-desktop ~ $ gcc test.c -I/usr/local/include/luajit-2.1 -Wl,-rpath=/usr/local/lib/ -lluajit-5.1 kenan@kenan-desktop ~ $ ./a.out Hello, Lua! ~ $ ~ $ ldd ./a.out linux-vdso.so.1 => (0x00007ffd6c5d7000) libluajit-5.1.so.2 => /usr/local/lib/libluajit-5.1.so.2 (0x00007f5ea238c000) libc.so.6 => /lib/x86_64-linux-gnu/libc.so.6 (0x00007f5ea1fa5000) libm.so.6 => /lib/x86_64-linux-gnu/libm.so.6 (0x00007f5ea1c9b000) libdl.so.2 => /lib/x86_64-linux-gnu/libdl.so.2 (0x00007f5ea1a97000) libgcc_s.so.1 => /lib/x86_64-linux-gnu/libgcc_s.so.1 (0x00007f5ea1881000) /lib64/ld-linux-x86-64.so.2 (0x0000565491551000)
再使用ldd命令查看,libluajit-5.1.so.2在/sur/local/lib下。code
對於運行時找不到動態庫的問題,除了經過-Wl,-rpath指定路徑外,還能夠經過靜態連接庫的方式來解決。實際生產環境中一般只在一臺機器上編譯二進制程序,再將二進制程序分發到線上運行環境。程序須要的庫可能實際線上環境中根本沒有,也須要將庫靜態連接。htm
靜態連接庫有下面幾種方式。文檔
如安裝luajit後,在/usr/local/lib下既有靜態庫,也有動態庫。連接時優先連接動態庫。若是將動態庫刪除,只保留靜態庫,這時連接器就會連接靜態庫.get
gcc會對-Wl,-Bstatic 後面的庫使用靜態連接。對-Wl,-Bdynamic後面跟的庫使用動態連接。 若是須要對指定的庫使用靜態連接,其餘的庫使用默認的動態連接,能夠這樣用
gcc test -Wl,-Bstatic -lluajit-5.1 -Wl,-Bdynamic -lxxx -lxxx
這樣gcc會連接libluajit-5.1.a,而對其餘庫使用動態連接。
gcc編譯時使用-static參數,會阻止使用動態連接的方式。與以前兩個方法不一樣,-static參數會致使gcc對全部的庫使用靜態連接,通常不推薦使用這種方式。
~ $ gcc test.c -I/usr/local/include/luajit-2.1 -Wl,-rpath=/usr/local/lib/ -L/usr/local/lib -lluajit-5.1 -ldl -lm -static ~ $ ldd ./a.out 不是動態可執行文件
對程序使用ldd命令提示不是動態可執行文件
沒有使用-static時ldd能夠看到程序須要的動態庫,以及庫的路徑。
~ $ gcc test.c -I/usr/local/include/luajit-2.1 -Wl,-rpath=/usr/local/lib/ -L/usr/local/lib -lluajit-5.1 -ldl -lm ~ $ ldd ./a.out linux-vdso.so.1 => (0x00007ffd057f1000) libluajit-5.1.so.2 => /usr/local/lib/libluajit-5.1.so.2 (0x00007f1e72a48000) libc.so.6 => /lib/x86_64-linux-gnu/libc.so.6 (0x00007f1e7267f000) libm.so.6 => /lib/x86_64-linux-gnu/libm.so.6 (0x00007f1e72375000) libdl.so.2 => /lib/x86_64-linux-gnu/libdl.so.2 (0x00007f1e72171000) libgcc_s.so.1 => /lib/x86_64-linux-gnu/libgcc_s.so.1 (0x00007f1e71f5b000) /lib64/ld-linux-x86-64.so.2 (0x000055875c7a0000)
gcc自己提供了參數能夠只對libgcc,libstdc++等庫進行靜態連接 主要有下面這些
-static-libgcc -static-libasan -static-libtsan -static-liblsan -static-libubsan -static-libmpx -static-libmpxwrappers -static-libstdc++
更詳細的介紹能夠參見官方文檔