1.软件å¼ååºç¡ï¼
2.FFmpeg编译参数分析
3.麒麟V10 SP2操作系统GDB多线程调试失败
4.软件å¼åçåºç¡ç¥è¯
5.理解 pkg-config 工具
软件å¼ååºç¡ï¼
å¦è½¯ä»¶å¼åéè¦å¤å°åºç¡ï¼
å¦ä¹ 软件å¼åéè¦å ·å¤ä¸å®çåºç¡ç¥è¯ï¼ä½å¹¶ä¸è¦æ±å¦ä¹ è å ·å¤å¾é«çææ¯æ°´å¹³ã以ä¸æ¯ä¸äºå¦ä¹ 软件å¼åçåºç¡è¦æ±ï¼
计ç®æºåºç¡ç¥è¯ï¼å¦ä¹ 软件å¼åç第ä¸æ¥æ¯è¦çæ计ç®æºåºç¡ç¥è¯ï¼å¦è®¡ç®æºç»æåçãæä½ç³»ç»ãæ°æ®ç»æåç®æ³çã
ç¼ç¨åºç¡ï¼å¦ä¹ 软件å¼åéè¦ææ¡è³å°ä¸ç§ç¼ç¨è¯è¨ï¼å¦JavaãPythonãC++çï¼ä»¥åææ¡åºæ¬çç¼ç¨æ¦å¿µåææ¯ï¼å¦é¢å对象ç¼ç¨ã软件设计模å¼ãçæ¬æ§å¶çã
æ°æ®åºç¥è¯ï¼å¦ä¹ 软件å¼åéè¦äºè§£æ°æ®åºçåºç¡ç¥è¯ï¼å¦å ³ç³»åæ°æ®åºãéå ³ç³»åæ°æ®åºãSQLè¯è¨çã
Webå¼åç¥è¯ï¼å¦æä½ æ³å¦ä¹ Webå¼åï¼é£ä¹ä½ éè¦äºè§£Webå¼åçåºæ¬æ¦å¿µï¼å¦HTMLãCSSãJavaScriptãWebæ¡æ¶çã
æ»çæ¥è¯´ï¼å¦ä¹ 软件å¼åéè¦å ·å¤ä¸å®çåºç¡ç¥è¯ï¼ä½å¹¶ä¸è¦æ±ä½ æ¥æå¾é«çææ¯æ°´å¹³ãå¦æä½ æ²¡æç¸å ³çåºç¡ç¥è¯ï¼å¯ä»¥éè¿èªå¦æåå å¹è®è¯¾ç¨æ¥ææ¡æéçæè½åç¥è¯ã
软件å¼åçåºç¡è¯¾ç¨æåªäºï¼è½¯ä»¶å¼åçåºç¡è¯¾ç¨æåªäº?源码å大éé¸ä¸»è¦è¯¾ç¨æ¯ACCP7.0软件工ç¨å¸è¯¾ç¨ã
é¦å ï¼æ们å ä»çºµåä¸æ¥çæ´ä¸ªACCP7.0çå 容å®æï¼ACCP6.0课ç¨å å«å大åææ¯å 容ï¼å³ï¼æ°æ®åºææ¯ã客æ·ç«¯é¡µé¢ææ¯ãJavaå¼åææ¯å.NETå¼åææ¯ï¼
1ãæ°æ®åºææ¯æ¯åºç¨å¼åçåºç¡ææ¯ï¼%以ä¸çåºç¨ç³»ç»éè¦ä½¿ç¨æ°æ®åºæ¥åæ¾ä¸å¡æ°æ®;
2ã客æ·ç«¯é¡µé¢ææ¯æ¯å®¢æ·ç«¯/æå¡å¨å¼å模å¼ä¸æåºæ¬çææ¯ï¼è°æ¥æ¾ç¤ºï¼è¦å¼åä¸ä¸ªå ¸åçåºç¨ç³»ç»ï¼ç¼å客æ·ç«¯é¡µé¢ãå¨æèæ¬å页é¢å¨ç»ï¼éè¦è±æ项ç®ç»%-%çå¼åæ¶é´ï¼å¹¶ä¸å¾å¤ä¼ä¸ä¼æè¿äºå·¥ä½å®æç»æ°å ¥èçåå·¥ï¼æ以çç»ææ¡å®¢æ·ç«¯ææ¯æ¯ç¨åºåçåºæ¬çç´ å »;
3ãJavaææ¯ï¼Javaææ¯æ¯ç®åæ为æµè¡ç软件å¼åææ¯ï¼æ们对家ä¼ä¸çèä½åææ°æ®è¡¨ç¤ºï¼æ.%ç软件å¼åä¼ä¸è¦ä½¿ç¨å°Javaè¯è¨ï¼å æ¤ï¼ACCP7.0课ç¨ä¸å°ç±æµ å ¥æ·±è¯¦ç»è®²è§£è¿é¨ææ¯ã
软件å¼åçåºç¡ç¥è¯æ¯ä»ä¹ï¼
软件å 计ç®æºèåå¨ï¼è计ç®æºçå®è´¨æ¯æ°å¦ï¼æ以计ç®æºçç¥è¯æ¬è´¨ä¸å°±æ¯æ°å¦ç¥è¯ï¼\x0d\ä¹å¯ä»¥è¿ä¹è¯´æ°å¦ç¥è¯ä¹æ¯è®¡ç®æºçåºç¡ç¥è¯ï¼è®¡ç®æºçåºç¡ç¥è¯ä¹æ¯è½¯ä»¶çåºç¡ç¥è¯ãå¨ã软件åå±çè¿ç¨ä¸ï¼è½¯ä»¶çç¥è¯ä¹å¨æ ¢æ ¢å°ç§¯ç´¯ï¼å¾å¤è½¯ä»¶ç¥è¯ä¸æ°å¦å¹¶æ ç´æ¥çèç³»ï¼èãå¨è¿éæ们æè¦è¯´çå°±æ¯çº¯è½¯ä»¶çåºç¡ç¥è¯ã\x0d\æ们å¯ä»¥æ软件çç¥è¯å为两个é¨åï¼ä¸ä¸æè½ç¥è¯åé¢åç¥è¯æ说è¡ä¸ç¥è¯ã\x0d\1ï¼ä¸ä¸æè½ç¥è¯\x0d\ä¸é¨ç¼ç¨è¯è¨ååº\x0d\ä½ å¯ä»¥å¨ä¹¦åºéæ¾å°åè²åæ ·çå ³äºç¼ç¨æ¹é¢ç书ç±ï¼ä½æ¯æå»ºè®®ä½ åªéè¦æ·±å ¥å°ææ¡\x0d\ä¸é¨ä¾¿å¯ï¼èä¸ä»»ä½ç¨åºåé½éè¦çæCè¯è¨ãä½ ææ·±å ¥ææ¡çè¯è¨å¯æå¤ç§éæ©ãå¦æä½ ä»äºçæ¯é©±å¨ç¨åºå¼åï¼ææ³å¿ é¡»è¦ææ¡æ±ç¼è¯è¨ï¼Cè¯è¨ä¹æ¯ä¸ªä¸éçéæ©ï¼èå¦ææ¯åUIçè¯Cï¼ï¼ä¹è®¸æ´å¥½ï¼Javaè¯è¨æ¯è¾éåç½ç»ç¨åºçå¼åï¼å½ç¶JavaScriptå¨googleè¯å®å¾åæ¨å´ã\x0d\对äºç¨åºåæ¥è¯´ï¼ç¼ç¨è¯è¨å°±ç¸å½äºæ¸¸ä¾ æä¸çæ¦å¨ï¼å¯ä»¥æ¯é¿åï¼ä¹å¯æ¯ä»¥æ¯çåï¼å¯ä»¥æ¯å¤§åï¼ä¹å¯ä»¥æ¯åé¦ãè¿äºæ¦å¨åææé¿ï¼èè¦åæ¥è¿äºæ¦å¨çé¿å¤å¿ é¡»åºäºä¸å¥è·¯æ°ä¸ï¼é£ä¹å¯¹äºç¨åºåæ¥è¯´å°±æ¯åºäºæä¸ç§ç¼ç¨è¯è¨ç代ç åºãå¦GNUCçåºå°±æ¯libcæulibcãå¦æä½ æ¯ç¨Cè¯è¨ï¼èä¸ä½ æ¯å¨ç±»UNIXå¹³å°ä¸å¼åï¼é£ä¹ä½ å°±å¿ é¡»æ£ç¡®ç解libcçå·¥ä½åçï¼ä½ 代ç éæè°ç¨çæ¯ä¸ä¸ªå½æ°çè¾å ¥ä¸è¾åºï¼å¯è½çé误ï¼å¯è½çæ§ä¹ï¼å¯¹ç³»ç»å¯è½äº§ççå½±åãæ¯å¦æä¸ä¸ªå½æ°æ¯å¦æ¯å¯åå ¥çï¼è¿æ¯ä¸å¯åå ¥çï¼å¦æåºç°äºå¤çº¿ç¨åæ¶è°ç¨çæ åµä¼åçä»ä¹é误ççç»èä¸çé®é¢ã\x0d\ä¸ç§ç¼ç¨ææ³\x0d\å ¨ä¸çé½æå¹äºæ¯æ³½ä¸çé¢å¯¼ååäºæè½ï¼èå¨ä»çæè½è¡¨è±¡ä¹åæ¯ä»ä¹ï¼æ¯ä»çé©å½\x0d\ç²¾ç¥ï¼æ¯ä»çç¿æºçææ³ãç¼ç¨ä¹ä¸æ ·ï¼å¦æ没æäºç¼ç¨ææ³å°±æ²¡æäºæ导åè¿çå¨åï¼å°±æ²¡æäºåé ççµæçå壤ã软件ç¥è¯åå±å°ç°å¨æ¯è¾å¸¸ç¨çç¼ç¨ææ³å°±æ¯ç»æåï¼æ¨¡ååï¼åé¢å对象åï¼è®¾è®¡æ¨¡å¼ï¼ã\x0d\æäºè¯è¨æ¯å¨æ¨¡åå大è¡å ¶éçåå²èæ¯ä¸è¢«åæåºæ¥çï¼å¦Cè¯è¨ï¼èæäºè¯è¨åæ¯ä¸ºäºæ»¡è¶³é¢å对象çç¼ç¨ææ³èæé åºæ¥çï¼å¦Cï¼ï¼ãæä¸é¨åç¨åºåä¼è®¤ä¸ºCè¯è¨æ¯ç»æåçç¼ç¨è¯è¨æ æ³å®ç°é¢å对象çç¼ç¨ææ³ãå ¶å®ä¸ç¶ï¼Cè¯è¨åæ ·å¯ä»¥å¾å¥½å°å®ç°é¢å对象çç¼ç¨ææ³ï¼åªä¸è¿æäºé¢å对象çå·¥ä½ç±ç¨åºåæ¥åèå·²ãåæ ·ï¼é¢å对象çç¼ç¨è¯è¨ä¹å¯ä»¥ç¨äºå模ååçç¨åºã\x0d\ä¸ç§ä¿¡ä»°\x0d\å°±æææ¥è§¦è¿çç³»ç»éï¼Windowsæåªä¼å®è£ ï¼ä½¿ç¨ï¼VCï¼VBä¹åªè½åä¸äºç®åçå¼åï¼èMACOSä½éªè¿ä¸æ¬¡å®è£ ï¼ä¸è¿æç»è¿æ¯å¤±è´¥äºï¼iPhoneçç³»ç»è¿æ²¡ææºä¼ä½éªè¿ãæ¾ç»å¨AIXä¸åè¿å¼åï¼ç®åæ£å¨Fedora9ä¸åå¼åï¼ç®æ æ¿çCPUæ¯SH4ï¼å°æ¥ä¹å¯è½æ¯MIPSã\x0d\ä¸ç®¡æ¯MACOSï¼Windowsï¼UNIXï¼Linuxçé½æåèªç追éçï¼ææè¿ç§ç°å称为信仰ãå°±æ¿æèªå·±æ¥è¯´ï¼æä¿¡ä»°Linuxï¼Linuxå æ ¸çæºä»£ç 对äºææ¥è¯´å°±æ¯ç¥è¯ã\x0d\æè§å¾å¨Linuxä¸å·¥ä½æ¯ä¸ä»¶å¾å¨±æ¦çäºæ ãå¦æä½ æ¯æ¯è§£å³ä¸äºæ¯è¾æ£æçé®é¢ï¼é½ä¼\x0d\æä¸ç§æå°±æï¼è¿æ¯å¨Windowså¹³å°ä¸æåä¸å°çãæ以对äºè¿ä¸ä¿¡ä»°ï¼æè§å¾è³å°éè¦ç¥éå®çå®è£ ï¼å¯å¨ï¼é ç½®ï¼å®å ¨ï¼å¦å¼å¯¼ç¨åºGRUBï¼ftp,telnet,sshd,smbd,namedççæå¡å¨çé ç½®ï¼ç½ç»å®å ¨çé ç½®ççã\x0d\å¦æä½ è¦å¨Linuxä¸è¿è¡å¼åï¼ä½ å¿ é¡»äºè§£LinuxçAPIï¼æ ååºï¼ä¹å°±æ¯libcãå¦æä½ \x0d\çç¨åºæ¯å¤çº¿ç¨çï¼ä½ è¿å¾ææ¡libpthread.soéçå½æ°ä½¿ç¨æ¹æ³ãGCC,GDB,LD,AS,AR,以\x0d\åMakefileåmakeççå·¥å ·ç使ç¨ãå¦æä½ è½ææ¡find,awk,sed,grep,od,nm,objdump\x0d\çå®ç¨å·¥å ·çè¯ï¼å°ä¼å¤§å¤§æé«ä½ çå·¥ä½æçã\x0d\è¿ï¼å°±æ¯æçä¿¡ä»°ã\x0d\æ»ä¹ä¸å¥è¯ï¼ä¸ç§ç¼ç¨è¯è¨ååºï¼ä¸ç§ç¼ç¨ææ³åä¸ç§ä¿¡ä»°ãä¸åOKï¼\x0d\2ï¼é¢åç¥è¯/è¡ä¸ç¥è¯\x0d\æè®°å¾æç第ä¸ä»½å·¥ä½æ¯é¶è¡ç交æå¼åç¨åºåï¼å½æ¶æ¯ä¸å®¶å¤å å ¬å¸ææå¤æ´¾å°å·¥å\x0d\é¶è¡ï¼æ对工åé¶è¡çä¸å¡ä¸æ æç¥ãä¸è¿ååºè åºä¸æèï¼ç¡¬æ¯ä¸ä¸ªäººå®æäºä¸ä¸ªæä¸æ æç¥ç项ç®ï¼èä» åæ对èªå·±ææ¯å®åçèªä¿¡ã\x0d\ä½äºåæå´æäºåæï¼å 为æ并ä¸æç½ï¼ä¸ºä»ä¹é£ä¸ªæ´æ°è¦ä¹ä»¥ä¸ª0.åå ¥å°æ°æ®åºï¼\x0d\ä¹ä¸ç¥éé¶è¡å¯¹æ°æ®ç精确度æ¯å¤å¤§ï¼ççç»èä¸çé®é¢æä¸æ æç¥ãé£æåªè½æ±ä¸å¤©ä¿ä½ï¼åªå¤©ä¸è¦å¤æ£äºäººå®¶çé±ï¼å¤©åï¼è¿äºæä¹åäºï¼ï¼å½ç¶ä¸è³äºé£ä¹ä¸¥é:)\x0d\åæ¥æç¡®å®åç°èªå·±å¯¹äºé¶è¡è¿å¥ä¸å¡ç³»ç»äºè§£èµ·æ¥æ¯è¾ååï¼æå®æ¿è±ç¹æ¶é´åäºå°\x0d\çCç¨åºä¹ä¸æ¿è±æ¶é´å»è¯é£äºè¦æ¶©çä¸å¡æµç¨ææ¡£ãæ以å¨é£å®¶å ¬å¸å_ä¸å¹´åæè¾èäºã\x0d\ææ³ï¼å¤§é¨åç¨åºåé½æ³åä¸äºç¸å¯¹ææ¯å«éé«çå¼åå·¥ä½ï¼åé£ç§æ´å¤©ä¸æ°æ®åæ°æ®\x0d\åºæ交éçå¼åå·¥ä½ï¼é便æç¹å¿åçç¨åºåä¹ä¸æ¿æå»åï¼å½ç¶å¦æé±è¶³å¤å¤çè¯æè¿æ¯æ¿æç:)\x0d\ä½ç°å¨æåç°æéäºãå 为è¿é¨åä¹æ¯è½¯ä»¶ç¥è¯çä¸é¨åãå°±æ¿æç®åçå·¥ä½æ¥è¯´ï¼ææ¯ä¸ä¸ä¼æ太大çå°é¾ï¼ä½æ¯èå è§æ ¼ä»¥åå ¶æ¶åå°çè§æ ¼ç¸å½çå¤ï¼ææ没æåå¹´æ¶é´æ æ³åå°ç²¾éãè¿å°±æ¯é¢åç¥è¯æ说æ¯è¡ä¸ç¥è¯ãæäºäººä¸çåªåä¸ä»¶äºï¼è¿ä¸ä¸å®è½å好ï¼èæç°å¨åªåäºä¸å°ä¸¤å¹´ï¼è½è§æ¶é´ä¸é¿ä½ä¹ä¸çï¼çºµæ¯ä¸æ æè·ã\x0d\æ以ï¼æè§å¾èªå·±ä»ä¸æ¯ä¸ååæ ¼çå¼åè ã软件å¼åçåºç¡ç¥è¯å æ¬ä¸ä¸ç¥è¯åè¡ä¸\x0d\ç¥è¯ï¼å¦æåºç¡ç¥è¯ä¸å®æ´ï¼é£ä¹è¿ä¸ªç¨åºåä¸ä¼æ¯ä¸ä¸ªåæ ¼ä¸é«æçç¨åºåã
å¦è½¯ä»¶å¼åéè¦æä»ä¹åºç¡ï¼å¦ä¹ 软件å¼åè¦æ以ä¸åºç¡ï¼
1ãåºç¡ç¼ç¨è¯è¨
ç¼ç¨è¯è¨æ¯å¦è½¯ä»¶å¼åçé¥åï¼åå¦è å¥½æ ¹æ®èªèº«çå好æè èä¸è§åéæ©è¯è¨ãç®å主æµçç¼ç¨è¯è¨å æ¬JavaãPHPã.netãC#è¯è¨çï¼æ°æ建议ä»Cè¯è¨å¼å§ï¼æ¯åºç¡ä¹å®ç¨çè¯è¨ï¼ä¹åä¹å¯ä»¥æ ¢æ ¢æ©å±ãå ¶å®å¾å¤ç¼ç¨è¯è¨ä¹é´ææäºéï¼æ¯å¦æ°æ®ç±»åãåéã常éçãå¨å¦ä¹ å®è·µè¿ç¨ä¸ï¼äºè§£ç¼ç¨å 涵ï¼å »æç¼ç¨æç»´ï¼è¿æ ·è·¨è¯è¨å¦ä¹ ä¼é常快ã
2ãæ°æ®åºï¼SQLServerï¼ç¥è¯
é¤äºåºç¡å¦ä¹ ï¼æ°æ®åºç¸å ³çä¹æ¯å¿ ä¸å¯å°çãæ°æ®çåå¨ãè°ç¨å¨è½¯ä»¶å¼åè¿è¡è¿ç¨ä¸å¿ ä¸å¯å°ã
3ãwebç¸å ³ç¥è¯
主è¦å为HTMLãCSSãJavaScript
软件å¼åéè¦å¦ä¹ ä»ä¹åºç¡ç¥è¯å¦ä¹ 软件å¼åç»å¸¸ä¼æ¶åå°æ°å¦åè±è¯çç¥è¯ï¼æ以éè¦æä¸å®çæ°å¦åè±è¯åºç¡ï¼è¿æ ·å¯ä»¥è®©è½¯ä»¶å¼ååå¾äºåååãåéæè²å°±æ线ä¸å è´¹ç软件å¼åå ¬å¼è¯¾ï¼ã
åéæè²éç¨å ¨ç¨é¢æé«åè´¨ãé«ä½éªå¹å »æ¨¡å¼ï¼å¦ç§å¤§çº²ç´§è·ä¼ä¸éæ±ï¼æ¥æå½å ä¸ä½åæå¦ç®¡çåå¦åæå¡ï¼å¨èä¸æè²åå±éè·¯ä¸ä¸ææ¢ç´¢åè¡ãå¦æä½ æ é¿è±è¯åæ°å¦ï¼ä½ å¯ä»¥è·³è¿è¿ä¸æ¥ã软件çæä½æ¯éè¿æç§ç¨åºè¯è¨æ¥å®ç°çï¼æ以å¦å¥½ç¨åºè¯è¨æ¯å好软件å¼åçå¿ ä¿®è¯¾ãæ以ï¼å¦æä½ æ³å¦è½¯ä»¶å¼åï¼ç¬¬äºæ¥å°±æ¯éæ©ä¸é¨ç¼ç¨å¼åè¯è¨æ¥å¦ä¹ ï¼éä¸ç²¾åå¦å¥½ä¸é¨è¯è¨ãä¸è¬æ¥è¯´ï¼è¦æ³å好软件å¼åï¼è³å°è¦å¦ä¸é¨ç¼ç¨è¯è¨ãç®å主æµçç¼ç¨è¯è¨æJavaãPHPãC#è¯è¨ï¼è½¯ä»¶å¼åå½¢å¼æå¤ç§ï¼å å¦å¥½è¿äºåºç¡è¯è¨ï¼ä¹ååæ ¢æ ¢æ©å±ãé¤äºå¦ä¹ åºç¡è¯è¨ï¼è¿è¦å¦ä¹ æ°æ®åºçç¥è¯ãå¨è½¯ä»¶å¼åä¸ï¼æ°æ®çåå¨åè°ç¨è³å ³éè¦ãHTMLï¼CSSï¼Javaèæ¬çç¸å ³çå端è¯è¨ä¹æ¯éè¦ææ¡çï¼ç»è¿è¿å个å¦ä¹ é¶æ®µï¼æ们已ç»åºæ¬ææ¡äºä¸å¥å®æ´ç软件å¼åæµç¨ï¼åé¢æ·±å ¥å¦ä¹ çè¯ï¼å°±éè¦ææ¡åç§æ¡æ¶ãåéå®ç½æ¯æ¥æ´æ°ææ°è½¯ä»¶å¼ååºç¡ç¥è¯å 容ï¼å·©åºæ¥å¸¸å¦ä¹ ä¸çåºç¡æè½ãæ´æå è´¹ç软件å¼åè§é¢æç¨å¸®å©å¦åå¿«éå¦ä¹ ã
软件å¼åéè¦æä»ä¹åºç¡ï¼è½¯ä»¶å¼å主è¦å为WEBå¼åã移å¨ç«¯å¼åãåµå ¥å¼å¼åä¸ä¸ªå¼åæ¹åï¼ä¸åæ¹åçå¦ä¹ å 容ä¹ä¸åã
1ãWEBå为å端å¼ååå端å¼åï¼å端å¼åéè¦å¦CSS3ãJavaScriptãHtml5ï¼å端å¼åå¼åéè¦å¦PHPãPythonãJavaã
2ã移å¨ç«¯å¼åéè¦å¦OCæè Swiftã
3ãåµå ¥å¼å¼åéè¦å¦Cè¯è¨ã计ç®æºåºç¡ç¥è¯çã
FFmpeg编译参数分析
FFmpeg的编译参数通过configure脚本提供,生成config.mak传递给makefile,分析config.h用于C程序引入。源码configure脚本接受多种编译参数,分析如--logfile=FILE指定日志文件路径,源码默认为ffbuild/config.log。分析壁纸api源码--prefix、源码--bindir、分析--libdir、源码--shlibdir、分析--incdir、源码--pkgconfigdir等用于指定安装目录。分析
参数--disable-static与--enable-shared控制静态库与动态库生成,源码FFmpeg默认生成静态库。分析启用--enable-shared时,源码仅生成动态库,静态库生成需二次编译。
编译参数--enable-small减少FFmpeg体积,--disable-programs则不生成ffmpeg.exe、ffplay.exe、ffprobe.exe等可执行文件,仅生成库文件。--disable-doc禁止生成文档,节省编译时间。
不生成特定库如--disable-avdevice、--disable-avcodec等可以减小程序大小,但可能影响功能。--disable-pthreads、--disable-wthreads、--disable-os2threads控制多线程支持。
在configure脚本中,启用--disable-pthreads实际上在shell中设置pthreads=no,影响后续链接器选项,但不隐藏多线程代码。在C源代码中通过宏判断多线程代码启用。
不启用--disable-network可以减少软件大小和编译时间。java web书籍源码configure脚本提供裁剪功能,如禁用特定编码器、复用器等,适用于嵌入式设备。--enable-libx、--enable-libx启用特定编解码器。自定义编译器、链接器、库及额外标识选项等参数可进一步定制编译过程。
所有编译参数及注释可在configure --help中查看,易于理解。
麒麟V SP2操作系统GDB多线程调试失败
在FT/4芯片及麒麟V SP2操作系统下,使用GDB进行多线程调试时,遇到了错误。
经过网络搜索,发现可能导致此问题的原因有两种。首先,libthread_db-1.0.so和libpthread.so都源自glibc库,理论上不应存在版本不一致的情况。其次,在检查版本一致时,会从libpthread.so的符号表中获取nptl_version,即版本信息。若无法获取该信息,则可能引发上述问题。
可以通过以下命令查看libpthread.so.0中是否存在nptl_version信息。在出现问题的环境下,可能会得到无符合的结果。同时,也可以尝试查看nptl_version,但由于被stripped,因此无法看到结果。
使用file命令查看libpthread-2..so文件,可以发现其被stripped。strip的补码0000000的源码作用是在动态库中移除符号表,以减小动态库占用空间。显然,我们需要用到的符号也被清除了。
为了解决这个问题,我使用了glibc 2.版本,因此需要创建一个no stripped的libpthread-2..so。最简单的方式是下载glibc2.源码编译,然后提取所需的libpthread库。
1. 从官网下载glibc-2..tar.xz。
2. 解压tar xvf glibc-2..tar.xz。
3. 创建编译目录mkdir build。
4. 进入build目录,执行../configure --prefix=/opt/glibc-2.。
5. 配置后执行make完成编译,注意我们不需要安装。有编译错误也没有关系,只要build的nptl目录下完成libpthread动态库即可。完成编译后的库名为build/nptl/libpthread.so。通过file命令可看到它是no stripped。
接下来查看其版本,可以确认是2.版。
接下来让配置vim ~/.gdbinit加入以下语句,目的是在调用GDB时优先加载我们编译的libpthread.so。修改后,gdb进行多线程调试不再提示错误。
如果你有把握,也可以使用自己编译的libpthread.so替换环境中的对应库。
软件å¼åçåºç¡ç¥è¯
软件å 计ç®æºèåå¨ï¼è计ç®æºçå®è´¨æ¯æ°å¦ï¼æ以计ç®æºçç¥è¯æ¬è´¨ä¸å°±æ¯æ°å¦ç¥è¯ï¼
ä¹å¯ä»¥è¿ä¹è¯´æ°å¦ç¥è¯ä¹æ¯è®¡ç®æºçåºç¡ç¥è¯ï¼è®¡ç®æºçåºç¡ç¥è¯ä¹æ¯è½¯ä»¶çåºç¡ç¥è¯ãå¨ã软件åå±çè¿ç¨ä¸ï¼è½¯ä»¶çç¥è¯ä¹å¨æ ¢æ ¢å°ç§¯ç´¯ï¼å¾å¤è½¯ä»¶ç¥è¯ä¸æ°å¦å¹¶æ ç´æ¥çèç³»ï¼èãå¨è¿éæ们æè¦è¯´çå°±æ¯çº¯è½¯ä»¶çåºç¡ç¥è¯ã
æ们å¯ä»¥æ软件çç¥è¯å为两个é¨åï¼ä¸ä¸æè½ç¥è¯åé¢åç¥è¯æ说è¡ä¸ç¥è¯ã
1ï¼ä¸ä¸æè½ç¥è¯
ä¸é¨ç¼ç¨è¯è¨ååº
ä½ å¯ä»¥å¨ä¹¦åºéæ¾å°åè²åæ ·çå ³äºç¼ç¨æ¹é¢ç书ç±ï¼ä½æ¯æå»ºè®®ä½ åªéè¦æ·±å ¥å°ææ¡
ä¸é¨ä¾¿å¯ï¼èä¸ä»»ä½ç¨åºåé½éè¦çæCè¯è¨ãä½ ææ·±å ¥ææ¡çè¯è¨å¯æå¤ç§éæ©ãå¦æä½ ä»äºçæ¯é©±å¨ç¨åºå¼åï¼ææ³å¿ é¡»è¦ææ¡æ±ç¼è¯è¨ï¼Cè¯è¨ä¹æ¯ä¸ªä¸éçéæ©ï¼èå¦ææ¯åUIçè¯Cï¼ï¼ä¹è®¸æ´å¥½ï¼Javaè¯è¨æ¯è¾éåç½ç»ç¨åºçå¼åï¼å½ç¶JavaScriptå¨googleè¯å®å¾åæ¨å´ã
对äºç¨åºåæ¥è¯´ï¼ç¼ç¨è¯è¨å°±ç¸å½äºæ¸¸ä¾ æä¸çæ¦å¨ï¼å¯ä»¥æ¯é¿åï¼ä¹å¯æ¯ä»¥æ¯çåï¼å¯ä»¥æ¯å¤§åï¼ä¹å¯ä»¥æ¯åé¦ãè¿äºæ¦å¨åææé¿ï¼èè¦åæ¥è¿äºæ¦å¨çé¿å¤å¿ é¡»åºäºä¸å¥è·¯æ°ä¸ï¼é£ä¹å¯¹äºç¨åºåæ¥è¯´å°±æ¯åºäºæä¸ç§ç¼ç¨è¯è¨ç代ç åºãå¦GNUCçåºå°±æ¯libcæulibcãå¦æä½ æ¯ç¨Cè¯è¨ï¼èä¸ä½ æ¯å¨ç±»UNIXå¹³å°ä¸å¼åï¼é£ä¹ä½ å°±å¿ é¡»æ£ç¡®ç解libcçå·¥ä½åçï¼ä½ 代ç éæè°ç¨çæ¯ä¸ä¸ªå½æ°çè¾å ¥ä¸è¾åºï¼å¯è½çé误ï¼å¯è½çæ§ä¹ï¼å¯¹ç³»ç»å¯è½äº§ççå½±åãæ¯å¦æä¸ä¸ªå½æ°æ¯å¦æ¯å¯åå ¥çï¼è¿æ¯ä¸å¯åå ¥çï¼å¦æåºç°äºå¤çº¿ç¨åæ¶è°ç¨çæ åµä¼åçä»ä¹é误ççç»èä¸çé®é¢ã
ä¸ç§ç¼ç¨ææ³
å ¨ä¸çé½æå¹äºæ¯æ³½ä¸çé¢å¯¼ååäºæè½ï¼èå¨ä»çæè½è¡¨è±¡ä¹åæ¯ä»ä¹ï¼æ¯ä»çé©å½
ç²¾ç¥ï¼æ¯ä»çç¿æºçææ³ãç¼ç¨ä¹ä¸æ ·ï¼å¦æ没æäºç¼ç¨ææ³å°±æ²¡æäºæ导åè¿çå¨åï¼å°±æ²¡æäºåé ççµæçå壤ã软件ç¥è¯åå±å°ç°å¨æ¯è¾å¸¸ç¨çç¼ç¨ææ³å°±æ¯ç»æåï¼æ¨¡ååï¼åé¢å对象åï¼è®¾è®¡æ¨¡å¼ï¼ã
æäºè¯è¨æ¯å¨æ¨¡åå大è¡å ¶éçåå²èæ¯ä¸è¢«åæåºæ¥çï¼å¦Cè¯è¨ï¼èæäºè¯è¨åæ¯ä¸ºäºæ»¡è¶³é¢å对象çç¼ç¨ææ³èæé åºæ¥çï¼å¦Cï¼ï¼ãæä¸é¨åç¨åºåä¼è®¤ä¸ºCè¯è¨æ¯ç»æåçç¼ç¨è¯è¨æ æ³å®ç°é¢å对象çç¼ç¨ææ³ãå ¶å®ä¸ç¶ï¼Cè¯è¨åæ ·å¯ä»¥å¾å¥½å°å®ç°é¢å对象çç¼ç¨ææ³ï¼åªä¸è¿æäºé¢å对象çå·¥ä½ç±ç¨åºåæ¥åèå·²ãåæ ·ï¼é¢å对象çç¼ç¨è¯è¨ä¹å¯ä»¥ç¨äºå模ååçç¨åºã
ä¸ç§ä¿¡ä»°
å°±æææ¥è§¦è¿çç³»ç»éï¼Windowsæåªä¼å®è£ ï¼ä½¿ç¨ï¼VCï¼VBä¹åªè½åä¸äºç®åçå¼åï¼èMACOSä½éªè¿ä¸æ¬¡å®è£ ï¼ä¸è¿æç»è¿æ¯å¤±è´¥äºï¼iPhoneçç³»ç»è¿æ²¡ææºä¼ä½éªè¿ãæ¾ç»å¨AIXä¸åè¿å¼åï¼ç®åæ£å¨Fedora9ä¸åå¼åï¼ç®æ æ¿çCPUæ¯SH4ï¼å°æ¥ä¹å¯è½æ¯MIPSã
ä¸ç®¡æ¯MACOSï¼Windowsï¼UNIXï¼Linuxçé½æåèªç追éçï¼ææè¿ç§ç°å称为信仰ãå°±æ¿æèªå·±æ¥è¯´ï¼æä¿¡ä»°Linuxï¼Linuxå æ ¸çæºä»£ç 对äºææ¥è¯´å°±æ¯ç¥è¯ã
æè§å¾å¨Linuxä¸å·¥ä½æ¯ä¸ä»¶å¾å¨±æ¦çäºæ ãå¦æä½ æ¯æ¯è§£å³ä¸äºæ¯è¾æ£æçé®é¢ï¼é½ä¼
æä¸ç§æå°±æï¼è¿æ¯å¨Windowså¹³å°ä¸æåä¸å°çãæ以对äºè¿ä¸ä¿¡ä»°ï¼æè§å¾è³å°éè¦ç¥éå®çå®è£ ï¼å¯å¨ï¼é ç½®ï¼å®å ¨ï¼å¦å¼å¯¼ç¨åºGRUBï¼ftp,telnet,sshd,smbd,namedççæå¡å¨çé ç½®ï¼ç½ç»å®å ¨çé ç½®ççã
å¦æä½ è¦å¨Linuxä¸è¿è¡å¼åï¼ä½ å¿ é¡»äºè§£LinuxçAPIï¼æ ååºï¼ä¹å°±æ¯libcãå¦æä½
çç¨åºæ¯å¤çº¿ç¨çï¼ä½ è¿å¾ææ¡libpthread.soéçå½æ°ä½¿ç¨æ¹æ³ãGCC,GDB,LD,AS,AR,以
åMakefileåmakeççå·¥å ·ç使ç¨ãå¦æä½ è½ææ¡find,awk,sed,grep,od,nm,objdump
çå®ç¨å·¥å ·çè¯ï¼å°ä¼å¤§å¤§æé«ä½ çå·¥ä½æçã
è¿ï¼å°±æ¯æçä¿¡ä»°ã
æ»ä¹ä¸å¥è¯ï¼ä¸ç§ç¼ç¨è¯è¨ååºï¼ä¸ç§ç¼ç¨ææ³åä¸ç§ä¿¡ä»°ãä¸åOKï¼
2ï¼é¢åç¥è¯/è¡ä¸ç¥è¯
æè®°å¾æç第ä¸ä»½å·¥ä½æ¯é¶è¡ç交æå¼åç¨åºåï¼å½æ¶æ¯ä¸å®¶å¤å å ¬å¸ææå¤æ´¾å°å·¥å
é¶è¡ï¼æ对工åé¶è¡çä¸å¡ä¸æ æç¥ãä¸è¿ååºè åºä¸æèï¼ç¡¬æ¯ä¸ä¸ªäººå®æäºä¸ä¸ªæä¸æ æç¥ç项ç®ï¼èä» åæ对èªå·±ææ¯å®åçèªä¿¡ã
ä½äºåæå´æäºåæï¼å 为æ并ä¸æç½ï¼ä¸ºä»ä¹é£ä¸ªæ´æ°è¦ä¹ä»¥ä¸ª0.åå ¥å°æ°æ®åºï¼
ä¹ä¸ç¥éé¶è¡å¯¹æ°æ®ç精确度æ¯å¤å¤§ï¼ççç»èä¸çé®é¢æä¸æ æç¥ãé£æåªè½æ±ä¸å¤©ä¿ä½ï¼åªå¤©ä¸è¦å¤æ£äºäººå®¶çé±ï¼å¤©åï¼è¿äºæä¹åäºï¼ï¼å½ç¶ä¸è³äºé£ä¹ä¸¥é:)
åæ¥æç¡®å®åç°èªå·±å¯¹äºé¶è¡è¿å¥ä¸å¡ç³»ç»äºè§£èµ·æ¥æ¯è¾ååï¼æå®æ¿è±ç¹æ¶é´åäºå°
çCç¨åºä¹ä¸æ¿è±æ¶é´å»è¯é£äºè¦æ¶©çä¸å¡æµç¨ææ¡£ãæ以å¨é£å®¶å ¬å¸åæºä¸å¹´åæè¾èäºã
ææ³ï¼å¤§é¨åç¨åºåé½æ³åä¸äºç¸å¯¹ææ¯å«éé«çå¼åå·¥ä½ï¼åé£ç§æ´å¤©ä¸æ°æ®åæ°æ®
åºæ交éçå¼åå·¥ä½ï¼é便æç¹å¿åçç¨åºåä¹ä¸æ¿æå»åï¼å½ç¶å¦æé±è¶³å¤å¤çè¯æè¿æ¯æ¿æç:)
ä½ç°å¨æåç°æéäºãå 为è¿é¨åä¹æ¯è½¯ä»¶ç¥è¯çä¸é¨åãå°±æ¿æç®åçå·¥ä½æ¥è¯´ï¼ææ¯ä¸ä¸ä¼æ太大çå°é¾ï¼ä½æ¯èå è§æ ¼ä»¥åå ¶æ¶åå°çè§æ ¼ç¸å½çå¤ï¼ææ没æåå¹´æ¶é´æ æ³åå°ç²¾éãè¿å°±æ¯é¢åç¥è¯æ说æ¯è¡ä¸ç¥è¯ãæäºäººä¸çåªåä¸ä»¶äºï¼è¿ä¸ä¸å®è½å好ï¼èæç°å¨åªåäºä¸å°ä¸¤å¹´ï¼è½è§æ¶é´ä¸é¿ä½ä¹ä¸çï¼çºµæ¯ä¸æ æè·ã
æ以ï¼æè§å¾èªå·±ä»ä¸æ¯ä¸ååæ ¼çå¼åè ã软件å¼åçåºç¡ç¥è¯å æ¬ä¸ä¸ç¥è¯åè¡ä¸
ç¥è¯ï¼å¦æåºç¡ç¥è¯ä¸å®æ´ï¼é£ä¹è¿ä¸ªç¨åºåä¸ä¼æ¯ä¸ä¸ªåæ ¼ä¸é«æçç¨åºåã
理解 pkg-config 工具
你在 Unix 或 Linux 下开发过软件吗?写完一个程序,编译运行完全正常,在你本机上工作得好好的,你放到源代码管理系统中。然后,告诉你的同事说,你可以取下来用了。这时,免费阅读漫画源码你长长的出了一口气,几天的工作没有白费,多么清新的空气啊,你开始飘飘然了。“Hi,怎么编译不过去?”你还沉浸在那种美妙的感觉之中,双臂充满着力量,似乎没有什么问题能难倒你的。正在此时,那个笨蛋已经冲着你嚷开了。
“不会吧,我这边好好的!”表面上你说得很客气,其实,你心里已经骂开了,真笨,不知道脑子干嘛用的。也许,你想的没错,上次,他犯了一个简单的错误,不是你一去就解决了吗。
他喊三次之后,你不得不放下你手上的工作,刚才那种美妙的感觉已经消失得无影无踪了,要不是你把情绪控制得很好,一肚子气就要撒在他身上了。你走到他的电脑前,键入 make,优雅的按下回车。怎么可能出错呢?你信心十足。然而,屏幕上的结果多少有点让人脸红,该死的,libxxx.so 怎么会让不到呢?
你在/usr目录中查找 libxxx.so,源码后台对接支付一切都逃不过你的眼睛。奇怪,libxxx.so 怎么在 /usr/local/lib 下,不是应该在 /usr/lib 下的吗?这你可不能怪别人,别人想安装在哪里都行,下次还可能安装到 /lib 目录下呢。
以上的场景并非虚构,我都经历过好几次,明明在本机上好好的,在别人的机器上连编译都过不去。可能两人的操作系统一模一样,需要的库都安装上,只是由于个人 喜好不同,安装在不同的目录而已。遇到这种情况,每次都技巧性的绕过去了,用的补丁型的方法,心里老惦记其它地方能不能工作。
今天我们要介绍的 pkg-config,为解决以上问题提供了一个优美方案。从此,你再也不为此担忧了。pkg-config提供了下面几个功能:
检查库的版本号。如果所需要的库的版本不满足要求,它会打印出错误信息,避免链接错误版本的库文件。
获得编译预处理参数,如宏定义,头文件的位置。
获得链接参数,如库及依赖的其它库的位置,文件名及其它一些连接参数。
自动加入所依赖的其它库的设置。
这一切都自动的,库文件安装在哪里都没关系!
在使用前,我们说说 pkg-config 的原理,pkg-config 并非精灵,可以凭空得到以上信息。事实上,为了让pkg-config可以得到这些信息,要求库的提供者,提供一个.pc文件。比如gtk+-2.0的pc文件内容如下:
复制代码
代码如下:
prefix=/usr
exec_prefix=/usr
libdir=/usr/lib
includedir=/usr/include
target=x/ppgtk_binary_version=2.4.0
gtk_host=i-redhat-linux-gnu/ppName: GTK+
Description: GIMP Tool Kit (${ target} target)
Version: 2.6.7
Requires: gdk-${ target}-2.0 atk
Libs: -L${ libdir} -lgtk-${ target}-2.0
Cflags: -I${ includedir}/gtk-2.0
这个文件一般放在 /usr/lib/pkgconfig/ 或者 /usr/local/lib/pkgconfig/ 里,当然也可以放在其它任何地方,如像 X 相关的pc文件是放在 /usr/XR6/lib/pkgconfig 下的。为了让pkgconfig可以找到你的pc文件,你要把pc文件所在的路径,设置在环境变量 PKG_CONFIG_PATH 里。
使用 pkg-config 的 –cflags 参数可以给出在编译时所需要的选项,而 –libs 参数可以给出连接时的选项。例如,假设一个 sample.c 的程序用到了 Glib 库,就可以这样编译:
复制代码
代码如下:
$ gcc -c `pkg-config –cflags glib-2.0` sample.c
然后这样连接:
复制代码
代码如下:
$ gcc sample.o -o sample `pkg-config –libs glib-2.0`
或者上面两步也可以合并为以下一步:
复制代码
代码如下:
$ gcc sample.c -o sample `pkg-config –cflags –libs glib-2.0`
可以看到:由于使用了 pkg-config 工具来获得库的选项,所以不论库安装在什么目录下,都可以使用相同的编译和连接命令,带来了编译和连接界面的统一。
使用 pkg-config 工具提取库的编译和连接参数有两个基本的前提:
库本身在安装的时候必须提供一个相应的 .pc 文件(不这样做的库说明不支持 pkg-config 工具的使用)。
pkg-config 必须知道要到哪里去寻找此 .pc 文件。
GTK+ 及其依赖库支持使用 pkg-config 工具,所以剩下的问题就是如何告诉 pkg-config 到哪里去寻找库对应的 .pc 文件,这也是通过设置搜索路径来解决的。
对于支持 pkg-config 工具的 GTK+ 及其依赖库来说,库的头文件的搜索路径的设置变成了对 .pc 文件搜索路径的设置。.pc 文件的搜索路径是通过环境变量 PKG_CONFIG_PATH 来设置的,pkg-config 将按照设置路径的先后顺序进行搜索,直到找到指定的 .pc 文件为止。
安装完 Glib 后,在 bash 中应该进行如下设置:
复制代码
代码如下:
$ export PKG_CONFIG_PATH=/opt/gtk/lib/pkgconfig:$PKG_CONFIG_PATH
可以执行下面的命令检查是否 /opt/gtk/lib/pkgconfig 路径已经设置在 PKG_CONFIG_PATH 环境变量中:
复制代码
代码如下:
$ echo $PKG_CONFIG_PATH
这样设置之后,使用 glib 库的其它程序或库在编译的时候 pkg-config 就知道首先要到 /opt/gtk/lib/pkgconfig 这个目录中去寻找 glib-2.0.pc 了(GTK+ 和其它的依赖库的 .pc 文件也将拷贝到这里,也会首先到这里搜索它们对应的 .pc 文件)。之后,通过 pkg-config 就可以把其中库的编译和连接参数提取出来供程序在编译和连接时使用。
另外还需要注意的是:环境变量的设置只对当前的终端窗口有效。如果到了没有进行上述设置的终端窗口中,pkg-config 将找不到新安装的 glib-2.0.pc 文件、从而可能使后面进行的安装(如 glib 之后的 Atk 的安装)无法进行。
在我们采用的安装方案中,由于是使用环境变量对 GTK+ 及其依赖库进行的设置,所以当系统重新启动、或者新开一个终端窗口之后,如果想使用新安装的 GTK+ 库,需要如上面那样重新设置 PKG_CONFIG_PATH 和 LD_LIBRARY_PATH 环境变量。
这种使用 GTK+ 的方法,在使用之前多了一个对库进行设置的过程。虽然显得稍微繁琐了一些,但却是一种最安全的使用 GTK+ 库的方式,不会对系统上已经存在的使用了 GTK+ 库的程序(比如 GNOME 桌面)带来任何冲击。
为了使库的设置变得简单一些,可以把下面的这两句设置保存到一个文件中(比如 set_gtk-2. 文件):
复制代码
代码如下:
export PKG_CONFIG_PATH=/opt/gtk/lib/pkgconfig:$PKG_CONFIG_PATH
export LD_LIBRARY_PATH=/opt/gtk/lib:$LD_LIBRARY_PATH
之后,就可以用下面的方法进行库的设置了(其中的 source 命令也可以用 . 代替):
复制代码
代码如下:
$ source set_gtk-2.
只有在用新版的 GTK+ 库开发应用程序、或者运行使用了新版 GTK+ 库的程序的时候,才有必要进行上述设置。
如果想避免使用 GTK+ 库之前上述设置的麻烦,可以把上面两个环境变量的设置在系统的配置文件中(如 /etc/profile)或者自己的用户配置文件中(如 ~/.bash_profile) ;库的搜索路径也可以设置在 /etc/ld.so.conf 文件中,等等。这种设置在系统启动时会生效,从而会导致使用 GTK+ 的程序使用新版的 GTK+ 运行库,这有可能会带来一些问题。当然,如果你发现用新版的 GTK+ 代替旧版没有什么问题的话,使用这种设置方式是比较方便的。
库文件在连接(静态库和共享库)和运行(仅限于使用共享库的程序)时被使用,其搜索路径是在系统中进行设置的。一般 Linux 系统把 /lib 和 /usr/lib 两个目录作为默认的库搜索路径,所以使用这两个目录中的库时不需要进行设置搜索路径即可直接使用。对于处于默认库搜索路径之外的库,需要将库的位置添加到库的搜索路径之中。设置库文件的搜索路径有下列两种方式,可任选其一使用:
在环境变量 LD_LIBRARY_PATH 中指明库的搜索路径。
在 /etc/ld.so.conf 文件中添加库的搜索路径。
将自己可能存放库文件的路径都加入到 /etc/ld.so.conf 中是明智的选择。( ^_^)
添加方法也极其简单,将库文件的绝对路径直接写进去就OK了,一行一个。例如:
复制代码
代码如下:
/usr/XR6/lib
/usr/local/lib
/opt/lib
需要注意的是:第二种搜索路径的设置方式对于程序连接时的库(包括共享库和静态库)的定位已经足够了,但是对于使用了共享库的程序的执行还是不够的。这是 因为为了加快程序执行时对共享库的定位速度,避免使用搜索路径查找共享库的低效率,所以是直接读取库列表文件 /etc/ld.so.cache 从中进行搜索的。/etc/ld.so.cache 是一个非文本的数据文件,不能直接编辑,它是根据 /etc/ld.so.conf 中设置的搜索路径由 /sbin/ldconfig 命令将这些搜索路径下的共享库文件集中在一起而生成的(ldconfig 命令要以 root 权限执行)。因此,为了保证程序执行时对库的定位,在 /etc/ld.so.conf 中进行了库搜索路径的设置之后,还必须要运行 /sbin/ldconfig 命令更新 /etc/ld.so.cache 文件之后才可以。ldconfig ,简单的说,它的作用就是将 /etc/ld.so.conf 列出的路径下的库文件缓存到/etc/ld.so.cache以供使用。因此当安装完一些库文件(例如刚安装好 glib 或者修改 ld.so.conf 增加新的库路径)后,需要运行一下 /sbin/ldconfig 使所有的库文件都被缓存到 ld.so.cache 中,如果没做,即使库文件明明就在 /usr/lib 下的,也是不会被使用的,结果编译过程中抱错,缺少xxx库,去查看发现明明就在那放着,搞的想大骂 computer 蠢猪一个。 (^_^)
在程序连接时,对于库文件(静态库和共享库)的搜索路径,除了上面的设置方式之外,还可以通过 -L 参数显式指定。因为用 -L 设置的路径将被优先搜索,所以在连接的时候通常都会以这种方式直接指定要连接的库的路径。
前面已经说明过了,库搜索路径的设置有两种方式:在环境变量 LD_LIBRARY_PATH 中设置以及在 /etc/ld.so.conf 文件中设置。其中,第二种设置方式需要 root 权限,以改变 /etc/ld.so.conf 文件并执行 /sbin/ldconfig 命令。而且,当系统重新启动后,所有的基于 GTK2 的程序在运行时都将使用新安装的 GTK+ 库。不幸的是,由于 GTK+ 版本的改变,这有时会给应用程序带来兼容性的问题,造成某些程序运行不正常。为了避免出现上面的这些情况,在 GTK+ 及其依赖库的安装过程中对于库的搜索路径的设置将采用第一种方式进行。这种设置方式不需要 root 权限,设置也简单:
复制代码
代码如下:
$ export LD_LIBRARY_PATH=/opt/gtk/lib:$LD_LIBRARY_PATH
可以用下面的命令查看 LD_LIBRAY_PATH 的设置内容:
复制代码
代码如下:
$ echo $LD_LIBRARY_PATH
最后,我来总结一下,PKG_CONFIG_PATH 主要指明.pc文件的所在路径,这样 pkg-config 工具就可以根据.pc文件的内容动态生成编译和连接选项,比如 Cflags (编译用)和 Libs (连接用),如果使用的是动态链接库,那么程序在连接和运行时,一般 Linux 系统把 /lib 和 /usr/lib 两个目录作为默认的库搜索路径,对于处于默认库搜索路径之外的库,系统管理员可以设置 LD_LIBRARY_PATH 环境变量或在 /etc/ld.so.conf 文件中添加库的搜索路径。值得说明的是,使用 gcc 连接时的选项,如果不用 pkg-config 工具,需要显示的声明连接的动态链接库名。使用 gcc 的同学可以查看下面的注意事项。
Linux 系统中,为了让动态链接库能被系统中其它程序共享,其名字应符合 lib*.so.* 这种格式。如果某个动态链接库不符合此格式,则 Linux 的动态链接库自动装入程序(ld)将搜索不到此链接库,其它程序也无法共享之。格式中,第一个*通常表示为简写的库名,第二个*通常表示为该库的版本号。如在我的系统中,基本C动态链接库的名字为 libc.so.6,线程 pthread 动态链接库的名字为 libpthread.so.0 等等。如果没有指定版本号,比如 libmy.so ,这也是符合要求的格式。
gcc 命令几个重要选项:
-shared 该选项指定生成动态连接库(让连接器生成T类型的导出符号表,有时候也生成弱连接W类型的导出符号,不用该标志外部程序无法连接。相当于一个可执行文件)。
-fPIC:表示编译为位置独立的代码,不用此选项的话编译后的代码是位置相关的所以动态载入时是通过代码拷贝的方式来满足不同进程的需要,而不能达到真正代码段共享的目的。
-L.:表示要连接的库在当前目录中。
-lmy:编译器查找动态连接库时有隐含的命名规则,即在给出的名字前面加上lib,后面加上.so来确定库的名称(libmy.so)。
当然如果有 root 权限的话,可以修改 /etc/ld.so.conf 文件,然后调用 /sbin/ldconfig 来达到同样的目的,不过如果没有 root 权限,那么只能采用输出 LD_LIBRARY_PATH 的方法了。