Geliştirici

Appimage yapımı serisi – Bölüm 1

Image
Paylaş

Giriş

Bu yazı serisinde sizlere nasıl appimage dosyası yapılacağı anlatılacakdır.

İlk bölümde çalıştırılabilir dosyaların sistemden bağımsız çalıştırılması üzerinde durulacaktır. Bu bölümü net bir şekilde anlayabilmeniz için orta düzeyde gnu/linux bilgisine sahip olmalısınız.

Static ve dynamic binary kavramı

Static olarak derlenmiş bir kod herhangi bir ek kütüphaneye ihtiyaç duymadan çalışabilir. Bir dosyanın static olup olmadığını anlamak için ldd komutu ile o dosyaya bakmamız gerekir.

Plain text
Copy to clipboard
Open code in new window
EnlighterJS 3 Syntax Highlighter
$ ldd /bin/bash
linux-vdso.so.1 (0x00007ffc8f136000)
libtinfo.so.6 => /lib/x86_64-linux-gnu/libtinfo.so.6 (0x00007ff10adcd000)
libdl.so.2 => /lib/x86_64-linux-gnu/libdl.so.2 (0x00007ff10adc7000)
libc.so.6 => /lib/x86_64-linux-gnu/libc.so.6 (0x00007ff10ac02000)
/lib64/ld-linux-x86-64.so.2 (0x00007ff10af6c000)
$ ldd /bin/bash linux-vdso.so.1 (0x00007ffc8f136000) libtinfo.so.6 => /lib/x86_64-linux-gnu/libtinfo.so.6 (0x00007ff10adcd000) libdl.so.2 => /lib/x86_64-linux-gnu/libdl.so.2 (0x00007ff10adc7000) libc.so.6 => /lib/x86_64-linux-gnu/libc.so.6 (0x00007ff10ac02000) /lib64/ld-linux-x86-64.so.2 (0x00007ff10af6c000)
$ ldd /bin/bash
linux-vdso.so.1 (0x00007ffc8f136000)
libtinfo.so.6 => /lib/x86_64-linux-gnu/libtinfo.so.6 (0x00007ff10adcd000)
libdl.so.2 => /lib/x86_64-linux-gnu/libdl.so.2 (0x00007ff10adc7000)
libc.so.6 => /lib/x86_64-linux-gnu/libc.so.6 (0x00007ff10ac02000)
/lib64/ld-linux-x86-64.so.2 (0x00007ff10af6c000)

Burada görüldüğü gibi dosyamız dynamic olarak derlendiği için bağımlılıkları listelenmektedir. Eğer dosyamız static olarak derlenseydi aşağıdaki gibi bir çıktı elde etmemiz gerekirdi.

Plain text
Copy to clipboard
Open code in new window
EnlighterJS 3 Syntax Highlighter
$ ldd test.bin
not a dynamic executable
$ ldd test.bin not a dynamic executable
$ ldd test.bin
not a dynamic executable

libc ve interpreter kavramı

Dynamic olarak derlenmiş bütün dosyalar temelde libc.so.6 ve ld-linux-x86-64.so.2 bağımlılıklarına ihtiyaç duyar. Bu dosyalardan libc.so.6 temel C kütüphanesidir. Bu kütüphane sayesinde program temel işlevlerini yerine getirebilir hale gelir. ld-linux-x86-64.so.2 ise interpreter olup dosyanın ne şekilde çalıştırılacağını belirler. Bir dosyanın hangi interpreter ile çalıştığını bulmak için file komutundan yararlanabiliriz. linux-vdso.so.1 ise kernel tarafından sağlanır ve herhangi bir dosya şeklinde bulunmaz.

Plain text
Copy to clipboard
Open code in new window
EnlighterJS 3 Syntax Highlighter
$ file /bin/bash
/bin/bash: ELF 64-bit LSB pie executable, x86-64, version 1 (SYSV), dynamically linked,
interpreter /lib64/ld-linux-x86-64.so.2, for GNU/Linux 3.2.0, stripped
$ file /bin/bash /bin/bash: ELF 64-bit LSB pie executable, x86-64, version 1 (SYSV), dynamically linked, interpreter /lib64/ld-linux-x86-64.so.2, for GNU/Linux 3.2.0, stripped
$ file /bin/bash
/bin/bash: ELF 64-bit LSB pie executable, x86-64, version 1 (SYSV), dynamically linked,
interpreter /lib64/ld-linux-x86-64.so.2, for GNU/Linux 3.2.0, stripped

LD_LIBRARY_PATH kavramı

Bir çalıştırılabilir dosyanın bağımlılığı genellikle sistemde kurulu bulunmalıdır. Fakat bazı durumlarda sistem dizinlerinden farklı bir yerde bulunması gerekebilir. Bu gibi durumlarda LD_LIBRARY_PATH çevresel değişkeni tanımlanarak kütüphanenin aranacağı ek dizinin konumu belirtilir.

Plain text
Copy to clipboard
Open code in new window
EnlighterJS 3 Syntax Highlighter
$ ldd test.bin
linux-vdso.so.1 (0x00007ffc1c5c5000)
libtest.so => not found
libc.so.6 => /lib64/libc.so.6 (0x00007feaab862000)
/lib64/ld-linux-x86-64.so.2 (0x00007feaaba76000)
$ ldd test.bin linux-vdso.so.1 (0x00007ffc1c5c5000) libtest.so => not found libc.so.6 => /lib64/libc.so.6 (0x00007feaab862000) /lib64/ld-linux-x86-64.so.2 (0x00007feaaba76000)
$ ldd test.bin
linux-vdso.so.1 (0x00007ffc1c5c5000)
libtest.so => not found
libc.so.6 => /lib64/libc.so.6 (0x00007feaab862000)
/lib64/ld-linux-x86-64.so.2 (0x00007feaaba76000)

Yukarıdaki örnekte libtest.so dosyası sistemde bulunamadığı için ldd çıktımızda uyarı ile karşılaştık. Şimdi de çevresel değişkenimizi tanımlayarak aynı işlemi tekrar deneyelim.

Plain text
Copy to clipboard
Open code in new window
EnlighterJS 3 Syntax Highlighter
$ export LD_LIBRARY_PATH=/home/user/test/libs/
$ ldd test.bin
linux-vdso.so.1 (0x00007ffe22bbc000)
libtest.so => /home/user/test/libs/libtest.so (0x00007f4c97790000)
libc.so.6 => /lib64/libc.so.6 (0x00007f4c97583000)
/lib64/ld-linux-x86-64.so.2 (0x00007f4c9779c000)
$ export LD_LIBRARY_PATH=/home/user/test/libs/ $ ldd test.bin linux-vdso.so.1 (0x00007ffe22bbc000) libtest.so => /home/user/test/libs/libtest.so (0x00007f4c97790000) libc.so.6 => /lib64/libc.so.6 (0x00007f4c97583000) /lib64/ld-linux-x86-64.so.2 (0x00007f4c9779c000)
$ export LD_LIBRARY_PATH=/home/user/test/libs/
$ ldd test.bin
linux-vdso.so.1 (0x00007ffe22bbc000)
libtest.so => /home/user/test/libs/libtest.so (0x00007f4c97790000)
libc.so.6 => /lib64/libc.so.6 (0x00007f4c97583000)
/lib64/ld-linux-x86-64.so.2 (0x00007f4c9779c000)

Gördüğünüz gibi kütüphaneyi tanımladığımız dizinde buldu.

Bu şekilde bir dosyanın bütün bağımlılıklarını bir dizine kopyalarsak o dosyayı sistemden bağımsız şekilde çalıştırmamız mümkün olur.

Plain text
Copy to clipboard
Open code in new window
EnlighterJS 3 Syntax Highlighter
$ ldd /bin/bash
linux-vdso.so.1 (0x00007fff2c359000)
libreadline.so.8 => /lib64/libreadline.so.8 (0x00007fce1e004000)
libtinfo.so.6 => /lib64/libtinfo.so.6 (0x00007fce1dfc5000)
libc.so.6 => /lib64/libc.so.6 (0x00007fce1ddcc000)
libtinfow.so.6 => /lib64/libtinfow.so.6 (0x00007fce1dd8c000)
/lib64/ld-linux-x86-64.so.2 (0x00007fce1e154000)
# Şimdi tüm dosyaları libs adındaki bir dizine kopyalayalım.
$ mkdir libs
$ ldd /bin/bash | cut -f3 -d" " | grep "^/" | sed "s/.*/install & libs\//g" | sh
# Bağımlılıkları toplu olarak kopyalamak için yukarıdaki komutu kullanabilirsiniz.
$ ls libs
libc.so.6 libreadline.so.8 libtinfo.so.6 libtinfow.so.6
# Şimdi çevresel değişkenimizi tanımlayalım.
export LD_LIBRARY_PATH=/home/user/test/libs/
$ ldd /bin/bash
linux-vdso.so.1 (0x00007ffdeddc6000)
libreadline.so.8 => /home/user/test/libs/libreadline.so.8 (0x00007fd9ce7ea000)
libtinfo.so.6 => /home/user/test/libs/libtinfo.so.6 (0x00007fd9ce7ab000)
libc.so.6 => /home/user/test/libs/libc.so.6 (0x00007fd9ce5b2000)
libtinfow.so.6 => /home/user/test/libs/libtinfow.so.6 (0x00007fd9ce572000)
/lib64/ld-linux-x86-64.so.2 (0x00007fd9ce926000)
$ ldd /bin/bash linux-vdso.so.1 (0x00007fff2c359000) libreadline.so.8 => /lib64/libreadline.so.8 (0x00007fce1e004000) libtinfo.so.6 => /lib64/libtinfo.so.6 (0x00007fce1dfc5000) libc.so.6 => /lib64/libc.so.6 (0x00007fce1ddcc000) libtinfow.so.6 => /lib64/libtinfow.so.6 (0x00007fce1dd8c000) /lib64/ld-linux-x86-64.so.2 (0x00007fce1e154000) # Şimdi tüm dosyaları libs adındaki bir dizine kopyalayalım. $ mkdir libs $ ldd /bin/bash | cut -f3 -d" " | grep "^/" | sed "s/.*/install & libs\//g" | sh # Bağımlılıkları toplu olarak kopyalamak için yukarıdaki komutu kullanabilirsiniz. $ ls libs libc.so.6 libreadline.so.8 libtinfo.so.6 libtinfow.so.6 # Şimdi çevresel değişkenimizi tanımlayalım. export LD_LIBRARY_PATH=/home/user/test/libs/ $ ldd /bin/bash linux-vdso.so.1 (0x00007ffdeddc6000) libreadline.so.8 => /home/user/test/libs/libreadline.so.8 (0x00007fd9ce7ea000) libtinfo.so.6 => /home/user/test/libs/libtinfo.so.6 (0x00007fd9ce7ab000) libc.so.6 => /home/user/test/libs/libc.so.6 (0x00007fd9ce5b2000) libtinfow.so.6 => /home/user/test/libs/libtinfow.so.6 (0x00007fd9ce572000) /lib64/ld-linux-x86-64.so.2 (0x00007fd9ce926000)
$ ldd /bin/bash
linux-vdso.so.1 (0x00007fff2c359000)
libreadline.so.8 => /lib64/libreadline.so.8 (0x00007fce1e004000)
libtinfo.so.6 => /lib64/libtinfo.so.6 (0x00007fce1dfc5000)
libc.so.6 => /lib64/libc.so.6 (0x00007fce1ddcc000)
libtinfow.so.6 => /lib64/libtinfow.so.6 (0x00007fce1dd8c000)
/lib64/ld-linux-x86-64.so.2 (0x00007fce1e154000)
# Şimdi tüm dosyaları libs adındaki bir dizine kopyalayalım.
$ mkdir libs
$ ldd /bin/bash | cut -f3 -d" " | grep "^/" | sed "s/.*/install & libs\//g" | sh
# Bağımlılıkları toplu olarak kopyalamak için yukarıdaki komutu kullanabilirsiniz.
$ ls libs
libc.so.6  libreadline.so.8  libtinfo.so.6  libtinfow.so.6
# Şimdi çevresel değişkenimizi tanımlayalım.
export LD_LIBRARY_PATH=/home/user/test/libs/
$ ldd /bin/bash
linux-vdso.so.1 (0x00007ffdeddc6000)
libreadline.so.8 => /home/user/test/libs/libreadline.so.8 (0x00007fd9ce7ea000)
libtinfo.so.6 => /home/user/test/libs/libtinfo.so.6 (0x00007fd9ce7ab000)
libc.so.6 => /home/user/test/libs/libc.so.6 (0x00007fd9ce5b2000)
libtinfow.so.6 => /home/user/test/libs/libtinfow.so.6 (0x00007fd9ce572000)
/lib64/ld-linux-x86-64.so.2 (0x00007fd9ce926000)

Yukarıdaki örnekte bütün bağımlılıkları sistemdeki konumundan çekip ayrı bir dizine kopyaladık ve bu dizinden kullanmasını sağladık. Burada dikkat ettiyseniz interpreter kopyalamadık. Bunun sebebi interpreter dosyayı çalıştırdığımızda dosya tarafından çağırılır. Bu durumun üstesinden gelmek için interpreter ve çalıştırılacak dosyayı da kopyalayalım ve aşağıdaki gibi çalıştıralım.

Plain text
Copy to clipboard
Open code in new window
EnlighterJS 3 Syntax Highlighter
$ install /bin/bash ./
$ install /lib64/ld-linux-x86-64.so.2 ./
$ ./ld-linux-x86-64.so.2 --library-path "/home/user/test/libs/" ./bash --version
GNU bash, version 5.1.16(1)-release (x86_64-pc-linux-gnu)
...
$ install /bin/bash ./ $ install /lib64/ld-linux-x86-64.so.2 ./ $ ./ld-linux-x86-64.so.2 --library-path "/home/user/test/libs/" ./bash --version GNU bash, version 5.1.16(1)-release (x86_64-pc-linux-gnu) ...
$ install /bin/bash ./
$ install /lib64/ld-linux-x86-64.so.2 ./
$ ./ld-linux-x86-64.so.2 --library-path "/home/user/test/libs/" ./bash --version
GNU bash, version 5.1.16(1)-release (x86_64-pc-linux-gnu)
...

Artık programımızı herhangi bir sistemde bütün bağımlılıkları ile birlikte çalıştırmamız mümkün hale geldi.

Yazımızın devamına buradan ulaşabilirsiniz.

Series Navigation<< Appimage yapımı serisi – Bölüm 2
  • Ali Rıza Keskin

    Gentoo kullancısı - Özgür yazılım sevdalısı - Pardus gönüllüsü

Etiketler:
[wpdiscuz_comments]