http://ipkg.nslu2-linux.org/feeds/optware/ts509/cross/stable/
利用
ipkg-opt install pacage_name
2012年9月14日 星期五
Asterisk設定(centOS)
安裝gcc
rpm -ivh cpp-4.1.2-48.el5.i386.rpm
rpm -ivh kernel-headers-2.6.18-194.el5.i386.rpm
rpm -ivh glibc-headers-2.5-49.i386.rpm
rpm -ivh glibc-devel-2.5-49.i386.rpm
rpm -ivh libgomp-4.4.0-6.el5.i386.rpm
rpm -ivh gcc-4.1.2-48.el5.i386.rpm
安裝g++
rpm -ivh libstdc++-devel-4.1.2-48.el5.i386.rpm
rpm -ihv gcc-c++-4.1.2-48.el5.i386.rpm
安裝kernel source
rpm -ivh kernel-2.6.18-194.el5.i686.rpm
rpm -ihv kernel-devel-2.6.18-194.el5.i686.rpm
安裝網卡
rpm -ivh kmod-atl2-2.2.3-1.i686.rpm
cd /lib/modules/2.6.18-92.1.18.e15.centos.plus/extra/atl2
insmod atl2.ko
depmod -A
看/lib/modules/2.6.18-164.11.1.e15/modules.dep有沒有 atl2
vi /etc/sysconfig/network-scripts/ifcfg-eth0
#---------------------------------------
DEVICE=eth0
#BOOTPROTO=dhcp
BOOTPROTO=static
BROADCAST=192.168.1.255
IPADDR=192.168.1.2
NETMASK=255.255.255.0
NETWORK=192.168.1.0
ONBOOT=yes
HWADDR=xx:xx:xx:xx:xx:xx
#---------------------------------------
yum install ethtool
yum install net-tool
在/etc/sysconfig/network-scripts/ifup-post的exit 0上面加上
/usr/sbin/ethtool -s eth0 wol g
利用
$ ethtool eth0
確認是否有
Settings for eth0:
Supports Wake-on: g
Wake-on: g
Link detected: yes
出現
測試
#>nmap -sU -p 5060 <對方主機 IP 位址>
/etc/asterisk/sip.conf
;-------------------------------------------------------
[general]
[001] ;sip 的帳號
username=001 ;sip 的電話號碼
type=friend
secret=xxx ;sip 的密碼
qualify=yes
nat=yes
host=dynamic
dtmfmode=rfc2833
context=internal
canreinvite=no
;-------------------------------------------------------
[002] ;sip 的帳號
username=002 ;sip 的電話號碼
type=friend
secret=ooo ;sip 的密碼
qualify=yes
nat=yes
host=dynamic
dtmfmode=rfc2833
context=internal
canreinvite=no
/etc/asterisk/extensions.conf
;-------------------------------------------------------
[internal]
exten => 900,1,Playback(pls-try-call-later)
exten => 900,n,Hangup
exten => _555XX,1,MeetMe(${EXTEN:3}di)
exten => _555XX,n,Hangup()
exten => _X.,1,Dial(SIP/${EXTEN},,Tt)
exten => _X.,n,Hangup()
; _:代表開頭
;X:代表 0-9
;.:代表任意長度的字元
; _X.:指電話號碼是以數字開始不管任何長度
;T:允許發話端使用轉接
;t:允許受話端使用轉接
;撥打555XX進入會議室,555啟動會議室、XX為會議室代碼,可視需求增減長度(${EXTEN:3}需跟著修改)。
;d為不要求會議室密碼,想設密碼可改為D
;i為使用者進出時提示,靜音為q
存檔後
#sudo /usr/sbin/asterisk -rx 'sip reload'
#sudo /usr/sbin/asterisk -rx 'dialplan reload'
或
#sudo /usr/sbin/asterisk -r
CLI> core reload now
vim /etc/asterisk/features.conf
featuredigittimeout = 500 ;組合鍵的抓取時間(毫秒)
pickupexten = *8 ;代接組合鍵
blindxfer = #2 ;直接轉接(轉接方直接斷線)
atxfer = *2 ;轉接(轉接後可先與受話方通話)
重啟Asterisk
#sudo /usr/sbin/asterisk -r
免費可用的STUN server
stun.xten.com stun.xten.com
stun.fwdnet.net stun.fwdnet.net
stun.fwdnet.net:3478 stun.fwdnet.net:3478
stun.wirlab.net stun.wirlab.net
stun01.sipphone.com stun01.sipphone.com
stun.iptel.org stun.iptel.org
stun.softjoys.com:3478 stun.softjoys.com:3478
stun.counterpath.com
rpm -ivh cpp-4.1.2-48.el5.i386.rpm
rpm -ivh kernel-headers-2.6.18-194.el5.i386.rpm
rpm -ivh glibc-headers-2.5-49.i386.rpm
rpm -ivh glibc-devel-2.5-49.i386.rpm
rpm -ivh libgomp-4.4.0-6.el5.i386.rpm
rpm -ivh gcc-4.1.2-48.el5.i386.rpm
安裝g++
rpm -ivh libstdc++-devel-4.1.2-48.el5.i386.rpm
rpm -ihv gcc-c++-4.1.2-48.el5.i386.rpm
安裝kernel source
rpm -ivh kernel-2.6.18-194.el5.i686.rpm
rpm -ihv kernel-devel-2.6.18-194.el5.i686.rpm
安裝網卡
rpm -ivh kmod-atl2-2.2.3-1.i686.rpm
cd /lib/modules/2.6.18-92.1.18.e15.centos.plus/extra/atl2
insmod atl2.ko
depmod -A
看/lib/modules/2.6.18-164.11.1.e15/modules.dep有沒有 atl2
vi /etc/sysconfig/network-scripts/ifcfg-eth0
#---------------------------------------
DEVICE=eth0
#BOOTPROTO=dhcp
BOOTPROTO=static
BROADCAST=192.168.1.255
IPADDR=192.168.1.2
NETMASK=255.255.255.0
NETWORK=192.168.1.0
ONBOOT=yes
HWADDR=xx:xx:xx:xx:xx:xx
#---------------------------------------
yum install ethtool
yum install net-tool
在/etc/sysconfig/network-scripts/ifup-post的exit 0上面加上
/usr/sbin/ethtool -s eth0 wol g
利用
$ ethtool eth0
確認是否有
Settings for eth0:
Supports Wake-on: g
Wake-on: g
Link detected: yes
出現
測試
#>nmap -sU -p 5060 <對方主機 IP 位址>
5060/udp open|filtered sip表可連
5060/udp closed sip表不可連
/etc/asterisk/sip.conf
;-------------------------------------------------------
[general]
externhost=mypbx.mydomain.com
或
externaddr=aaa.aaa.aaa.aaa
localnet=192.168.x.x/255.255.255.0
transport=tls,tcp,udp
[001] ;sip 的帳號
username=001 ;sip 的電話號碼
type=friend
secret=xxx ;sip 的密碼
qualify=yes
nat=yes
host=dynamic
dtmfmode=rfc2833
context=internal
canreinvite=no
;-------------------------------------------------------
[002] ;sip 的帳號
username=002 ;sip 的電話號碼
type=friend
secret=ooo ;sip 的密碼
qualify=yes
nat=yes
host=dynamic
dtmfmode=rfc2833
context=internal
canreinvite=no
/etc/asterisk/extensions.conf
;-------------------------------------------------------
[internal]
exten => 900,1,Playback(pls-try-call-later)
exten => 900,n,Hangup
exten => _555XX,1,MeetMe(${EXTEN:3}di)
exten => _555XX,n,Hangup()
exten => _X.,1,Dial(SIP/${EXTEN},,Tt)
exten => _X.,n,Hangup()
; _:代表開頭
;X:代表 0-9
;.:代表任意長度的字元
; _X.:指電話號碼是以數字開始不管任何長度
;T:允許發話端使用轉接
;t:允許受話端使用轉接
;撥打555XX進入會議室,555啟動會議室、XX為會議室代碼,可視需求增減長度(${EXTEN:3}需跟著修改)。
;d為不要求會議室密碼,想設密碼可改為D
;i為使用者進出時提示,靜音為q
存檔後
#sudo /usr/sbin/asterisk -rx 'sip reload'
#sudo /usr/sbin/asterisk -rx 'dialplan reload'
或
#sudo /usr/sbin/asterisk -r
CLI> core reload now
vim /etc/asterisk/features.conf
featuredigittimeout = 500 ;組合鍵的抓取時間(毫秒)
pickupexten = *8 ;代接組合鍵
blindxfer = #2 ;直接轉接(轉接方直接斷線)
atxfer = *2 ;轉接(轉接後可先與受話方通話)
重啟Asterisk
#sudo /usr/sbin/asterisk -r
CLI> core restart now
顯示設定
CLI>sip show settings
免費可用的STUN server
stun.xten.com stun.xten.com
stun.fwdnet.net stun.fwdnet.net
stun.fwdnet.net:3478 stun.fwdnet.net:3478
stun.wirlab.net stun.wirlab.net
stun01.sipphone.com stun01.sipphone.com
stun.iptel.org stun.iptel.org
stun.softjoys.com:3478 stun.softjoys.com:3478
stun.counterpath.com
2012年9月13日 星期四
建linux系統
要用make menuconfig要先有ncurses
#sudo apt-get install libncurses5-dev
http://www.kernel.org/
http://www.busybox.net/downloads/
在home目錄下建立;
rootfs
rootfs/etc
rootfs/www
在rootfs/etc目錄下分別建立
######################/etc/inittab ######################
::sysinit:/etc/rcS
tty1::askfirst:-/bin/sh --login
tty2::askfirst:-/bin/sh --login
tty3::askfirst:-/bin/sh --login
<runlevels>:busybox 已忽略,只需留空
有效的actions包括: sysinit, respawn, askfirst, wait,once,restart,ctrlaltdel, shutdown.
askfirst和respawn類似,在運行前,先打印一句"Please press Enter to activate this console."
<process>: 指定執行的進程和它的命令行
如果busybox沒有inittab將默認按以下處理:
::sysinit:/etc/init.d/rcS
::askfirst:/bin/sh
::ctrlaltdel:/sbin/reboot
::shutdown:/sbin/swapoff -a
::shutdown:/bin/umount -a -r
::restart:/sbin/init
如果發現/dev/console不是一個串口設備,將執行:
tty2::askfirst:/bin/sh
tty3::askfirst:/bin/sh
tty4::askfirst:/bin/sh
在shell前加一個'-'前綴表示是一個登陸shell,比如:
tty2::askfirst:-/bin/sh
/sbin/getty可以指定選擇某個tty.比如:
tty4::respawn:/sbin/getty 38400 tty5 /* /sbin/getty 波特率 tty號 */
將串口輸出到終端:
::respawn:/sbin/getty -L ttyS0 9600 vt100
串口輸出到modem:
::respawn:/sbin/getty 57600 ttyS2
######################/etc/profile ######################
#!/bin/sh
cat <<EOF
Welcome to Neo's Linux
EOF
export PATH=/bin:/sbin:/usr/bin:/usr/sbin
######################/etc/protocols ######################
# Internet (IP) protocols
#
ip 0 IP
icmp 1 ICMP
igmp 2 IGMP
ggp 3 GGP
ipencap 4 IP-ENCAP
st 5 ST
tcp 6 TCP
egp 8 EGP
igp 9 IGP
pup 12 PUP
udp 17 UDP
hmp 20 HMP
xns-idp 22 XNS-IDP
rdp 27 RDP
iso-tp4 29 ISO-TP4
xtp 36 XTP
ddp 37 DDP
idpr-cmtp 38 IDPR-CMTP
idrp 45 IDRP
rsvp 46 RSVP
gre 47 GRE
esp 50 IPSEC-ESP
ah 51 IPSEC-AH
skip 57 SKIP
rspf 73 RSPF CPHB
vmtp 81 VMTP
eigrp 88 EIGRP
ospf 89 OSPFIGP
ax.25 93 AX.25
ipip 94 IPIP
etherip 97 ETHERIP
encap 98 ENCAP
pim 103 PIM
ipcomp 108 IPCOMP
vrrp 112 VRRP
l2tp 115 L2TP
isis 124 ISIS
sctp 132 SCTP
fc 133 FC
######################/etc/rcS ######################
#!/bin/sh
export PATH=/bin:/sbin:/usr/bin:/usr/sbin
mount -t proc none /proc
mount -t sysfs none /sys
mount -t tmpfs tmpfs /dev -o size=512K,mode=0755
echo NEOHOST > /proc/sys/kernel/hostname
mkdir -p /var/run /var/log /var/lock /var/state \
/var/tmp /var/mnt /dev/pts /dev/shm
mount devpts /dev/pts -t devpts
echo /bin/mdev > /proc/sys/kernel/hotplug
mdev -s
ifconfig lo 127.0.0.1 up
ifconfig eth0 192.168.1.253 netmask 255.255.255.0 up
telnetd -l /bin/sh
httpd -h /www
###################/etc/services #################
rootfs/www目錄下建立一個index.html
###################/www/index.html #################
<h1>Success!</h1>
<p>Welcome to Neo's linux!</p>
接著編譯busybox
#make menuconfig
Busybox Settings => Build Options選Build as a static binary
Busybox Settings => Installation Options 選../rootfs
存檔
make
make install
原本有rootfs/etc,rootfs/www
現在busybox又加了rootfs/bin,rootfs/sbin,rootfs/usr/bin,rootfs/usr/sbin
補齊剩下的dev,proc,tmp,var,lib,root和sys目錄
接著製作initrd
在home目錄下
#dd if=/dev/zero of=initrd bs=1024 count=8192
#mkfs.ext2 -F initrd
在home目錄下
#mkdir temp_initrd
#sudo mount -o loop initrd temp_initrd
#cp -fR rootfs/* temp_initrd/
#sudo umount temp_initrd
編譯Linux Kernel
清除前次設定
#make mrproper
清除之前編譯的檔案
#make clean
#make menuconfig
存檔
make
交叉編譯
make ARCH=arm CROSS_COMPILE=arm-linux-uclibc-
make ARCH=sh CROSS_COMPILE=sh4-linux-
對x86,Kernel是 arch/x86/boot/bzImage
對MIPS,Kernel是 arch/powerpc/boot/bzImage
對arm,Kernel是 arch/arm/boot/bzImage
加載內核
bzImage和initrd拷貝到linux系統的/boot
#vi /boot/grub/menu.lst
title My OS
root (hd0,0)
kernel /boot/bzImage rw root=/dev/ram rootfs_size=8M
initrd /boot/initrd
#sudo apt-get install libncurses5-dev
http://www.kernel.org/
http://www.busybox.net/downloads/
在home目錄下建立;
rootfs
rootfs/etc
rootfs/www
在rootfs/etc目錄下分別建立
######################/etc/inittab ######################
::sysinit:/etc/rcS
tty1::askfirst:-/bin/sh --login
tty2::askfirst:-/bin/sh --login
tty3::askfirst:-/bin/sh --login
busybox初始化配置
<id>:<runlevels>:<action>:<process>
其中<id>指進程運行的tty。其內容是/dev下的tty設備或者別名<runlevels>:busybox 已忽略,只需留空
有效的actions包括: sysinit, respawn, askfirst, wait,once,restart,ctrlaltdel, shutdown.
askfirst和respawn類似,在運行前,先打印一句"Please press Enter to activate this console."
<process>: 指定執行的進程和它的命令行
如果busybox沒有inittab將默認按以下處理:
::sysinit:/etc/init.d/rcS
::askfirst:/bin/sh
::ctrlaltdel:/sbin/reboot
::shutdown:/sbin/swapoff -a
::shutdown:/bin/umount -a -r
::restart:/sbin/init
如果發現/dev/console不是一個串口設備,將執行:
tty2::askfirst:/bin/sh
tty3::askfirst:/bin/sh
tty4::askfirst:/bin/sh
在shell前加一個'-'前綴表示是一個登陸shell,比如:
tty2::askfirst:-/bin/sh
/sbin/getty可以指定選擇某個tty.比如:
tty4::respawn:/sbin/getty 38400 tty5 /* /sbin/getty 波特率 tty號 */
將串口輸出到終端:
::respawn:/sbin/getty -L ttyS0 9600 vt100
串口輸出到modem:
::respawn:/sbin/getty 57600 ttyS2
######################/etc/profile ######################
#!/bin/sh
cat <<EOF
Welcome to Neo's Linux
EOF
export PATH=/bin:/sbin:/usr/bin:/usr/sbin
######################/etc/protocols ######################
# Internet (IP) protocols
#
ip 0 IP
icmp 1 ICMP
igmp 2 IGMP
ggp 3 GGP
ipencap 4 IP-ENCAP
st 5 ST
tcp 6 TCP
egp 8 EGP
igp 9 IGP
pup 12 PUP
udp 17 UDP
hmp 20 HMP
xns-idp 22 XNS-IDP
rdp 27 RDP
iso-tp4 29 ISO-TP4
xtp 36 XTP
ddp 37 DDP
idpr-cmtp 38 IDPR-CMTP
idrp 45 IDRP
rsvp 46 RSVP
gre 47 GRE
esp 50 IPSEC-ESP
ah 51 IPSEC-AH
skip 57 SKIP
rspf 73 RSPF CPHB
vmtp 81 VMTP
eigrp 88 EIGRP
ospf 89 OSPFIGP
ax.25 93 AX.25
ipip 94 IPIP
etherip 97 ETHERIP
encap 98 ENCAP
pim 103 PIM
ipcomp 108 IPCOMP
vrrp 112 VRRP
l2tp 115 L2TP
isis 124 ISIS
sctp 132 SCTP
fc 133 FC
######################/etc/rcS ######################
#!/bin/sh
export PATH=/bin:/sbin:/usr/bin:/usr/sbin
mount -t proc none /proc
mount -t sysfs none /sys
mount -t tmpfs tmpfs /dev -o size=512K,mode=0755
echo NEOHOST > /proc/sys/kernel/hostname
mkdir -p /var/run /var/log /var/lock /var/state \
/var/tmp /var/mnt /dev/pts /dev/shm
mount devpts /dev/pts -t devpts
echo /bin/mdev > /proc/sys/kernel/hotplug
mdev -s
ifconfig lo 127.0.0.1 up
ifconfig eth0 192.168.1.253 netmask 255.255.255.0 up
telnetd -l /bin/sh
httpd -h /www
###################/etc/services #################
rootfs/www目錄下建立一個index.html
###################/www/index.html #################
<h1>Success!</h1>
<p>Welcome to Neo's linux!</p>
接著編譯busybox
#make menuconfig
Busybox Settings => Build Options選Build as a static binary
Busybox Settings => Installation Options 選../rootfs
存檔
make
make install
原本有rootfs/etc,rootfs/www
現在busybox又加了rootfs/bin,rootfs/sbin,rootfs/usr/bin,rootfs/usr/sbin
補齊剩下的dev,proc,tmp,var,lib,root和sys目錄
接著製作initrd
在home目錄下
#dd if=/dev/zero of=initrd bs=1024 count=8192
#mkfs.ext2 -F initrd
在home目錄下
#mkdir temp_initrd
#sudo mount -o loop initrd temp_initrd
#cp -fR rootfs/* temp_initrd/
#sudo umount temp_initrd
編譯Linux Kernel
清除前次設定
#make mrproper
清除之前編譯的檔案
#make clean
#make menuconfig
存檔
make
即以下三步
make vmlinux <==未經壓縮的核心(放在source根目錄)
make modules <==僅核心模組(insmod用)
make bzImage <==經壓縮過的核心(在arch/xxx/boot/bzimage)
通常把bzImage命名成vmlinuz (bzImage=vmlinuz,用bzip壓縮的kernel,zImagem用gzip壓縮的kernel,vmlinux就是沒有壓縮的kernel)
make module_install <==會幫忙拷貝module到目錄/lib/modules
交叉編譯
make ARCH=arm CROSS_COMPILE=arm-linux-uclibc-
make ARCH=sh CROSS_COMPILE=sh4-linux-
對x86,Kernel是 arch/x86/boot/bzImage
對MIPS,Kernel是 arch/powerpc/boot/bzImage
對arm,Kernel是 arch/arm/boot/bzImage
加載內核
bzImage和initrd拷貝到linux系統的/boot
#vi /boot/grub/menu.lst
title My OS
root (hd0,0)
kernel /boot/bzImage rw root=/dev/ram rootfs_size=8M
initrd /boot/initrd
2012年9月10日 星期一
rTurrent cross compiler
安裝編譯所需要的依賴包
apt-get install libcurl4-openssl-dev
apt-get install libsigc++-2.0-dev
apt-get install libncurses5-dev
編譯安裝xmlrpc-c
apt-get install subversion
cd /usr/local/src
svn checkout https://xmlrpc-c.svn.sourceforge.net/svnroot/xmlrpc-c/advanced xmlrpc-c
cd ./xmlrpc-c
./configure
make
sudo make install
編譯安裝libtorrent
wget http://libtorrent.rakshasa.no/downloads/libtorrent-0.13.2.tar.gz
tar -xzvf libtorrent-0.13.2.tar.gz
cd libtorrent-0.13.2/
./configure
make
sudo make install
編譯安裝rtorrent
wget http://libtorrent.rakshasa.no/downloads/rtorrent-0.9.2.tar.gz
tar -xzvf rtorrent-0.9.2.tar.gz
cd rtorrent-0.9.2
./configure --with-xmlrpc-c libtorrent_CFLAGS="-I/usr/local/include" libtorrent_LIBS="-ltorrent" CFLAGS="-I/usr/local/include" LDFLAGS="-L/usr/local/lib" LIBS="-lxmlrpc"
make
sudo make install
#-----------------------------------------------------------------------
# ----------------------------------------
# rtorrent 設定檔
# 檔名:.rtorrent.rc (隱藏檔,前面有點)
# 存放位置:~ (使用者家目錄)
# ----------------------------------------
# 每 torrent 最小/最大連接數
min_peers = 50
max_peers = 200
# 每 torrent 最大上傳數
max_uploads = 2
# 上傳和下載速度限制,設0=無限制.(單位 KiB)
download_rate = 150
upload_rate = 8
# 隨機 port 範圍
# 範例:port_range = 6890-6999
port_range = 19000-19000
# 下載檔名編碼
encoding_list = UTF-8
# 下載檔案存放目錄
directory = /home/neo/bt
# 快取存放目錄
session = /home/neo/bt/session
# torrent 存放目錄 和 排程設定
# 放在此目錄的中的 torrent 會自動加入列表
schedule = watch_directory,5,5,load_start=/home/neo/bt/seeds/*.torrent
# DHT 開關
dht = on
# DHT port (預設為 6881)
dht_port = 19000
#------------------------------------------------------------------------------------
先試$:/usr/bin/pkg-config看有沒有這程式
沒有的話sudo apt-get install pkg-config
等等編譯libtorrent會用到
還有 sudo apt-get install gettext
1:curl-7.23.1.tar.gz
wget http://curl.haxx.se/download/curl-7.23.1.tar.gz
tar xvf curl-7.23.1.tar.gz
./configure --prefix=/opt/curl7231 --host=sh4-linux
make
sudo make install
$:/opt/curl7231/curl -L www.google.com
2:GNU M4
wget http://ftp.gnu.org/gnu/m4/m4-latest.tar.gz
tar xvf m4-latest.tar.gz
./configure --prefix=/opt/m4 --host=sh4-linux
make
sudo make install
3:libsigc++-2.2.10
sudo cp /opt/m4/bin/m4 /sbin/m4
wget http://ftp.gnome.org/pub/GNOME/sources/libsigc++/2.2/libsigc++-2.2.10.tar.bz2
tar xvf libsigc++-2.2.10.tar.bz2
./configure --prefix=/opt/libsigc++ --host=sh4-linux
make
sudo make install
sudo rm /sbin/m4
4:glib2.3
wget http://ftp.acc.umu.se/pub/gnome/sources/glib/2.30/glib-2.30.0.tar.bz2
tar jxvf glib-2.30.0.tar.bz2
./configure --prefix=/opt/glib230 --host=sh4-linux
make
sudo make install
5:libtorrent
sudo cp /opt/STM/STLinux-2.3/devkit/sh4/target/usr/lib/libstdc++.la /usr/lib
sudo cp /opt/STM/STLinux-2.3/devkit/sh4/target/usr/lib/libstdc++.so /usr/lib
wget http://libtorrent.rakshasa.no/downloads/libtorrent-0.13.2.tar.gz
tar xvf libtorrent-0.13.2.tar.gz
export
./configure --without-PACKAGE --prefix=/opt/libtorrent --disable-openssl
vi Makefile
replace gcc => sh4-linux-gcc
replace cpp => sh4-linux-cpp
replace g++ => sh4-linux-g++
replace ar => sh4-linux-ar
replace /use/bin/ld => /opt/STM/STLinux-2.3/devkit/sh4/sh4-linux/bin/ld
#-------------------------------------------------------------
apt-get install libcurl4-openssl-dev
apt-get install libsigc++-2.0-dev
編譯安裝libtorrent
wget http://libtorrent.rakshasa.no/downloads/libtorrent-0.12.6.tar.gz
tar -xzvf libtorrent-0.12.2.tar.gz
cd libtorrent-0.12.2/
./configure
make
make install
apt-get install libcurl4-openssl-dev
apt-get install libsigc++-2.0-dev
apt-get install libncurses5-dev
編譯安裝xmlrpc-c
apt-get install subversion
cd /usr/local/src
svn checkout https://xmlrpc-c.svn.sourceforge.net/svnroot/xmlrpc-c/advanced xmlrpc-c
cd ./xmlrpc-c
./configure
make
sudo make install
編譯安裝libtorrent
wget http://libtorrent.rakshasa.no/downloads/libtorrent-0.13.2.tar.gz
tar -xzvf libtorrent-0.13.2.tar.gz
cd libtorrent-0.13.2/
./configure
make
sudo make install
編譯安裝rtorrent
wget http://libtorrent.rakshasa.no/downloads/rtorrent-0.9.2.tar.gz
tar -xzvf rtorrent-0.9.2.tar.gz
cd rtorrent-0.9.2
./configure --with-xmlrpc-c libtorrent_CFLAGS="-I/usr/local/include" libtorrent_LIBS="-ltorrent" CFLAGS="-I/usr/local/include" LDFLAGS="-L/usr/local/lib" LIBS="-lxmlrpc"
make
sudo make install
#-----------------------------------------------------------------------
# ----------------------------------------
# rtorrent 設定檔
# 檔名:.rtorrent.rc (隱藏檔,前面有點)
# 存放位置:~ (使用者家目錄)
# ----------------------------------------
# 每 torrent 最小/最大連接數
min_peers = 50
max_peers = 200
# 每 torrent 最大上傳數
max_uploads = 2
# 上傳和下載速度限制,設0=無限制.(單位 KiB)
download_rate = 150
upload_rate = 8
# 隨機 port 範圍
# 範例:port_range = 6890-6999
port_range = 19000-19000
# 下載檔名編碼
encoding_list = UTF-8
# 下載檔案存放目錄
directory = /home/neo/bt
# 快取存放目錄
session = /home/neo/bt/session
# torrent 存放目錄 和 排程設定
# 放在此目錄的中的 torrent 會自動加入列表
schedule = watch_directory,5,5,load_start=/home/neo/bt/seeds/*.torrent
# DHT 開關
dht = on
# DHT port (預設為 6881)
dht_port = 19000
#------------------------------------------------------------------------------------
先試$:/usr/bin/pkg-config看有沒有這程式
沒有的話sudo apt-get install pkg-config
等等編譯libtorrent會用到
還有 sudo apt-get install gettext
1:curl-7.23.1.tar.gz
wget http://curl.haxx.se/download/curl-7.23.1.tar.gz
tar xvf curl-7.23.1.tar.gz
./configure --prefix=/opt/curl7231 --host=sh4-linux
make
sudo make install
$:/opt/curl7231/curl -L www.google.com
2:GNU M4
wget http://ftp.gnu.org/gnu/m4/m4-latest.tar.gz
tar xvf m4-latest.tar.gz
./configure --prefix=/opt/m4 --host=sh4-linux
make
sudo make install
3:libsigc++-2.2.10
sudo cp /opt/m4/bin/m4 /sbin/m4
wget http://ftp.gnome.org/pub/GNOME/sources/libsigc++/2.2/libsigc++-2.2.10.tar.bz2
tar xvf libsigc++-2.2.10.tar.bz2
./configure --prefix=/opt/libsigc++ --host=sh4-linux
make
sudo make install
sudo rm /sbin/m4
4:glib2.3
wget http://ftp.acc.umu.se/pub/gnome/sources/glib/2.30/glib-2.30.0.tar.bz2
tar jxvf glib-2.30.0.tar.bz2
./configure --prefix=/opt/glib230 --host=sh4-linux
make
sudo make install
5:libtorrent
sudo cp /opt/STM/STLinux-2.3/devkit/sh4/target/usr/lib/libstdc++.la /usr/lib
sudo cp /opt/STM/STLinux-2.3/devkit/sh4/target/usr/lib/libstdc++.so /usr/lib
wget http://libtorrent.rakshasa.no/downloads/libtorrent-0.13.2.tar.gz
tar xvf libtorrent-0.13.2.tar.gz
export
PKG_CONFIG_PATH="
/opt/libsigc++/lib/pkgconfig:/opt/curl7231
/lib/pkgconfig
"
./configure --without-PACKAGE --prefix=/opt/libtorrent --disable-openssl
vi Makefile
replace gcc => sh4-linux-gcc
replace cpp => sh4-linux-cpp
replace g++ => sh4-linux-g++
replace ar => sh4-linux-ar
replace /use/bin/ld => /opt/STM/STLinux-2.3/devkit/sh4/sh4-linux/bin/ld
#-------------------------------------------------------------
apt-get install libcurl4-openssl-dev
apt-get install libsigc++-2.0-dev
編譯安裝libtorrent
wget http://libtorrent.rakshasa.no/downloads/libtorrent-0.12.6.tar.gz
tar -xzvf libtorrent-0.12.2.tar.gz
cd libtorrent-0.12.2/
./configure
make
make install
2012年9月9日 星期日
gcc 4.2 build-essential tarball
sudo dpkg -i (deb_name)
#-------------------------------------------------
gcc4.2:
1:gcc-4.2-base (The GNU Compiler Collection)
2:libc6 & libgcc1_4.2 (GNU C Library: Shared libraries & GCC support library )
3:binutils_2.18 (The GNU assembler, linker and binary utilities)
4:cpp-4.2 (The GNU C preprocessor)
5:libgomp1 (GCC OpenMP (GOMP) support library )
6:gcc-4.2_4
7:linux-libc-dev
8:libc6-dev_2.7
#-------------------------------------------------
g++4.2:
9:libstdc++6_4.2 (The GNU Standard C++ Library v3 )
10:libstdc++6-4.2-dev & g++-4.2 (The GNU Standard C++ Development Libraries and Header Files & GNU C++ compiler)
sudo ln -s /usr/bin/gcc-4.2 /usr/bin/gcc
sudo ln -s /usr/bin/g++-4.2 /usr/bin/g++
#-------------------------------------------------
make 3.81:
1:libc6
2:make3.81
#--------------------------------------------------
有時候需要下列檔案
libncurses5_5.6+20071124-1ubuntu2_i386.deb
libncurses5-dev_5.6+20071124-1ubuntu2_i386.deb
libc6-i686_2.7-10ubuntu8.1_i386.deb
sudo dpkg -L gcc-4.2
sudo dpkg -L g++-4.2
sudo dpkg -L make
#-------------------------------------------------
gcc4.2:
1:gcc-4.2-base (The GNU Compiler Collection)
2:libc6 & libgcc1_4.2 (GNU C Library: Shared libraries & GCC support library )
3:binutils_2.18 (The GNU assembler, linker and binary utilities)
4:cpp-4.2 (The GNU C preprocessor)
5:libgomp1 (GCC OpenMP (GOMP) support library )
6:gcc-4.2_4
7:linux-libc-dev
8:libc6-dev_2.7
#-------------------------------------------------
g++4.2:
9:libstdc++6_4.2 (The GNU Standard C++ Library v3 )
10:libstdc++6-4.2-dev & g++-4.2 (The GNU Standard C++ Development Libraries and Header Files & GNU C++ compiler)
sudo ln -s /usr/bin/gcc-4.2 /usr/bin/gcc
sudo ln -s /usr/bin/g++-4.2 /usr/bin/g++
#-------------------------------------------------
make 3.81:
1:libc6
2:make3.81
#--------------------------------------------------
有時候需要下列檔案
libncurses5_5.6+20071124-1ubuntu2_i386.deb
libncurses5-dev_5.6+20071124-1ubuntu2_i386.deb
libc6-i686_2.7-10ubuntu8.1_i386.deb
sudo dpkg -L gcc-4.2
sudo dpkg -L g++-4.2
sudo dpkg -L make
rp-pppoe & ppp
download rp-pppoe-3.11.tar.gz & ppp-2.4.5.tar.gz
編譯
rp-pppoe:
sudo ./go
ppp-2.4.5
./configure
CC=gcc make
sudo make install
sudo make install-etcppp
拷貝到目的地
rp-pppoe:
copy /usr/sbin
pppoe pppoe-server pppoe-sniff pppoe-relay pppoe-setup pppoe-start pppoe-stop pppoe-status pppoe-connect
to target /usr/sbin
pppd:
copy /usr/local/sbin
pppd chat pppdump pppstats pppoe-discovery
to target /usr/sbin
copy etc.ppp/
options chap-secrets pap-secrets
to target /etc/ppp/
using ppp:
create
/etc/ppp/peers/neo
/etc/ppp/peers/neo-connect-chat
$:sudo pppd call neo
using pppoe client:
$: sudo pppoe-setup
$: sudo pppoe-start
sudo route add default gw 61.59.238.1 irtt ppp0
編譯
rp-pppoe:
sudo ./go
ppp-2.4.5
./configure
CC=gcc make
sudo make install
sudo make install-etcppp
拷貝到目的地
rp-pppoe:
copy /usr/sbin
pppoe pppoe-server pppoe-sniff pppoe-relay pppoe-setup pppoe-start pppoe-stop pppoe-status pppoe-connect
to target /usr/sbin
pppd:
copy /usr/local/sbin
pppd chat pppdump pppstats pppoe-discovery
to target /usr/sbin
copy etc.ppp/
options chap-secrets pap-secrets
to target /etc/ppp/
using ppp:
create
/etc/ppp/peers/neo
/etc/ppp/peers/neo-connect-chat
$:sudo pppd call neo
using pppoe client:
$: sudo pppoe-setup
$: sudo pppoe-start
sudo route add default gw 61.59.238.1 irtt ppp0
2012年9月5日 星期三
DirectFB安裝
安裝zlib-1.2.7.tar.gz
安裝libpng-1.5.12.tar.gz
安裝jpegsrc.v6b.tar.gz
安裝Freetype-2.1.3.tar.gz
安裝DirectFB-1.6.1.tar.gz
#--------------
Zlib-1.2.7
CC=sh4-linux-gcc
./configure --prefix=/opt/zlib127 --shared –build=i686
–target=sh4-linux –host=sh4-linux
make
make install
#--------------
libpng1512
cp zlib.h zconf.h到資料夾
CC=sh4-linux-gcc
./configure --prefix=/opt/libpng1512 LDFLAGS="-L/opt/zlib127/lib " LIBS="-lz"
--build=i686 –target=sh4-linux –host=sh4-linux
make
make install
#--------------
libjpeg6b
CC=sh4-linux-gcc
./configure --prefix=/opt/libjpeg6b –enable-static --enable-shared
--build=i686 –target=sh4-linux –host=sh4-linux
make
mkdir /opt/libjpeg6b/include
mkdir /opt/libjpeg6b/lib
mkdir /opt/libjpeg6b/bin
mkdir /opt/libjpeg6b/man
mkdir /opt/libjpeg6b/man1
make install
#-----------------------------
freetype
./configure --prefix=/opt/freetype
make
make install
把/opt/freetype/include/freetype2/freetype拷貝到 /opt/freetype/include/freetype
#-----------------------------
DirectFB16
./configure --prefix=/opt/db16 CFLAGS="-I/opt/zlib127/include -I/opt/libjpeg6b/include" LDFLAGS="-L/opt/zlib127/lib -L/opt/libpng1512/lib -L/opt/freetype/lib -L/opt/libjpeg6b/lib" LIBPNG_LIBS="-lpng -lm" LIBPNG_CFLAGS="-I/opt/libpng1512/include" FREETYPE_LIBS="-lfreetype" FREETYPE_CFLAGS="-I/opt/freetype/include" LIBJPEG="-ljpeg"
--build=i686 –target=sh4-linux –host=sh4-linux
#-------------------------------
DirectFB-examples-1.6.0.tar.gz
CC=sh4-linux-gcc
./configure --prefix=$HOME LDFLAGS="-L/opt/db16/lib" DIRECTFB_CFLAGS="-I/opt/db16/include/directfb" DIRECTFB_LIBS="-ldirectfb"
--build=i686 –target=sh4-linux –host=sh4-linux
安裝libpng-1.5.12.tar.gz
安裝jpegsrc.v6b.tar.gz
安裝Freetype-2.1.3.tar.gz
安裝DirectFB-1.6.1.tar.gz
#--------------
Zlib-1.2.7
CC=sh4-linux-gcc
./configure --prefix=/opt/zlib127 --shared –build=i686
–target=sh4-linux –host=sh4-linux
make
make install
#--------------
libpng1512
cp zlib.h zconf.h到資料夾
CC=sh4-linux-gcc
./configure --prefix=/opt/libpng1512 LDFLAGS="-L/opt/zlib127/lib " LIBS="-lz"
--build=i686 –target=sh4-linux –host=sh4-linux
make
make install
#--------------
libjpeg6b
CC=sh4-linux-gcc
./configure --prefix=/opt/libjpeg6b –enable-static --enable-shared
--build=i686 –target=sh4-linux –host=sh4-linux
make
mkdir /opt/libjpeg6b/include
mkdir /opt/libjpeg6b/lib
mkdir /opt/libjpeg6b/bin
mkdir /opt/libjpeg6b/man
mkdir /opt/libjpeg6b/man1
make install
#-----------------------------
freetype
./configure --prefix=/opt/freetype
make
make install
把/opt/freetype/include/freetype2/freetype拷貝到 /opt/freetype/include/freetype
#-----------------------------
DirectFB16
./configure --prefix=/opt/db16 CFLAGS="-I/opt/zlib127/include -I/opt/libjpeg6b/include" LDFLAGS="-L/opt/zlib127/lib -L/opt/libpng1512/lib -L/opt/freetype/lib -L/opt/libjpeg6b/lib" LIBPNG_LIBS="-lpng -lm" LIBPNG_CFLAGS="-I/opt/libpng1512/include" FREETYPE_LIBS="-lfreetype" FREETYPE_CFLAGS="-I/opt/freetype/include" LIBJPEG="-ljpeg"
--build=i686 –target=sh4-linux –host=sh4-linux
#-------------------------------
DirectFB-examples-1.6.0.tar.gz
CC=sh4-linux-gcc
./configure --prefix=$HOME LDFLAGS="-L/opt/db16/lib" DIRECTFB_CFLAGS="-I/opt/db16/include/directfb" DIRECTFB_LIBS="-ldirectfb"
--build=i686 –target=sh4-linux –host=sh4-linux
fb vga mode
- {0x301, RES_MODE_640x480, 8},
- {0x310, RES_MODE_640x480, 15},
- {0x311, RES_MODE_640x480, 16},
- {0x312, RES_MODE_640x480, 24},
- {0x303, RES_MODE_800x600, 8},
- {0x313, RES_MODE_800x600, 15},
- {0x314, RES_MODE_800x600, 16},
- {0x315, RES_MODE_800x600, 24},
- {0x305, RES_MODE_1024x768, 8},
- {0x316, RES_MODE_1024x768, 15},
- {0x317, RES_MODE_1024x768, 16},
- {0x318, RES_MODE_1024x768, 24},
- {0x161, RES_MODE_1152x864, 8},
- {0x162, RES_MODE_1152x864, 15},
- {0x163, RES_MODE_1152x864, 16},
- {0x307, RES_MODE_1280x1024, 8},
- {0x319, RES_MODE_1280x1024, 15},
- {0x31A, RES_MODE_1280x1024, 16},
- {0x31B, RES_MODE_1280x1024, 24},
2012年9月3日 星期一
用gcc 自製 Library (引用)
引用: PTT看板: LinuxDev (作者: cole945)
Library可分成三種,static、shared與dynamically loaded。
1. Static libraries
Static 程式庫用於靜態連結,簡單講是把一堆object檔用ar(archiver)
包裝集合起來,檔名以 `.a' 結尾。優點是執行效能通常會比後兩者快,
而且因為是靜態連結,所以不易發生執行時找不到library或版本錯置而
無法執行的問題。缺點則是檔案較大,維護度較低;例如library如果發
現bug需要更新,那麼就必須重新連結執行檔。
1.1 編譯
編譯方式很簡單,先例用 `-c' 編出 object 檔,再用 ar 包起來即可。
____ hello.c ____
#include <stdio.h>
void hello(){ printf("Hello "); }
____ world.c ____
#include <stdio.h>
void world(){ printf("world."); }
____ mylib.h ____
void hello();
void world();
$ gcc -c hello.c world.c /* 編出 hello.o 與 world.o */
$ ar rcs libmylib.a hello.o world.o /* 包成 limylib.a */
這樣就可以建出一個檔名為 libmylib.a 的檔。輸出的檔名其實沒有硬性規定,
但如果想要配合 gcc 的 '-l' 參數來連結,一定要以 `lib' 開頭,中間是你要
的library名稱,然後緊接著 `.a' 結尾。
1.2 使用
____ main.c ____
#include "mylib.h"
int main() {
hello();
world();
}
使用上就像與一般的 object 檔連結沒有差別。
$ gcc main.c libmylib.a
也可以配合 gcc 的 `-l' 參數使用
$ gcc main.c -L. -lmylib
`-Ldir' 參數用來指定要搜尋程式庫的目錄,`.' 表示搜尋現在所在的目錄。
通常預設會搜 /usr/lib 或 /lib 等目錄。
`-llibrary' 參數用來指定要連結的程式庫 ,'mylib' 表示要與mylib進行連結
,他會搜尋library名稱前加`lib'後接`.a'的檔案來連結。
$ ./a.out
Hello world.
2. Shared libraries
Shared library 會在程式執行起始時才被自動載入。因為程式庫與執行檔
是分離的,所以維護彈性較好。有兩點要注意,shared library是在程式起始
時就要被載入,而不是執行中用到才載入,而且在連結階段需要有該程式庫
才能進行連結。
首先有一些名詞要弄懂,soname、real name與linker name。
soname 用來表示是一個特定 library 的名稱,像是 libmylib.so.1 。
前面以 `lib' 開頭,接著是該 library 的名稱,然後是 `.so' ,接著
是版號,用來表名他的介面;如果介面改變時,就會增加版號來維護相容度。
real name 是實際放有library程式的檔案名稱,後面會再加上 minor 版號與
release 版號,像是 libmylib.so.1.0.0 。
一般來說,版號的改變規則是(印象中在 APress-Difinitive Guide to GCC中有
提到,但目前手邊沒這本書),最尾碼的release版號用於程式內容的修正,
介面完全沒有改變。中間的minor用於有新增加介面,但相舊介面沒改變,所以
與舊版本相容。最前面的version版號用於原介面有移除或改變,與舊版不相容
時。
linker name是用於連結時的名稱,是不含版號的 soname ,如: libmylib.so。
通常 linker name與 real name是用 ln 指到對應的 real name ,用來提供
彈性與維護性。
2.1 編譯
shared library的製作過程較複雜。
$ gcc -c -fPIC hello.c world.c
編譯時要加上 -fPIC 用來產生 position-independent code。也可以用 -fpic
參數。 (不太清楚差異,只知道 -fPIC 較通用於不同平台,但產生的code較大
,而且編譯速度較慢)。
$ gcc -shared -Wl,-soname,libmylib.so.1 -o libmylib.so.1.0.0 \
hello.o world.o
-shared 表示要編譯成 shared library
-Wl 用於參遞參數給linker,因此-soname與libmylib.so.1會被傳給linker處理。
-soname用來指名 soname 為 limylib.so.1
library會被輸出成libmylib.so.1.0.0 (也就是real name)
若不指定 soname 的話,在編譯結連後的執行檔會以連時的library檔名為
soname,並載入他。否則是載入soname指定的library檔案。
可以利用 objdump 來看 library 的 soname。
$ objdump -p libmylib.so | grep SONAME
SONAME libmylib.so.1
若不指名-soname參數的話,則library不會有這個欄位資料。
在編譯後再用 ln 來建立 soname 與 linker name 兩個檔案。
$ ln -s libmylib.so.1.0.0 libmylib.so
$ ln -s libmylib.so.1.0.0 libmylib.so.1
2.2 使用
與使用 static library 同。
$ gcc main.c libmylib.so
以上直接指定與 libmylib.so 連結。
或用
$ gcc main.c -L. -lmylib
linker會搜尋 libmylib.so 來進行連結。
如果目錄下同時有static與shared library的話,會以shared為主。
使用 -static 參數可以避免使用shared連結。
$ gcc main.c -static -L. -lmylib
此時可以用 ldd 看編譯出的執行檔與shared程式庫的相依性
$ldd a.out
linux-gate.so.1 => (0xffffe000)
libmylib.so.1 => not found
libc.so.6 => /lib/libc.so.6 (0xb7dd6000)
/lib/ld-linux.so.2 (0xb7f07000)
輸出結果顯示出該執行檔需要 libmylib.so.1 這個shared library。
會顯示 not found 因為沒指定該library所在的目錄,所找不到該library。
因為編譯時有指定-soname參數為 libmylib.so.1 的關係,所以該執行檔會
載入libmylib.so.1。否則以libmylib.so連結,執行檔則會變成要求載入
libmylib.so
$ ./a.out
./a.out: error while loading shared libraries: libmylib.so.1:
cannot open shared object file: No such file or directory
因為找不到 libmylib.so.1 所以無法執行程式。
有幾個方式可以處理。
a. 把 libmylib.so.1 安裝到系統的library目錄,如/usr/lib下
b. 設定 /etc/ld.so.conf ,加入一個新的library搜尋目錄,並執行ldconfig
更新快取
c. 設定 LD_LIBRARY_PATH 環境變數來搜尋library
這個例子是加入目前的目錄來搜尋要載作的library
$ LD_LIBRARY_PATH=. ./a.out
Hello world.
3. Dynamically loaded libraries
Dynamicaaly loaded libraries 才是像 windows 所用的 DLL ,在使用到
時才載入,編譯連結時不需要相關的library。動態載入庫常被用於像plug-ins
的應用。
3.1 使用方式
動態載入是透過一套 dl function來處理。
#include <dlfcn.h>
void *dlopen(const char *filename, int flag);
開啟載入 filename 指定的 library。
void *dlsym(void *handle, const char *symbol);
取得 symbol 指定的symbol name在library被載入的記憶體位址。
int dlclose(void *handle);
關閉dlopen開啟的handle。
char *dlerror(void);
傳回最近所發生的錯誤訊息。
____ dltest.c ____
#include <stdio.h>
#include <stdlib.h>
#include <dlfcn.h>
int main() {
void *handle;
void (*f)();
char *error;
/* 開啟之前所撰寫的 libmylib.so 程式庫 */
handle = dlopen("./libmylib.so", RTLD_LAZY);
if( !handle ) {
fputs( dlerror(), stderr);
exit(1);
}
/* 取得 hello function 的 address */
f = dlsym(handle, "hello");
if(( error=dlerror())!=NULL) {
fputs(error, stderr);
exit(1);
}
/* 呼叫該 function */
f();
dlclose(handle);
}
編譯時要加上 -ldl 參數來與 dl library 連結
$ gcc dltest.c -ldl
結果會印出 Hello 字串
$ ./a.out
Hello
關於dl的詳細內容請參閱 man dlopen
Library可分成三種,static、shared與dynamically loaded。
1. Static libraries
Static 程式庫用於靜態連結,簡單講是把一堆object檔用ar(archiver)
包裝集合起來,檔名以 `.a' 結尾。優點是執行效能通常會比後兩者快,
而且因為是靜態連結,所以不易發生執行時找不到library或版本錯置而
無法執行的問題。缺點則是檔案較大,維護度較低;例如library如果發
現bug需要更新,那麼就必須重新連結執行檔。
1.1 編譯
編譯方式很簡單,先例用 `-c' 編出 object 檔,再用 ar 包起來即可。
____ hello.c ____
#include <stdio.h>
void hello(){ printf("Hello "); }
____ world.c ____
#include <stdio.h>
void world(){ printf("world."); }
____ mylib.h ____
void hello();
void world();
$ gcc -c hello.c world.c /* 編出 hello.o 與 world.o */
$ ar rcs libmylib.a hello.o world.o /* 包成 limylib.a */
這樣就可以建出一個檔名為 libmylib.a 的檔。輸出的檔名其實沒有硬性規定,
但如果想要配合 gcc 的 '-l' 參數來連結,一定要以 `lib' 開頭,中間是你要
的library名稱,然後緊接著 `.a' 結尾。
1.2 使用
____ main.c ____
#include "mylib.h"
int main() {
hello();
world();
}
使用上就像與一般的 object 檔連結沒有差別。
$ gcc main.c libmylib.a
也可以配合 gcc 的 `-l' 參數使用
$ gcc main.c -L. -lmylib
`-Ldir' 參數用來指定要搜尋程式庫的目錄,`.' 表示搜尋現在所在的目錄。
通常預設會搜 /usr/lib 或 /lib 等目錄。
`-llibrary' 參數用來指定要連結的程式庫 ,'mylib' 表示要與mylib進行連結
,他會搜尋library名稱前加`lib'後接`.a'的檔案來連結。
$ ./a.out
Hello world.
2. Shared libraries
Shared library 會在程式執行起始時才被自動載入。因為程式庫與執行檔
是分離的,所以維護彈性較好。有兩點要注意,shared library是在程式起始
時就要被載入,而不是執行中用到才載入,而且在連結階段需要有該程式庫
才能進行連結。
首先有一些名詞要弄懂,soname、real name與linker name。
soname 用來表示是一個特定 library 的名稱,像是 libmylib.so.1 。
前面以 `lib' 開頭,接著是該 library 的名稱,然後是 `.so' ,接著
是版號,用來表名他的介面;如果介面改變時,就會增加版號來維護相容度。
real name 是實際放有library程式的檔案名稱,後面會再加上 minor 版號與
release 版號,像是 libmylib.so.1.0.0 。
一般來說,版號的改變規則是(印象中在 APress-Difinitive Guide to GCC中有
提到,但目前手邊沒這本書),最尾碼的release版號用於程式內容的修正,
介面完全沒有改變。中間的minor用於有新增加介面,但相舊介面沒改變,所以
與舊版本相容。最前面的version版號用於原介面有移除或改變,與舊版不相容
時。
linker name是用於連結時的名稱,是不含版號的 soname ,如: libmylib.so。
通常 linker name與 real name是用 ln 指到對應的 real name ,用來提供
彈性與維護性。
2.1 編譯
shared library的製作過程較複雜。
$ gcc -c -fPIC hello.c world.c
編譯時要加上 -fPIC 用來產生 position-independent code。也可以用 -fpic
參數。 (不太清楚差異,只知道 -fPIC 較通用於不同平台,但產生的code較大
,而且編譯速度較慢)。
$ gcc -shared -Wl,-soname,libmylib.so.1 -o libmylib.so.1.0.0 \
hello.o world.o
-shared 表示要編譯成 shared library
-Wl 用於參遞參數給linker,因此-soname與libmylib.so.1會被傳給linker處理。
-soname用來指名 soname 為 limylib.so.1
library會被輸出成libmylib.so.1.0.0 (也就是real name)
若不指定 soname 的話,在編譯結連後的執行檔會以連時的library檔名為
soname,並載入他。否則是載入soname指定的library檔案。
可以利用 objdump 來看 library 的 soname。
$ objdump -p libmylib.so | grep SONAME
SONAME libmylib.so.1
若不指名-soname參數的話,則library不會有這個欄位資料。
在編譯後再用 ln 來建立 soname 與 linker name 兩個檔案。
$ ln -s libmylib.so.1.0.0 libmylib.so
$ ln -s libmylib.so.1.0.0 libmylib.so.1
2.2 使用
與使用 static library 同。
$ gcc main.c libmylib.so
以上直接指定與 libmylib.so 連結。
或用
$ gcc main.c -L. -lmylib
linker會搜尋 libmylib.so 來進行連結。
如果目錄下同時有static與shared library的話,會以shared為主。
使用 -static 參數可以避免使用shared連結。
$ gcc main.c -static -L. -lmylib
此時可以用 ldd 看編譯出的執行檔與shared程式庫的相依性
$ldd a.out
linux-gate.so.1 => (0xffffe000)
libmylib.so.1 => not found
libc.so.6 => /lib/libc.so.6 (0xb7dd6000)
/lib/ld-linux.so.2 (0xb7f07000)
輸出結果顯示出該執行檔需要 libmylib.so.1 這個shared library。
會顯示 not found 因為沒指定該library所在的目錄,所找不到該library。
因為編譯時有指定-soname參數為 libmylib.so.1 的關係,所以該執行檔會
載入libmylib.so.1。否則以libmylib.so連結,執行檔則會變成要求載入
libmylib.so
$ ./a.out
./a.out: error while loading shared libraries: libmylib.so.1:
cannot open shared object file: No such file or directory
因為找不到 libmylib.so.1 所以無法執行程式。
有幾個方式可以處理。
a. 把 libmylib.so.1 安裝到系統的library目錄,如/usr/lib下
b. 設定 /etc/ld.so.conf ,加入一個新的library搜尋目錄,並執行ldconfig
更新快取
c. 設定 LD_LIBRARY_PATH 環境變數來搜尋library
這個例子是加入目前的目錄來搜尋要載作的library
$ LD_LIBRARY_PATH=. ./a.out
Hello world.
3. Dynamically loaded libraries
Dynamicaaly loaded libraries 才是像 windows 所用的 DLL ,在使用到
時才載入,編譯連結時不需要相關的library。動態載入庫常被用於像plug-ins
的應用。
3.1 使用方式
動態載入是透過一套 dl function來處理。
#include <dlfcn.h>
void *dlopen(const char *filename, int flag);
開啟載入 filename 指定的 library。
void *dlsym(void *handle, const char *symbol);
取得 symbol 指定的symbol name在library被載入的記憶體位址。
int dlclose(void *handle);
關閉dlopen開啟的handle。
char *dlerror(void);
傳回最近所發生的錯誤訊息。
____ dltest.c ____
#include <stdio.h>
#include <stdlib.h>
#include <dlfcn.h>
int main() {
void *handle;
void (*f)();
char *error;
/* 開啟之前所撰寫的 libmylib.so 程式庫 */
handle = dlopen("./libmylib.so", RTLD_LAZY);
if( !handle ) {
fputs( dlerror(), stderr);
exit(1);
}
/* 取得 hello function 的 address */
f = dlsym(handle, "hello");
if(( error=dlerror())!=NULL) {
fputs(error, stderr);
exit(1);
}
/* 呼叫該 function */
f();
dlclose(handle);
}
編譯時要加上 -ldl 參數來與 dl library 連結
$ gcc dltest.c -ldl
結果會印出 Hello 字串
$ ./a.out
Hello
關於dl的詳細內容請參閱 man dlopen