嵌入式linux第一階段筆記

1.虛擬網絡編輯器(vm):三種模式:(VMnet0)橋接模式(vm和windows公用同個網絡(同個物理端口)),(VMnet1)僅主機模式,(VMnet8)NAT模式(vm鏈接一個虛擬的路由(WAN,LAN),windows也連在裏面(LAN口裏),造成一個局域網,具體的格式由WAN口發送)
2.安裝完Ubuntu18.0.4後(用戶名:lkb 密碼:lkb),而後要建立root並將root升級爲超級管理員
打開終端,輸入:sudo passwd root,而後輸入密碼(此時是註冊時的密碼)-輸入給root建立的密碼(此時123)-su -(將root升級爲超級用戶),su - 用戶名(從超級用戶切換到普通用戶)
3.更新操做系統的源泉,以即可如下載最新的安裝包
upt-get update
4.添加vim編輯器:apt install vim-nox(推薦下載vim-nox而不是vim)-輸入y肯定-等待下載完成-以後直接輸入vim便可-退出(:q),強退(:q!)
5.vim:命令模式:esc
編輯模式:i
6.sshd:SecureCRT客戶端
SSHD服務端 (更新SSHD服務端:apt-get install openssh-server)
經過CRT鏈接虛擬機的ip地址(ifconfig),來完成遠程登陸
7.SecureCRT下有個Zmodem,rz是從window中傳文件到vm中,sz是從vm中傳文件到windows中
8.samba服務(windows和linux之間數據通訊)也就是SMB:Server Message Block
9.CRT下安裝sanba服務器:sudo apt-get install samba
10.samba服務器的配置:/etc/samba/smb.conf(配置須要共享哪一個目錄,以及這個目錄的訪問權限)
sudo vi samba
而後在末端添加
[lkb_share]
comment = My share
path = /home/lkb/lab
writable = yes (可寫)
browseable = yes (可瀏覽)
11.在/etc/samba下建立samba用戶:sudo smbpasswd -a lkb ,密碼123
而後重啓一下smbd,nmbd; sudo /etc/init.d/smbd restart,sudo /etc/init.d/nmbd restart
12.在CRT裏面ifconfig一下,得到ip地址,在windows端cmd,輸入\\+ip地址
13.在CRT的/etc/samba 進入 /home/lkb/下,mkdir lab,進入lab/,而後就能夠進入Samba訪問了
14.第二種訪問形式便是在windows計算機映射網絡虛擬器,文件夾輸入\\+CRT下的ip+lkb_share,而後在windows計算機出現了網絡位置,至關於已u盤形式訪問linux(可鼠標操做複製黏貼,不用寫指令)
15.安裝source insight並破解(百度)
16.在虛擬機共享文件夾下新建Myapp文件,在Myapp文件下新建pro文件,用source insight新建工程放入pro文件下,.c文件放入Myapp下(pro的上一層目錄)
17.source insight添加已有工程,而後在project files將添加的工程右鍵Synchronize Files,將文件同步進去
18.在linux下輸入gcc -v 可查看是否安裝了gcc,沒有的話能夠用指令apt-get install gcc安裝
19.可使用vi xx.c新建c文件(後綴名必須爲.c,gcc對後綴名很是敏感),而後gcc -o 輸出的文件名 xx.c來編譯,無錯誤則./輸出的文件名便可查看編譯結果
20.預處理:cpp -o xx.i yy.c
替換:gcc -E
編譯:gcc -S
彙編:gcc -c
連接:gcc -o
21.#include後用""包含的.h文件是自定義的,<>包含的是系統庫的
22.not find 頭文件的話能夠用gcc -I跟查找文件的目錄
23.#define 宏名 宏體 (宏體最好加上括號)
24.預約義宏
__FUNCTION__ :函數名
__LINE__:行號
__FILE__:文件名
25.gcc -DABC ==#define ABC
26.# 字符串化 #x === "x"
## 鏈接符號 day##x === dayx
27.數據類型:char,short,int,long,unsigned,signed,float,double(8字節),void
28.struct(結構體):元素之間的和
struct myabc{
unsigned int a;
unsigned int b;
unsigned ing c;
}
struct myabc mybuf;
union(共用體):公用起始地址的一段內存
union myabc{
char a;
int b;
}
union myabc abc;
29.sizeof()默認是unsigned long 類型,則基本不用%d 而是用%lu
30.enum {MOD,TUE,WED}(被命名的整型常量的集合),從左到右依次加1,若是第一個沒有賦值,默認爲0
31.類型修飾符
auto:分配的內存可讀可寫的區域(區域若是在{}裏面,即在棧空間裏面)
register:限制變量定義在寄存器上的修飾符
定義一些快速訪問的變量,編譯器會盡可能的安排CPU的寄存器去存放這個定義的變量,若是寄存器不足時,這個定義的變量仍是放在存儲器中(內存(存儲器) 寄存器)

&取地址這個符號對register不起做用
static:靜態變量
const:常量的定義,只讀的變量
volatile:告知編譯器編譯方法的關鍵字,不優化編譯
修飾變量的值的修改,不只僅能夠經過軟件,也能夠經過其餘方式(硬件外部的用戶)
32.算數運算符(+,-,*,/,%)
%:n%m=[0~m-1]
邏輯運算{ ||、%% (A||B(當A爲真的時候就不用判斷B了),A&&B(當A爲假的時候就不用判讀B了),AB交換結果是不同的)
>、>=、<、<=
!
? :
}
位運算{<<(左移,乘以2的倍數)、>>(右移,除以2的倍數)
&、|、 (將某一位置爲高電平:a|(0x1<<5),清除某一位:a&~(0x1<<5))
^, ~ (a=a^b,b=a^b,a=a^b,能夠互換ab兩個值)

33.-1的二進制表達式:11111111
10000001
取反後 11111110
補碼爲 11111111(即爲計算機中-1的二進制表達式)
34.指針:內存類型資源地址、門牌號的代名詞
在32bit系統中,指針就4個字節
35.指針讀取內存的方法:int *p 讀取32位地址,char *p讀取8位地址
36.const:常量、只讀(不能變)
左數右指
37.char *p ="hello";此時沒法經過*p='a'來修改其中的第一個字符
char buf[]={"hello"};
char *p2=buf;此時能夠經過*p2='a'來修改其中的第一個字符
38.指針的加法、減法運算,實際上加的是一個單位,單位的大小可使用sizeof(p[0])
p++,p--:更新地址
p+1:[*p+1*(sizeof(*p))]
*(p+n)=p[n]
39.指針必須是同類型的比較纔有意義
指針跟一個特殊值進行比較 0x0:地址的無效值,結束標誌
40.二級指針:指向指針的指針,即一個指針指向的是另外一個指針
int a =100;int *p1 = &a;int **p2 = &p1;
41.數組的定義:定義一個空間:一、大小 二、讀取方式
數據類型 數組名[m] m的做用域是在申請的時候
數組名是一個常量符號,必定不要放到=的左邊
42.字符拷貝函數的原則:內存空間和內存空間的逐一賦值的功能的一個封裝體(strcpy,strncpy)
一旦空間中出現了0這個特殊值,函數就即將結束
43.非字符串空間拷貝:memcpy(void *dest,const void *src,size_t n)
44.定義一個指針,指向int a[10]的首地址:int *p1=a;
定義一個指針,指向int b[5][6]的首地址:int (*p2)[6]=b;
45.字節對齊: 在結構體中,結構體最終的大小必定是4的倍數
結構體裏成員變量的 順序不一致,也會影響到它的大小
小於四字節的按四字節算,大於的按八字節或以上算
例如:struct abc{ struct abc2{
char a; char a;
short b; int c;
int c; short b;
}: (8字節) }:(12字節)linux

46.內核分佈
內核空間 應用程序不準訪問
-----------------------------3G
棧空間 局部變量 RW (函數執行完自動釋放空間)
------------
運行時的堆空間 malloc
----------------
全局的數據空間(初始化的,未初始化的) static RW data(數據段),bss(未初始化的數據段)
只讀數據段 "Hello World" 字符串常量 (雙引號其實就是一個地址,裏面的值修改不了) R text(代碼段)
代碼段 R text(代碼段)
---------
0x0
47.size + 編譯後的文件名 則能夠查看函數的代碼段運行的具體數據
nm + 編譯後的文件名 則能夠看段名
48.堆空間:運行時纔有,能夠自由,自我管理的分配和釋放的空間,生存週期是又程序員來決定
分配:malloc(),一旦成功,返回分配好的地址給咱們,只須要接受,對於這個新地址的讀法,又程序員靈活把握,輸入參數指定分配的大小,單位就是B
char *p; p=(char *)malloc(n);if(p==NULL){ error } malloc(n*sizeof(char))
釋放:free(q)
棧空間:運行時纔有 ,函數一旦返回就釋放,生存週期內是函數內
只讀空間:靜態空間,整個程序結束時釋放內存,生存週期最長
49.函數具有三要素:函數名(地址),輸入參數,返回值
50.例子:
int (*myshow)(const char *,...);(和printf函數同樣的函數名)
printf("the printf is %p\n",printf);
myshow=printf;
myshow("===========\n");
經過上面這樣操做,myshow就具有了printf同樣的功能,輸出=========
51.地址傳遞:上層調用者讓下層子函數修改本身空間值的方式
相似結構體這樣的空間,函數與函數之間調用關係
連續空間的傳遞
52.const char *p:只讀空間,爲了讓空間看看
char *p:該空間可能修改
53.字符空間:char *p strlen,strcpy (結束標誌:0)
非字符空間:unsigned char *p,int *p......,memcpy,void * (結束標誌:數量)
結束標誌:內存裏面存放了0x00(1B),字符空間
非字符空間0x00,不能當成結束標誌
54.返回值返回類型:基本數據類型、指針類型(空間),不能返回數組
55.返回連續空間類型:指針做爲空間返回的惟一數據類型(函數內部實現:1.靜態區 2.只讀區 3.堆區)
地址:指向的合法性
做爲函數的設計者,必須保證函數返回的地址所指向的空間是合法的(不是局部變量)
例子:char *fun(void)

char buf[]="hello world";
return buf;

int main()
{
char *p;
p=fun();
printf("the p is %s\n",p);
return 0;
}
這個例子輸出不來hello world,由於在fun函數中,buf[]是局部變量,函數一返回地址就自動釋放,而函數返回buf其實就是返回buf[]的地址,故返回的是NULL。
在 char buf[]="hello world"; 前加static便可將局部變量變爲靜態變量,存放在全局數據區,函數返回地址就不會被釋放
56.嵌入式工程系面試必備的0x10道題目:(網頁收藏夾查看其餘題目以及解析)
1.用預處理指令#define 聲明一個常熟,用以代表1年中有多少秒(忽略閏年問題)
#define 宏名 宏體 (宏名:大寫字母表示)
#define SECOND_OF_YEAR (365*24*3600)UL (UL代表無符號長整型)
2.數據聲明
(1)一個整型數:int a;
(2)一個指向整型數的指針:int *a;
(3)一個指向指針的指針,它指向的指針是指向一個整型數:int **a;
(4)一個有10個整型數的數組:int a[10];
(5)一個有10個指針的數組,該指針是指向一個整型數的:int* a[10];
(6)一個指向有10個整型數組的指針:int (*a)[10];
(7)一個指向函數的指針,該函數有一個整型參數並返回一個整型數:int (*a)(int);
(8)一個有10個指針的數組,該指針指向一個函數,該函數有一個整型參數並返回一個整型數:int (*a[10])(int);
3.修飾符的使用總結
(1)關鍵字static的做用是什麼?
修飾局部變量:默認局部變量在棧空間存在,生存期比較短
加上static後局部靜態化,局部變量在靜態數據段保存,生存期很是長
修飾全局變量:編譯時防止重命名,限制變量名只在本文件內起做用
修飾全局函數:編譯時防止重命名,限制該函數只在x本文件內起做用
(2)關鍵字const有什麼含意
C:只讀,建議性,不具有強制性 !=常量
C++:常量
(3)關鍵字volatile有什麼含意?並給出三個不一樣的例子
防止C語言編譯器的優化
它修飾的變量,該變量的修改可能經過第三方來修改
a.並行設備的硬件寄存器(如:狀態寄存器)
b.一箇中斷服務子程序中會訪問到的非自動變量(Non-automatic variables)
c.多線程應用中被幾個任務共享的變量
4.位操做
嵌入式系統老是要用戶對變量或寄存器進行位操做,給定一個整型變量a,寫兩段代碼,第一個設置a的bit3,第二個清除a的bit3,在以上倆個操做中,要保存其餘位不變
unsigned int a;
a|=(0x1<<3);
a&=~(0x1<<3);
5.訪問固定內存位置
在某工程中,要求設置一絕對地址爲0x67a9的整型變量的值爲0xaa66,編譯器是一個純粹的ANSI編譯器,寫代碼去完成這一任務
int *p=(int *)0x67a9;
p[0]=0xaa66;
或者
*((int*)0x67a9)=0xaa66;
或者
((void(*)(void))0x67a9();
6.寫一個"標準"宏MIN ,這個宏輸入兩個參數並返回較小的一個。
#define MIN(A,B) ((A) <= (B) ? (A) : (B))
7.預處理器標識#error的目的是什麼?
#error預處理指令的做用是,編譯程序時,只要遇到#error就會生成一個編譯錯誤提示消息,並中止編譯
8.嵌入式系統中常常要用到無限循環,你怎麼樣用C編寫死循環呢?
(1).while(1){};
(2).for(;;){};
(3).Loop:
...
goto Loop;

LINUX
57.ctrl+alt+F2,F3,F4,F6:圖形轉命令界面
ctrl+alt+F7:命令轉圖形界面
若是不是從圖形界面切換到tty模式,而是系統啓動時候直接進入的命令行模式,在登錄後可使用」startx」來啓動圖形界面。
58.文件系統分類
磁盤文件系統:NTFS.EXT3
閃存文件系統:JFFS2,YAFFS
數據庫文件系統:BFFS,WINFS
網絡文件系統:NFS
虛擬文件系統:VFS(Proc)
59.Linux文件類型
普通文件:-
目錄文件:d
連接文件:l
塊設備:b
字符設備:c
Socket:S
普通文件:p
60.Linux文件屬性
藍色:目錄
綠色:可執行
淺藍色:鏈接
紅色:壓縮
灰色:其餘n
黃色:字符設備
61.命令行格式
$command [option(s)] [arguments]
命令行 空格 選項 空格 參數
62.命令行編輯
命令行別名使用
alias alias-name='value' 創建別名
alias 列出已經創建的別名列表
unalias 取消別名
63.shell的特殊字符
1.通配符: *,?,[]
*,通配0個或多個字符
?,通配任意單個字符
[s],通配某個範圍內的任意一個字符
2.一行執行多條指令: ;(例如:cd ; ls 先進入根目錄再ls全部)
3.輸入輸出重定向:>,<,>>
輸出重定向:>,>>
>:將一個命令的輸出放入文件而非屏幕 (例如 pwd > 1.txt,在1.txt中會顯示當前的目錄)
>>:輸出重定向但不會把原文件覆蓋,在原文件末尾追加
輸入重定向:< 從標準輸入設備鍵盤輸入
4.管道符:|
將一個進程的輸出做爲另外一個進程的輸入(例如:ls -l /etc | more 讓etc下的目錄按分頁顯示)
5.其餘,%,$,~
%:做業控制,提示符等
$:取某一列的值,取變量值等
64.聯機幫助
man name
man -k keyword
spacebar 翻屏或翻頁
Enter 翻行
b 向前翻一屏或一頁
f 向後翻一屏或一頁
q 退出
/string 查找前面符合string指定的信息
n 查找下一個符合string指定的信息
65.清屏
clear
66.歷史記錄
history
history n
!n
!1
方向上鍵
67.查看文件和目錄
pwd :顯示當前工做目錄
cd:改變當前工做目錄
ls:列出當前目錄的文件和子目錄
ls -a:列出全部目錄、子目錄、文件和隱藏文件
ls -R:列出從當前目錄開始的全部的子目錄、文件而且一層層往下顯示
ls -F:列出文件、文件名並顯示出文件類型
ls -t:以修改時間爲時間倒敘來列出文件、子目錄
ls -l: 以長列表格式顯示文件、目錄的詳細信息
file:file filename 列出文件類型
68.建立文件
touch filename
filename 不存在則建立一個新的空文件
filename 存在則更新該文件的修改訪問時間
69.建立目錄
mkdir [-p] directory_name
-p 目錄不存在時能夠創建目錄
70.刪除文件
rm [-i/f] filename(s)
-i 詢問是否刪除
-f 強制刪除
71.刪除目錄
rmdir directory_name(s) 刪除空目錄
rm -r[i] directory_name(s)
-r 刪除非空目錄
-i 刪除前訪問是否刪除
72.顯示文本文件內容
cat:不分屏顯示文本內容
把小文件鏈接成大文件
cat filename(s)
more:more filename(s)分屏顯示
spacbebar 向下顯示一屏
Enter 向下顯示一行
b 向上一屏
f 向下一屏
h 顯示幫助菜單
q 退出
/string 查找字符串string
n 查找下一個string
head:查找文件的前多少行
head [-n] filename(s)
tail:查找文件的末尾多少行
tail [-n] filename(s)
73.拷貝和移動文件目錄
cp
拷貝複製文件目錄
拷貝文件
cp [-i] source_file destination_file
cp [-i] source_file(s) destination_directory
-i選項做用,當目標文件存在,會詢問是否覆蓋,沒有-i選項則不詢問直接覆蓋

拷貝目錄
cp -r source_directory(s) destination_directory(s)
mv
移動文件目錄或重命名文件目錄
mv [-i] source_file target_file 重命名源文件爲目標文件
mv [-i] source_file target_directory 移動文件到目標目錄
74.文件目錄權限
r 讀權限:能夠打開文件、目錄讀取查看
w 寫權限:對文件、目錄能夠編寫更改
x 執行權限:對文件可執行(可執行文件)、對目錄可查找該目錄下的內容
- 沒有權限:如ls -l -rwxr-xr-x
權限所屬對象
擁有者:生成文件或目錄時登錄的當前人,權限最高,用u表示
同組人:系統管理員分配的同組的一個或幾我的,用g表示
其餘人:除擁有者,同組人之外的人,用o表示
全部人:包括擁有者、同組人及其餘人,用a表示

chmod:修改文件目錄的訪問權限,修改權限的前提條件是在修改權限時要注意本身是文件
(1)使用字母表示權限
chmod mode filename
mode: who cp permission(s)
u 擁有者 = 設置權限 r
g 同組人 + 添加權限 w
o 其餘人 - 刪除權限 x
a 全部人
例如:chmod u=r,g+w,o-x filename
(2)使用八進制數字來表示權限
r w x
0 0 0 無權限
1 1 1 有權限
例如:chmod 555 filename
chown:更改某個文件或目錄的屬主和屬組,可用於受權
chown [選項] 用戶或組 文件
chown將指定文件的擁有者改成指定的用戶或組,用戶能是用戶名或用戶ID,組能是組名或組ID
文件是以空格分開的要改動權限的文件列表,支持通配符

-R 遞歸式地改動指定目錄及其下的全部子目錄和文件的擁有者
-v 顯示chown命令所作的工做
chgrp:改動文件或目錄所屬的組
chgrp [選項] group filename
該命令改動指定指定文件所屬的用戶組,其中group能是用戶組ID,也能是/etc/group文件中用戶名的組名
文件名是以空格分開的要改動屬組的文件列表,支持通配符
若是用戶不是該文件的屬主或終極用戶,則不能改動該文件的組

-R 遞歸式地改動指定目錄及其下的全部子目錄和文件的屬組
chgrp -R book /opt/local/book
改動/opt/local/book/及其子目錄下的全部文件的屬組爲book
75.查找文件
find
find file path expression [action] 查找文件和目錄
前提條件:要對被查找的目錄及其全部子目錄有讀權限才能查找
查找選項:經過文件屬性來查找
-name 按文件名
-user 按用戶(文件屬主)
-size 按大小
-mtime 按最後一次修改時間
-atime 按最後一次訪問時間
-type 按文件類型 f:flie d:directory
-perm 按權限
例如:find / -name b*
locate
locate [-d <數據庫文件>][--help][--version][keywords]
locate指令用於查找符合條件的文件,它會去保存文件與目錄名稱的數據庫內查找合乎範本樣式條件的文件或目錄
-d<數據庫文件>--database=<數據庫文件>,設置locate指令使用的數據庫
--help 在線幫助
--versio 顯示版本信息
76.過濾與統計
grep:查出包含某些字符串的結果,對文件或輸出結果進行過濾,大小寫敏感
grep [option(s)] string filename
-l 忽略大小寫
-v 反向匹配(查出不包含字符串的結果)
wc:統計文件或輸出結果
wc [option(s)] filename(s)
-l 統計多少行
-w 統計多少個單詞
-c 統計多少個字符
77.日期時間與進程查看
date:顯示當前日期
cal:顯示日曆
cal 月份 年份
cal 顯示當前月份的日曆
cal 年份
ps:列出當前系統中已在運行的進程
進程,一個能完成必定功能的一個程序
ps [options]
ps -e 列出正在運行的進程
-f 列出一個完整的進程列表形式
-U 查找出由某個用戶啓動的進程
-auwx 列出一個完整的進程列表形式,形式與-f不同
78.切換用戶、設置普通用戶的超級權限與關機重啓
su
su 用戶名
sudo
sudo 命令行
shutdown:安全的關閉或重啓Linux系統
shutdown [-etFhknr][-t 秒數][時間][警告信息]
-c:當執行"shutdown -h 11:50"指令時,只要按+鍵就可中斷關機的指令
-f:從新啓動時不執行fsck
-F:從新啓動時執行fsck
-h:將系統關機
-k:只是送出信息給全部用戶,但不會實際關機
-n:不調用init程序進行關機,而由shutdown本身進行
-r:shutdown以後從新啓動
-t<秒數>:送出警告信息和刪除信息之間要延遲多少秒
[時間] 設置多久時間後執行shutdown指令
[警告信息] 要傳送給全部登入用戶的信息
#shutdown -r +10 系統在十分鐘後關機而且立刻從新啓動
#shutdown -h now 系統立刻關機且不從新啓動
reboot
reboot的工做過程差很少跟halt同樣,不過它是引起主機重啓,而halt是關機,它的參數與halt相差很少
79.用戶管理
用戶密碼設置要求:6-8個字符,至少包含2個字母,1個數字或特殊符合
不一樣於用戶ID,不一樣於之前的密碼,而且至少3個字符不一樣於之前的密碼
修改密碼命令:passwd
查找用戶
id:查看用戶ID(用戶名),所屬組ID(組名)
users:查看已經登錄到當前系統中的用戶,只顯示出用戶名
who:查看用戶的詳細信息
who am i:查看當前用戶本身的信息
whoami:查看當前用戶本身的用戶名
80.查看磁盤信息
du:顯示磁盤使用摘要信息
du以Block爲單位方式顯示
-k 以k字節方式顯示
-m 以m字節方式顯示
-s 顯示當前目錄下的內容總的佔用磁盤的大小,以Block爲單位
以Block單位顯示的數字是以k字節方式顯示的數字的2倍:1k字節=2個Block
df:顯示整個文件系統的空間使用磁盤狀況
-k 以k字節方式顯示
81.查看網絡鏈接
ping:查看當前機器與另外一臺機器的聯通情況
ping 主機ID/主機名
向ping後面的主機發送數據包,若被ping的主機有回覆則代表是聯通的
ifconfig:查看和配置當前機器的網絡參數信息
ifconfig -a:顯示查看當前機器的IP、Netmask、Gateway等網絡信息
ifconfig eth0 up(down) 激活與關閉某個網絡適配卡(關閉後ifconfig查看不到eth0,ifconfig -a能夠查看到)
ifconfig etho [ipaddress] 或者 netmask [address] 設置IP和子網掩碼 (重啓Ubuntu後又恢復默認狀態)
82.Linux下安裝卸載應用程序的方式
安裝包離線安裝和卸載:dpkg
dpkg -i <package> 安裝包
dpkg -p <package> 移除包和配置文件
源文件編譯安裝和卸載:配置configure、編譯make和安裝make install
程序管理包在線安裝和卸載:aptitude
apt-get install <package> 安裝
apt-get remove -purge <package> 卸載徹底
83.vi:vi filename
filename不存在則建立filename文件並可編輯和保存退出
filename存在則打開文件編輯
vi使用的三種模式:命令模式(k 向上;j向下;h向左;l向右;0移動到行首;$移動到行尾;G移動到文件末尾;1G移動到文件首;[n]G移動到第[n]行;[n]+向下移動[n]行;[n]-向上移動[n]行)
輸入模式
末行模式(set nu 設置行號;set nonu 取消行號)
經過vi打開或者新建一個文件的時候,按o進入下一行,按a進入當行下一個,按i當前位置輸入
最後行(末行模式):按 : ! ?

GNU開發環境基礎
84.GCC程序編譯過程程序員

預處理 編譯 彙編 連接
c源代碼---------->.i預編譯文件------>.s彙編文件------>.o目標文件----->可執行文件
GCC支持的後綴名
.c:C原始程序
.C/.cc/.cxx:C++原始程序
.m:Objective-C原始程序
.i:已經預處理的C原始程序
.ii:已經預處理的C++原始程序
.s/.S:彙編語言原始程序
.h:預處理文件(頭文件)
.o:目標文件
.a/.so:編譯後的庫文件,靜態庫和動態庫
85.編譯過程參數
-c:只編譯不連接,生成目標文件
-S:只編譯不彙編,生成彙編代碼
-E:只預編譯
-g:包含調試信息
-o file:指定目標輸出文件
-Idir:搜索頭文件路徑
具體編譯過程:
gcc -E xxx.c -o xxx.i
gcc -S xxx.i -o xxx.s
gcc -c xxx.s -o xxx.o
gcc xxx.o -o xxx (或者直接gcc xxx.c -o xxx,省略前面三步)
./xxx(執行可執行文件)
gcc -g xxx.c -o xxx (包含調試信息)
gcc -I+路徑 xxx.c -o xxx(會在指定路徑下尋找頭文件)
86.庫選項
linux下靜態連接庫和動態連接庫格式
.a[libname.a]
.so[libname.so]
-static 靜態編譯
-shared 生成動態庫文件、進行動態編譯
-L dir 庫文件搜索中添加路徑
-fPIC 生成使用相對位置無關的目標代碼,而後一般用於使用gcc的-static選項從該PIC目標文件生成動態庫文件
編譯靜態連接庫
1.先生成目標文件 .o
2.打包:ar crv [*.a][*.o]
調用靜態連接庫
gcc -o [file] [file.c] -L.
編譯動態連接庫
1.生成位置無關的目標代碼gcc -fPIC -c [*.c]
2.gcc -shared -o [*.so] [*.o]
調用動態連接庫
gcc -o [file] [file.c] -L.
87.警告選項
-w 關閉全部警告
-Wall 發出gcc提供的全部有用的警告
-pedantic 發出ansic的全部警告
88.優化選項
-Olevel 優化等級,通常只是最終發佈的時候才用
89.gcc編譯
編譯和安裝gcc工具包須要幾個類庫:gmp(須要依賴m4,直接sudo apt-get install m4便可),mpfr(須要依賴gmp),mpc(須要依賴gmp,mpfr)
將gmp,mpfr,mpc,gcc四個包解壓到當前目錄下,而後分別一次安裝配置,順序都是:./configure ---> make ---> sudo make install
90.gdb調試
gcc -g xxx.c -o xxx
gdb xxx (便可進入調試)
查看程序
打斷點:b(reak) 函數名
b(reak) 行號
b(reak) 文件名:行號
b(reak) 行號 if 條件
查看斷點:info break (簡寫:i b)
刪除斷點: delete 斷點號(簡寫:d 斷點號)
運行:r(un),c(ontinue),q(uit)
單步調試:n(ext) -- step over
s(tep) -- step into
f(inish) -- step return
繼續運行:continue
打印值:p(rint)值
監控值:w(atch)值
wi(特別的模式)
91.Makefile
gnu的make做用:工程文件組織,編譯成複雜的程序
安裝及卸載咱們的程序
新建三個.c文件 main.c,func1.c,func2.c,其中main.c的調用func1,func2
將這三個.c文件編譯成main.o,func1.o,func2.o
新建makefile,最後輸出hello
makefile裏面寫代碼:hello:main.c func1.c func2.c
gcc main.c func1.c func2.c -o hello
而後make後生成hello
./hello執行 面試

makefile裏面代碼能夠換成:hello:main.o func1.o func2.o
gcc main.o func1.o func2.o -o hello
main.o:main.c
gcc -c main.c
func1.o:func1.c
gcc -c func1,c
func2.o:func2.c
gcc -c func2.c
能夠在makefile裏面再加入代碼:
clean:
rm main.o func1.o func2.o hello
install:
cp hello /usr/local/hello
uninstall:
rm /usr/local/hello
而後直接make +clean/install/uninstall就能夠執行了

Makefile由若干條的規則構成
每一個規則又是這樣的:
targets(目標):prerequisites(依賴)
commandshell

1.makefile變量:
用戶自定義變量:在新建的makeflile中,能夠隨便定義一個變量=xxx,要使用這個變量只需$(+變量)便可,若是在=前面加上:的話代表該變量不會遞歸(遞歸就是=號後邊再有變量是不會去增長的)
預約義變量:AR :庫文件維護程序的名稱,默認值爲ar
AS: 彙編程序的名稱,默認值爲as
CC: C編譯器的名稱,默認值爲cc
CXX:C++編譯器的名稱,默認值爲g++
ARFLAGS:庫文件維護程序選項,無默認值
ASFLAGS:彙編程序選項,無默認值
CFLAGS: C編譯器選項,無默認值
CXXFLAGS:C++編譯器選項,無默認值
自動變量及環境變量:
$*:不包含擴展名的目標文件名稱
$<:第一個依賴文件名稱
$?:全部時間戳比目標文件晚的依賴文件
$@:目標文件完整名稱
$^:全部不重複的依賴文件
2.make工做流程
make會在當前目錄下找名字叫「Makefile」或「makefile」的文件
若是找到,它會找文件中的第一個目標文件(target)並把這個文件做爲最終的目標文件
根據時間戳生成目標文件
遞歸去尋找目標文件依賴文件,而且遞歸生成(一樣有時間戳問題)
3.引用其它makefile及makefile嵌套
包含:include pro/makefile
嵌套:subsystem:
cd subdir && gcc -c main.c
等價於:
subsystem:
gcc -c main.c -C subdir
4.條件判斷(放在行開頭,不能空格)
foo:
ifeq ($(CC).gcc)
.......
else
.......
endif
5.使用函數
6.makefile管理命令
-C dir 讀入指定目錄下面的makefile
-f file 讀入當前目錄下的file文件爲makefile
-i 忽略全部命令執行錯誤
-l dir 指定被包含的makefile所在目錄
7.僞目標:沒有依賴關係,也不會生成文件
clean:
gcc -c main.c
但爲了避免和已經生成的同名文件衝突,咱們能夠指定clean是個僞目標
.PHONY:clean
clean:
gcc -c main.c
用僞目標生成多個文件
all:prog1 prog2 prog3
.PHONY:all
prog1:prog1.o utils.o
cc -o prog1 prog1.o utils.o
prog2:prog2.o
cc -o prog2 prog2.o
prog3:prog3.o sort.o utils.o
8.makefile規則
顯示規則
隱式規則:
OBJS=kang.o yul.o
CC=gcc
CFLAGS=-Wall -o -g
davild:$(OBJS)
$(CC)$^ -o $@

問題:
源文件或者依賴文件不少怎麼辦?
makefile分開多文件或者分級
output不只僅一個文件怎麼辦?
用多個makefile文件,相互include(嵌套)
使用僞目標make all
92.Autotools
1.創建hello.c
2.autoscan掃描,生成configure.scan文件
3.將 configure.scan更名成 configure.ac或者 configure.in :mv configure.scan configure.ac
4.編輯configure.ac文件
將第五行改爲AC_INIT(hello,1.0,945105629@qq.com)
第八行增長 AM_INIT_AUTOMAKE(hello,1.0)
註釋第七行
將最後一行改爲 AC_OUTPUT(Makefile),讓其最後輸出文件爲Makefile
5.aclocal 生成aclocal.m4和autom4te.cache文件
6.autoconf 生成configure文件
7.創建vi Makefile.am(am是automake的縮寫)
寫入:bin_PROGRAMS = hello
hello_SOURCES = hello.c
8.automake --add-missing
9.創建文件:touch NEWS README AUTHORS ChangeLog
10.再執行automake --add-missing 生成Makefile.in
11../configure生成configure.status 和Makefile
12.make 後便可生成hello
13../hello便可
14.sudo make install後就會在/usr/local/bin/hello下生成hello,這樣在任何目錄下面輸入hello均可以執行hello.c
15.make dist後生成這個hello.c的壓縮包,能夠取出來供別人下載數據庫

//在第四步的時候能夠不註釋第七行,而後繼續執行5,6步,接着執行autoheader 生成configure.h.in文件,而後接着從第八步開始執行
express

Autotools流程:
autoscan
aclocal
autoconf
[autoheader]
automake
93.Linux下eclipse的開發
Linux下安裝Eclipse
JDK下載,安裝及配置
Eclipse(CDT下載),安裝
Eclipse使用(調試及編譯)
1.下載jdk和eclipse安裝包
2.複製到download下
3.解壓
4.將解壓的jdk文件夾複製到/usr/local/bin下
5.配置jdk環境 sudo vi /etc/profile
在第四行添加
export JAVA_HOME=/usr/local/jdk1.8.0_11
export PATH=$PATH:$JAVA_HOME/bin
6.進入解壓到的eclipse文件夾下
7. ./eclipse啓動eclipse

編程

相關文章
相關標籤/搜索