Linux下項目開發工具(gcc,makefile,git)

GCC編譯器

簡介

GCC(GNU Compiler Collection,GNU編譯器套件// GUN is Not Unix),是由 GNU 開發的編程語言編譯器。它是以GPL許可證所發行的自由軟件,也是 GNU計劃的關鍵部分。GCC原本作爲GNU操作系統的官方編譯器,現已被大多數類Unix操作系統(如Linux、BSD、Mac OS X等)採納爲標準的編譯器,GCC同樣適用於微軟的Windows。
GCC 原名爲 GNU C 語言編譯器(GNU C Compiler),因爲它原本只能處理 C語言。GCC 很快地擴展,變得可處理 C++。後來又擴展能夠支持更多編程語言,如Fortran、Pascal、Objective-C、Java、Ada、Go以及各類處理器架構上的彙編語言等,所以改名GNU編譯器套件(GNU Compiler Collection)。

執行過程

使用gcc由C語言源代碼文件生成可執行文件的過程不僅僅是編譯的過程,而是要經歷四個相互關聯的步驟∶預處理、編譯、彙編和鏈接。
命令gcc首先調用cpp進行預處理,在預處理過程中,對源代碼文件中的文件包含、預編譯語句進行分析。接着調用cc1進行編譯,這個階段根據輸入文件生成以.i爲後綴的目標文件。彙編過程是針對彙編語言的步驟,調用as進行工作,一般來講,.S爲後綴的彙編語言源代碼文件和彙編、.s爲後綴的彙編語言文件經過預編譯和彙編之後都生成以.o爲後綴的目標文件。當所有的目標文件都生成之後,gcc就調用ld來完成最後的關鍵性工作,這個階段就是連接。在連接階段,所有的目標文件被安排在可執行程序中的恰當的位置,同時,該程序所調用到的庫函數也從各自所在的檔案庫中連到合適的地方。

gcc格式

gcc [-c|-S|-E] [-std=standard]
           [-g] [-pg] [-Olevel]
           [-Wwarn...] [-Wpedantic]
           [-Idir...] [-Ldir...]
           [-Dmacro[=defn]...] [-Umacro]
           [-foption...] [-mmachine-option...]
           [-o outfile] [@file] infile...

這裏寫圖片描述


動態庫靜態庫的生成

動態庫編譯

gcc -fpic -shared a.c b.c -o libtest.so

鏈接不到動態庫的解決方案

export LD_LIBRARY_PATH=.  // 設置環境目錄
sudo cp libtest.so /usr/lib  // 把庫拷貝到系統庫目錄

通過代碼鏈接動態庫

#include <dlfcn.h>

typedef void(*func)();

int main()
{
    void* funlib = dlopen("use/lib/libtest.so",RTLD_LAZY);

    func myfunc = (func)dlsym(funlib, "foo");
    mufunc();

    dlclose(funlib);
}

關於插件功能的簡單實現

#include <stdio.h>
#include <dlfcn.h>
#include <dirent.h>
typedef void(*func)();

int main()
{
    char buf[256];
    DIR* dir = opendir("./xxx");    
    struct dirent* entry;
    while(entry = readdir(dir))
    {
        if(entry->d_name[0] == '.') continue;

        sprintf(buf, "./xxx/%s", entry->d_name);

        void* handle = dlopen(buf, RTLD_LAZY);

        func myfunc = (func)dlsym(handle, "foo");
        myfunc();

        dlclose(handle);
    }
}

靜態庫打包

ar rcs libtest.a a.o b.o   // 通過gcc -c a.c編譯成.o文件

當同時存在動態靜態庫時,通過-l鏈接的優先是鏈接動態庫 加上-static則是默認所有鏈接都是靜態庫


項目管理Makefile

簡介

make是一個命令工具,它解釋Makefile 中的指令。在Makefile文件中描述了整個工程所有文件的編譯順序、編譯規則。Makefile 有自己的書寫格式、關鍵字、函數。像C 語言有自己的格式、關鍵字和函數一樣。而且在Makefile 中可以使用系統shell所提供的任何命令來完成想要的工作。Makefile在絕大多數的IDE 開發環境中都在使用,已經成爲一種工程的編譯方法。

基本元素

目標: 依賴
     命令
  • 目標:目標文件, 可以是 Object File, 也可以是可執行文件

  • 依賴:生成 target 所需要的文件或者目標

  • 命令: make需要執行的命令

目標可以有多個依賴,依賴有傳遞性。make命令去執行Makefile,Makefile的名字固定爲Makefile或者makefile,如果名字不是固定的名字,需要用-f指定makefile。

make默認生成第一個依賴項。如果想生成其他依賴項,直接在make後跟依賴項即可。比如make install。約定俗成第一個目標一般叫做all

變量

可以使用變量來簡化Makefile,定義變量可以使用

allobj := a.o b.o c.o
# allobj = a.o b.o c.o
a.out: $(allobj)
gcc a.o b.o c.o

a.out: $(allobj)
gcc $^

make的自動變量
    # $^ 表示所有依賴項
    # $< 表示第一個依賴項
    # $@ 表示目標

其中 = 和 := 的區別在於 —— 如果使用:=那麼立即賦值,使用=那麼使用時才賦值。

缺省規則

缺省規則是make系統提供默認的規則,比如x.o如果沒有指定規則,那麼默認有:

x.o: x.c
$(CC) -c $(CPPFLAGS) $(CFLAGS) $<

使用函數

Makefile 中自帶了一些函數, 利用這些函數可以簡化 Makefile 的編寫

調用語法如下:

$(<function> <arguments>)
# 或者
${<function> <arguments>}
  • 是函數名

  • 是函數參數


shell函數可以用來執行shell命令,並且將標準輸出賦值給變量。

allc := $(shell ls *.c)
allcpp := $(shell ls *.cpp)

替換.c爲.o

allobj := $(allc:.c=.o)
allobj := $(allcpp:.cpp=.o)

使用子Makefile

可以通過include包含其他子makefile。

include mymk.mk
# 使用-開頭表示如果mymk.mk不存在,那麼也繼續執行
-include mymk.mk

自動推導依賴

main : main.o
gcc -o main main.o

#會自動變爲:
main : main.o
gcc -o main main.o

main.o: main.c
gcc -c main.c

版本管理git

簡介

Git 是用於 Linux內核開發的版本控制工具。與常用的版本控制工具 CVS, Subversion 等不同,它採用了分佈式版本庫的方式,不必服務器端軟件支持,使源代碼的發佈和交流極其方便。 Git 的速度很快,這對於諸如 Linux kernel 這樣的大項目來說自然很重要。

個人使用

  • 步驟1:安裝 sudo apt-get install git
    Windows: gitbash(百度搜索)
  • 步驟2:創建代碼倉庫
    git init
    該命令在當前目錄下,創建一個git倉庫
  • 步驟3:將修改的代碼加入到倉庫
    git add lm.c
    git commit -m “version1”
  • 步驟4:步驟3重複執行多次
  • 步驟5:提交內容可以通過
    git revert進行撤銷
  • 步驟6:可以通過分支來進行大版本管理
    git branch查看當前倉庫的分支
    git branch {branchname} 在當前分支的狀態下,創建分支
    git checkout {branchname}切換分支
    git branch -d {branchname}刪除分支
    git branch -D {branchname} 強制刪除有代碼修改的分支,慎重使用

第一次使用git提交代碼之前,應該使用
git config –global user.name “your name”
git config –global user.email “your email”

合作開發

  • git push 遠程服務器名字 本地分支:遠程分支
    // 把代碼庫中的代碼上傳到git服務器
  • git pull 遠程服務器名字 分支名字
    // 從git服務器上下載代碼
  • git init xxxx –bare
    // 在服務器上創建代碼庫
  • git clone 服務器名字ip:遠程代碼路徑
    // 克隆服務器的目錄
  • git merge 分支號
    //將指定的分支代碼

暫存區

Git和其他版本控制系統如SVN的一個不同之處就是有暫存區的概念。

前面講的個人使用步驟3:

第一步是用git add把文件添加進去,實際上就是把文件修改添加到暫存區;
第二步是用git commit提交更改,實際上就是把暫存區的所有內容提交到當前分支。

所謂暫存區可簡單理解爲需要提交的文件修改通通放到暫存區,然後,一次性提交暫存區的所有修改。

常用命令

  • git help < command > # 顯示command的help

  • git show # 顯示某次提交的內容 git show $id

  • git add < file > # 將工作文件修改提交到本地暫存區

  • git rm < file > # 從版本庫中刪除文件

  • git revert < $id > # 恢復某次提交的狀態,恢復動作本身也創建次提交對象

  • git diff < file > # 比較當前文件和暫存區文件差異 git diff

  • git log git log < file > # 查看該文件每次提交記錄

  • git br < new_branch > # 創建新的分支

  • git co < branch > # 切換到某個分支

  • git br -d < branch > # 刪除某個分支

  • git merge < branch > # 將branch分支合併到當前分支

  • git stash # 暫存

  • git stash list # 列所有stash

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章