HOWTO ãéá ÂéâëéïèÞêåò ÐñïãñáììÜôùí - Program Library HOWTO David A. Wheeler Ýêäïóç 1.20, 11 Áðñéëßïõ 2003 Áõôü ôï HOWTO ãéá ðñïãñáììáôéóôÝò, ðñáãìáôåýåôáé èÝìáôá ãýñù áðü ôç äçìéïõñãßá êáé ÷ñÞóç âéâëéïèçêþí ðñïãñáììÜôùí óôï Linux. Óôéò ôåëåõôáßåò óõìðåñéëáìâÜíïíôáé ïé óôáôéêÝò (static), ïé äéáìïéñáæüìåíåò (shared) êáé ïé äõíáìéêÝò ( dynamically loaded ) âéâëéïèÞêåò. _________________________________________________________ Ðßíáêáò Ðåñéå÷ïìÝíùí 1. ÅéóáãùãÞ 2. ÓôáôéêÝò (static) âéâëéïèÞêåò 3. Äéáìïéñáæüìåíåò (shared) âéâëéïèÞêåò 3.1. ÓõìâÜóåéò 3.1.1. Ïíüìáôá äéáìïéñáæüìåíùí âéâëéïèçêþí 3.1.2. ÔïðïèÝôçóç óôï Óýóôçìá Áñ÷åßùí 3.2. Ðùò ÷ñçóéìïðïéïýíôáé ïé âéâëéïèÞêåò 3.3. ÌåôáâëçôÝò ðåñéâÜëëïíôïò 3.3.1. LD_LIBRARY_PATH 3.3.2. LD_DEBUG 3.3.3. ¢ëëåò ìåôáâëçôÝò ðåñéâÜëëïíôïò 3.4. Äçìéïõñãþíôáò ìéáò äéáìïéñáæüìåíç âéâëéïèÞêç 3.5. ÅãêáôÜóôáóç êáé ÷ñÞóç äéáìïéñáæüìåíçò âéâëéïèÞêçò 3.6. Áóõìâßâáóôåò ìåôáîý ôïõò âéâëéïèÞêåò 4. ÄõíáìéêÝò (Dynamically Loaded - DL) âéâëéïèÞêåò 4.1. dlopen() 4.2. dlerror() 4.3. dlsym() 4.4. dlclose() 4.5. ÐáñÜäåéãìá äõíáìéêÞò âéâëéïèÞêçò 5. ÄéÜöïñá 5.1. Ç åíôïëÞ nm 5.2. ÓõíáñôÞóåéò êáôáóêåõáóôþí (constructor) êáé êáôáóôñïöÝùí (destructor) âéâëéïèÞêçò 5.2.1. ÅéäéêÝò óõíáñôÞóåéò _init êáé _fini (ÐÁÑÙ×ÇÌÅÍÏ/ÅÐÉÊÉÍÄÕÍÏ) 5.3. Ïé äéáìïéñáæüìåíåò âéâëéïèÞêåò ìðïñåß íá åßíáé áñ÷åßá åíôïëþí (scripts ) 5.4. Åêäüóåéò óõìâüëùí (Symbol versioning) êáé Áñ÷åßùí åíôïëþí Ýêäïóçò (Version scripts) 5.5. GNU libtool 5.6. Áöáßñåóç óõìâüëùí ãéá åîïéêïíüìçóç ÷þñïõ 5.7. ÅîáéñåôéêÜ ìéêñÜ åêôåëÝóéìá 5.8. C++ åíáíôßïí C 5.9. ÊÜíïíôáò ôá÷ýôåñç ôçí áñ÷éêïðïßçóç óôç C++ 5.10. Linux Standard Base (LSB - ÂÜóç Ðñüôõðùí ôïõ Linux) 5.11. Óõã÷ùíåýïíôáò âéâëéïèÞêåò óå ìåãáëýôåñåò äéáìïéñáæüìåíåò (shared) âéâëéïèÞêåò 6. Ðåñéóóüôåñá ðáñáäåßãìáôá 6.1. Áñ÷åßï libhello.c 6.2. Áñ÷åßï libhello.h 6.3. Áñ÷åßï demo_use.c 6.4. Áñ÷åßï script_static 6.5. Áñ÷åßï script_shared 6.6. Áñ÷åßï demo_dynamic.c 6.7. Áñ÷åßï script_dynamic 7. Áëëåò ðçãÝò ðëçñïöïñéþí 8. ¢äåéá êáé ÐíåõìáôéêÜ Äéêáéþìáôá 1. ÅéóáãùãÞ Áõôü ôï HOWTO ãéá ðñïãñáììáôéóôÝò ðñáãìáôåýåôáé èÝìáôá ó÷åôéêÜ ìå ôï ðþò ìðïñåß êáíåßò íá äçìéïõñãÞóåé êáé íá ÷ñçóéìïðïéÞóåé âéâëéïèÞêåò ðñïãñáììÜôùí óôï Linux, ÷ñçóéìïðïéþíôáò ôï óýíïëï åñãáëåßùí GNU. Ìéá "âéâëéïèÞêç ðñïãñÜììáôïò'' åßíáé áðëÜ Ýíá áñ÷åßï ðïõ ðåñéÝ÷åé ôï ìåôáãëùôôéóìÝíï (compiled) êþäéêá (êáé ôá äåäïìÝíá), ðïõ ðñüêåéôáé íá åíóùìáôùèïýí áñãüôåñá óå Ýíá ðñüãñáììá. Ïé âéâëéïèÞêåò ðñïãñáììÜôùí åðéôñÝðïõí óôá ðñïãñÜììáôá íá åßíáé ðéï ðáñáìåôñïðïéÞóéìá, ãñçãïñüôåñá óôç äéáäéêáóßá åðáíáìåôáãëþôéóóçò (recompilation), êáé åõêïëüôåñá óôç óõíôÞñçóç êáé ôçí åíçìÝñùóç (update). Ïé âéâëéïèÞêåò ðñïãñÜììáôïò ìðïñïýí íá äéáéñåèïýí óå ôñåéò ôýðïõò: óôáôéêÝò âéâëéïèÞêåò (static), äéáìïéñáæüìåíåò âéâëéïèÞêåò (shared), êáé äõíáìéêÜ öïñôùìÝíåò âéâëéïèÞêåò (dynamically loaded - DL). Áõôü ôï Üñèñï áíáöÝñåôáé áñ÷éêÜ óôéò óôáôéêÝò âéâëéïèÞêåò, ïé ïðïßåò åãêáèßóôáíôáé óå Ýíá åêôåëÝóéìï (executable) ðñïôïý åêôåëåóôåß ôï áíôßóôïé÷ï ðñüãñáììá. ÓõæçôÜ Ýðåéôá ôéò äéáìïéñáæüìåíåò âéâëéïèÞêåò, ïé ïðïßåò öïñôþíïíôáé óôï îåêßíçìá ôïõ ðñïãñÜììáôïò êáé ìïéñÜæïíôáé ìåôáîý ôùí ðñïãñáììÜôùí. ÔÝëïò, óõæçôÜ ôéò äõíáìéêÝò âéâëéïèÞêåò, ïé ïðïßåò ìðïñïýí íá öïñôùèïýí êáé íá ÷ñçóéìïðïéçèïýí ïðïéáäÞðïôå óôéãìÞ åíþ Ýíá ðñüãñáììá ôñÝ÷åé. Ïé äõíáìéêÝò âéâëéïèÞêåò äåí åßíáé ðñáãìáôéêÜ Ýíá äéáöïñåôéêü åßäïò ìïñöïðïßçóçò (format) âéâëéïèçêþí (ôüóï ïé óôáôéêÝò üóï êáé äéáìïéñáæüìåíåò âéâëéïèÞêåò ìðïñïýí íá ÷ñçóéìïðïéçèïýí ùò äõíáìéêÝò) áíô' áõôïý, ç äéáöïñÜ Ýãêåéôáé óôïí ôñüðï ìå ôïí ïðïßï ïé äõíáìéêÝò âéâëéïèÞêåò ÷ñçóéìïðïéïýíôáé áðü ôïõò ðñïãñáììáôéóôÝò. Áõôü ôï HOWTO êëåßíåé ìå Ýíá êåöÜëáéï ìå ðåñéóóüôåñá ðáñáäåßãìáôá êáé Ýíá áêüìá ìå áíáöïñÝò óå Üëëåò ðçãÝò ðëçñïöïñéþí. Ïé ðåñéóóüôåñïé õðåýèõíïé óå áíÜðôõîç ðñïãñáììÜôùí (developers) ðïõ áíáðôýóóïõí âéâëéïèÞêåò, ïöåßëïõí íá äçìéïõñãÞóïõí äéáìïéñáæüìåíåò âéâëéïèÞêåò, äåäïìÝíïõ üôé áõôÝò åðéôñÝðïõí óôïõò ÷ñÞóôåò íá åíçìåñþóïõí (update) ôéò âéâëéïèÞêåò ôïõò ÷ùñéóôÜ áðü ôéò åöáñìïãÝò ðïõ ôéò ÷ñçóéìïðïéïýí. Ïé äõíáìéêÝò âéâëéïèÞêåò åßíáé ÷ñÞóéìåò, áëëÜ áðáéôïýí ëßãï ðåñéóóüôåñç äïõëåéÜ ãéá íá êáôáóôåß äõíáôüí íá ÷ñçóéìïðïéçèïýí êáé ðïëëÜ ðñïãñÜììáôá äåí ÷ñåéÜæïíôáé ôçí åõåëéîßá ðïõ ðñïóöÝñïõí. Áð' ôçí Üëëç ðÜëé, ïé óôáôéêÝò, êÜíïõí ôçí áíáâÜèìéóç (upgrading) ôùí âéâëéïèçêþí ðïëý ðéï ðñïâëçìáôéêÞ, ïðüôå äýóêïëá èá ôéò óõíéóôïýóå êáíåßò ãéá ãåíéêÞ ÷ñÞóç. Ùóôüóï, êÜèå ìßá Ý÷åé ôá ðëåïíåêôÞìáôÜ ôçò, êáé ôá ðëåïíåêôÞìáôá ôïõ êÜèå ôýðïõ ðåñéãñÜöïíôáé óôçí áíôßóôïé÷ç ðáñÜãñáöï ôïõ Üñèñïõ. Ïé ðñïãñáììáôéóôÝò ðïõ ÷ñçóéìïðïéïýí C++ êáé äõíáìéêÝò âéâëéïèÞêåò, èá ðñÝðåé åðßóçò íá óõìâïõëåõèïýí ôï "C++ mini- howto". Äåí Ý÷åé óçìáóßá ðïõ ìåñéêïß Üíèñùðïé ÷ñçóéìïðïéïýí ôïí üñï äõíáìéêÜ óõíäåäåìÝíåò âéâëéïèÞêåò (dynamically linked libraries - DLLs) ãéá íá áíáöåñèïýí óôéò äéáìïéñáæüìåíåò (shared) âéâëéïèÞêåò,ìåñéêïß Üëëïé ôïí üñï DLL ãéá íá óçìÜíïõí ïðïéáäÞðïôå âéâëéïèÞêç ðïõ ÷ñçóéìïðïéåßôáé ùò äõíáìéêÞ âéâëéïèÞêç (DL), êáé ìåñéêïß áêüìá ðïõ ÷ñçóéìïðïéïýí ôïí üñï DLL ãéá íá áíáöåñèïýí óå ïðïéáäÞðïôå áðü ôéò ðáñáðÜíù ðåñéðôþóåéò. ÏðïéïäÞðïôå óçìáóéïëïãéêü ïñéóìü êáé íá åðéëÝîåôå, áõôü ôï HOWTO êáëýðôåé ôéò DLLs óå Linux. Óå áõôü ôï HOWTO áó÷ïëïýìáóôå ìüíï ôç óýã÷ñïíç êáé êáèéåñùìÝíç ìïñöïðïßçóç åêôåëÝóéìùí êáé âéâëéïèçêþí ó÷åäüí óå êÜèå óýóôçìá/äéáíïìÞ GNU/Linux : ôç ìïñöïðïßçóç ELF (Executable and Linking Format). Ôï óýíïëï åñãáëåßùí GCC ôïõ GNU (GNU GCC toolset) ìðïñåß óôçí ðñáãìáôéêüôçôá íá ÷åéñéóôåß âéâëéïèÞêåò ìå ìïñöïðïßçóç êáé äéáöïñåôéêÞ ôçò ELF - åéäéêüôåñá, ïé ðåñéóóüôåñåò äéáíïìÝò Linux ìðïñïýí áêüìá íá õðïóôçñßîïõí ôçí îåðåñáóìÝíç ìïñöÞ a.out ( ç õðïóôÞñéîç óõíå÷ßæåôáé êáé óôïí 2.6 ðõñÞíá ). Åíôïýôïéò, ôÝôïéåò ìïñöïðïéÞóåéò äå èá êáëõöèïýí åäþ. ÅÜí ÷ôßæåôå ìéá åöáñìïãÞ ðïõ èá èÝëáôå íá ìðïñåß íá ìåôáöåñèåß óå ðïëëÜ óõóôÞìáôá, ßóùò èá Ýðñåðå íá óêåöôåßôå íá ÷ñçóéìïðïéÞóåôå ôï GNU libtool ãéá íá ÷ôßóåôå êáé íá åãêáôáóôÞóåôå âéâëéïèÞêåò, áíôß íá ÷ñçóéìïðïéÞóåé ôá åñãáëåßá ôïõ Linux áõôÜ êáè\ åõáôÜ. Ôï GNU Libtool åßíáé Ýíá ãåíéêü script (áñ÷åßï åíôïëþí) õðïóôÞñéîçò âéâëéïèçêþí, ðïõ êñýâåé ôçí ðïëõðëïêüôçôá ÷ñÞóçò ôùí äéáìïéñáæüìåíùí âéâëéïèçêþí (ð.÷., äçìéïõñãþíôáò êáé åãêáèéóôþíôáò ôåò) ðßóù áðü ìéá êáé óõìðáãÞò êáé öïñçôÞ, ìåôáîý óõóôçìÜôùí, äéåðáöÞ. Óôï Linux, ôï GNU Libtool ÷ôßæåôáé ðÜíù áðü ôá åñãáëåßá êáé ôéò óõìâÜóåéò ðïõ ðåñéãñÜöïíôáé óå áõôü ôï HOWTO. Ãéá ìéá öïñçôÞ äéåðáöÞ (portable interface) óôéò äõíáìéêÝò âéâëéïèÞêåò, ìðïñåßôå íá ÷ñçóéìïðïéÞóåôå ôá äéÜöïñá portability wrappers (ðåñéôõëßãìáôá öïñçôüôçôáò). Ôï GNU Libtool ðåñéëáìâÜíåé Ýíá ôÝôïéï, áðïêáëïýìåíï "libltdl". ÅíáëëáêôéêÜ, èá ìðïñïýóáôå íá ÷ñçóéìïðïéÞóåôå ôçí glib âéâëéïèÞêç (ìçí ôç ìðåñäåýåôå ìå ôçí glibc) ìå ôç öïñçôÞ õðïóôÞñéîÞ ôçò ãéá dynamic module loading (äõíáìéêÞ öüñôùóç ôìçìÜôùí). Ìðïñåßôå íá ìÜèåôå ðåñéóóüôåñá ó÷åôéêÜ ìå ôç glib óôï http://developer.gnome.org/doc/API/glib/glib-dynamic-loading-o f-modules.html. Êáé ðÜëé ðÜíôùò, óôï Linux áõôÞ ç ëåéôïõñãéêüôçôá õëïðïéåßôáé ÷ñçóéìïðïéþíôáò ôá âáóéêÜ åñãáëåßá ðïõ ðåñéãñÜöïíôáé óå áõôü ôï HOWTO. ÅÜí ðñÜãìáôé áíáðôýóóåôå Þ äéïñèþíåôå êþäéêá óå Linux, ðéèáíþò ïé ðëçñïöïñßåò ðïõ õðÜñ÷ïõí óå áõôü ôï HOWTO èá åîáêïëïõèïýí íá óáò åßíáé ÷ñÞóéìåò. Ç ÁããëéêÞ (êáé "áõèåíôéêÞ" Ýêäïóç) áõôïý ôïõ HOWTO âñßóêåôáé óôï http://www.dwheeler.com/program-library, and it has been êáé Ý÷åé óõìðåñéëçöèåß óôï Ðñüãñáììá Ôåêìçñßùóçò ôïõ Linux (http://www.tldp.org). Ôá ðíåõìáôéêÜ äéêáéþìáôá (C) 2000 áíÞêïõí óôïí David A. Wheeler êáé äéáíÝìåôáé ìÝóù ôçò Üäåéáò GPL (Gerneral Public License) - äåßôå ôçí áíôßóôïé÷ç ðáñÜãñáöï óôï ôÝëïò ôïõ Üñèñïõ ãéá ðåñéóóüôåñåò ðëçñïöïñßåò. _________________________________________________________ 2. ÓôáôéêÝò (static) âéâëéïèÞêåò Ïé óôáôéêÝò âéâëéïèÞêåò åßíáé áðëÜ ìéá óõëëïãÞ áðü ôá óõíçèéóìÝíá object files (áñ÷åßá áíôéêåéìÝíïõ) - óõíÞèùò, ïé óôáôéêÝò âéâëéïèÞêåò ôåëåéþíïõí ìå Ýíá åðßèçìá ".a". ÁõôÞ ç óõëëïãÞ äçìéïõñãåßôáé ÷ñçóéìïðïéþíôáò ôï ðñüãñáììá ar (archiver). Ïé óôáôéêÝò âéâëéïèÞêåò äåí ÷ñçóéìïðïéïýíôáé ðéá ôüóï óõ÷íÜ üóï êÜðïôå, ëüãù ôùí ðëåïíåêôçìÜôùí ôùí äéáìïéñáæüìåíùí âéâëéïèçêþí (ðïõ ðåñéãñÜöïíôáé ðáñáêÜôù). Ùóôüóï, óõíå÷ßæïõí íá åðéëÝãïíôáé ìåñéêÝò öïñÝò, åìöáíßóôçêáí ðñþôåò éóôïñéêÜ, êáé åßíáé áðëïýóôåñåò óôçí åîÞãçóç. Ïé óôáôéêÝò âéâëéïèÞêåò åðéôñÝðïõí óôïõò ÷ñÞóôåò íá ôéò óõíäÝóïõí ìå ôá ðñïãñÜììáôá ôïõò (link to programs), ÷ùñßò íá ðñÝðåé íá ãßíåé áíáãêáóôéêÜ recompilation ôïõ êþäéêá ôïõ ðñïãñÜììáôïò, êåñäßæïíôáò Ýôóé áõôü ôï ÷ñüíï ôçò åðáíáìåôáãëþôôéóçò. ÂÝâáéá ï ÷ñüíïò ãéá ôç äéáäéêáóßá åðáíáìåôáãëþôôéóçò äåí åßíáé ôç óÞìåñïí çìÝñá ôüóï óðïõäáßïò, äåäïìÝíùí ôùí óçìåñéíþí ôá÷ýôáôùí ìåôáãëùôôéóôþí, ïðüôå ôï ðëåïíÝêôçìá áõôü Ý÷åé åîáóèåíßóåé óå ó÷Ýóç ìå ðáëéüôåñá. Ïé óôáôéêÝò âéâëéïèÞêåò åßíáé óõ÷íÜ ÷ñÞóéìåò ãéá ôïõò developers åÜí åðéèõìïýí íá åðéôñÝøïõí óôïõò ðñïãñáììáôéóôÝò íá óõíäÝóïõí ôá ðñïãñÜììáôá ôïõò ìå ôç âéâëéïèÞêç ôùí ðñþôùí, áëëÜ äåí èÝëïõí íá äþóïõí ôïí ðçãáßï êþäéêá ôçò (ðïõ åßíáé Ýíá ðëåïíÝêôçìá ãéá ôïí êáôáóêåõáóôÞ âéâëéïèçêþí âÝâáéá, áëëÜ ðñïöáíþò äåí åßíáé ôÝôïéï ãéá ôïí ðñïãñáììáôéóôÞ ðïõ ðñïóðáèåß íá ÷ñçóéìïðïéÞóåé ôç âéâëéïèÞêç). ÈåùñçôéêÜ, ï êþäéêáò óôéò óôáôéêÝò âéâëéïèÞêåò ELF ðïõ óõíäÝåôáé ìå Ýíáí åêôåëÝóéìï ðñÝðåé íá ôñÝîåé åëáöñþò ãñçãïñüôåñá (áðü 1-5%) áðü üôé áí ï ßäéïò êþäéêáò ðáñå÷üôáí áðï ìéá äéáìïéñáæüìåíç Þ ìéá äõíáìéêÞ âéâëéïèÞêç, áëëÜ óôçí ðñÜîç áõôü öáßíåôáé óðÜíéá íá óõìâáßíåé åîáéôßáò Üëëùí, áëëçëïáíáéñïýìåíùí ðáñáãüíôùí. Ãéá íá äçìéïõñãÞóåôå ìéá óôáôéêÞ âéâëéïèÞêç, Þ íá ðñïóèÝóåôå ôá ðñüóèåôá êé Üëëá object files óå ìéá õðÜñ÷ïõóá, ÷ñçóéìïðïéÞóôå ìéá åíôïëÞ óáí ôçí ðáñáêÜôù: ar rcs my_library.a file1.o file2.o Ç åíôïëÞ óôï ðáñáðÜíù ðáñÜäåéãìá ðñïóèÝôåé ôá object files: file1.o êáé file2.ï óôç óôáôéêÞ âéâëéïèÞêç my_library.a, äçìéïõñãüíôáò ôç âéâëéïèÞêç my_library.a, åÜí äåí õðÜñ÷åé Þäç. Ãéá ðåñéóóüôåñåò ðëçñïöïñßåò ãéá ôç äçìéïõñãßá ôùí óôáôéêþí âéâëéïèçêþí, äåßôå ôï ar(1). Ìüëéò äçìéïõñãÞóåôå ìéá óôáôéêÞ âéâëéïèÞêç, èá èåëÞóåôå, öõóéêÜ, íá ôç ÷ñçóéìïðïéÞóåôå. Ìðïñåßôå íá ÷ñçóéìïðïéÞóåôå ìéá óôáôéêÞ âéâëéïèÞêç êáëþíôáò ôç êáôÜ ôç äéáäéêáóßá ôçò ìåôáãëþôôéóçò êáé óýíäåóçò (compilation and linking process) ãéá ôç äçìéïõñãßá åíüò åêôåëÝóéìïõ ðñïãñÜììáôïò . ÅÜí ÷ñçóéìïðïéåßôå ôï gcc(1) ãéá íá ðáñáãÜãåôå ôï åêôåëÝóéìü óáò, ìðïñåßôå íá ÷ñçóéìïðïéÞóåôå ôçí (ðñïáéñåôéêÞ) ðáñÜìåôñï -l êáé íá ðñïóäéïñßóåôå ôç âéâëéïèÞêç. Ðåñéóóüôåñåò ðëçñïöïñßåò ó÷åôéêÜ ìðïñåßôå íá äåßôå ÷ñçóéìïðïéþíôáò ôï info (info:gcc). Íá åßóôå ðñïóåêôéêïß óôç óåéñÜ ôùí ðáñáìÝôñùí ðïõ ÷ñçóéìïðïéåßôå ìå ôï GCC - ç ðñïáéñåôéêÞ ðáñÜìåôñïò -l åßíáé ìéá ðñïáéñåôéêÞ äõíáôüôçôá ãéá ôïí linker (ôï ôìÞìá ðïõ åßíáé õðåýèõíï ãéá ôç óýíäåóç ð.÷. ôçò âéâëéïèÞêçò ìå ôï êõñßùò ðñüãñáììá), êáé ðñÝðåé ãé' áõôü íá ôïðïèåôçèåß ÌÅÔÁ ôï üíïìá ôïõ áñ÷åßïõ ðïõ ìåôáãëùôôßæåôáé. Áõôü åßíáé áñêåôÜ äéáöïñåôéêü áðü ôç óõíÞèç óýíôáîç ôùí ðñïáéñåôéêþí ðáñáìÝôñùí. ÅÜí ôïðïèåôÞóåôå ôçí ðñïáéñåôéêÞ ðáñÜìåôñï -l ðñéí áðü ôï üíïìá áñ÷åßïõ, ìðïñåß íá áðïôý÷åé ðëÞñùò ôï linkning, êáé íá êáôáëÞîåôå ìå Ýíá óùñü áðü ìõóôÞñéá óöÜëìáôá. Ìðïñåßôå åðßóçò íá ÷ñçóéìïðïéÞóåôå ôïí linker ld(1) Üìåóá, ÷ñçóéìïðïéþíôáò ôéò ðáñáìÝôñïõò ôïõ -l êáé -L, åíôïýôïéò, óôéò ðåñéóóüôåñåò ðåñéðôþóåéò åßíáé êáëýôåñï íá ÷ñçóéìïðïéçèåß ï GCC (1) äåäïìÝíïõ üôé ç äéåðáöÞ ôïõ LD (1) åßíáé ðéèáíüôåñï íá áëëÜîåé. _________________________________________________________ 3. Äéáìïéñáæüìåíåò (shared) âéâëéïèÞêåò Ïé äéáìïéñáæüìåíåò âéâëéïèÞêåò åßíáé âéâëéïèÞêåò ðïõ öïñôþíïíôáé áðü ôá ðñïãñÜììáôá üôáí áñ÷ßæïõí. ¼ôáí ìéá äéáìïéñáæüìåíç âéâëéïèÞêç åãêáôáóôáèåß êáôÜëëçëá, üëá ôá ðñïãñÜììáôá ðïõ áñ÷ßæïõí êáôüðéí, êÜíïõí áõôüìáôá ÷ñÞóç ôçò íÝáò äéáìïéñáæüìåíçò âéâëéïèÞêçò. Óôçí ðñáãìáôéêÜ ç ðáñáðÜíù ðåñéãñáöÞ åßíáé ó÷åôéêÜ áðëÞ êáé óôáôéêÞ, áöïý ç ðñïóÝããéóç ðïõ ÷ñçóéìïðïéåßôáé áðü ôï Linux óáò åðéôñÝðåé: * íá åíçìåñþóåôå (update) âéâëéïèÞêåò, äéáôçñþíôáò ôçí õðïóôÞñéîç ãéá ôá ðñïãñÜììáôá ðïõ ðñÝðåé íá ÷ñçóéìïðïéïýí ðáëéüôåñåò åêäüóåéò, áêüìá êáé åÜí ïé íÝåò âéâëéïèÞêåò äåí åßíáé ðñïò-ôá-ðßóù óõìâáôÝò * íá ðáñáêÜìøåôå óõãêåêñéìÝíåò âéâëéïèÞêåò Þ áêüìá êáé óõãêåêñéìÝíåò ëåéôïõñãßåò ìéáò âéâëéïèÞêçò, êáôÜ ôïí åêôÝëåóç åíüò óõãêåêñéìÝíïõ ðñïãñÜììáôïò. * íá êÜíåôå üëá ôá ðáñáðÜíù åíþ ôá ðñïãñÜììáôá ôñÝ÷ïõí ÷ñçóéìïðïéþíôáò ôéò õðÜñ÷ïõóåò âéâëéïèÞêåò _________________________________________________________ 3.1. ÓõìâÜóåéò Ãéá íá ìðïñïýí ïé äéáìïéñáæüìåíåò âéâëéïèÞêåò íá õðïóôçñßîïõí üëåò áõôÝò ôéò åðéèõìçôÝò éäéüôçôåò, ðñÝðåé íá ãßíïõí äéÜöïñåò óõìâÜóåéò êáé íá áêïëïõèçèïýí êÜðïéåò ïäçãßåò. ÐñÝðåé íá êáôáëÜâåôå ôç äéáöïñÜ ìåôáîý ôïõ ïíïìÜôùí ìéáò âéâëéïèÞêçò, êáé óõãêåêñéìÝíá áõôïý ðïõ ëÝãåôáé ôï "soname" ôçò, êáé ôïõ ðñáãìáôéêïý ïíüìáôïò ôçò (real name), êáé ðþò áëëçëåðéäñïýí. ÐñÝðåé åðßóçò íá êáôáëÜâåôå ðïõ ðñÝðåé íá ôïðïèåôçèïýí óôï óýóôçìá áñ÷åßùí. _________________________________________________________ 3.1.1. Ïíüìáôá äéáìïéñáæüìåíùí âéâëéïèçêþí ÊÜèå äéáìïéñáæüìåíç âéâëéïèÞêç Ý÷åé Ýíá åéäéêü üíïìá, ôï ëåãüìåíï "soname". Ôï soname îåêéíÜ ìå ôï ðñüèåìá "lib", áêïëïõèåß ôï üíïìá ôçò âéâëéïèÞêçò, ç öñÜóç ".so" êáé ôÝëïò ìéá áêüìá ðåñßïäïò ( ôåëåßá - ".") áêïëïõèïýìåíç áðü Ýíáí áñéèìü Ýêäïóçò ðïõ áõîÜíåôáé üðïôå ôï interface ôçò âéâëéïèÞêçò áëëÜæåé (ùò åéäéêÞ åîáßñåóç, ïé ÷áìçëüôåñïõ åðéðÝäïõ âéâëéïèÞêåò ôçò C äåí áñ÷ßæïõí ìå ôï ðñüèåìá "lib"). ¸íá ðëÞñåò êáé êáôÜëëçëï ( (fully-qualified) soname ðåñéëáìâÜíåé ùò ðñüèåìá ôïí êáôÜëïãï áñ÷åßùí óôïí ïðïßïí âñßóêåôáé ìÝóá óôï óýóôçìá áñ÷åßùí - óå Ýíá óýóôçìá ðïõ ëåéôïõñãåß, Ýíá ðëÞñùò-êáôÜëëçëï soname åßíáé áðëÜ Ýíáò óõìâïëéêüò óýíäåóìïò (symbolic link) ðïõ äåß÷íåé óôï "ðñáãìáôéêü üíïìá" ôçò äéáìïéñáæüìåíçò âéâëéïèÞêçò. ÊÜèå äéáìïéñáæüìåíç âéâëéïèÞêç Ý÷åé åðßóçò Ýíá "ðñáãìáôéêü üíïìá", ôï ïðïßï åßíáé ôï üíïìá áñ÷åßïõ ðïõ ðåñéÝ÷åé ôïí ðñáãìáôéêü êþäéêá âéâëéïèÞêçò. Ôï ðñáãìáôéêü üíïìá ðñïóèÝôåé óôï soname ìéá åðéðëÝïí ðåñßïäï, Ýíá äåõôåñåýùí áñéèìü (minor number), ìéá áêüìá ðåñßïäï, êáé ôïí áñéèìüò Ýêäïóçò (release number). Ç ôåëåõôáßá ðåñßïäïò êáé ï áñéèìüò Ýêäïóçò åßíáé ðñïáéñåôéêü åðßèåìá. Ï minor êáé ï release áñéèìüò åðéôñÝðïõí ôïí Ýëåã÷ï ôçò äéáìüñöùóçò (configuration control ), åíçìåñþíïíôáò óáò áêñéâþò ðïéá Ýêäïóç Þ ðïéåò åêäüóåéò ôçò âéâëéïèÞêçò Ý÷ïõí åãêáôáóôáèåß. Óçìåéþóôå üôé áõôïß ïé áñéèìïß ìðïñåß íá ìçí åßíáé ïé ßäéïé ìå ôïõò áñéèìïýò ðïõ ÷ñçóéìïðïéÞèçêáí ãéá íá ðåñéãñÜøïõí ôç âéâëéïèÞêç óôçí ôåêìçñßùóç, áí êáé êÜôé ôÝôïéï êáèéóôÜ ôá ðñÜãìáôá åõêïëüôåñá. ÅðéðëÝïí, õðÜñ÷åé ôï üíïìá ðïõ ï ìåôáãëùôôéóôÞò ÷ñçóéìïðïéåß êáôÜ ôïí áßôçóç ìéáò âéâëéïèÞêçò, (Èá ôï áðïêáëþ "linker name"), ðïõ åßíáé áðëÜ ôï soname ÷ùñßò ïðïéïäÞðïôå áñéèìü Ýêäïóçò. Ôï êëåéäß ãéá ôçí êáôáíüçóç êáé äéá÷åßñéóç ôùí äéáìïéñáæüìåíùí âéâëéïèçêþí åßíáé ï äéá÷ùñéóìüò áõôþí ôùí ïíïìÜôùí. Ôá ðñïãñÜììáôá, üôáí öôéÜ÷íïõí åóùôåñéêÜ ìéá ëßóôá ìå ôéò äéáìïéñáæüìåíåò âéâëéïèÞêåò ðïõ ÷ñåéÜæïíôáé, ðñÝðåé íá åìöáíßóïõí óôç ëßóôá ìüíï ôá áíôßóôïé÷á soname. ÁíôéèÝôùò, üôáí äçìéïõñãåßôå ìéá êïéíÞ âéâëéïèÞêç, äçìéïõñãåßôå ôç âéâëéïèÞêç ìüíï ìå Ýíá óõãêåêñéìÝíï üíïìá áñ÷åßïõ (ìå ëåðôïìåñåßò ðëçñïöïñßåò Ýêäïóçò). ¼ôáí åãêáèéóôÜôå ìéá íÝá Ýêäïóç ìéáò âéâëéïèÞêçò, ôçí ôïðïèåôåßôå óå Ýíáí áðü ìåñéêïýò åéäéêïýò êáôáëüãïõò áñ÷åßùí êáé ôñÝ÷åôå Ýðåéôá ôï ðñüãñáììá ldconfig(8). Ôï ldconfig åîåôÜæåé ôá õðÜñ÷ïíôá áñ÷åßá êáé äçìéïõñãåß ôá sonames ùò óõìâïëéêÝò óõíäÝóåéò óôá ðñáãìáôéêÜ ïíüìáôá, êáèþò åðßóçò äçìéïõñãåß Þ áíáíåþíåé ôï áñ÷åßï cache /etc/ld.so.cache (ðïõ èá ðåñéãñáöåß óå ëßãï). Ôï ldconfig äåí ïñãáíþíåé ôá linker names ( ãéá ôï ïðïßá ìéëÞóáìå ðáñáðÜíù) - ôõðéêÜ áõôü ãßíåôáé êáôÜ ôç äéÜñêåéá ôçò åãêáôÜóôáóçò âéâëéïèçêþí, êáé ôï linker name äçìéïõñãåßôáé áðëÜ ùò Ýíá symbolic link óôï "ðéï ðñüóöáôï" soname Þ ôï ðéï ðñüóöáôï ðñáãìáôéêü üíïìá. Èá óýóôçíá íá Ý÷åôå ôï linker name óáí Ýíá óõìâïëéêü óýíäåóìï óôï soname, áöïý óôéò ðåñéóóüôåñåò ðåñéðôþóåéò åÜí áíáíåþóåôå ôç âéâëéïèÞêç èá åðéèõìåßôå íá ôç ÷ñçóéìïðïéÞóåôå áõôüìáôá êáôÜ ôç óýíäåóç (linking). Ñþôçóá ôïí H. J. Lu ãéáôß ôï ldconfig äåí ïñãáíþíåé áõôüìáôá ôá linker names. Ç åîÞãçóÞ ôïõ Þôáí âáóéêÜ üôé ßóùò íá èåëÞóåôå íá ôñÝîåôå êþäéêá ÷ñçóéìïðïéþíôáò ôçí ðéï ðñüóöáôç Ýêäïóç ìéáò âéâëéïèÞêçò, áëëÜ áíô' áõôïý íá èåëÞóåôå êáô ôçí áíÜðôõîç íá óõíäÝóåôå ôï ðñüãñáììá óáò ìå ìéá ðáëáéÜ (åíäå÷ïìÝíùò áóõìâßâáóôç) âéâëéïèÞêç. ÅðïìÝíùò, áöïý ôï ldconfig äåí êÜíåé êáìßá õðüèåóç ãéá ôï ìå ðïéá âéâëéïèÞêç èÝëåôå íá óõíäÝóåôå ôá ðñïãñÜììáôá óáò, êáôÜ ôçí åãêáôÜóôáóç èá ðñÝðåé íá ãßíïõí óõìâïëéêÝò óõíäÝóåéò ãéá íá åíçìåñùèåß ï linker ó÷åôéêÜ ìå ôï ðïßá âéâëéïèÞêç èá ÷ñçóéìïðïéÞóåé. ÊáôÜ óõíÝðåéá, ôï /usr/lib/libreadline.so.3 åßíáé Ýíá ðëÞñùò êáôÜëëçëï soname, ôï ïðïßï ôï ldconfig èá Ýèåôå óáí Ýíá óõìâïëéêü óýíäåóìï óå êÜðïéï ðñáãìáôéêü üíïìá (realname) üðùò ôï /usr/lib/libreadline.so.3.0. ÐñÝðåé åðßóçò íá õðÜñîåé Ýíá üíïìá ãéá ôïí linker, /usr/lib/libreadline.so ôï ïðïßï èá ìðïñïýóå íá åßíáé Ýíáò óõìâïëéêüò óýíäåóìïò ðïõ äåß÷íåé óôo /usr/lib/libreadline.so.3. _________________________________________________________ 3.1.2. ÔïðïèÝôçóç óôï Óýóôçìá Áñ÷åßùí Ïé äéáìïéñáæüìåíåò âéâëéïèÞêåò ðñÝðåé íá ôïðïèåôçèïýí êÜðïõ óôï óýóôçìá áñ÷åßùí (filesystem). Ôï áíïéêôïý êþäéêá ëïãéóìéêü (open source software) ôåßíåé íá áêïëïõèåß ôá ðñüôõðá ôïõ GNU - ãéá ðåñéóóüôåñåò ðëçñïöïñßåò äåßôå ôç ó÷åôéêÞ ôåêìçñßùóç óôï info:standards#Directory_Variables. Ôá ðñüôõðá ôïõ GNU óõóôÞíïõí, óáí ðñïêáèïñéóìÝíç åðéëïãÞ, ôçí åãêáôÜóôáóç üëùí ôùí âéâëéïèçêþí óôïí êáôÜëïãï /usr/local/lib üôáí äéáíÝìåôáé ï ðçãáßïò êþäéêáò (êáé üëåò ïé åíôïëÝò ðñÝðåé íá ìðïõí óôï /usr/local/bin). Êáèïñßæïõí åðßóçò Ýíáí óõìöùíçìÝíï ôñüðï ãéá ðáñÜêáìøç áõôþí ôùí ðñïêáèïñéóìÝíùí åðéëïãþí êáé ãéá ôçí êëÞóç ôùí ñïõôéíþí åãêáôÜóôáóçò. Ôá Ðñüôõðá Éåñáñ÷ßáò ÓõóôÞìáôïò Áñ÷åßùí (Filesystem Ierarchy Standards - FHS) óõæçôïýí ôï ôé ðñÝðåé íá ðÜåé ðïõ óå ìéá äéáíïìÞ (âë. http://www.pathname.com/fhs). Óýìöùíá ìå ôï FHS, ïé ðåñéóóüôåñåò âéâëéïèÞêåò ðñÝðåé íá åßíáé åãêáôåóôçìÝíåò óôï /usr/lib, áëëÜ ïé âéâëéïèÞêåò ðïõ áðáéôïýíôáé ãéá ôï îåêßíçìá ôïõ óõóôÞìáôïò èá ðñÝðåé íá åßíáé óôï /lib êáé ïé âéâëéïèÞêåò ðïõ äåí åßíáé ìÝñïò ôïõ óõóôÞìáôïò ðñÝðåé íá åãêáôáóôáèïýí óôï /usr/local/lib. Äåí õðÜñ÷åé ðñáãìáôéêÜ êÜðïéá óýãêñïõóç ìåôáîý áõôþí ôùí äýï åããñÜöùí - ôá ðñüôõðá ôïõ GNU óõóôÞíïõí ôéò ðñïêáèïñéóìÝíåò åðéëïãÝò ãéá ôïõò õðåýèõíïõò ãéá ôçí áíÜðôõîç ôïõ ðçãáßïõ êþäéêá, åíþ ôï FHS áíôßóôïé÷á ãéá ôïõò äéáíïìåßò (ðïõ åðéëåêôéêÜ õðåñðçäïýí ôéò ðñïêáèïñéóìÝíåò åðéëïãÝò ãéá ôïí ðçãáßï êþäéêá, óõíÞèùò ìÝóù ôïõ óõóôÞìáôïò äéá÷åßñéóçò ðáêÝôùí ôïõ óõóôÞìáôïò). Óôçí ðñÜîç áõôü äïõëåýåé ðïëý üìïñöá: ç ðëÝïí ðñüóöáôç (åíäå÷ïìÝíùò ìå ëÜèç - bugs) Ýêäïóç ôïõ ðçãáßïõ êþäéêá ðïõ "êáôåâÜæåôå", áõôüìáôá åãêáèßóôáôáé óôïí "local" (ôïðéêü) êáôÜëïãï áñ÷åßùí (/usr/local), êáé ìüëéò "ùñéìÜóåé" åêåßíïò ï êþäéêáò, ïé äéá÷åéñéóôÝò ðáêÝôùí ôçò äéáíïìÞò (package managers) ìðïñïýí åýêïëá íá ðáñáêÜìøïõí ôéò ðñïêáèïñéóìÝíåò åðéëïãÝò ãéá íá ôïðïèåôÞóïõí ôïí êþäéêá óôçí ðñüôõðç èÝóç ãéá ôç äéáíïìÞ. Óçìåéþóôå üôé åÜí ç âéâëéïèÞêç óáò êáëåß ðñïãñÜììáôá ðïõ ìðïñïýí íá êëçèïýí ìüíïí ìÝóù âéâëéïèçêþí, ðñÝðåé íá ôïðïèåôÞóåôå åêåßíÜ ôá ðñïãñÜììáôá óôïí öÜêåëï /usr/local/libexec (ðïõ óå ìéá äéáíïìÞ ìåôáôñÝðåôáé óå /usr/libexec). Ìéá ðåñéðëïêÞ åßíáé üôé ôá Red-Hat-"ïåéäÞ" óõóôÞìáôá äåí ðåñéëÜâïõí ôïí êáôÜëïãï /usr/local/lib "åî' ïñéóìïý" óôçí áíáæÞôçóÞ ôïõò ãéá âéâëéïèÞêåò - äåßôå ó÷åôéêÜ ôç óõæÞôçóç ãéá ôï /etc/ld.so.conf ðáñáêÜôù. ¢ëëåò ðñüôõðåò (standard) èÝóåéò âéâëéïèçêþí ðåñéëáìâÜíïõí ôïí êáôÜëïãï /usr/X11R6/lib ãéá ôá ×-Windows, ê.ô.ë.. Óçìåéþóôå üôé ôï /lib/security ÷ñçóéìïðïéåßôáé ãéá ôá PAM modules, áëëÜ áõôÜ öïñôþíïíôáé óõíÞèùò ùò äõíáìéêÝò âéâëéïèÞêåò (ðïõ óõæçôïýíôáé åðßóçò êáôùôÝñù). _________________________________________________________ 3.2. Ðùò ÷ñçóéìïðïéïýíôáé ïé âéâëéïèÞêåò Óôá GNU óõóôÞìáôá ðïõ âáóßæïíôáé óôç glibc, óõìðåñéëáìâáíïìÝíùí üëùí ôùí óõóôçìÜôùí Linux, ôï îåêßíçìá åíüò ELF åêôåëÝóéìïõ áíáãêÜæåé áõôüìáôá ôïí program loader (öïñôùôÞ ðñïãñÜììáôïò) íá öïñôùèåß êáé íá ôñÝîåé. Óôá óõóôÞìáôá Linux, áõôüò ï öïñôùôÞò ïíïìÜæåôáé /lib/ld-linux.so.X (üðïõ ôï × åßíáé Ýíáò áñéèìüò Ýêäïóçò). Áõôüò ï öïñôùôÞò, ìå ôç óåéñÜ ôïõ, âñßóêåé êáé öïñôþíåé üëåò ôéò Üëëåò äéáìïéñáæüìåíåò âéâëéïèÞêåò ðïõ ÷ñçóéìïðïéïýíôáé áðü ôï ðñüãñáììá. Ç ëßóôá ôùí êáôáëüãùí áñ÷åßùí ðïõ åëÝã÷ïíôáé åßíáé áðïèçêåõìÝíç óôï áñ÷åßï /etc/ld.so.conf. ÐïëëÝò äéáíïìÝò ðïõ Ý÷ïõí óáí "ðçãÞ" ôïõò RedHat óõóôÞìáôá, êáôÜ êáíüíá, äåí óõìðåñéëáìâÜíïõí ôïí êáôÜëïãï /usr/local/lib óôï áñ÷åßï /etc/ld.so.conf. Ôï ôåëåõôáßï ôï èåùñþ bug (óöÜëìá), êáé ç ðñïóèÞêç ôïõ /usr/local/lib óôï /etc/ld.so.conf åßíáé ìéá óõíÞèçò "åðéäéüñèùóç" áðáñáßôçôç ãéá ôçí åêôÝëåóç ðïëëþí ðñïãñáììÜôùí óå RedHat-derived óõóôÞìáôá. ÅÜí èÝëåôå áðëÜ íá ðáñáêÜìøåôå ìåñéêÝò ëåéôïõñãßåò óå ìéá âéâëéïèÞêç, áëëÜ íá êñáôÞóåôå ôï õðüëïéðï ôçò âéâëéïèÞêçò, ìðïñåßôå íá åéóáãÜãåôå ôá ïíüìáôá ôùí âéâëéïèçêþí ðïõ èá áíôéêáôáóôÞóïõí ôéò áñ÷éêÝò óôï áñ÷åßï /etc/ld.so.conf - áõôÝò ïé âéâëéïèÞêåò èá Ý÷ïõí ðñïôåñáéüôçôá Ýíáíôé áõôþí ôïõ ðñüôõðïõ óõíüëïõ (standard set), áöïý öïñôþíïõí åê ôùí ðñïôÝñùí (preloading). ÁõôÞ ç ìÝèïäïò âÝâáéá, ìÝóù, ÷ñçóéìïðïéåßôáé êõñßùò ãéá "ìðáëþìáôá" (patches) Ýêôáêôçò áíÜãêçò - ìéá äéáíïìÞ óðÜíéá èá ðåñéëÜâåé Ýíá ôÝôïéï áñ÷åßï óå ìéá óôáèåñÞ Ýêäïóç. ÅÜì èÝëåôå áðëÜ íá ðáñáêÜìøåôå ìåñéêÝò óõíáñôÞóåéò óôç âéâëéïèÞêç, ìá íá êñáôÞóåôå ôçí õðüëïéðç âéâëéïèÞêç, ìðïñåßôå íá åéóÜãåôå ôá ïíüìáôá ôùí ðáñáêáìðôÞñéùí âéâëéïèçêþí (.o áñ÷åßá) óôï /etc/ld.so.preload; áõôÝò ïé âéâëéïèÞêåò "ðñï-öüñôùóçò" èá ëÜâïõí ðñïôåñáßïôçôá Ýíáíôé áõôþí ôïõ âáóéêïý óõíüëïõ. Áõôü ôï áñ÷åßï ðñïöüñôùóçò ÷ñçóéìïðïåßôáé êáôÜ êáíüíá ãéá Ýêôáêôá patches - ìéá äéáíïìÞ óõíÞèùò äå èá óõìðåñéëÜâåé Ýíá ôÝôïéï áñ÷åßï êáôÜ ôç äßáèåóç ôçò. Ç Ýñåõíá üëùí áõôþí ôùí êáôáëüãùí áñ÷åßùí óôï îåêßíçìá êÜèå ðñïãñÜììáôïò èá Þôáí óõíïëéêÜ ìç ëåéôïõñãéêÞ, Ýôóé óôçí ðñáãìáôéêüôçôá ÷ñçóéìïðïéåßôáé ìéá ìÝèïäïò caching. Ôï ðñüãñáììá ldconfig (8) åî ïñéóìïý, äéáâÜæåé ôï áñ÷åßï /etc/ld.conf, ïñãáíþíåé (sets up) ôïõò êáôÜëëçëïõò óõìâïëéêïýò óõíäÝóìïõò óôïõò êáôáëüãïõò áñ÷åßùí ìå ôïõò äõíáìéêïýò óõíäÝóìïõò (dynamic link directoriew), Ýôóé þóôå íá áêïëïõèïýí ôéò ðñüôõðåò óõìâÜóåéò (standard conventions), êáé êñáôÜ ôéò áðáñáßôçôåò ðëçñïöïñßåò "óõíïðôéêÜ" óôï /etc/ld.so.cache, ðïõ ìðïñåß íá ÷ñçóéìïðïéçèåß óôç óõíÝ÷åéá áðü Üëëá ðñïãñÜììáôá. Áõôü åðéôá÷ýíåé ðïëý ôçí ðñüóâáóç óôéò âéâëéïèÞêåò. ÂÝâáéá ç ðáñáðÜíù ôáêôéêÞ ðáñïõóéÜæåé êáé ìéá "åðéðëïêÞ" : ôï ìåéïíÝêôçìá íá åßíáé áðáñáßôçôç ç åêôÝëåóç ôïõ ldconfig êÜèå öïñÜ ðïõ Ýíá DLL ðñïóôßèåôáé, áöáéñåßôáé, Þ üôáí ôï óýíïëï êáôáëüãùí áñ÷åßùí DLL áëëÜæåé - ôï ôñÝîéìï ôïõ ldconfig åßíáé óõ÷íÜ Ýíá áðü ôá âÞìáôá ðïõ åêôåëïýíôáé áðü ôïõò äéá÷åéñéóôÝò ðáêÝôùí êáôÜ ôçí åãêáôÜóôáóç ìéáò âéâëéïèÞêçò. Êáôüðéí, óôï îåêßíçìá, ï dynamic loader ÷ñçóéìïðïéåß ðñÜãìáôé ôï áñ÷åßï /etc/ld.so.cache êáé öïñôþíåé Ýðåéôá ôéò âéâëéïèÞêåò ðïõ ÷ñåéÜæåôáé. Ðáñåìðéðôüíôùò, ôï FreeBSD ÷ñçóéìïðïéåß åëáöñþò äéáöïñåôéêÜ ïíüìáôá áñ÷åßïõ ãéá áõôÞí ôçí cache. Óå FreeBSD, ç ELF cache åßíáé ôï áñ÷åßï /var/ld- elf.so.hints êáé ç a.out cache ôï /var/run/ld.so.hints. ÁõôÜ åíçìåñþíïíôáé ðÜíôá áðü ôï ldconfig (8), Ýôóé áõôÞ ç äéáöïñÜ óôç èÝóç ðñÝðåé ìüíï íá ðåéñÜîåé óå ìåñéêÝò åîáéñåôéêÝò êáôáóôÜóåéò. _________________________________________________________ 3.3. ÌåôáâëçôÝò ðåñéâÜëëïíôïò ÄéÜöïñåò ìåôáâëçôÝò ðåñéâÜëëïíôïò ìåôáâëçôþí ðåñéâÜëëïíôïò ìðïñïýí íá åëÝãîïõí áõôÞí ôçí äéáäéêáóßá, åíþ õðÜñ÷ïõí êáé ìåôáâëçôÝò ðåñéâÜëëïíôïò ðïõ óáò åðéôñÝðïõí ôçí ðáñáêÜìøåôå. _________________________________________________________ 3.3.1. LD_LIBRARY_PATH Ìðïñåßôå ðñïóùñéíÜ íá áíôéêáôáóôÞóåôå ìéá âéâëéïèÞêç ìå êÜðïéá Üëëç, ãéá ìéá óõãêåêñéìÝíç åêôÝëåóç. Óôï Linux, ç ìåôáâëçôÞ ðåñéâÜëëïíôïò LD_LIBRARY_PATH ðåñéÝ÷åé ìéá óåéñÜ áðü êáôáëüãïõò áñ÷åßùí, ÷ùñéóìÝíá ìåôáîý ôïõò ìå Üíù êáé êÜôù ôåëåßá, üðïõ ðñÝðåé íá áíáæçôçèïýí ðñþôá ïé âéâëéïèÞêåò , ðñéí áíáæçôçèïýí óôï ðñüôõðï (default) óýíïëï êáôáëüãùí áñ÷åßùí. Áõôü åßíáé ÷ñÞóéìï êáôÜ ôçí áðïóöáëìÜôùóç (debugging) ìéáò íÝáò âéâëéïèÞêçò Þ ôç ÷ñçóéìïðïßçóç ôçò "íÝáò" âéâëéïèÞêçò ãéá áóõíÞèéóôïõò ëüãïõò. Ç ìåôáâëçôÞ ðåñéâÜëëïíôïò LD_PRELOAD ðåñéÝ÷åé ìéá ëßóôá ìå âéâëéïèÞêåò ðïõ Ý÷ïõí ëåéôïõñãßåò ðïõ "õðåñéó÷ýïõí" áõôþí ôïõ ðñüôõðï óõíüëïõ, áêñéâþò üðùò ãßíåôáé ìå ôï /etc/ld.so.preload. ÁõôÝò ïé ìåôáâëçôÝò ôßèåíôáé áðü ôïí /lib/ld-linux.so loader. ÐñÝðåé íá óçìåéþóù åäþ ðùò, åíþ ç LD_LIBRARY_PATH äïõëåýåé ãéá ðïëëÜ óõóôÞìáôá Unix, äå ëåéôïõñãåß óå üëá - ðáñáäåßãìáôïò ÷Üñéí, ç ßäéá ëåéôïõñãßá åßíáé äéáèÝóéìç óå HP- UX áëëÜ ç ìåôáâëçôÞ ðåñéâÜëëïíôïò åßíáé áíôßóôïé÷á ç SHLIB_PATH, êáé óôï ÁÉ×, áõôÞ ç ëåéôïõñãéêüôçôá ðáñÝ÷åôáé ìÝóù ôçò ìåôáâëçôÞò ðåñéâÜëëïíôïò LIBPATH (ìå ôçí ßäéá áêñéâþò óýíôáîç, ìéá ëßóôá áðü ïíüìáôá êáôáëüãùí áñ÷åßùí ÷ùñéóìÝíá ìå Üíù êáé êÜôù ôåëåßá). Ç LD_LIBRARY_PATH åßíáé ðñáêôéêÞ ãéá ôçí áíÜðôõîç êáé äïêéìÞ êþäéêá, áëëÜ äå èá ÝðñÝðå íá ôñïðïðïéçèåß ðïôÝ êáôÜ ôç äéáäéêáóßá åãêáôÜóôáóçò åíüò ðñïãñÜììáôïò ãéá óõíÞèç ÷ñÞóç áðü ôïõò áðëïýò ÷ñÞóôåò - ìðïñåßôå íá äåßôå ðåñéóóüôåñá ó÷åôéêÜ ìå ôï ãéáôß óôï "Why LD_LIBRARY_PATH is bad", óôï http://www.visi.com/~barr/ldpath.html Ùóôüóï ðáñáìÝíåé ÷ñÞóéìç ãéá ôçí áíÜðôõîç Þ äïêéìÞ êþäéêá, êáé ãéá ôï øÜîéìï ëýóåùí ðÜíù óå ðñïâëÞìáôá ðïõ äåí ìðïñïýí åýêïëá íá åðéëõèïýí åéäÜëëùò. ÅÜí äåí èÝëåôå íá èÝóåôå ôç ìåôáâëçôÞ ðåñéâÜëëïíôïò LD_LIBRARY_PATH, óôï Linux ìðïñåßôå áêüìç êáé íá êáëÝóåôå ôï öïñôùôÞ ðñïãñÜììáôïò (program loader) Üìåóá êáé íá ôïõ ðåñÜóåôå ïñßóìáôá. Ãéá ðáñÜäåéãìá, ìå ôçí áêüëïõèç êëÞóç èá ÷ñçóéìïðïéçèåß ôï ÌÏÍÏÐÁÔÉ ðïõ äßíåôáé óáí üñéóìá áíôß ôïõ ðåñéå÷ïìÝíïõ ôçò ìåôáâëçôÞò ðåñéâÜëëïíôïò LD_LIBRARY_PATH, ãéá íá ôñÝîïõìå ôï óõãêåêñéìÝíï åêôåëÝóéìï: /lib/ld-linux.so.2 --library-path PATH EXECUTABLE Åêôåëþíôáò áðëÜ ôï ld-linux.so ÷ùñßò ïñßóìáôá, èá ðÜñåôå ïäçãßåò ãéá ôç ÷ñçóç ôïõ, áëëÜ êáé ðÜëé, ìç ÷ñçóéìïðïéåßôå áõôÞ ôç ìÝèïäï ãéá ôç óõíÞèç ÷ñÞóç - ôÝôïéåò åõêïëßåò Ý÷ïõí åðéíïçèåß êõñßùò ãéá ôçí áðïóöáëìÜôùóç ðñïãñáììÜôùí. _________________________________________________________ 3.3.2. LD_DEBUG Ìéá Üëëç ÷ñÞóéìç ìåôáâëçôÞ ðåñéâÜëëïíôïò óôïí GNU C loader åßíáé ç LD_DEBUG. ÁõôÞ "ðåéñÜæåé" ôéò ëåéôïõñãßåò dl þóôå íá äßíïõí ìðüëéêåò ðñïöïñßåò ãéá áõôü ðïõ êÜíïõí. Ðáñáäåßãìáôïò ÷Üñéí ìå ôï: export LD_DEBUG=files command_to_run ðáñïõóéÜæåôáé ç åðåîåñãáóßá áñ÷åßùí êáé âéâëéïèçêþí êáôÜ ôï ÷åéñéóìü ôùí âéâëéïèçêþí, ëÝãïíôáò óáò ðïéåò åîáñôÞóåéò (dependencies) áíé÷íåýïíôáé, ðïßåò SOs öïñôþíïíôáé êáé ìå ðïéá óåéñÜ. Ç èÝóç ôçò LD_DEBUG óôç ôéìÞ "bindings", Ý÷åé óáí áðïôÝëåóìá ôçí ðñïâïëÞ ðëçñïöïñéþí ãéá ôï óõó÷åôéóìü óõìâüëùí (symbol binding), óôçí ôéìÞ "libs" ôçí ðñïâïëÞ ôùí ìïíïðáôéþí üðïõ ãßíåôáé áíáæÞôçóç âéâëéïèçêþí (library search paths), êáé óôçí ôéìÞ "versions", ôçí ðñïâïëÞ ôùí åîáñôÞóåùí ôçò Ýêäïóçò (version dependencies). Áí èÝóåé êáíåßò óôç ìåôáâëçôÞ LD_DEBUG ôçí ôéìÞ "help" êáé ðñïóðáèÞóåé íá ôñÝîåé êÜðïéï ðñüãñáììá, èá ðÜñåé ìéá ëßóôá ìå ôçò ðéèáíÝò åðéëïãÝò. Éó÷ýåé ðÜíôá âÝâáéá, ðùò êáé ç LD_DEBUG äåí ðñïïñßæåôáé ãéá êáíïíéêÞ ÷ñÞóç, áëëÜ ìðïñåß íá öáíåß ÷ñÞóéìç óå ðåñéðôþóåéò debugging êáé testing. _________________________________________________________ 3.3.3. ¢ëëåò ìåôáâëçôÝò ðåñéâÜëëïíôïò ÕðÜñ÷ïõí óôçí ðñáãìáôéêüôçôá Ýíáò áñéèìüò áðü êÜðïéåò ìåôáâëçôÝò ðåñéâÜëëïíôïò áêüìá, ðïõ åëÝã÷ïõí ôç äéáäéêáóßá öüñôùóçò (loading process) - ôá ïíüìáôÜ ôïõò áñ÷ßæïõí ìå ôï LD _ Þ RTLD _. Ïé ðåñéóóüôåñåò áðü ôéò õðüëïéðåò åßíáé ãéá ÷áìçëïý åðéðÝäïõ debugging ôçò äéåñãáóßáò öüñôùóçò (loader process) Þ ãéá ôçí åöáñìïãÞ ðñï÷ùñçìÝíùí äõíáôïôÞôùí . Ïé ðåñéóóüôåñåò áð' áõôÝò äåí åßíáé êáëÜ ôåêìçñéùìÝíåò- åÜí ðñÝðåé íôå êáé êáëÜ íá âñåßôå ðëçñïöïñßåò ãé' áõôÝò, ï êáëýôåñïò ôñüðïò íá ìÜèåôå åßíáé íá äéáâÜóåôå ôïí ðçãáßï êþäéêá ôïõ loader (ìÝñïò ôïõ GCC). Ôï íá åðéôñÝðåôáé óôïí ÷ñÞóôç íá Ý÷åé Ýëåã÷ï ðÜíù óôéò äõíáìéêÜ óõíäåìÝíåò âéâëéïèÞêåò (DLLs) èá Þôáí êáôáóôñïöéêü ãéá ôá setuid/setgid ðñïãñÜììáôá (äçëáäÞ åêåßíá ðïõ Ý÷ïõí ôá áíôßóôïé÷á permissions set), åÜí äåí ëáìâÜíïíôáí åéäéêÜ ìÝôñá. ÅðïìÝíùò, óôïí GNU loader (ðïõ öïñôþíåé ôï õðüëïéðï ôïõ ðñïãñÜììáôïò êáôÜ ôçí åêêßíçóç ôïõ), åÜí ôï ðñüãñáììá åßíáé setuid Þ setgid, áõôÝò ïé ìåôáâëçôÝò (êáé Üëëåò ðáñüìïéåò ìåôáâëçôÝò) áãíïïýíôáé Þ ðåñéïñßæïíôáé ðïëý óå áõôü ðïõ ìðïñïýí íá êÜíïõí. Ï loader êáèïñßæåé åÜí Ýíá ðñüãñáììá åßíáé setuid Þ setgid ìå ôïí Ýëåã÷ï ôùí credentials ("ðéóôïðïéçôéêþí") ôïõ ðñïãñÜììáôïò - åÜí ôá uid êáé euid äéáöÝñïõí, Þ ôá gid êáé egid äéáöÝñïõí, ï öïñôùôÞò èåùñåß üôé ôï ðñüãñáììá åßíáé setuid/setgid (Þ Ý÷åé ðñïêýøåé áðü êÜðïéï ðïõ Þôáí) êáé åðïìÝíùò ðåñéïñßæåé ðïëý ôéò äõíáôüôçôÝò ôïõ íá åëÝãîåé ôç äéáäéêáóßá óýíäåóçò (linking). ÅÜí äéáâÜóåôå ôïí ðçãáßï ôùí GNU glibc âéâëéïèçêþí, ìðïñåßôå íá ôï äéáðéóôþóåôå - äåßôå åéäéêÜ ôá áñ÷åßá /elf/rtld.c êáé sysdeps/generic/dl-sysdep.c. Áõôü óçìáßíåé üôé åÜí áíáãêÜóåôå ôï uid êáé ôï gid íá ôáõôßæïíôáé ìå ôá euid êáé egid, êáé êáëÝóåôå Ýðåéôá Ýíá ðñüãñáììá, áõôÝò ïé ìåôáâëçôÝò èá Ý÷ïõí ôçí ðëÞñç åðßäñáóç ôïõò. ¢ëëá Unix-ïåéäÞ óõóôÞìáôá ÷åéñßæïíôáé ôçí ðáñáðÜíù êáôÜóôáóç äéáöïñåôéêÜ áëëÜ ãéá ôïí ßäéï ëüãï: Ýíá setuid/setgid ðñüãñáììá äåí ðñÝðåé íá åðçñåáóôåß áäéêáéïëüãçôá áðü ôéò ìåôáâëçôÝò ðåñéâÜëëïíôïò ðïõ Ý÷ïõí ôåèåß. _________________________________________________________ 3.4. Äçìéïõñãþíôáò ìéáò äéáìïéñáæüìåíç âéâëéïèÞêç Ç äçìéïõñãßá ìéáò äéáìïéñáæüìåíçò âéâëéïèÞêçò åßíáé åýêïëç õðüèåóç. Êáô' áñ÷Üò, äçìéïõñãÞóôå ôá object files ðïõ èá ðÜíå óôç äéáìïéñáæüìåíç âéâëéïèÞêç ÷ñçóéìïðïéþíôáò ôï GCC ìå ôéò ðáñáìÝôñïõò (flags) -fPIC Þ -fpic. Ïé ðñïáéñåôéêÝò ðáñÜìåôñïé -fPIC êáé -fpic åíåñãïðïéïýí ôç äçìéïõñãßá "áíåîáñôÞôïõ èÝóåùò êþäéêá" (position independent code), ðïõ åßíáé ìéá âáóéêÞ áðáßôçóç ãéá ôéò äéáìïéñáæüìåíåò âéâëéïèÞêåò - ïé äéáöïñÝò áíáëýïíôáé ðáñáêÜôù. Ôï soname ôï ðåñíÜôå ìå ôçí ðñïáéñåôéêÞ ðáñÜìåôñï -Wl ôïõ gcc. Ç ðáñÜìåôñïò -Wl ðåñíÜåé ðåñíÜ ôéò åðéëïãÝò ðïõ áêïëïõèïýí óôïí linker (óå áõôÞí ôçí ðåñßðôùóç ôçí ðáñÜìåôñï -soname ìå ôï üñéóìá ôçò) - ôá êüììáôá ìåôÜ áðü ôï -Wl äåí åßíáé ôõðéêÜ, ïýôå ôõðïãñáöéêü ëÜèïò, üðùò åðßóçò ðñïóÝîôå íá ìçí óõìðåñéëÜâåôå êåíÜ (white spaces) óôï üñéóìá. Êáôüðéí äçìéïõñãÞóôå ôçí êïéíÞ âéâëéïèÞêç ÷ñçóéìïðïéþíôáò ìéá åíôïëÞ ôïõ ðáñáêÜôù ôýðïõ: gcc -shared -Wl,-soname,your_soname \ -o library_name file_list library_list Áêïëïõèåß Ýíá ðáñÜäåéãìá, üðïõ äçìéïõñãïýíôáé äýï object files (a.o êáé b.o) êáé Ýðåéôá ìéá êïéíÞ âéâëéïèÞêç ðïõ ðåñéÝ÷åé êáé ôá äýï. Óçìåéþóôå üôé áõôÞ ç ìåôáãëþôôéóç ðåñéëáìâÜíåé ôéò ðëçñïöïñßåò debugging (-g - èá ìðïñïýóå íá åßíáé -ggdb ãéá íá óõìðåñéëçöèïýí åðéðëÝïí debugging ðëçñïöïñßåò ãéá ÷ñÞóç ìå ôïí gdb) êáé èá ðáñáãÜãåé êáé ðñïåéäïðïéÞóåéò (warnings - ðñïáéñåôéêÞ ðáñÜìåôñïò - Wall), ðïõ äåí áðáéôïýíôáé, öõóéêÜ, ãéá ôéò êïéíÝò âéâëéïèÞêåò áëëÜ óõóôÞíïíôáé. Ç ìåôáãëþôôéóç (compilation) ðáñÜãåé ôá object filesõ (÷ñçóéìïðïéåßôáé ç ðáñÜìåôñïò -c), êáé ðåñéëáìâÜíåé êáé ôçí áðáéôïýìåíç åðéëïãÞ fPIC: gcc -fPIC -g -c -Wall a.c gcc -fPIC -g -c -Wall b.c gcc -shared -Wl,-soname,libmystuff.so.1 \ -o libmystuff.so.1.0.1 a.o b.o -lc ÌåñéêÜ óçìåßá Üîéá ðåñéóóüôåñçò ðñïóï÷Þò: * Ìç "ãäýóåôå" (strip) ôçí ðñïêýðôïõóá âéâëéïèÞêç, êáé ìçí ÷ñçóéìïðïéÞóôå ôçí ðáñÜìåôñï -fomit-frame-pointer óôïí compiler, åêôüò êáé ðñáãìáôéêÜ, äå ãßíåôáé äéáöïñåôéêÜ. Ç ðñïêýðôïõóá âéâëéïèÞêç èá ëåéôïõñãÞóåé, áëëÜ áõôÝò ïé åíÝñãåéåò êáèéóôïýí ôïõò debuggers (ðñïãñÜììáôá áðïóöáëìÜôùóçò) óõíÞèùò Ü÷ñçóôïõò. * ×ñçóéìïðïéÞóôå ôéò ðáñáìÝôñïõò -fPIC Þ -fpic ãéá íá ðáñáãÜãåôå ôïí êþäéêá. Ç ÷ñÞóç -fPIC Þ - fpic ãéá ôçí ðáñáãùãÞ êþäéêá åîáñôÜôáé áðü ôïí óôü÷ï óáò. Ç åðéëïãÞ -fPIC ëåéôïõñãåß ðÜíôá, áëëÜ ìðïñåß íá Ý÷åé óáí áðïôÝëåóìá ìåãáëýôåñï êþäéêá áðü ôçí -fpic (Ýíáò áðëüò ôñüðïò ãéá íá èõìÜóôå ôçí ðáñáðÜíù ðáñáôÞñçóç åßíáé íá Ý÷åôå êáôÜ íïõ ðùò ôá êåöáëáßá, ìåãÜëá ãñÜììáôá PIC óôçí ðáñÜìåôñï -fPIC èá ðáñÜãïõí ìåãáëýôåñï óå ìÝãåèïò êþäéêá, áð' üôé ìÜëëïí èá ãßíåé êÜíïíôáò ÷ñÞóç ôçò -fpic). ×ñÞóç ôçò ðáñáìÝôñïõ -fpic ðáñÜãåé óõíÞèùò ìéêñüôåñï êáé ãñçãïñüôåñï êþäéêá, áëëÜ èá Ý÷åé ôïõò ðåñéïñéóìïýò åîáñôþìåíïõò áðü ôï óýóôçìá ðïõ ÷ôßóôçêå ç âéâëéïèÞêç (platform-dependent), üðùò ï áñéèìüò ôùí ìåôáâëçôþí ðïõ åßíáé êáèïëéêÝò (globally visible symbols), Þ ôï ìÝãåèïò ôïõ êþäéêá. Ï linker èá óáò ðåé åÜí "ôïõ êÜíåé" (ç åðéëïãÞ óáò äå äçìéïõñãåß ðñïâëÞìáôá) üôáí äçìéïõñãåßôå ôç äéáìïéñáæüìåíç âéâëéïèÞêç. Óå ðåñßðôùóç áìöéâïëßáò, åðéëÝîôå -fPIC - ëåéôïõñãåß ðÜíôá. * Óå ìåñéêÝò ðåñéðôþóåéò, ç êëÞóç óôïí ìåôáãëùôôéóôÞ gcc ãéá äçìéïõñãßá áñ÷åßïõ áíôéêåéìÝíïõ (object file) èá ðñÝðåé åðßóçò íá óõìðåñéëáìâÜíåé ôçí ðñïáéñåôéêÞ ðáñÜìåôñï "- Wl, -export-dynamic". ÊáíïíéêÜ, ï äõíáìéêüò ðßíáêáò óõìâüëùí (dynamic symbol table) ðåñéÝ÷åé ìüíï ôá óýìâïëá ðïõ ÷ñçóéìïðïéïýíôáé áðü Ýíá äõíáìéêü áíôéêåßìåíï. ÁõôÞ ç åðéëïãÞ (êáôÜ ôï äçìéïõñãßá åíüò áñ÷åßïõ óå ELF) ðñïóèÝôåé üëá ôá óýìâïëá óôï äõíáìéêü ðßíáêá óõìâüëùí ((âë. ld(1) ãéá ðåñéóóüôåñåò ðëçñïöïñßåò). ÐñÝðåé íá ÷ñçóéìïðïéÞóåôå áõôÞí ôçí ðñïáéñåôéêÞ äõíáôüôçôá üôáí õðÜñ÷ïõí "áíôßóôñïöåò åîáñôÞóåéò", Þôïé, ìéá âéâëéïèÞêç DL Ý÷åé áðñïóäéüñéóôá-åêêñåìÞ óýìâïëá ðïõ ðñÝðåé íá êáèïñéóôïýí óôá ðñïãñÜììáôá ðïõ óêïðåýïõí íá ôç öïñôþóïõí (ó.ô.ì. ãéá íá ãßíåé ðéï êáôáíïçôü óå ôé áêñéâþò áíáöåñüìáóôå ëÝãïíôáò "óýìâïëï" - ãéá ôç ìåôÜöñáóç ÷ñçóéìïðïéÞèçêå áêñéâþò ï åëëçíéêüò üñïò ôïõ symbol, áíáöÝñïõìå ðùò, üðùò öáßíåôáé ð.÷. óôï ðáñÜäåéãìá ôçò ðáñáãñÜöïõ 4.5, ç cos åßíáé symbol ôçò math âéâëéïèÞêçò). Ãéá íá äïõëÝøïõí ïé "áíôßóôñïöåò åîáñôÞóåéò", ôï êýñéï ðñüãñáììá ðñÝðåé íá êáôáóôÞóåé ôá óýìâïëÜ ôïõ äéáèÝóéìá äõíáìéêÜ. Óçìåéþóôå üôé èá ìðïñïýóáôå íá ðåßôå "- rdynamic" áíôß "- Wl, -export-dynamic", åÜí åñãÜæåóôå ìüíï ìå óõóôÞìáôá Linux, áëëÜ óýìöùíá ìå ôçí ôåêìçñßùóç ELF (ELF documentation), ç åðéëïãÞ "- rdynamic" äåí ëåéôïõñãåß ðÜíôá ãéá ôï gcc óôá ìç-linux óõóôÞìáôá. ÊáôÜ ôç äéÜñêåéá ôçò áíÜðôõîçò êþäéêá, õðÜñ÷åé ôï ðéèáíü ðñüâëçìá ôçò ôñïðïðïßçóçò ìéáò âéâëéïèÞêçò ðïõ ÷ñçóéìïðïéåßôáé åðßóçò êé áðü ðïëëÜ Üëëá ðñïãñÜììáôá - êáé åóåßò äåí èá èÝëáôå ãéá íá ÷ñçóéìïðïéÞóïõí ôç âéâëéïèÞêç ðïõ âñßóêåôáé õðü áíÜðôõîç ôá Üëëá ðñïãñÜììáôá, ðáñÜ ìüíï ìéá óõãêåêñéìÝíç åöáñìïãÞ ðïõ åîåôÜæåôå ùò ðñïò ôç óõìðåñéöïñÜ ôçò áðÝíáíôé óôç íÝá âéâëéïèÞêç. Ìéá ðñïáéñåôéêÞ äõíáôüôçôá ãéá ôç óýíäåóç (linking option) ðïõ ìðïñåßôå íá ÷ñçóéìïðïéÞóåôå åßíáé ç "rpath" ôïõ ld, ðïõ ðñïóäéïñßæåé ôï ìïíïðÜôé áíáæÞôçóçò runtime (÷ñüíïõ åêôÝëåóçò) âéâëéïèçêþí ôïõ ôïõ óõãêåêñéìÝíïõ åêåßíïõ ðñïãñÜììáôïò ðïõ ìåôáãëùôôßæåôáé. Áðü ôï gcc, ìðïñåßôå íá èÝóåôå ôçí åðéëïãÞ rpath ìå ôïí ðáñáêÜôù ôñüðï : -Wl,-rpath,$(DEFAULT_LIB_INSTALL_PATH) ÅÜí ÷ñçóéìïðïéåßôå áõôÞí ôçí ðñïáéñåôéêÞ äõíáôüôçôá êáôÜ ôçí êáôáóêåõÞ ôïõ client ðñïãñÜììáôïò, äåí ðñÝðåé íá ðåéñÜîåôå ôç ìåôáâëçôÞ ðåñéâÜëëïíôïò LD_LIBRARY_PATH (ðïõ ðåñéãñÜöåôáé ðáñáêÜôù) ãéá êÜðïéïí Üëëï ëüãï åêôüò áðü ôï íá åîáóöáëßóåôå üôé äåí äçìéïõñãïýíôáé óõíèÞêåò óõãêñïýóåùí, Þ üôé äå ÷ñçóéìïðïéïýíôáé Üëëåò ôå÷íéêÝò áðüêñõøçò ôçò âéâëéïèÞêçò. _________________________________________________________ 3.5. ÅãêáôÜóôáóç êáé ÷ñÞóç äéáìïéñáæüìåíçò âéâëéïèÞêçò Ìüëéò äçìéïõñãÞóåôå ìéá äéáìïéñáæüìåíç âéâëéïèÞêç, èá èåëÞóåôå íá ôçí åãêáôáóôÞóåôå. Ç áðëÞ ðñïóÝããéóç åßíáé áðëÜ íá áíôéãñáöåß ç âéâëéïèÞêç óå Ýíáí áðü ôïõò ðñüôõðïõò êáôáëüãïõò áñ÷åßùí (ð.÷. /usr/lib) êáé íá ôñÝîåôå ôï ldconfig(8). Êáô' áñ÷Üò, èá ðñÝðåé êÜðïõ íá äçìéïõñãÞóåôå ôéò êïéíÝò âéâëéïèÞêåò . Êáôüðéí, èá ðñÝðåé íá åôïéìÜóåôå ôïõò áðáñáßôçôïõò óõìâïëéêïýò óõíäÝóìïõò, êáé åéäéêüôåñá Ýíá link áðü Ýíá soname óå Ýíá realname (êáèþò åðßóçò êáé áðü Ýíá versionless soname, äçëáäÞ Ýíá soname ðïõ Ý÷åé åðßèåìá ìüíïí ôï ".so", ãéá ôïõò ÷ñÞóôåò ðïõ äåí ðñïóäéïñßæïõí êáèüëïõ ìéá Ýêäïóç). Ç áðëïýóôåñç ðñïóÝããéóç åßíáé íá ôñÝîåôå: ldconfig -n directory_with_shared_libraries ÔÝëïò, üôáí ìåôáãëùôôßæåôå ôá ðñïãñÜììáôÜ óáò, èá ðñÝðåé íá ðåßôå óôïí linker üôé ãéá ôéò óôáôéêÝò êáé äéáìïéñáæüìåíåò âéâëéïèÞêåò ðïõ ÷ñçóéìïðïéåßôå. ×ñçóéìïðïéÞóôå ôéò ðñïáéñåôéêÝò ðáñáìÝôñïõò -l êáé -L ãéá íá ôï êÜíåôå. ÅÜí äåí ìðïñåßôå Þ äåí èÝëåôå íá åãêáôáóôÞóåôå ìéá âéâëéïèÞêç óå ìéá standard èÝóç (ð.÷. äåí Ý÷åôå ôá äéêáéþìáôá íá ôñïðïðïéÞóåôå ôïí êáôÜëïãï /usr/lib), èá ðñÝðåé íá áëëÜîåôå ôçí ðñïóÝããéóÞ óáò. Óå áõôÞ ôçí ðåñßðôùóç, èá ðñÝðåé íá åãêáôáóôÞóåôå ôéò âéâëéïèÞêåò êÜðïõ, êáé íá äþóåôå Ýðåéôá óôï ðñüãñáììÜ óáò áñêåôÝò ðëçñïöïñßåò Ýôóé þóôå íá ìðïñåß íá âñåß ôç âéâëéïèÞêç... êáé õðÜñ÷ïõí äéÜöïñïé ôñüðïé íá ãßíåé áõôü. Ìðïñåßôå íá ÷ñçóéìïðïéÞóåôå ôç óçìáßá (flag) -L ôïõ gcc óôéò áðëïýóôåñåò ôùí ðåñéðôþóåùí. Ìðïñåßôå íá ÷ñçóéìïðïéÞóåôå êáé ôçí "ðñïóÝããéóç rpath" (ðïõ ðåñéåãñÜöç áíùôÝñù), éäéáßôåñá åÜí èÝëåôå ìüíï Ýíá óõãêåêñéìÝíï ðñüãñáììá íá ÷ñçóéìïðïéÞóåé ôç âéâëéïèÞêç ðïõ ôïðïèåôåßôå óå Ýíáí êáôÜëïãï åêôüò ôùí standard. Ìðïñåßôå åðßóçò íá ÷ñçóéìïðïéÞóåôå ôéò ìåôáâëçôÝò ðåñéâÜëëïíôïò ãéá íá åëÝãîåôå ôá ðñÜãìáôá. Åéäéêüôåñá, ìðïñåßôå íá èÝóåôå ôçí LD_LIBRARY_PATH, ðïõ åßíáé ìéá ëßóôá áðü ïíüìáôá êáôáëüãùí ÷ùñéóìÝíá ìå Üíù êáé êÜôù ôåëåßá ôá ïðïßá åñåõíþíôáé ãéá ýðáñîç äéáìïéñáæüìåíùí âéâëéïèçêþí ðñéí áðü ôçí áíáæÞôçóç óôéò óõíçèéóìÝíåò èÝóåéò. ÅÜí ÷ñçóéìïðïéåßôå bash, èá ìðïñïýóáôå íá êáëÝóåôå ôï my_program ìå áõôüí ôïí ôñüðï ÷ñçóéìïðïéþíôáò: LD_LIBRARY_PATH=.:$LD_LIBRARY_PATH my_program ÅÜí èÝëåôå íá ðáñáêÜìøåôå áðëÜ ìåñéêÝò åðéëåãìÝíåò ëåéôïõñãßåò/óõíáñôÞóåéò, ìðïñåßôå íá ôï êÜíåôå äçìéïõñãþíôáò Ýíá "ðáñáêáìðôÞñéï" object file êáé èÝôïíôáò ôç ìåôáâëçôÞ LD_PRELOAD - ïé óõíáñôÞóåéò óå áõôü ôï áñ÷åßï áíôéêåéìÝíïõ èá õðåñéó÷ýóïõí áêñéâþò åêåßíùí ôùí ëåéôïõñãéþí ðïõ ðñÝðåé (áöÞíïíôáò ôéò Üëëåò üðùò åß÷áí). ÓõíÞèùò ìðïñåßôå íá åíçìåñþóåôå (update) âéâëéïèÞêåò ÷ùñßò êÜðïéá éäéáßôåñç áíçóõ÷ßá - åÜí õðÞñîå áëëáãÞ óôç äéåðáöÞ (API), ï äçìéïõñãüò âéâëéïèçêþí åßíáé èåùñçôéêÜ õðï÷ñåùìÝíïò íá áëëÜîåé ôï soname. Ìå áõôü ôïí ôñüðï ìðïñïýí óå Ýíá óýóôçìá íá óõíõðÜñ÷ïõí ðïëëáðëÝò âéâëéïèÞêåò, êáé ç êáôÜëëçëç íá åðéëÝãåôáé ãéá êÜèå ðñüãñáììá. Åíôïýôïéò, åÜí Ýíá ðñüãñáììá äå ëåéôïõñãåß ëüãù ôçò åíçìÝñùóçò ìéáò âéâëéïèÞêçò ðïõ êñÜôçóå ôï ßäéï soname, ìðïñåßôå íá ôï áíáãêÜóåôå íá ÷ñçóéìïðïéÞóåé ôçí ðáëáéüôåñç Ýêäïóç âéâëéïèçêþí ìå ôï íá áíôéãñÜøåôå ôçí ðáëéÜ âéâëéïèÞêç êÜðïõ, íá ìåôïíïìÜóåôå ôï ðñüãñáììá (ð.÷, äþóôå óôï ðáëáéü ôï ßäéï üíïìá ðñïóèÝôïíôáò ôï åðßèåìá ".orig"), êáé íá äçìéïõñãÞóåôå Ýðåéôá Ýíá ìéêñü wrapper script ðïõ ñõèìßæåé îáíÜ ôç âéâëéïèÞêç ðïõ ÷ñçóéìïðïéåßôáé êáé êáëåß ôï ðñáãìáôéêü (ìåôïíïìáóìÝíï) ðñüãñáììá. Èá ìðïñïýóáôå íá ôïðïèåôÞóåôå ôçí ðáëáéÜ âéâëéïèÞêç óå ìéá åéäéêÞ, "ðñïóùðéêÞ" ðåñéï÷Þ, åÜí èÝëåôå, áí êáé åßíáé äõíáôüí íá õðÜñ÷ïõí ðïëëáðëÝò åêäüóåéò ôçò ßäéáò âéâëéïèÞêçò óôïí ßäéï êáôÜëïãï, ÷Üñç óôçí áñéèìïäüôçóç ðïõ åðéâÜëëåôáé óôçí ïíïìáóßá ôùí äéáöüñùí åêäüóåùí âéâëéïèçêþí. Ôï wrapper script èá ìðïñïýóå íá íáé êÜðùò Ýôóé: #!/bin/sh export LD_LIBRARY_PATH=/usr/local/my_lib:$LD_LIBRARY_PATH exec /usr/bin/my_program.orig $* ÐÜíôùò èá óáò ðáñáêáëïýóá áí âáóéóôåßôå óôéò ðáñáðÜíù "äéåõêïëýíóåéò" êáôÜ ôç óõããñáöÞ ôùí ðñïãñáììÜôùí óáò- ðñïóðáèÞóôå íá óéãïõñåõôåßôå êáëýôåñá üôé ïé âéâëéïèÞêåò óáò åßíáé åßôå ðñïò-ôá-ðßóù-óõìâáôÝò (backwards-compatible) åßôå üôé Ý÷åôå áõîÞóåé ôïí áñéèìü Ýêäïóçò óôï soname êÜèå öïñÜ ðïõ êÜíåôå ìéá áëëáãÞ ðïõ äåí åßíáé óõìâáôÞ ìå ôá Ýùò ôþñá. Ôá áíùôÝñù åßíáé ìéá "ðñïóÝããéóç Ýêôáêôïõ áíÜãêçò" ãéá ôçí áíôéìåôþðéóç ðñïâëçìÜôùí "ôçò êáêßáò þñáò". Ìðïñåßôå íá äåßôå ôïí êáôÜëïãï ôùí äéáìïéñáæüìåíùí âéâëéïèçêþí ðïõ ÷ñçóéìïðïéïýíôáé áðü Ýíá ðñüãñáììá ÷ñçóéìïðïéþíôáò ôçí ldd (1). ¸ôóé, ðáñáäåßãìáôïò ÷Üñéí, ìðïñåßôå íá äåßôå ôéò êïéíÝò âéâëéïèÞêåò ðïõ ÷ñçóéìïðïéïýíôáé áðï ôï ls ðëçêôñïëïãþíôáò: ldd /bin/ls ÂáóéêÜ, èá äåßôå ìéá ëßóôá áðü sonames áðü ôá ïðïßá åîáñôÜôáé ôï ðñüãñáììá (ç ls óôç óõãêåêñéìÝíç ðåñßðôùóç), ìáæß ìå ôïí êáôÜëïãï áñ÷åßùí óôïí ïðïßï áõôÜ âñßóêïíôáé. ÐÜíôùò ó÷åäüí óå êÜèå ðåñßðôùóç èá Ý÷åôå ôïõëÜ÷éóôïí äýï dependencies (åîáñôÞóåéò): * /lib/ld-linux.so.Í (üðïõ ôï N åßíáé ìåãáëýôåñï Þ ßóïí ôïõ 1, óõíÞèùò ôïõëÜ÷éóôïí 2). Áõôü åßíáé ç âéâëéïèÞêç ðïõ öïñôþíåé üëåò ôéò Üëëåò âéâëéïèÞêåò. * libc.so.Í (üðïõ ôï N åßíáé ìåãáëýôåñï Þ ßóïí ôïõ 6). Áõôü åßíáé ç âéâëéïèÞêç ôçò C. Áêüìç êáé Üëëåò ãëþóóåò ôåßíïõí íá ÷ñçóéìïðïéïýí ôç âéâëéïèÞêç C (ôïõëÜ÷éóôïí ãéá íá õëïðïéÞóïõí ôéò äéêÝò ôïõò âéâëéïèÞêåò), ïðüôå ôá ðåñéóóüôåñá ðñïãñÜììáôá ðåñéëáìâÜíïõí ôïõëÜ÷éóôïí êáé áõôÞí åäþ. Ðñïóï÷Þ: ìçí ôñÝîåôå ôï ldd óå ðñïãñÜììáôá ðïõ äåí åìðéóôåýåóôå. ¼ðùò äçëþíåôáé óáöþò óôï åã÷åéñßäéï ôïõ ldd (1), ç ldd äïõëåýåé (óå ïñéóìÝíåò ðåñéðôþóåéò) ìå ôï íá èÝôåé ìéáò åéäéêÞ ìåôáâëçôÞ ðåñéâÜëëïíôïò (ãéá ôá áíôéêåßìåíá ELF, ôçí LD_TRACE_LOADED_OBJECTS) êáé åêôåëþíôáò Ýðåéôá ôï ðñüãñáììá. Ìðïñåß íá åßíáé äõíáôü ãéá Ýíá ìç áîéüðéóôï ðñüãñáììá íá áíáãêÜóåé ôïí ÷ñÞóôç ôçò ldd íá ôñÝîåé áõèáßñåôï êáé ðéèáíüôáôá åðéâëáâÞ êþäéêá (áíôß áðëÜ íá åìöáíßóåé ðëçñïöïñßåò ôçò ldd). ¸ôóé, ãéá ëüãïõò áóöáëåßáò, ìçí ÷ñçóéìïðïéåßôå ldd óôá ðñïãñÜììáôá ðïõ äåí åìðéóôåýåóôå ðñïò åêôÝëåóç. _________________________________________________________ 3.6. Áóõìâßâáóôåò ìåôáîý ôïõò âéâëéïèÞêåò ¼ôáí ç íÝá Ýêäïóç ìéá âéâëéïèÞêçò åßíáé binary incompatible ("äõáäéêÜ- áóõìâßâáóôç") ìå ôçí ðáëáéüôåñç Ýêäïóç ôçò, ôï soname ðñÝðåé íá áëëÜîåé. Óôçí C, õðÜñ÷ïõí ôÝóóåñéò âáóéêïß ëüãïé ãéá ôïõò ïðïßïõò ìéá âéâëéïèÞêç èá ãéíüôáí binary-incompatible ìå ôï óýóôçìá: 1. Ç óõìðåñéöïñÜ ìéáò ëåéôïõñãßáò (óõíÜñôçóçò) áëëÜæåé Ýôóé þóôå äåí áíôáðïêñßíåôáé ðëÝïí óôéò áñ÷éêÝò ðñïäéáãñáöÝò ôçò, 2. Ôá áíôéêåßìåíá ðïõ "åîÜãïíôáé" (exported data items) áëëÜæïõí (åîáßñåóç: ç ðñïóèÞêç ðñïáéñåôéêþí áíôéêåéìÝíùí óôéò Üêñåò ôùí äïìþí åßíáé åíôÜîåé, åö' üóïí åêåßíåò ïé äïìÝò äåóìåýïíôáé ìüíï ìÝóá óôç âéâëéïèÞêç). 3. Ìéá åîáãüìåíç óõíÜñôçóç (exported function) áöáéñåßôáé. 4. Ôï interface ìéáò åîáãüìåíçò ëåéôïõñãßáò áëëÜæåé. ÅÜí ìðïñåßôå íá áðïöýãåôå ôïõò ðáñáðÜíù ëüãïõò, ìðïñåßôå íá êñáôÞóåôå ôéò âéâëéïèÞêåò óáò binary-compatible ìå ôï óýóôçìá. Ãéá íá ôï ðïýìå êáé êÜðùò äéáöïñåôéêÜ, ìðïñåßôå íá êñáôÞóåôå ôo Application Binary Interface (ABI, êÜôé óáí "ÄõáäéêÞ ÄéåðáöÞ Åöáñìïãþí") óõìâáôü, åÜí áðïöåýãåôå ôÝôïéåò áëëáãÝò. Ðáñáäåßãìáôïò ÷Üñéí, ìðïñåß íá èåëÞóåôå íá ðñïóèÝóåôå íÝåò ëåéôïõñãßåò/óõíáñôÞóåéò áëëÜ íá ìçí äéáãñÜøåôå ôéò ðáëéÝò. Ìðïñåßôå íá ðñïóèÝóåôå ôá íÝá áíôéêåßìåíá óôéò äïìÝò óáò, áëëÜ ìüíï åÜí ìðïñåßôå íá óéãïõñåõôåßôå üôé ôá ðáëéÜ ðñïãñÜììáôá äåí èá åßíáé "åõáßóèçôá" óå ôÝôïéåò áëëáãÝò, êÜíïíôáò ôçí ðñïóèÞêç ôùí áíôéêåéìÝíùí ìüíï óôï ôÝëïò ôçò äïìÞò, åðéôñÝðïíôáò ìüíï óôç âéâëéïèÞêç (êáé ü÷é ôçí åöáñìïãÞ) íá äåóìåýåé ôç äïìÞ, êáèéóôþíôáò ôá ðñüóèåôá áíôéêåßìåíá ðñïáéñåôéêÜ (Þ èÝôïíôáò ôç âéâëéïèÞêç íá ôá óõìðëçñþíåé), êáé ôá ëïéðÜ. ÐñïóÝîôå: äåí ìðïñåßôå ðéèáíþò íá åðåêôåßíåôå ôéò äïìÝò åÜí ïé ÷ñÞóôåò ôéò ÷ñçóéìïðïéïýí óå ðßíáêåò (arrays). Ó÷åôéêÜ ìå ôçí C++ (êáé Üëëåò ãëþóóåò ðïõ õðïóôçñßæïõí compiled-in templates êáé/Þ compiled dispatched ìåèüäïõò), ç êáôÜóôáóç åßíáé ðéï ðåñßðëïêç. ¼ëá ôá áíùôÝñù æçôÞìáôá éó÷ýïõí, óõí ðïëëÜ áêüìá. Ï ëüãïò åßíáé üôé êÜðïéåò ðëçñïöïñßåò õëïðïéïýíôáé êÜðùò "êñõöÜ" óôï ìåôáãëùôôéóìÝíï êþäéêá, ìå óõíÝðåéá åîáñôÞóåéò ðïõ ðéèáíüôáôá íá ìçí åßíáé ðñïöáíåßò åÜí äåí îÝñåôå ðþò õëïðïéåßôáé ôõðéêÜ ç C++. Ãéá íá êõñéïëåêôÞóïõìå, äåí åßíáé "êáéíïýñéá æçôÞìáôá", åßíáé áêñéâþò üôé ï ìåôáãëùôôéóìÝíïò êþäéêáò C++ åðçñåÜæåé ôÝôïéåò åõáßóèçôåò ðëçñïöïñßåò ìå ðïëý ðñùôüôõðïõò ôñüðïõò ðïõ ðéèáíüí íá ìçí ðÜåé ï íïõò óáò. Ï áêüëïõèïò åßíáé Ýíáò (ðéèáíþò åëëéðÞò) êáôÜëïãïò ðñáãìÜôùí ðïõ äåí ìðïñåßôå íá êÜíåôå óå C++ êáé íá äéáôçñÞóåôå binary-compatibilty ("äõáäéêÞ óõìâáôüôçôá"), üðùò áíáöÝñåôáé áðü ôï Troll Tech's Technical FAQ: 1. íá ðñïóèÝóåôå åê íÝïõ õëïðïéçìÝíåò åéêïíéêÝò óõíáñôÞóåéò (åêôüò áí åßíáé áóöáëÝò ãéá ðáëáéüôåñá binaries íá êáëïýí ôçí áñ÷éêÞ åöáñìïãÞ), åðåéäÞ ï ìåôáãëùôôéóôÞò "áîéïëïãåß" (evaluates) ôéò êëÞóåéò SuperClass::virtualFunction() êáôÜ ôç ìåôáãëþôôéóç (compile-time, ü÷é link-time). 2. íá ðñïóèÝóåôå Þ áöáéñÝóåôå virtual member functions (ëåéôïõñãßåò åéêïíéêþí ìåëþí), åðåéäÞ áõôü èá Üëëáæå ôï ìÝãåèïò êáé ôï layout ôïõ vtbl êÜèå õðïêëÜóçò. 3. íá áëëÜîåôå ôïí ôýðï ïðïéùíäÞðïôå data members (ìåëþí äåäïìÝíùí) Þ íá ìåôáêéíÞóåôå ôÝôïéá, åíþ ìðïñïýí íá ðñïóåããéóôïýí ìÝóù inline member functions. 4. íá áëëÜîåôå ôçí class ierarchy (éåñáñ÷ßá êëÜóçò), åêôüò áðü ôï ãéá íá ðñïóôåèïýí íÝá öýëëá. 5. íá ðñïóèÝóåôå Þ í' áðïìáêñýíåôå private data members (ìÝëç éäéùôéêþí óôïé÷åßùí), åðåéäÞ áõôü èá Üëëáæå ôï ìÝãåèïò êáé ôï layout êÜèå õðïêáôçãïñßáò. 6. íá áöáéñÝóôå public Þ protected member functions åêôüò áí åßíáé inline. 7. íá êáôáóôÞóôå ìéá public Þ protected member function óå inline. 8. íá áëëÜîåôå áõôü ðïõ êÜíåé ìéá inline óõíÜñôçóç, åêôüò áí ç ðáëáéÜ Ýêäïóç óõíå÷ßæåé íá ëåéôïõñãåß. 9. íá áëëÜîåôå ôá äéêáéþìáôá ðñüóâáóçò (Þôïé public, protected Þ private) ìéáò member function óå Ýíá öïñçôü (portable) ðñüãñáììá, åðåéäÞ êÜðïéïé ìåôáãëùôôéóôÝò áíôéóôïé÷ßæïõí ôá äéêáéþìáôá ðñüóâáóçò óôï üíïìá ôçò óõíÜñôçóçò. ËáìâÜíïíôáò õðüøç áõôüí ôïí ìåãÜëï êáôÜëïãï, ïé õðåýèõíïé ãéá ôçí áíÜðôõîç âéâëéïèçêþí óå C++ åéäéêüôåñá, ðñÝðåé íá ðñïó÷åäéÜæïõí éäéáßôåñá ôáêôéêÜ updates áí åßíáé íá êáôáóôñáôçãïýí ôç äõáäéêÞ óõìâáôüôçôá êáôÜ ôçí áíáíÝùóç ìéáò âéâëéïèÞêçò. Åõôõ÷þò, óôá Unix-ïåéäÞ óõóôÞìáôá (óõìðåñéëáìâáíïìÝíïõ ôïõ Linux) ìðïñåßôå íá Ý÷åôå ðïëëáðëÝò åêäüóåéò ìéáò âéâëéïèÞêçò íá öïñôþíïíôáé óõã÷ñüíùò, Ýôóé ìå ôï ìéêñü êüóôïò ôçò áðþëåéáò (ìéêñïý) äéáóôÞìáôïò óôï äßóêï, ïé ÷ñÞóôåò íá ìðïñïýí áêüìá íá ôñÝîïõí "ðáëéÜ" ðñïãñÜììáôá, ðïõ ÷ñåéÜæïíôáé ôéò ðáëáéÝò âéâëéïèÞêåò. _________________________________________________________ 4. ÄõíáìéêÝò (Dynamically Loaded - DL) âéâëéïèÞêåò Ïé äõíáìéêÝò (Þ, "äõíáìéêÜ öïñôùìÝíåò") âéâëéïèÞêåò (DL) åßíáé âéâëéïèÞêåò ðïõ öïñôþíïíôáé óå óôéãìÝò Üëëåò åêôüò áðü (êáôÜ) ôï îåêßíçìá åíüò ðñïãñÜììáôïò. Åßíáé éäéáßôåñá ÷ñÞóéìåò ãéá õëïðïßçóç plugins Þ modules, åðåéäÞ åðéôñÝðïõí áíáìïíÞ Ýôóé þóôå íá öïñôùèåß ôï plugin ìüíï üôáí áðáéôåßôáé. Ðáñáäåßãìáôïò ÷Üñéí, ôï óýóôçìá Pluggable Authentication Modules (PAM), ÷ñçóéìïðïéåß ôéò DL âéâëéïèÞêåò ãéá íá åðéôñÝøåé óôïõò äéá÷åéñéóôÝò ôïõ óõóôÞìáôïò íá "ðåéñÜîïõí" (configure) îáíÜ êáé îáíÜ ôç äéáäéêáóßá ðéóôïðïßçóçò ôáõôüôçôáò. Åßíáé åðßóçò ÷ñÞóéìïé ãéá ôçí õëïðïßçóç äéåñìçíåõôþí (interpreters) ðïõ åðéèõìïýí ðåñéóôáóéáêÜ íá ìðïñïýí íá ìåôáãëùôôßóïõí ôïí êþäéêÜ ôïõò óå êþäéêá ìç÷áíÞò êáé íá ÷ñçóéìïðïéÞóïõí ôç ìåôáãëùôôéóìÝíç Ýêäïóç ãéá ëüãïõò áðïäïôéêüôçôáò, êáé üëá ôá ðáñáðÜíù ÷ùñßò íá äéáêüøïõí ôç ëåéôïõñãßá ôïõò. Ðáñáäåßãìáôïò ÷Üñéí, áõôÞ ç ðñïóÝããéóç ìðïñåß íá åßíáé ÷ñÞóéìç óôçí åöáñìïãÞ åíüò just-in-time compiler Þ åíüò multi-user dungeon (MUD). Óôï Linux, ïé DL âéâëéïèÞêåò äåí åßíáé ðñáãìáôéêÜ "îå÷ùñéóôÝò" áðü Üðïøç ìïñöïðïßçóçò (format) ôïõëÜ÷éóôïí - äçìéïõñãïýíôáé üðùò ôá óõíÞèç object files Þ ïé äéáìïéñáæüìåíåò âéâëéïèÞêåò, üðùò óõæçôÞèçêáí ðáñáðÜíù. Ç âáóéêÞ äéáöïñÜ åßíáé üôé ïé âéâëéïèÞêåò äåí öïñôþíïíôáé áõôüìáôá êáôÜ ôï link-time Þ êáôÜ ôï îåêßíçìá åíüò ðñïãñÜììáôïò - áíô' áõôïý, õðÜñ÷åé Ýíá API (Application Programming Interface - óýóôçìá äéåðáöÞò ðñïãñáììáôéóôéêþí åöáñìïãþí) ãéá Üíïéãìá ìéáò âéâëéïèÞêçò, áíáöïñÜ óå "óýìâïëá" ôçò, äéá÷åßñéóç óöáëìÜôùí, êáé êëåßóéìï ôçò. Ïé ÷ñÞóôåò ôçò C èá ðñÝðåé íá óõìðåñéëÜâïõí ôï áñ÷åßï åðéêåöáëßäùí <dlfcn.h> ãéá íá ÷ñçóéìïðïéÞóïõí áõôü ôï ÁÑÉ. Ç äéåðáöÞ ðïõ ÷ñçóéìïðïéåßôáé áðü ôï Linux åßíáé ïõóéáóôéêÜ ç ßäéá ìå áõôÞí ðïõ ÷ñçóéìïðïéåßôáé óôï Solaris êáé ôçí ïðïßá èá áðïêáëþ "dlopen()" API. Åíôïýôïéò, áõôÞ ç äéåðáöÞ äåí õðïóôçñßæåôáé áðü üëåò ôéò ðëáôöüñìåò - ôï HP- UX ÷ñçóéìïðïéåß ôï äéáöïñåôéêü ìç÷áíéóìü shl_load (), êáé ôá Windows ÷ñçóéìïðïéïýí DLLs, ðïõ Ý÷ïõí êáé áðïëýôùò äéáöïñåôéêü interface. ÅÜí ï óôü÷ïò óáò åßíáé ôï ðñüãñáììá óáò íá åßíáé öïñçôü ôüóï ðïõ íá ìðïñåß íá ÷ñçóéìïðïéçèåß óå üëá áõôÜ ôá äéáöïñåôéêÜ óõóôÞìáôá, ïöåßëåôå ìÜëëïí íá óêåöôåßôå óïâáñÜ íá ÷ñçóéìïðïéÞóåôå êÜðïéá wrapping library ðïõ íá êñýâåé ôéò äéáöïñÝò ìåôáîý ôùí ðëáôöüñìùí. Ìéá ðñïóÝããéóç åäþ åßíáé ç âéâëéïèÞêç glib ìå ôçí õðïóôÞñéîÞ ôçò ãéá ôç äõíáìéêÞ öüñôùóç modules (DLM, Dynamic Loading of Modules) - ÷ñçóéìïðïéåß ôéò ÷áìçëüôåñïõ åðéðÝäïõ äõíáìéêÝò ñïõôßíåò öüñôùóçò ôçò ðëáôöüñìáò ãéá íá äçìéïõñãÞóåé ìéá öïñçôÞ äéåðáöÞ óå áõôÝò ôéò óõíáñôÞóåéò. Ìðïñåßôå íá ìÜèåôå ðåñéóóüôåñùí ãéá ôçí glib óôï http://developer.gnome.org/doc/API/glib/glib-dynamic-loading-o f-modules.html. ÄåäïìÝíïõ üôé ç glib äéåðáöÞ Ý÷åé ðïëý êáëÞ ôåêìçñßùóÞ (documentation), äåí èá áó÷ïëçèþ Üëëï ì' áõôÞ åäþ. Ìéá Üëëç ðñïóÝããéóç åßíáé íá ÷ñçóéìïðïéÞóåôå ôçí libltdl, ðïõ åßíáé êáé ìÝñïò ôïõ GNU libtool. ÅÜí èÝëåôå áêüìá ðåñéóóüôåñç ëåéôïõñãéêüôçôá áðü áõôÞ ðïõ óáò ðáñÝ÷ïõí ïé ðáñáðÜíù åðéëïãÝò, ßóùò èá ðñÝðåé íá ñßîåôå ìéá ìáôéÜ óå Ýíá CORBA Object Request Broker (ORB). ÅÜí ðÜëé óáò áñêåß ç áðåõèåßáò ÷ñÞóç ôïõ API ðïõ õðïóôçñßæåôáé áðü ôï Linux êáé ôï Solaris, óõíå÷ßóôå ôï äéÜâáóìá êáé ðáñáêÜôù. Ïé developers ðïõ ÷ñçóéìïðïéïýí C++ êáé äõíáìéêÝò âéâëéïèÞêåò (DL), ðñÝðåé åðßóçò íá óõìâïõëåõèïýí ôï "C++ dlopen mini-HOWTO". _________________________________________________________ 4.1. dlopen() Ç óõíÜñôçóç dlopen(3) áíïßãåé ìéá âéâëéïèÞêç êáé ôçí ðñïåôïéìÜæåé ãéá ôç ÷ñÞóç. Óôï C ôï ðñùôüôõðü ôçò åßíáé ùò åîÞò: void * dlopen(const char *filename, int flag); ÅÜí ôï üíïìá ôïõ áñ÷åßïõ îåêéíÜåé ìå "/" ( äßíåôáé ôï ðëÞñåò ìïíïðÜôé), ç dlopen() èá ðñïóðáèÞóåé áðëÜ íá ôï ÷ñçóéìïðïéÞóåé (äåí èá øÜîåé ãéá ìéá âéâëéïèÞêç). ÄéáöïñåôéêÜ, èá øÜîåé ãéá ôç âéâëéïèÞêç áêïëïõèþíôáò ôçí åîÞò óåéñÜ âçìÜôùí: 1. Èá ôçí áíáæçôÞóåé óôïõò êáôáëüãïõò ðïõ ðåñéÝ÷ïíôáé ( ÷ùñéóìÝíïé ìå Üíù êáé êÜôù ôåëåßá) óôç ìåôáâëçôÞ ðåñéâÜëëïíôïò LD_LIBRARY_PATH ôïõ ÷ñÞóôç. 2. Èá øÜîåé åÜí åßíáé áíÜìåóá óôéò âéâëéïèÞêåò ðïõ ðñïóäéïñßæïíôáé áðü ôï áñ÷åßï /etc/ld.so.cache (ðïõ äçìéïõñãåßôáé áðü ôï ld.so.conf). 3. Èá åëÝãîåé óôïí êáôÜëïãï /usr/lib. ÓõãêñáôÞóôå ãéá ëßãï ôç óåéñÜ ðïõ áêïëïõèÞèçêå åäþ: åßíáé ç áíôßóôñïöç áðü ôç óåéñÜ ðïõ áêïëïõèïýóå ï ðáëéüò a.out loader. Ï ðáëéüò loader, êáôÜ ôç öüñôùóç åíüò ðñïãñÜììáôïò, Ýøá÷íå áñ÷éêÜ óôïí êáôÜëïãï /usr/lib, Ýðåéôá óôïí /lib (âë. man page ld.so(8)). Áõôü êáíïíéêÜ äå èá 'ðñåðå íá ðåéñÜæåé , äåäïìÝíïõ üôé ìéá âéâëéïèÞêç ðñÝðåé íá âñßóêåôáé óå Ýíáí ìüíï áðü ôïõò äõï êáôáëüãïõò áñ÷åßùí (ðïôÝ êáé óôïõò äýï), êáé äéáöïñåôéêÝò âéâëéïèÞêåò ìå ôï ßäéï üíïìá áðëÜ åßíáé ç êáôáóôñïöÞ ðïõ ðÜíôá ðåñéìÝíåé óôç ãùíßá. Óôçí dlopen(), ç ôéìÞ ôçò ðáñáìÝôñïõ flag ðñÝðåé íá åßíáé åßôå RTLD_LAZY, Þôïé "íá ðñïóäéïñéóôïýí ôá áðñïóäéüñéóôá óýìâïëá (unresolved symbols) êáèþò ï êþäéêáò áðü ôç äõíáìéêÞ âéâëéïèÞêç åêôåëåßôáé", åßôå RTLD_NOW, äçëáäÞ "íá ðñïóäéïñéóôïýí ðñïôïý ç dlopen() åðéóôñÝøåé êáé, åÜí áõôü äåí åßíáé äõíáôüí, íá èåùñçèåß ðùò ç óõíÜñôçóç áðÝôõ÷å". Óôçí ôéìÞ RTLD_GLOBAL ðÜëé, ìðïñåß ðñïáéñåôéêÜ íá åöáñìïóôåß ï ëïãéêüò ôåëåóôÞò OR ìå ïðïéáäÞðïôå ôéìÞ ôçò flag, óçìáßíïíôáò üôé ôá åîùôåñéêÜ óýìâïëá (external symbols) ðïõ êáèïñßæïíôáé óôç âéâëéïèÞêç èá ôåèïýí óôçí äéÜèåóç âéâëéïèçêþí ðïõ èá öïñôùèïýí óôç óõíÝ÷åéá. ÊáôÜ ôï debugging, èá èåëÞóåôå ðéèáíþò íá ÷ñçóéìïðïéÞóåôå ôçí RTLD_NOW - ç ÷ñÞóç ôçò RTLD_LAZY ìðïñåß íá äçìéïõñãÞóåé óöÜëìáôá ðïõ äåí ìðïñïýí íá åíôïðéóôïýí åÜí õðÜñ÷ïõí åêêñåìåßò áíáöïñÝò (unresolved references). Ç ÷ñÞóç ôçò RTLD_NOW êÜíåé ôï Üíïéãìá ôçò âéâëéïèÞêçò åëáöñþò ðéï áñãü (áëëÜ åðéôá÷ýíåé ôéò áíáæçôÞóåéò áñãüôåñá) - åÜí áõôü óáò ðñïêáëåß ðñüâëçìá, ìðïñåßôå íá áëëÜîåôå ðÜëé óå RTLD_LAZY áñãüôåñá. ÅÜí ïé âéâëéïèÞêåò åîáñôþíôáé ç ìéá áðü ôçí Üëëç (ð.÷. ç × åîáñôÜôáé áðü ôçí Õ), ðñÝðåé íá öïñôþóåôå ôéò åîáñôçìÝíåò âéâëéïèÞêåò äåýôåñåò óôç óåéñÜ (óå áõôü ôï ðáñÜäåéãìá, ôï Õ ðñþôá, êáé Ýðåéôá X). Ç ôéìÞ ðïõ åðéóôñÝöåé ç dlopen() åßíáé Ýíá "handle" ðïõ ãéá íá ÷ñçóéìïðïéçèåß áðü ñïõôßíåò Üëëùí DL âéâëéïèçêþí ðñÝðåé íá èåùñçèåß "áäéáöáíÞò ôéìÞ" (opaque value). Ç dlopen() èá åðéóôñÝøåé NULL åÜí ç ðñïóðÜèåéá ôçò íá öïñôþóåé äåí ðåôý÷åé, ðñÜãìá ôï ïðïßï ðñÝðåé íá åëÝãîåôå. ÅÜí ç ßäéá âéâëéïèÞêç ãßíåé áðüðåéñá íá öïñôùèåß ðåñéóóüôåñåò áðü ìßá öïñÜ ìå ôçí dlopen(), åðéóôñÝöåôáé ôï ßäéï file handle. Óôá ðáëáéüôåñá óõóôÞìáôá, åÜí ç âéâëéïèÞêç ìïéñÜæåôáé ("åîÜãåé" - exports) ìéá ñïõôßíá ìå ôçí ïíïìáóßá _init, ï êþäéêáò ôçò åêôåëåßôáé ðñéí åðéóôñÝøåé ç dlopen(). Ìðïñåßôå íá ÷ñçóéìïðïéÞóåôå áõôü ôï ãåãïíüò óôéò âéâëéïèÞêåò óáò ãéá íá õëïðïéÞóåôå ñïõôßíåò áñ÷éêïðïßçóçò. Ùóôüóï, ïé âéâëéïèÞêåò äåí ðñÝðåé íá "åîÜãïõí" ôéò ñïõôßíåò ìå ôçí üíïìá _init Þ _fini. Áõôïß ïé ìç÷áíéóìïß åßíáé îåðåñáóìÝíïé, êáé ìðïñåß íá ïäçãÞóïõí óå áíåðéèýìçôç óõìðåñéöïñÜ. Áíô' áõôïý, ïé âéâëéïèÞêåò ðñÝðåé íá åîáãÜãïõí ôéò ñïõôßíåò ÷ñçóéìïðïéþíôáò ôéò éäéüôçôåò óõíáñôÞóåùí __attribute__((constructor)) êáé __attribute__((destructor)) (äåäïìÝíïõ üôé ÷ñçóéìïðïéåßôáé ôïí gcc). Äåßôå ôçí ðáñÜãñáöï ÔìÞìá 5.2 ãéá ðåñéóóüôåñåò ðëçñïöïñßåò. _________________________________________________________ 4.2. dlerror() Ãéá ôçí áíáöïñÜ óöáëìÜôùí ìðïñåß íá ÷ñçóéìïðïéçèåß ç dlerror (), ðïõ åðéóôñÝöåé ìéá óõìâïëïóåéñÜ ç ïðïßá ðåñéãñÜöåé ôï óöÜëìá áðü ôçí ôåëåõôáßá êëÞóç êÜðïéáò åê ôùí dlopen(), dlsym (), Þ dlclose (). Åßíáé áîéïðñüóåêôï ôï ãåãïíüò ðùò ìåëëïíôéêÝò êëÞóåéò (ìåôÜ áðü êÜðïéá åðéôõ÷Þ) óôçí dlerror() èá åðéóôñÝöïõí NULL, Ýùò üôïõ åìöáíéóôåß Ýíá Üëëï óöÜëìá. _________________________________________________________ 4.3. dlsym() Ôï íá öïñôþóåé êáíåßò ìéá äõíáìéêÞ âéâëéïèÞêç äå èá åß÷å êáìßá óçìáóßá åÜí äåí ìðïñïýóå íá êÜíåé ÷ñÞóç áõôÞò ôçò óõíÜñôçóçò. Ç âáóéêÞ ñïõôßíá ãéá ôç ÷ñçóéìïðïßçóç ìéáò DL âéâëéïèÞêçò åßíáé ç dlsym (3), üðïéá áíáæçôÜ ôçí ôéìÞ åíüò óõìâüëïõ óå ìéá äåäïìÝíç (áíïéãìÝíç) âéâëéïèÞêç. ÁõôÞ ç óõíÜñôçóç ïñßæåôáé ùò åîÞò: void * dlsym(void *handle, char *symbol); üðïõ ôï handle åßíáé ç ôéìÞ ðïõ åðéóôñÝöåé ç dlopen(), êáé ôï symbol åßíáé ìéá óõìâïëïóåéñÜ ( NIL-terminated - ôåëåéþíåé ìå NIL). ÅÜí ìðïñåßôå íá ôï êÜíåôå, áðïöýãåôå íá êáôá÷ùñÞóôå ôçí ôéìÞ ðïõ åðéóôñÝöåé ç dlsym() óå äåßêôç void *, åðåéäÞ Ýðåéôá èá ðñÝðåé íá êÜíåôå casting êÜèå öïñÜ ðïõ ôç ÷ñçóéìïðïéåßôå (êáé èá äþóåôå ëéãüôåñåò ðëçñïöïñßåò óå Üëëïõò áíèñþðïõò ðïõ ðñïóðáèïýí íá óõíôçñÞóïõí ôï ðñüãñáììá). Ç dlsym() èá åðéóôñÝøåé NULL åÜí ôï óýìâïëï äåí âñÝèçêå. ÅÜí îÝñåôå üôé ôï óýìâïëï äåí èá ìðïñïýóå ðïôÝ íá Ý÷åé ôçí ôéìÞ NULL Þ ìçäÝí, ôï áðïôÝëåóìá áõôü äåí ìáò åíï÷ëåß, ìá äéáöïñåôéêÜ ìðïñåß íá äçìéïõñãÞóåé ìðÝñäåìá: åÜí åðåóôñÜöç ìçäÝí, áõôü óçìáßíåé ðùò äåí õðÜñ÷åé êáíÝíá ôÝôïéï óýìâïëï, Þ ðùò ç ôéìÞ ôïõ åßíáé ìçäÝí; Ç ðñüôõðç ëýóç åßíáé íá êëçèåß ç dlerror() ðñþôá (ãéá íá êáèáñßóåé ïðïéïäÞðïôå óöÜëìá åß÷å ßóùò íùñßôåñá êáôáãñáöåß), êáôüðéí íá êëçèåß ç dlsym() ãéá íá æçôÞóåé Ýíá óýìâïëï, êáé ôÝëïò ðÜëé ç dlerror() ãéá íá åëåã÷èåß ðùò äåí ðñïÝêõøå êÜðïéï óöÜëìá. Ôá ðáñáðÜíù óå êþäéêá èá Þôáí êÜðùò Ýôóé: dlerror(); /* clear error code */ s = (actual_type) dlsym(handle, symbol_being_searched_for); if ((err = dlerror()) != NULL) { /* handle error, the symbol wasn't found */ } else { /* symbol found, its value is in s */ } _________________________________________________________ 4.4. dlclose() Tï áíôßóôñïöï ôçò dlopen() åßíáé ç dlclose(), ç üðïéá êëåßíåé ìéá äõíáìéêÞ âéâëéïèÞêç. Ç äõíáìéêÞ âéâëéïèÞêç óõãêñáôåß Ýíáí áñéèìü óõíäÝóåùí ãéá ôá äõíáìéêÜ file handles, Ýôóé äåí áðåëåõèåñþíåôáé (deallocated) ðñáãìáôéêÜ Ýùò üôïõ ç dlclose() êëçèåß ôüóåò öïñÝò üóåò êáé ç dlopen() ãéá ôç óõãêåêñéìÝíç âéâëéïèÞêç. ÊáôÜ óõíÝðåéá, äåí åßíáé ðñüâëçìá ãéá ôï ßäéï ðñüãñáììá íá öïñôùèïýí ïé ßäéåò âéâëéïèÞêåò ðïëëÝò öïñÝò. ¼ôáí ìéá âéâëéïèÞêç áðåëåõèåñþíåôáé, êáëåßôáé ç óõíÜñôçóç ôçò _fini (åÜí õðÜñ÷åé) óôéò ðáëéüôåñåò âéâëéïèÞêåò, áëëÜ ï ðáñáðÜíù åßíáé Ýíáò îåðåñáóìÝíïò ìç÷áíéóìüò êáé äåí èá ðñÝðåé íá âáóéóôåßôå óå áõôüí. Áíô' áõôïý, ïé âéâëéïèÞêåò ðñÝðåé íá åîáãÜãïõí ñïõôßíåò (export routines) ÷ñçóéìïðïéþíôáò ôéò éäéüôçôåò óõíáñôÞóåùí (function attributes) __attribute__((constructor)) êáé __attribute__((destructor)). Äåßôå ôçí ðáñÜãñáöï ÔìÞìá 5.2 ãéá ðåñéóóüôåñåò ðëçñïöïñßåò. Óçìåßùóç: Ç dlclose() åðéóôñÝöåé 0 áí ïëïêëçñþóåé åðéôõ÷þò, êáé êÜðïéá ôéìÞ äéÜöïñç ôïõ ìçäåíüò óå áíôßèåôç ðåñßðôùóç, ðñÜãìá ôï ïðïßï äåí áíáöÝñåôáé óå ìåñéêÝò man pages ôïõ Linux. _________________________________________________________ 4.5. ÐáñÜäåéãìá äõíáìéêÞò âéâëéïèÞêçò Ôï áêüëïõèï ðáñÜäåéãìá õðÜñ÷åé êáé óôçí man page ôçò dlopen(3). Óå áõôü ôï ðáñÜäåéãìá öïñôþíåôáé ç âéâëéïèÞêç math, ôõðþíåôáé ôï óõíçìßôïíï ôïõ 2.0, êáé ãßíåôáé åëÝã÷ïò ãéá óöÜëìáôá óå êÜèå âÞìá (êÜôé ôï ïðïßï óõóôÞíåôáé áíåðéöýëáêôá): #include <stdlib.h> #include <stdio.h> #include <dlfcn.h> int main(int argc, char **argv) { void *handle; double (*cosine)(double); char *error; handle = dlopen ("/lib/libm.so.6", RTLD_LAZY); if (!handle) { fputs (dlerror(), stderr); exit(1); } cosine = dlsym(handle, "cos"); if ((error = dlerror()) != NULL) { fputs(error, stderr); exit(1); } printf ("%f\n", (*cosine)(2.0)); dlclose(handle); } ÅÜí ôï ðáñáðÜíù ðñüãñáììá Þôáí óå Ýíá áñ÷åßï ìå üíïìá "foo.c", èá êÜíáôå build ìå ôçí áêüëïõèç åíôïëÞ: gcc -o foo foo.c -ldl _________________________________________________________ 5. ÄéÜöïñá 5.1. Ç åíôïëÞ nm Ç åíôïëÞ nm(1) ìðïñåß íá ðáñáèÝóåé ôç ëßóôá óõìâüëùí óå ìéá äåäïìÝíç âéâëéïèÞêç. Ëåéôïõñãåß ôüóï ãéá ôéò óôáôéêÝò üóï êáé ãéá ôéò äéáìïéñáæüìåíåò âéâëéïèÞêåò. Ãéá ìéá äåäïìÝíç âéâëéïèÞêç ç nm(1) ìðïñåß íá åìöáíßóåé ìéá ëßóôá ìå ôá ïíüìáôá ôùí óõìâüëùí ðïõ Ý÷ïõí ïñéóôåß, ôçí ôéìÞ êÜèå óõìâüëïõ, êáé ôïí ôýðï ôïõ. Ìðïñåß åðßóçò íá ðñïóäéïñßóåé ôï óçìåßï óôïí ðçãáßï êþäéêá ôçò âéâëéïèÞêçò üðïõ ôï óýìâïëï ïñßóôçêå(ìå âÜóç üíïìá áñ÷åßïõ êáé áñéèìü ãñáììÞò), åÜí ïé áíôßóôïé÷åò ðëçñïöïñßåò Ý÷ïõí åíóùìáôùèåß óôç âéâëéïèÞêç (âë. - ðñïáéñåôéêÞ ðáñÜìåôñïò -l). Ç ðëçñïöïñßá ôçò nm ðïõ áöïñÜ ôùí ôýðï ôùí óõìâüëùí (symbol type) áðáéôåß ëßãï ðåñéóóüôåñç åðåîÞãçóç. Ï ôýðïò ðáñïõóéÜæåôáé ùò Ýíá ãñÜììá : ìéêñÜ ãñÜììáôá óçìáßíïõí üôé ôï óýìâïëï åßíáé ôïðéêü (local), åíþ êåöáëáßá üôé ôï óýìâïëï åßíáé êáèïëéêü (åîùôåñéêü - global,external). Ïé ÷áñáêôçñéóôéêïß ôýðïé óõìâüëùí ðåñéëáìâÜíïõí ôï T (ôï óýìâïëï Ý÷åé áðëÜ ïñéóôåß óå áíôßóôïé÷ï óçìåßï óôïí êþäéêá), ôï D(áíÞêåé óôï ôìÞìá ìå ôá áñ÷éêïðïéçìÝíá äåäïìÝíá), ôï  (ôï óýìâïëï áíÞêåé óôï ôìÞìá ìå ôá ìç áñ÷éêïðïéçìÝíá óýìâïëá), ôï U(áðñïóäéüñéóôï - ôï óýìâïëï ÷ñçóéìïðïéåßôáé áðü ôç âéâëéïèÞêç áëëÜ äåí ïñßæåôáé óå áõôÞ), êáé ôï W("áäýíáìï -weak- óýìâïëï": åÜí ìéá Üëëç âéâëéïèÞêç êáèïñßæåé åðßóçò áõôü ôï óýìâïëï, åêåßíïò ï êáèïñéóìüò õðåñéó÷ýåé áõôïý). ÅÜí îÝñåôå ôï üíïìá ìéáò óõíÜñôçóçò, áëëÜ äåí ìðïñåßôå íá èõìçèåßôå óå ðïéá âéâëéïèÞêç êáèïñßóôçêå, ìðïñåßôå íá ÷ñçóéìïðïéÞóåôå ôçí ðñïáéñåôéêÞ ðáñÜìåôñï "-ï" ôçò nm (ðïõ ðñïôÜóóåé ôï üíïìá áñ÷åßïõ óå êÜèå ãñáììÞ) ìáæß ìå ôç grep ãéá íá âñåßôå ôï üíïìá ôçò âéâëéïèÞêçò. Áðü Ýíá Bourne shell, ìðïñåßôå íá øÜîåôå üëåò ôéò âéâëéïèÞêåò óôïõò êáôáëüãïõò /lib, /usr/lib, óõìðåñéëáìâáíïìÝíùí ôùí (direct) õðïêáôáëüãùí ôïõ /usr/lib, êáé óôïí /usr/local/lib ãéá ôï "cos" ùò åîÞò: nm -o /lib/* /usr/lib/* /usr/lib/*/* \ /usr/local/lib/* 2> /dev/null | grep 'cos$' Ðïëý ðåñéóóüôåñåò ðëçñïöïñßåò ãéá ôçí nm ìðïñïýí íá âñåèïýí óôçí áíôßóôïé÷ç ôåêìçñßùóç ðïõ åãêáèßóôáôáé ôïðéêÜ óôï info:binutils#nm. _________________________________________________________ 5.2. ÓõíáñôÞóåéò êáôáóêåõáóôþí (constructor) êáé êáôáóôñïöÝùí (destructor) âéâëéïèÞêçò Ïé âéâëéïèÞêåò ðñÝðåé íá åîáãÜãïõí ôéò ñïõôßíåò áñ÷éêïðïßçóçò (initialization) êáé "êáèáñéóìïý" (cleanup) ÷ñçóéìïðïéþíôáò ôéò gcc__attribute__((constructor)) êáé gcc__attribute__((destructor)). Äåßôå ôéò info pages ôïõ gcc ãéá ó÷åôéêÝò ðëçñïöïñßåò. Ïé ñïõôßíåò ôùí constructors åêôåëïýíôáé ðñéí åðéóôÝøåé ç dlopen() (Þ ðñïôïý áñ÷ßóåé ç main(), åÜí ç âéâëéïèÞêç öïñôþíåôáé êáôÜ ôï load time). Ïé ñïõôßíåò ôùí destructors åêôåëïýíôáé ðñéí åðéóôñÝøåé ç dlclose (Þ ìåôÜ áðü ôçí exit() Þ ôçí ïëïêëÞñùóç ôçò main(), åÜí ç âéâëéïèÞêç öïñôþíåôáé êáôÜ ôï load time). Ôá ðñùôüôõðá ôçò C (C prototypes) ãéá áõôÝò ôéò ëåéôïõñãßåò åßíáé: void __attribute__ ((constructor)) my_init(void); void __attribute__ ((destructor)) my_fini(void); Ïé êïéíÝò âéâëéïèÞêåò äåí ðñÝðåé íá ìåôáãëùôôéóôïýí ìå ôá ïñßóìáôá ôïõ gcc "- nostartfiles" Þ "-nostdlib". ÅÜí ÷ñçóéìïðïéçèïýí áõôÜ ôá ïñßóìáôá, ïé ñïõôßíåò êáôáóêåõáóôþí/êáôáóôñïöÝùí äåí èá åêôåëåóèïýí (åêôüò áí ëåéöèïýí åéäéêÜ ìÝôñá). _________________________________________________________ 5.2.1. ÅéäéêÝò óõíáñôÞóåéò _init êáé _fini (ÐÁÑÙ×ÇÌÅÍÏ/ÅÐÉÊÉÍÄÕÍÏ) ÉóôïñéêÜ Ý÷ïõí õðÜñîåé äýï åéäéêÜ óõíáñôÞóåéò, ïé _init êáé _fini, ðïõ ìðïñïýí íá ÷ñçóéìïðïéçèïýí ãéá íá åëÝãîïõí ôïõò êáôáóêåõáóôÝò êáé ôïõò êáôáóôñïöåßò. Åíôïýôïéò, åßíáé îåðåñáóìÝíåò, êáé ç ÷ñÞóç ôïõò ìðïñåß íá ïäçãÞóåé óå áðñüâëåðôá áðïôåëÝóìáôá. Ïé âéâëéïèÞêåò óáò äåí ðñÝðåé íá ôéò ÷ñçóéìïðïéÞóïõí - ÷ñçóéìïðïéÞóôå ôïí êáôáóêåõáóôÞ êáé ôïí êáôáóôñïöÝá éäéïôÞôùí óõíáñôÞóåùí (function attributes constructor/destructor) ðïõ ðáñïõóéÜóèçêáí áíùôÝñù áíô' áõôïý. ÅÜí ðñÝðåé ïðùóäÞðïôå íá åñãáóôåßôå ìå ðáëéÜ óõóôÞìáôá Þ êþäéêá ðïõ ÷ñçóéìïðïéïýóå _init Þ _fini, áêïëïõèåß ìéá ðåñéãñáöÞ ãéá ôïí ôñüðï ëåéôïõñãßáò ôïõò. Äýï åéäéêÝò ëåéôïõñãßåò êáèïñßóôçêáí ãéá ôçí áñ÷éêïðïßçóç êáé ôçí ðåñÜôùóç åíüò module: ïé _init êáé _fini. ÅÜí ìéá ëåéôïõñãßá ``_init '' åîÜãåôáé (is exported) óå ìéá âéâëéïèÞêç, ôüôå êáëåßôáé üôáí ðñùôïáíïßãåôáé ç âéâëéïèÞêç (ìÝóù ôçò dlopen() Þ áðëÜ ùò äéáìïéñáæüìåíç âéâëéïèÞêç). Óå Ýíá ðñüãñáììá C, áõôü áðëÜ óçìáßíåé ðùò ïñßóáôå (defined) êÜðïéá ëåéôïõñãßá ðïõ ïíïìÜóôçêå _init. ÕðÜñ÷åé ìéá áíôßóôïé÷ç ëåéôïõñãßá áðïêáëïýìåíç _fini, ðïõ êáëåßôáé üðïôå Ýíáò ÷ñÞóôçò ôåëåéþíåé ìå ôç ÷ñÞóç ôçò âéâëéïèÞêçò (ìÝóù ìéáò êëÞóçò óôçí dlclose() ðïõ öÝñíåé ôïí áñéèìü óõíäÝóåùí ôçò óôï ìçäÝí -âë. dlclose(), Þ ìå ôçí êáíïíéêÞ Ýîïäï ôïõ ðñïãñÜììáôïò). Ôá ðñùôüôõðá ôçò C ãéá áõôÝò ôéò óõíáñôÞóåéò åßíáé: void _init(void); void _fini(void); Óå áõôÞí ôçí ðåñßðôùóç, êáôÜ ôç ìåôáãëþôôéóç ôïõ áñ÷åßïõ óå Ýíá ".o" áñ÷åßï óôï gcc, óéãïõñåõôåßôå ðùò ðñïóèÝóáôå ôçí ðñïáéñåôéêÞ ðáñÜìåôñï ôïõ gcc "- nostartfiles". Áõôü åìðïäßæåé ôï ìåôáãëùôôéóôÞ ôçò C íá óõíäÝóåé (linking) ôéò âéâëéïèÞêåò åêêßíçóçò ôïõ óõóôÞìáôïò óôï áñ÷åßï. ÄéáöïñåôéêÜ, èá ðÜñåôå Ýíá óöÜëìá "multiple-definition" ("ðïëëáðëüò-ïñéóìüò"). Óçìåéþóôå ðùò ôá ðáñáðÜíù åßíáé êÜôé åíôåëþò äéáöïñåôéêü áðü ôï íá ìåôáãëùôôßæåôå modules ðïõ ÷ñçóéìïðïéïýí ôéò óõíéóôþìåíåò éäéüôçôåò óõíáñôÞóåùí. Ïé åõ÷áñéóôßåò ìïõ óôïí Jim Mischel êáé ôïí Tim Gentry ãéá ôçí ðñüôáóÞ ôïõò íá ðñïóôåèåß áõôÞ ç êïõâÝíôá ãýñù áðü ôéò óõíáñôÞóåéò _init êáé _fini, êáèþò åðßóçò êáé ãéá ôç âïÞèåéá ôïõò óôç äçìéïõñãßá ôçò. _________________________________________________________ 5.3. Ïé äéáìïéñáæüìåíåò âéâëéïèÞêåò ìðïñåß íá åßíáé áñ÷åßá åíôïëþí (scripts ) Áîßæåé íá óçìåéùèåß üôé ï GNU loader åðéôñÝðåé ïé êïéíÝò âéâëéïèÞêåò íá åßíáé áñ÷åßá åíôïëþí (script files) ðïõ ÷ñçóéìïðïéïýí ìéá åîåéäéêåõìÝíç scripting ãëþóóá, áíôß ôçò óõíçèéóìÝíçò ìïñöÞò âéâëéïèçêþí. Áõôü åßíáé ÷ñÞóéìï ãéá ôçí Ýììåóç óýíäåóç ìå Üëëåò âéâëéïèÞêåò. Ðáñáäåßãìáôïò ÷Üñéí, ïñßóôå ç ëßóôá /usr/lib/libc.so óå Ýíá áðü ôá óõóôÞìáôÜ ìïõ: /* GNU ld script Use the shared library, but some functions are only in the static library, so try that secondarily. */ GROUP ( /lib/libc.so.6 /usr/lib/libc_nonshared.a ) Ãéá ðåñéóóüôåñåò ðëçñïöïñßåò ó÷åôéêÜ, äåßôå ôçí ôåêìçñßùóç texinfo óôá scripts ôïõ ld linker (ld ãëþóóá åíôïëþí). Ïé ãåíéêÝò ðëçñïöïñßåò åßíáé óôç èÝóç info:ld#Options êáé info:ld#Commands, ìå ôéò ðéèáíÝò åíôïëÝò íá óõæçôïýíôáé óôï info:ld#Option Commands. _________________________________________________________ 5.4. Åêäüóåéò óõìâüëùí (Symbol versioning) êáé Áñ÷åßùí åíôïëþí Ýêäïóçò (Version scripts) ÔõðéêÜ, áíáöïñÝò óå åîùôåñéêÝò óõíáñôÞóåéò (external functions) åßíáé äåí åßíáé "ðñïóäåìÝíåò" (bound) êáôÜ ôçí åêêßíçóç ìéáò åöáñìïãÞò, áëëÜ ãßíïíôáé üôáí ÷ñåéáóôåß. ÅÜí ìéá êïéíÞ âéâëéïèÞêç äåí åßíáé ðñüóöáôá áíáíåùìÝíç (out of date), ìðïñåß íá ëåßðåé Ýíá áðáñáßôçôï interface- üôáí ç åöáñìïãÞ ðñïóðáèÞóåß íá ôï ÷ñçóéìïðïéÞóåé, ìðïñåß îáöíéêÜ êáé áðñïóäüêçôá íá áðïôý÷åé. Ìéá ëýóç óå áõôü ôï ðñüâëçìá åßíáé ç ÷ñÞóç symbol versioning (åêäüóåéò óõìâüëùí) ìáæß ìå ôá version scripts (áñ÷åßá åíôïëþí Ýêäïóçò). Ìå ôï symbol versioning, ï ÷ñÞóôçò ìðïñåß íá äå÷èåß ìéá ðñïåéäïðïßçóç üôáí áñ÷ßæåé ôï ðñüãñáììá ôïõ åÜí ïé âéâëéïèÞêåò ðïõ ÷ñçóéìïðïéïýíôáé ìå ôçí åöáñìïãÞ åßíáé ðÜñá ðïëý ðáëéÝò. Ìðïñåßôå íá ìÜèåôå ðåñéóóüôåñá ó÷åôéêÜ áðü ìéá óõæÞôçóç óôï åã÷åéñéäßïõ ôïõ ld (man) ãéá ôá vesrion scripts óôï http://www.gnu.org/manual/ld-2.9.1/html_node/ld_25.html. _________________________________________________________ 5.5. GNU libtool ÅÜí ÷ôßæåôå ìéá åöáñìïãÞ ðïõ èá èÝëáôå íá ìðïñåß íá ìåôáöåñèåß êáé íá ëåéôïõñãÞóåé óå ðïëëÜ óõóôÞìáôá, ßóùò èåëÞóåôå íá èåùñÞóåôå ôï GNU libtool ãéá íá ÷ôßóåôå êáé íá åãêáôáóôÞóåôå ôéò âéâëéïèÞêåò. Ôï GNU libtool åßíáé Ýíá ãåíéêü áñ÷åßï åíôïëþí õðïóôÞñéîçò âéâëéïèçêþí (generic library support script). Ôï libtool êñýâåé ôçí ðïëõðëïêüôçôá ôçò ÷ñçóéìïðïßçóçò ôùí äéáìïéñáæüìåíùí âéâëéïèçêþí ðßóù áðü ìéá óõíåðÞ, öïñçôÞ äéåðáöÞ. ÅðéðëÝïí ðáñÝ÷åé öïñçôÜ interfaces ãéá ôç äçìéïõñãßá object files, óôáôéêÝò êáé äéáìïéñáæüìåíåò âéâëéïèÞêåò óõíäÝóåùí (link libraries), óýíäåóç åêôåëÝóéìùí (link executables), áðïóöáëìÜôùóç åêôåëÝóéìùí (debug executables), åãêáôÜóôáóç âéâëéïèçêþí êáé åãêáôÜóôáóç åêôåëÝóéìùí. ÐåñéëáìâÜíåé åðßóçò ôï libltdl, Ýíá ðåñéôýëéãìá öïñçôüôçôáò (portability wrapper) ãéá ôá äõíáìéêÜ ðñïãñÜììáôá öüñôùóçò (dynamic loading programs). Ãéá ðåñéóóüôåñåò ðëçñïöïñßåò, äåßôå ôçí ôåêìçñßùóÞ ôïõ óôï http://www.gnu.org/software/libtool/manual.html _________________________________________________________ 5.6. Áöáßñåóç óõìâüëùí ãéá åîïéêïíüìçóç ÷þñïõ ¼ëá ôá óýìâïëá ðïõ óõìðåñéëáìâÜíïíôáé óôá ðáñáãüìåíá áñ÷åßá åßíáé ÷ñÞóéìá ãéá ôï debugging, áëëÜ ðéÜíïõí ÷þñï. ÅÜí ÷ñåéÜæåóôå ÷þñï, ìðïñåßôå íá áðïìáêñýíåôå ìåñéêÜ. Ç êáëýôåñç ðñïóÝããéóç åßíáé ðáñá÷èïýí áñ÷éêÜ ôá object files êáíïíéêÜ, êáé êÜíåôå üëï ôï debugging êáé ôéò äïêéìÝò ðñþôá (ç áðïóöáëìÜôùóç êáé ïé äïêéìÝò ãßíïíôáé ðïëý ðéï åýêïëá ìå ôç âïÞèåéá ôïõò). Êáôüðéí, ìüëéò åîåôÜóåôå ôï ðñüãñáììá ëåðôïìåñþò, ÷ñçóéìïðïéåßôå ôçí strip(1) ãéá íá áöáéñÝóåôå ôá óýìâïëá. Ç åíôïëÞ strip(1) óáò äßíåé ðëÞñç Ýëåã÷ï óôçí áðïìÜêñõíóç ôùí óõìâüëùí ðïõ èÝëåôå - äåßôå ôçí ôåêìçñßùóÞ ôçò ãéá ëåðôïìÝñåéåò. Ìéá Üëëç ðñïóÝããéóç åßíáé íá ÷ñçóéìïðïéçèïýí ïé ðñïáéñåôéêÝò ðáñÜìåôñïé "-s" êáé "-s" ôïõ GNU ld - ç "-S" ðáñáëåßðåé ôéò ðëçñïöïñßåò óõìâüëùí ãéá ôïí debugger (áëëÜ ü÷é ãá üëá ôá óýìâïëá) áðü ôï áñ÷åßï åîüäïõ, åíþ ç "-s" ðáñáëåßðåé üëåò ôéò ðëçñïöïñßåò óõìâüëùí áðü ôï áñ÷åßï åîüäïõ. Ìðïñåßôå íá êáëÝóåôå áõôÝò ôéò ðñïáéñåôéêÝò äõíáôüôçôåò ìÝóù ôïõ gcc ùò "-Wl,-S" êáé "-Wl,-s". ÅÜí ðÜíôá áðïìáêñýíåôå ôá óýìâïëá êáé áõôÝò ïé åðéëïãÝò óáò êáëýðôïõí, áéóèáíèåßôå åëåýèåñïò íá ôéò ÷ñçóéìïðïéåßôå, áí êáé ðáñáìÝíåé ìéá ëéãüôåñï "åëáóôéêÞ" ðñïóÝããéóç. _________________________________________________________ 5.7. ÅîáéñåôéêÜ ìéêñÜ åêôåëÝóéìá ºóùò âñåßôå ôï paper Whirlwind Tutorial on Creating Really Teensy ELF Executables for Linux ðïëý ÷ñÞóéìï. ÐåñéãñÜöåé ðþò íá öôéÜîåôå Ýíá ðñáãìáôéêÜ ìéêñïóêïðéêü åêôåëÝóéìï ðñïãñÜììáôïò . Åäþ ðïõ ôá ëÝìå, äåí ðñÝðåé íá ÷ñçóéìïðïéÞóåôå ôá ðåñéóóüôåñá áðü ôá ôå÷íÜóìáôá ðïõ ðåñéãñÜöåé êÜôù áðü ðñáãìáôéêÝò óõíèÞêåò, áëëÜ åßíáé áñêåôÜ áíáëõôéêÜ óôçí åðßäåéîç ôïõ ðñáãìáôéêïý ôñüðïõ ëåéôïõñãßáò ôùí ELF. _________________________________________________________ 5.8. C++ åíáíôßïí C Áîßæåé íá óçìåéùèåß ðùò åÜí ãñÜöåôå Ýíá ðñüãñáììá óå C++, êáé êáëåßôå ìéá óõíÜñôçóç áðü ìéá âéâëéïèÞêç óå C, óôïí C++ êþäéêá óáò èá ðñÝðåé íá êáèïñßóåôå ôç ëåéôïõñãßá C ùò "extern C". ÄéáöïñåôéêÜ, ï linker äåí èá åßíáé óå èÝóç íá åíôïðßóåé ôç óõíÜñôçóç C. ÅóùôåñéêÜ, ïé compilers ôçò C++ "êáôáêñåïõñãïýí" ("mangle") ôá ïíüìáôá ôùí óõíáñôÞóåùí óôçí C++ (ð.÷., ãéá ëüãïõò ôõðïðïßçóçò), êáé ðñÝðåé íá ôïõò åéðùèåß ñçôÜ üôé ìéá äåäïìÝíç ëåéôïõñãßá ðñÝðåé íá êëçèåß ùò ëåéôïõñãßá ôçò C (þóôå íá ìçí êÜíïõí êÜôé ôÝôïéï). ÅÜí ãñÜöåôå ìéá âéâëéïèÞêç ðñïãñÜììáôïò ðïõ èá ìðïñïýóå íá êëçèåß áðü C Þ C ++, óõíéóôÜôáé íá ðåñéëáìâÜíåôå ôéò åíôïëÝò "extern C" áêñéâþò óôá áñ÷åßá åðéêåöáëßäùí óáò, Ýôóé þóôå íá ôï êÜíåôå áõôüìáôá ãéá ôïõò ÷ñÞóôåò óáò. ¼ôáí óõíäõÜæåôáé ìå ôï óõíçèéóìÝíï # ifndef (ðïõ ìðáßíåé óôçí êïñõöÞ åíüò áñ÷åßïõ ãéá íá áðïöåõ÷èåß ç åðáí-åêôÝëåóç ôùí áñ÷åßùí åðéêåöáëßäùí), Ýíá ôõðéêü áñ÷åßï åðéêåöáëßäùí, Ýóôù ôï foobar.h, ðïõ ìðïñåß íá ÷ñçóéìïðïéçèåß åßôå áðü C åßôå áðü C++, èá Ýìïéáæå ìå ôï ðáñáêÜôù: /* Explain here what foobar does */ #ifndef FOOBAR_H #define FOOBAR_H #ifdef __cplusplus extern "C" { #endif ... header code for foobar goes here ... #ifdef __cplusplus } #endif #endif _________________________________________________________ 5.9. ÊÜíïíôáò ôá÷ýôåñç ôçí áñ÷éêïðïßçóç óôç C++ Ïé developers ôïõ KDE Ý÷ïõí ðáñáôçñÞóåé üôé ïé ìåãÜëåò åöáñìïãÝò GUI óå åöáñìïãÝò C++ ìðïñåß íá ðÜñïõí êÜðïéï ÷ñüíï íá îåêéíÞóïõí, åí ìÝñåé ëüãù ôïõ üôé ðñÝðåé íá êÜíïõí ðïëëÝò åðáíáìåôáèÝóåéò (relocations). ÕðÜñ÷ïõí äéÜöïñåò ëýóåéò óå áõôü ôï ðñüâëçìá. Äåßôå ôï Making C++ ready for the desktop (by Waldo Bastian) ãéá ðåñéóóüôåñåò ðëçñïöïñßåò. _________________________________________________________ 5.10. Linux Standard Base (LSB - ÂÜóç Ðñüôõðùí ôïõ Linux) Ï óôü÷ïò ôïõ LSB project åßíáé íá áíáðôõ÷èåß êáé íá ðñïùèçèåß Ýíá óýíïëï ðñïôýðùí (standards) ðïõ èá áõîÞóåé ôç óõìâáôüôçôá ìåôáîý ôùí äéáöüñùí äéáíïìþí Linux êáé èá åðéôñÝøåé óôéò åöáñìïãÝò ëïãéóìéêïý íá ôñÝîïõí óå ïðïéïäÞðïôå óýóôçìá óõìâáôü ìå ôï Linux. Ç áñ÷éêÞ óåëßäá ôïõ ðñïãñÜììáôïò åßíáé óôï http://www.linuxbase.org. ¸íá óõìðáèçôéêü Üñèñï ðïõ óõíïøßæåé ðþò íá áíáðôýîåôå LSB-óõìâáôÝò åöáñìïãÝò äçìïóéåýèçêå ôïí Ïêôþâñéï ôïõ 2002, ôï Developing LSB-certified applications: Five steps to binary-compatible Linux applications áð' ôïí George Kraft IV (Senior software engineer, IBM's Linux Technology Center). ÖõóéêÜ, ðñÝðåé íá ãñÜøåôå êþäéêá ðïõ Ý÷åé ðñüóâáóç ìüíï óôï ôõðïðïéçìÝíï óôñþìá öïñçôüôçôáò (standardized compatibility layer) åÜí èÝëåôå ï êþäéêÜ óáò íá åßíáé öïñçôüò. ÅðéðëÝïí, ôï LSB ðáñÝ÷åé ìåñéêÜ åñãáëåßá Ýôóé þóôå ïé óõããñáöåßò êþäéêá óå C Þ C++ íá ìðïñïýí íá åëÝãîïõí ïé åöáñìïãÝò ðïõ ãñÜöïõí åßíáé LSB- compliant - ôá áõôÜ åñãáëåßá ÷ñçóéìïðïéïýí êÜðïéåò äõíáôüôçôåò ôïõ linker êáé åéäéêÝò âéâëéïèÞêåò ãéá íá êÜíïõí ôÝôïéïõò åëÝã÷ïõò. Ðñïöáíþò, èá ðñÝðåé íá åãêáôáóôÞóåôå ôá åñãáëåßá ãéá íá êÜíåôå áõôïýò ôïõò åëÝã÷ïõò - ìðïñåßôå íá ôá êáôåâÜóåôå áðü ôç óåëßäá ôïõ LSB óôï äéáäßêôõï. Êáôüðéí, áðëÜ ÷ñçóéìïðïéÞóôå ôï ìåôáãëùôôéóôÞ "lsbcc" ùò ôïí C/C++ ìåôáãëùôôéóôÞ óáò (ï lsbcc åóùôåñéêÜ äçìéïõñãåß Ýíá ðåñéâÜëëïí óýíäåóçò - linking environment- ðïõ èá ðáñáðïíåèåß åÜí ïñéóìÝíïé êáíüíåò LSB äåí áêïëïõèïýíôáé): $ CC=lsbcc make myapplication (or) $ CC=lsbcc ./configure; make myapplication Ìðïñåßôå Ýðåéôá íá ÷ñçóéìïðïéÞóåôå ôï ðñüãñáììá lsbappchk ãéá íá åðéâåâáéþóåôå üôé ôï ðñüãñáììá ÷ñçóéìïðïéåß ìüíï óõíáñôÞóåéò ðïõ ôõðïðïéïýíôáé áðü ôï LSB: $ lsbappchk myapplication ÐñÝðåé åðßóçò íá áêïëïõèÞóåôå ôéò ïäçãßåò ãéá äçìéïõñãßá ðáêÝôùí ôïõ LSB (ð.÷. ÷ñçóéìïðïéÞóôå RPM v3. ïíüìáôá ðáêÝôùí êáôÜ LSB, åãêáôÜóôáóç add-on software óôïí êáôÜëïãï /opt by default). Äåßôå ôï Üñèñï êáé ôï website ôïõ LSB ãéá ðåñéóóüôåñåò ðëçñïöïñßåò. _________________________________________________________ 5.11. Óõã÷ùíåýïíôáò âéâëéïèÞêåò óå ìåãáëýôåñåò äéáìïéñáæüìåíåò (shared) âéâëéïèÞêåò Êé áí èåëÞóåôå íá äçìéïõñãÞóåôå ðñþôá ìéêñüôåñåò âéâëéïèÞêåò êáé óôç óõíÝ÷åéá íá ôéò óõãøùíÝõóåôå óå ìåãáëýôåñåò; Óå áõôÞ ôçí ðåñßðôùóç, ßóùò âñåßôå ôçí ðáñÜìåôñï ôïõ ld "--whole-archive" éäéáßôåñá ÷ñÞóéìç, áöïý ìðïñåß íá ÷ñçóéìïðïéçèåß ãéá íá ôç ìåôáöïñÜ êáé óýíäåóç áñ÷Ýéùí .a files óå Ýíá .so áñ÷åßï. Áêïëïõèåß Ýíá ðáñÜäåéãìá ó÷åôéêü ìå ôç ÷ñÞóç ôçò --whole-archive: gcc -shared -Wl,-soname,libmylib.$(VER) -o libmylib.so $(OBJECTS) \ -Wl,--whole-archive $(LIBS_TO_LINK) -Wl,--no-whole-archive \ $(REGULAR_LIBS) ¼ðùò óçìåéþíåôáé êáé óôçí ôåêìçñßùóç ôïõ ld, óéãïõñåõôåßôáé ðùò üôáí ÷ñçóéìïðïéåßôå ôçí ðáñÜìåôñï --no-whole-archive, ôç èÝôåôå óôï ôÝëïò, äéáöïñåôéêÜ ï gcc èá ðñïóðáèÞóåé íá óõã÷ùíåýóåé áêüìá êáé ôéò standard âéâëéïèÞêåò. Ïé åõ÷ñéóôßåò ìïõ óôïí Kendall Bennett ôüóï ãéá ôçí ðñüôáóç üóï êáé ôçí ðáñï÷Þ ôçò ðáñáðÜíù "óõíôáãÞò". _________________________________________________________ 6. Ðåñéóóüôåñá ðáñáäåßãìáôá Ôá ðáñáêÜôù åßíáé åðéðëÝïí ðáñáäåßãìáôá êáé ãéá ôéò ôñåéò åíáëëáêôéêÝò ðñïóåããßóåéò (static, shared, dynamically loaded). Ôï áñ÷åßï libhello.c åßíáé ìéá áðëïýóôáôç âéâëéïèÞêç, êáé ôï libhello.h ôï áñ÷åßï åðéêåöáëßäáò ôçò. Ôï demo_use.c åßíáé Ýíáò áðëïýóôáôïò caller ôçò âéâëéïèÞêçò. Ôá ðáñáðÜíù óõíïäåýïíôáé áðü scripts ó÷üëéá (script_static êáé script_dynamic), ðïõ õðïäåéêíýïõí ðùò íá ÷ñçóéìïðïéÞóåôå ôç âéâëéïèÞêç óáí óôáôéêÞ Þ äéáìïéñáæüìåíç âéâëéïèÞêç. ÔÝëïò, áêïëïõèïýí ôá demo_dynamic.c êáé script_dynamic, ðïõ õðïäåéêíýïõí ðùò íá ÷ñçóéìïðïéÞóåôå ôç âéâëéïèÞêç óáí äõíáìéêÞ âéâëéïèÞêç. _________________________________________________________ 6.1. Áñ÷åßï libhello.c /* libhello.c - demonstrate library use. */ #include <stdio.h> void hello(void) { printf("Hello, library world.\n"); } _________________________________________________________ 6.2. Áñ÷åßï libhello.h /* libhello.h - demonstrate library use. */ void hello(void); _________________________________________________________ 6.3. Áñ÷åßï demo_use.c /* demo_use.c -- demonstrate direct use of the "hello" routine */ #include "libhello.h" int main(void) { hello(); return 0; } _________________________________________________________ 6.4. Áñ÷åßï script_static #!/bin/sh # Static library demo # Create static library's object file, libhello-static.o. # I'm using the name libhello-static to clearly # differentiate the static library from the # dynamic library examples, but you don't need to use # "-static" in the names of your # object files or static libraries. gcc -Wall -g -c -o libhello-static.o libhello.c # Create static library. ar rcs libhello-static.a libhello-static.o # At this point we could just copy libhello-static.a # somewhere else to use it. # For demo purposes, we'll just keep the library # in the current directory. # Compile demo_use program file. gcc -Wall -g -c demo_use.c -o demo_use.o # Create demo_use program; -L. causes "." to be searched during # creation of the program. Note that this command causes # the relevant object file in libhello-static.a to be # incorporated into file demo_use_static. gcc -g -o demo_use_static demo_use.o -L. -lhello-static # Execute the program. ./demo_use_static _________________________________________________________ 6.5. Áñ÷åßï script_shared #!/bin/sh # Shared library demo # Create shared library's object file, libhello.o. gcc -fPIC -Wall -g -c libhello.c # Create shared library. # Use -lc to link it against C library, since libhello # depends on the C library. gcc -g -shared -Wl,-soname,libhello.so.0 \ -o libhello.so.0.0 libhello.o -lc # At this point we could just copy libhello.so.0.0 into # some directory, say /usr/local/lib. # Now we need to call ldconfig to fix up the symbolic links. # Set up the soname. We could just execute: # ln -sf libhello.so.0.0 libhello.so.0 # but let's let ldconfig figure it out. /sbin/ldconfig -n . # Set up the linker name. # In a more sophisticated setting, we'd need to make # sure that if there was an existing linker name, # and if so, check if it should stay or not. ln -sf libhello.so.0 libhello.so # Compile demo_use program file. gcc -Wall -g -c demo_use.c -o demo_use.o # Create program demo_use. # The -L. causes "." to be searched during creation # of the program; note that this does NOT mean that "." # will be searched when the program is executed. gcc -g -o demo_use demo_use.o -L. -lhello # Execute the program. Note that we need to tell the program # where the shared library is, using LD_LIBRARY_PATH. LD_LIBRARY_PATH="." ./demo_use _________________________________________________________ 6.6. Áñ÷åßï demo_dynamic.c /* demo_dynamic.c -- demonstrate dynamic loading and use of the "hello" routine */ /* Need dlfcn.h for the routines to dynamically load libraries */ #include <dlfcn.h> #include <stdlib.h> #include <stdio.h> /* Note that we don't have to include "libhello.h". However, we do need to specify something related; we need to specify a type that will hold the value we're going to get from dlsym(). */ /* The type "simple_demo_function" describes a function that takes no arguments, and returns no value: */ typedef void (*simple_demo_function)(void); int main(void) { const char *error; void *module; simple_demo_function demo_function; /* Load dynamically loaded library */ module = dlopen("libhello.so", RTLD_LAZY); if (!module) { fprintf(stderr, "Couldn't open libhello.so: %s\n", dlerror()); exit(1); } /* Get symbol */ dlerror(); demo_function = dlsym(module, "hello"); if ((error = dlerror())) { fprintf(stderr, "Couldn't find hello: %s\n", error); exit(1); } /* Now call the function in the DL library */ (*demo_function)(); /* All done, close things cleanly */ dlclose(module); return 0; } _________________________________________________________ 6.7. Áñ÷åßï script_dynamic #!/bin/sh # Dynamically loaded library demo # Presume that libhello.so and friends have # been created (see dynamic example). # Compile demo_dynamic program file into an object file. gcc -Wall -g -c demo_dynamic.c # Create program demo_use. # Note that we don't have to tell it where to search for DL libraries, # since the only special library this program uses won't be # loaded until after the program starts up. # However, we DO need the option -ldl to include the library # that loads the DL libraries. gcc -g -o demo_dynamic demo_dynamic.o -ldl # Execute the program. Note that we need to tell the # program where get the dynamically loaded library, # using LD_LIBRARY_PATH. LD_LIBRARY_PATH="." ./demo_dynamic _________________________________________________________ 7. Áëëåò ðçãÝò ðëçñïöïñéþí Éäéáßôåñá ÷ñÞóéìåò ðçãÝò ðëçñïöïñéþí ãéá ôéò âéâëéïèÞêåò åßíáé ïé áêüëïõèåò: * "The GCC HOWTO" áðü ôïí Daniel Barlow. Åéäéêüôåñá, áõôü ôï HOWTO óõæçôÜ ôéò ðñïáéñåôéêÝò ðáñáìÝôñïõò ôùí ìåôáãëùôôéóôþí ãéá ôéò âéâëéïèÞêåò êáé ðþò íá êÜíåôå queries óôéò âéâëéïèÞêåò. Êáëýðôåé ôéò ðëçñïöïñßåò ðïõ äåí êáëýðôïíôáé åäþ, êáé áíôßóôñïöá. Áõôü ôï HOWTO åßíáé äéáèÝóéìï ìÝóù ôïõ ðñïãñÜììáôïò ôåêìçñßùóçò ôïõ Linux óôï http://www.tldp.org. * "Executable and Linkable Format", áðü ôçí åðéôñïðÞ TIS (Tool Interface Standards) (áõôü åßíáé óôçí ðñáãìáôéêÜ Ýíá êåöÜëáéï áðü ôï "Portable Formats Specification" áðü ôçí ßäéá åðéôñïðÞ). ÐáñÝ÷åé ðëçñïöïñßåò ãéá ôç ìïñöÞ ELF (äåí åßíáé óõãêåêñéìÝíï ãéá Linux Þ GNU gcc), êáé ðáñÝ÷åé ìå ðïëëÝò ëåðôïìÝñåéåò. Äåßôå ôï ftp://tsx-11.mit.edu/pub/linux/packages/GCC/ELF.doc.tar.gz ÅÜí ðÜñåôå ôï áñ÷åßï áðü ôï MIT, óçìåéþóôå üôé ç ìïñöïðïßçóç ôïõ åßíáé áóõíÞèéóôç - èá ðÜñåôå Ýíá áñ÷åßï "hps" - áðëÜ áöáéñÝóôå ôéò ðñþôåò êáé ôéò ôåëéêÝò ãñáììÝò ôïõ áñ÷åßïõ êáé ìåôïíïìÜóôå ôï óå "ps", êáé èá ðÜñåôå Ýíá åêôõðþóéìï áñ÷åßï Postscript ìå ôï óõíçèéóìÝíï üíïìá áñ÷åßïõ. * "ELF: Áðü ôçí ðëåõñÜ ôïõ ðñïãñáììáôéóôÞ", áðü ôïí Hongjui Lu. Áõôü äßíåé ðëçñïöïñßåò ãéá ôï ELF ðñïóáíáôïëéóìÝíåò óôï Linux êáé ôï GNU gcc, êáé åßíáé äéáèÝóéìï óôï ftp://tsx-11.mit.edu/pub/linux/packages/GCC/elf.ps.gz. * Óôçí ôåêìçñßùóç ôïõ ld "Using LD, the GNU Linker", ðåñéãñÜöåôáé ï ld ìå ðïëý ðåñéóóüôåñåò ëåðôïìÝñåéåò. Åßíáé äéáèÝóéìï óôï http://www.gnu.org/manual/ld-2.9.1. * Èá ðñÝðåé íá ñßîåôå ïðùóäÞðïôå ìéá ìáôßá êáé óôç óõíÞèç ôåêìçñßùóç ðïõ ðáñÝ÷åôáé ìÝóù ôïõ "info", åéäéêÜ ãéá ôá ld êáé gcc. _________________________________________________________ 8. ¢äåéá êáé ÐíåõìáôéêÜ Äéêáéþìáôá Ôï ðáñüí Ýããñáöï åßíáé Copyright (C) 2000 ôïõ David Á. Wheeler. Êáëýðôåôáé áðü ôçí GNU General Public License (GPL). Ìðïñåßôå íá ôï áíáäéáíåßìåôå ÷ùñßò êüóôïò. Áíáöåñüìåíïé áêïëïýèùò óôï "ðñüãñáììá", áíáöåñüìáóôå óôïí ðçãáßï êþäéêá ðïõ ðáñïõóéÜóôçêå áðü áõôü ôï Ýããñáöï, êáé ãéá áõôü éó÷ýåé: Áõôü ôï ðñüãñáììá åßíáé åëåýèåñï ëïãéóìéêü - ìðïñåßôå íá ôïí áíáäéáíåßìåôå Þ/êáé íá ôïí ôñïðïðïéÞóåôå õðü ôïõò üñïõò ôçò General Public License ôïõ GNU üðùò äçìïóéåýåôáé áðü ôï Free Software Foundation - åßôå ç Ýêäïóç 2 ôçò Üäåéáò, åßôå (áöÞíåôå óôçí åõ÷Ýñåéá óáò) ïðïéáäÞðïôå ðéï ðñüóöáôç Ýêäïóç. Áõôü ôï ðñüãñáììá äéáíÝìåôáé ìå ôçí åëðßäá üôé èá åßíáé ÷ñÞóéìï, áëëÜ ×ÙÑÉÓ ÏÐÏÉÁÄÇÐÏÔÅ ÅÃÃÕÇÓÇ - ÷ùñßò êáí ôçí õðïíïïýìåíç åîïõóéïäüôçóç ÅÌÐÏÑÅÕÓÉÌÏÔÇÔÁ Þ ôçò ÊÁÔÁËËÇËÏÔÇÔÁÓ ÃÉÁ ÅÍÁÍ ÉÄÉÁÉÔÅÑÏ ÓÊÏÐÏ. Äåßôå ôçí GNU GPL ãéá ðåñéóóüôåñåò ëåðôïìÝñåéåò. Èá ðñÝðåé íá Ý÷åôå ëÜâåé Ýíá áíôßãñáöï ôçò GNU GPL ìáæß ìå áõôü ôï ðñüãñáììá - åÜí ü÷é, ãñÜøôå óôï Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA Áõôïß ïé üñïé åðéôñÝðïõí ôï mirroring áðü Üëëá sites, áëëÜ ðáñáêáëþ: * óéãïõñåõôåßôå ïé mirrors óáò ðáßñíïõí áõôüìáôá ôéò âåëôéþóåéò áðü ôo master site, * åìöáíßóôå óáöþò ôo url ôïõ master site, http://www.dwheeler.com/program-library, ìå Ýíá hypertext link óå áõôü, êáé * áíáöÝñáôå ìå (David A. Wheeler) ùò óõíôÜêôç. Ôá ðñþôá äýï óçìåßá ìå áðáëëÜóóïõí áðü ôï íá áêïýù åðáíåéëçììÝíá ãéá bugs ðïõ äéïñèþèçêáí. Äåí èÝëù íá ìÜèù ãéá bugs ðïõ äéüñèùóá ðñéí áðü Ýíá ÷ñüíï, áêñéâþò åðåéäÞ äåí êÜíåôå óùóôÜ mirroring. Ìå ôo link óôï master site, ïé ÷ñÞóôåò ìðïñïýí íá åëÝãîïõí êáé íá äïõí åÜí ï mirror óáò åßíáé åíçìåñùìÝíïò. Äåß÷íù éäéáßôåñç åõáéóèçóßá óôá ðñïâëÞìáôá ôùí sites ìå ðïëý ðåñéïñéóôéêÝò áðáéôÞóåéò áóöÜëåéáò êáé åðïìÝíùò äåí ìðïñïýí íá äéáêéíäõíåýóïõí links óôï Äéáäßêôõï - åÜí êÜôé ôÝôïéï ðåñéãñÜöåé ôçí êáôÜóôáóÞ óáò, ðñïóðáèÞóôå ôïõëÜ÷éóôïí íá áêïëïõèÞóåôå ôéò õðüëïéðåò ðáñáôçñÞóåéò êáé íá äïêéìÜóåôå íá ðåñíÜôå ôá updates óôï ðåñéâÜëëïí óáò áðü ìüíïé, ðåñéóôáóéáêÜ . Ìå áõôÞí ôçí Üäåéá, ìðïñåßôå íá ôñïðïðïéÞóåôå ôï Ýããñáöï, áëëÜ äåí ìðïñåßôå íá õðïóôçñßîåôå ðþò ï,ôé ãñÜøáôå åßíáé äéêüò óáò (ëïãïêëïðÞ) ïýôå íá ðáñïõóéÜóôå ìéá ôñïðïðïéçìÝíç Ýêäïóç óáí ßäéá ìå ôï áñ÷éêÞ Üñèñï. Ç ôñïðïðïßçóç ôïõ äåí ìåôáöÝñåé ôá ðíåõìáôéêÜ äéêáéþìáôá ïëüêëçñçò ôçò åñãáóßáò óå óáò - äåí ðñüêåéôáé ãéá "äçìüóéï Ýñãï" (public domain work) áðü ôçí Üðïøç ôïõ íüìïõ ðíåõìáôéêþí äéêáéùìÜôùí. Äåßôå ôçí Üäåéá ãéá ðåñéóóüôåñåò ëåðôïìÝñåéåò, óçìåéþíïíôáò åéäéêüôåñá ôçí åîÞò áíáöïñÜ: "You must cause the modified files to carry prominent notices stating that you changed the files and the date of any change". ÅÜí Ý÷åôå åñùôÞóåéò ãéá áõôÜ ðïõ ç Üäåéá åðéôñÝðåé, ðáñáêáëþ åëÜôå óå åðáöÞ ìáæß ìïõ. Óôéò ðåñéóóüôåñåò ðåñéðôþóåéò, åßíáé êáëýôåñï íá óôÝëíåôå ôéò áëëáãÝò óáò óôïí âáóéêü õðåýèõíï (ìÝ÷ñé óÞìåñá ôïí David A. Wheeler), Ýôóé þóôå ïé áëëáãÝò óáò íá åíóùìáôùèïýí, ìáæß ìå üóåò áêüìá ãßíïõí, óôï ðñùôüôõðï.