軟件項目在實際部署的時候,當客戶環境要求linux系統時,不可避免的需要將windows版本移植到linux系統中。下面來介紹linux系統下軟件開發的基礎及所遇到的問題。
1.Linux環境簡介
Linux版本號:num.num.num
其中第一個數字是主版本號,第二個數字是次版本號,第三個數字是修訂版本號.如果次版本號是偶數,那麼該內核就是穩定版的;若是奇數,則是開發版的.頭兩個數字合在一齊可以描述內核系列.如穩定版的2.6.4,它是2.6版內核系列。
1.2 Linux下應用軟件
語言及編程環境:c、c++、java、python和fortan等。
圖形環境:gnome、kde、gimp、windowmaker和icewm等。
編輯器:xemacs、vim、gedit和pico等。
shells:bash、tcsh、ash和csh等。
文字處理軟件:openoffices、kword和abiword等。
數據庫:mysql、postgresql和oracle等。
1.3 7個知識點
是大小寫敏感的系統;
文件名最多可以有256個字符;
文件名前面帶”.”的文件在輸入”ls”或者”dir” 命令時一般不顯示。可以把這些文件看作是隱含文件,當然你也可以使用命令”ls –a”來顯示這些文件;
目錄操作符,請用“/”代替“\”;
在Linux系統下,所有的目錄顯示在單一目錄樹下;
在配置文件裏,以#打頭的行是註釋行,總是在修改地方對應地加入一些關於修改的註釋,你會發覺在以後的管理中獲益多多;
和其他的多用戶操作系統類似,在Linux下,文件和目錄有自己的擁有者和訪問權限。學習一些關於文件權限管理的相關知識,否則你肯定會覺得Linux實在很麻煩。
2.基於文本的C/C++
爲什麼選擇文本編寫程序?
在以命令行方式啓動Linux,或者通過ssh 遠程登陸到某Linux 系統時,很可能只有vi這樣一個工具可以用來編寫程序。(何爲ssh:專爲遠程登錄會話和其他網絡服務提供安全性的協議。)
C/C++語言非常靈活,是衆多專業程序員最爲喜歡的編程語言之一。下面討論基於文本的C/C++編程問題,主要涉及:如何編寫程序,如何編譯,如何調試,如何運行。涉及的開發工具有GNU C/C++、GNU GDB。
2.1 vi 最基本操作
vi用不同的顏色表示不同的程序元素,增加了程序的可讀性,看起來也特別漂亮。好,下面結合一個簡單的例子,來討論vi的最基本操作。值得注意的是,vi支持的操作是非常豐富的,這裏只介紹最常用的操作。執行下面的指令,在當前目錄下建立一個文件名爲calculator.c的程序文件。如果該文件已存在,此命令將打開這個文件。
vi calculator.c
執行完上面的指令後,就進入了vi編輯界面。下面說說vi最基本的操作方法。進入編輯界面後,按i鍵就進入了“插入”模式,按Esc 鍵就退出了“插入”模式。如此可以來回切換。
不管哪種模式,都可以用光標鍵(←↑↓→)及Home、End、PageUp、PageDn鍵移動光標。這與圖形方式下的操作習慣是一致的。在“插入”模式下就可以輸入字符了。可以用Delete 和BackSpace鍵刪除字符。在非“插入”模式下可以執行一些帶冒號的指令。例如:w存盤,注意是輸入一個冒號後面再跟一個字母w。還有一些其他指令,列舉如下:
:wq 存盤並退出vi。
:q 退出vi。如果尚未保存,vi會提示,並拒絕退出。
:q! 不保存已做的修改,強制退出。
2.2 基於文本的C/C++
基本開發工具:
GNU C/C++(gcc/g++)、GNU GDB;
例:如果提示:bash: g++: command not foun,說明系統中沒有安裝g++,需要安裝。
Centos下:yum install gcc gcc-c++
ubuntu下:apt-get install gcc gcc-c++
(安裝軟件的另一種方式:
rpm -ivh XXX.rpm 卸載:rpm -e packgename)
2.3 GNU gdb 調試
如果編譯時,使用下面的指令(增加了參數-g),就會生成帶源代碼調試符號的可執行文件。編譯形成的可執行文件有7KB。之所以增加了2KB,就是因爲增加的調試符號。
gcc -o calc hello.c –g 或 g++ -o hw hello.cxx -g
進一步地,就可以執行下面的指令啓動調試工具進入調試環境對程序進行調試了。
gdb calc
在調試環境下,可以輸入下列指令來控制調試。
l 28 第一個字母是小寫的L,列出第28行附近的源程序。
b sum 在sum函數處設斷點
b 25 在第25行處設斷點
r 運行程序
n 單步執行,不進入函數
s 單步執行,進入函數
c 繼續連續執行
p choice 顯示變量choice 的值
q 退出調試環境
k 殺死程序
如果提示:bash: gdb: command not foun,說明系統中沒有安裝gdb,需要安裝。
圖2-3
3.集成開發環境的使用
QT是一個1991年由奇趣科技開發的跨平臺C++圖形用戶界面應用程序開發框架。它既可以開發GUI程序,也可用於開發非GUI程序,比如控制檯工具和服務器。Qt是面向對象的框架,使用特殊的代碼生成擴展(稱爲元對象編譯器(Meta Object Compiler, moc))以及一些宏,易於擴展,允許組件編程。
3.1 建立工程
圖3-1
圖3-3
3.2 動態鏈接庫的創建
TEMPLATE改爲lib
4.常見問題
4.1 時間函數
主要的兩個時間結構類型:
:長整形,保存從1970年1月1日0時0分0秒到現在時刻的秒數;
:struct tm:
{
int tm_sec; /* 秒 – 取值區間爲[0,59] */
int tm_min; /* 分 - 取值區間爲[0,59] */
int tm_hour; /* 時 - 取值區間爲[0,23] */
int tm_mday; /* 一個月中的日期 - 取值區間爲[1,31] */
int tm_mon; /* 月份(從一月開始,0代表一月) - 取值區間爲[0,11] */
int tm_year; /* 年份,其值等於實際年份減去1900 */
int tm_wday; /* 星期 – 取值區間爲[0,6],其中0代表星期天
int tm_yday; /* 從每年的1月1日開始的天數 – 取值區間爲[0,365]
int tm_isdst; /* 夏令時標識符,實行夏令時的時候,tm_isdst爲正。
不實行夏令時的進候,tm_isdst爲0;不瞭解情況時,tm_isdst()爲負。*/
};
char *asctime( const struct tm *ptr );
功能:函數將ptr所指向的時間結構轉換成下列字符串:
Mon Jun 26 12:03:53 2000
clock_t clock( void );
功能:函數返回自程序開始運行的處理器時間,如果無可用信息,返回-1。
轉換返回值以秒記, 返回值除以CLOCKS_PER_SECOND.
double difftime( time_t time2, time_t time1 );
功能:函數返回時間參數time2和time1之差的秒數表示。
struct tm *localtime( const time_t *time );
功能:函數返回本地日曆時間。
time_t mktime( struct tm *time );
功能:函數轉換參數time 類型的本地時間至日曆時間,並返回結果。
sleep()函數:
windows下:
#include <windows.h>
Sleep(1000),以毫秒爲單位;
Linux下:
#include "unistd.h"
sleep(1), 以秒爲單位
usleep(1000),以毫秒爲單位
4.2 日誌組件的使用
日誌組件是一個成熟的基於C++的庫,可以方便地引入程序中,實現關鍵代碼處的日誌記錄。
以下爲使用該日誌組件時所需的基本文件。
圖4-1
windows系統下,日誌組件的使用非常方便,只需將相應的.dll,.lib,及log4cxx.properties放入相應工程,並導入即可。由於日誌庫本身依賴於hpr庫,因此還需hpr.dll,hpr.lib文件。
圖4-2
在linux系統下使用日誌庫,需要更加繁瑣的步驟,與windows系統略有不同。步驟如下:
1、將相應.so共享庫放入相應工程;
2、編譯運行;
3、運行時會提示錯誤,找不到以下文件:libexpat.so.0
該文件一般存在於目錄/usr/lib下,如果是虛擬機環境,一般爲/usr/lib/vmware-tools/lib32。也可以使用命令方式來尋找該文件。Find -name 'libexpat.so.0',如果沒有,則鏈接libexpat.so.1,即
sudo ln -s /lib/libexpat.so.1.5.2 /usr/lib/libexpat.so.0。找到該文件,直接放入工程中,即可運行程序。
4.3 其他
4.3.1 多線程同步
定義對象互斥鎖:
pthread_mutex_t mutex = PTHREAD_MUTEX_INITIALIZER;
使用:
pthread_mutex_lock(&mutex);
g_trafficMap.clear();
pthread_mutex_unlock(&mutex);
4.3.2 Strace命令
strace可以跟蹤到一個進程產生的系統調用,包括參數,返回值,執行消耗的時間。
strace -f -T -tt -o a.txt ./cale
./cale爲執行程序命令,cale爲程序名。
4.3.3 複雜容器
複雜容器的定義,例如:
在windows下vector<pair<int, int>>v;正確
但在linux下會出現以下錯誤:
需要寫成:vector<pair<int, int> >v,即“>>”中間
多加一個空格“> >”
4.3.4 動態庫兼容問題
error:/usr/bin/ld:skipping incompatible ./libxxxx.so when searching for -lxxxx
可能是引用的庫可能跟當前操作系統位數不同的原因。
首先查看了當前系統下的位數 shell下輸入: getconf LONG_BIT
得知系統爲64位,再查詢庫文件編譯時的系統位數,shell下輸入:readelf -h libxxxx.so
返回CLASS一行顯示ELF32,可知該庫文件實在32位系統下編譯的。
readelf -h也可以查看可執行程序。
/usr/include/gnu/stubs.h:7:27: error: gnu/stubs-32.h: No such file or directory make: *** [TrafficInfo.o] Error 1
是缺少需要的程序包解決辦法:安裝缺少的包
yum install glibc-devel
但是如果在x86_64平臺下編譯32bits應用,則還需要安裝glibc-devel.i686,如下:
sudo yum -y install glibc-devel.i686
4.3.5 內存檢測工具
內存檢測:yum install valgrind
valgrind --tool=memcheck ./cale
圖4-4
4.3.6 安裝問題
在liunx系統安裝一些rpm軟件包時,經常會遇到如下錯誤,
warning: *****.rpm: Header V3 DSA signature: NOKEY, key ID e8562897 rpm Header V3 DSA signature: NOKEY, key ID rpm -ivh *****.rpm
warning: *****.rpm: Header V3 DSA signature: NOKEY, key ID e8562897
這是由於yum安裝了舊版本的GPG keys造成的。
解決辦法如下:
改爲 rpm -ivh *****.rpm --force --nodeps