g編譯cpp文件
① C++ .h和.cpp 組合編譯不能通過,求助!!!
g++ main.cpp point.cpp GPS.cpp
只此一句即可編譯,但是你的程序錯誤挺多,只列舉幾個。派搭
1,頭文件防止重包含褲羨汪,得加上#ifndef #define #endif之類的,看看你的C++標准頭文件是怎樣寫的。
2,main函數里for語句是個死循環。而且else後面是個大括弧。
3,要一個類一胡仔個類的測試,完了再組裝,如g++ -c point.cpp就可知道你的point類能否編譯通過。
② linux 下的vscode怎麼編譯cpp
vscode配置C/C++的編譯調試環境安裝debug插件,然後配置如下,//launch.json{"version":"0.2.0","configurations":[{"name":"Debug","type":"gdb","request":"launch","target":"${file}.o","cwd":"${workspaceRoot}","preLaunchTask":"gcc"}]}//tasks.json{"搏枝version":"0.1.0","辯銀寬command":"gcc","args":["-g","${file}","-o","${file}.o"攜亮],"problemMatcher":{"owner":"cpp","fileLocation":["relative","${workspaceRoot}"],"pattern":{"regexp":"^(.*):(\\d+):(\\d+):\\s+(warning|error):\\s+(.*)$","file":1,"line":2,"column":3,"severity":4,"message":5}}}
③ Linux平台Makefile文件的編寫基礎篇
目的:
基本掌握了 make 的用法,能在Linux系統上編程。
環境:
Linux系統,或者有一台Linux伺服器,通過終端連接。一句話:有Linux編譯環境。
准備:
准備三個文件:file1.c, file2.c, file2.h
file1.c:
#include
#include "file2.h"
int main()
{
printf("print file1$$$$$$$$$$$$ ");
File2Print();
return 0;
}
file2.h:
#ifndef FILE2_H_
#define FILE2_H_
#ifdef __cplusplus
extern "C" {
#endif
void File2Print();
#ifdef __cplusplus
}
#endif
#endif
file2.c:
#include "file2.h"
void File2Print()
{
printf("Print file2********************** ");
}
基礎:
先來個例子:
有這么個Makefile文件。(文件和Makefile在同一目錄)
=== makefile 開始 ===
helloworld:file1.o file2.o
gcc file1.o file2.o -o helloworld
file1.o:file1.c file2.h
gcc -c file1.c -o file1.o
file2.o:file2.c file2.h
gcc -c file2.c -o file2.o
clean:
rm -rf *.o helloworld
=== makefile 結束 ===
一個 makefile 主要含有一系列的規則,如下:
A: B
(tab)
(tab)
每個命令行前都必須有tab符號。
上面的makefile文件目的就是要編譯一個helloworld的可執行文件。讓我們一句一句來解釋:
helloworld : file1.o file2.o: helloworld依賴file1.o file2.o兩個目標文件。
gcc File1.o File2.o -o helloworld: 編譯出helloworld可執行文件。-o表示你指定 的目標文件名。
file1.o : file1.c: file1.o依賴file1.c文件。
gcc -c file1.c -o file1.o: 編譯出file1.o文件。-c表示gcc 只把給它的文件編譯成目標文件, 用源碼文件的文件名命名但把其後綴由「.c」或「.cc」變成「.o」。在這句中,可以省略-o file1.o,編譯器默認生成file1.o文件,這就是-c的作用。
file2.o : file2.c file2.h
gcc -c file2.c -o file2.o
這兩句和上兩句相同。
clean:
rm -rf *.o helloworld
當用戶鍵入make clean命令時,會刪除*.o 和helloworld文件。
如果要編譯cpp文件,只要把gcc改成g++就行了。
寫好Makefile文件,在命令行中直接鍵入make命令,就會執行Makefile中的內容了。
到這步我想你能編一個Helloworld程序了。
上一層樓:使用變數
上面提到一句,如果要編譯cpp文件,只要把gcc改成g++就行了。但如果Makefile中有很多gcc,那不就很麻煩了。
第二個例子:
=== makefile 開始 ===
OBJS = file1.o file2.o
CC = gcc
CFLAGS = -Wall -O -g
helloworld : $(OBJS)
$(CC) $(OBJS) -o helloworld
file1.o : file1.c file2.h
$(CC) $(CFLAGS) -c file1.c -o file1.o
file2.o : file2.c file2.h
$(CC) $(CFLAGS) -c file2.c -o file2.o
clean:
rm -rf *.o helloworld
=== makefile 結束 ===
這里我們應用到了變數。要設定一個變數,你只要在一行的開始寫下這個變數的名字,後 面跟一個 = 號,後面跟你要設定的這個變數的值。以後你要引用 這個變數,寫一個 $ 符號,後面是圍在括弧里的變數名。
CFLAGS = -Wall -O –g,解釋一下。這是配置編譯器設置,並把它賦值給CFFLAGS變數。
-Wall: 輸出所有的警告信息。
-O: 在編譯時進行優化。
-g: 表示編譯debug版本。
這樣寫的Makefile文件比較簡單,但很容易就會發現缺點,那就是要列出所有的c文件。如果你添加一個c文件,那就需要修改Makefile文件,這在項目開發中還是比較麻煩的。
再上一層樓:使用函數
學到這里,你也許會說,這就好像編程序嗎?有變數,也有函數。其實這就是編程序,只不過用的語言不同而已。
第三個例子:
=== makefile 開始 ===
CC = gcc
XX = g++
CFLAGS = -Wall -O –g
TARGET = ./helloworld
%.o: %.c
$(CC) $(CFLAGS) -c lt; -o [email protected]
%.o:%.cpp
$(XX) $(CFLAGS) -c lt; -o [email protected]
SOURCES = $(wildcard *.c *.cpp)
OBJS = $(patsubst %.c,%.o,$(patsubst %.cpp,%.o,$(SOURCES)))
$(TARGET) : $(OBJS)
$(XX) $(OBJS) -o $(TARGET)
chmod a+x $(TARGET)
clean:
rm -rf *.o helloworld
=== makefile 結束 ===
函數1:wildcard
產生一個所有以 '.c' 結尾的文件的列表。
SOURCES = $(wildcard *.c *.cpp)表示產生一個所有以 .c,.cpp結尾的文件的列表,然後存入變數 SOURCES 里。
函數2:patsubst
匹配替換,有三個參數。第一個是一個需要匹配的式樣,第二個表示用什麼來替換它,第三個是一個需要被處理的由空格分隔的列表。
OBJS = $(patsubst %.c,%.o,$(patsubst %.cc,%.o,$(SOURCES)))表示把文件列表中所有的.c,.cpp字元變成.o,形成一個新的文件列表,然後存入OBJS變數中。
%.o: %.c
$(CC) $(CFLAGS) -c lt; -o [email protected]
%.o:%.cpp
$(XX) $(CFLAGS) -c lt; -o [email protected]
這幾句命令表示把所有的.c,.cpp編譯成.o文件。
這里有三個比較有用的內部變數。 [email protected] 擴展成當前規則的目的文件名, lt; 擴展成依靠 列表中的第一個依靠文件,而 $^ 擴展成整個依靠的列表(除掉了裡面所有重 復的文件名)。
chmod a+x $(TARGET)表示把helloworld強制變成可執行文件。
④ linux 用g++編譯c++代碼的問題
*
運行 gcc/egcs
*
gcc/egcs 的主要選項
*
gdb
*
gdb 的常用命令
*
gdb 使用範例
*
其他程序/庫工具 (ar, objmp, nm, size, strings, strip, ...)
* 創建和使用靜態庫
* 創建和使用共享庫
* 使用高級共享庫特性
1.7.1 運行 gcc/egcs
Linux 中最重要的軟體開發工具是 GCC。GCC 是 GNU 的 C 和 C++ 編譯器。實際上,GCC 能夠編譯三種語言:C、C++ 和 Object C(C 語言的一種面向對象擴展)。利用 gcc 命令可同時編譯並連接 C 和 C++ 源程序。
#DEMO#: hello.c
如果你有兩個或少數幾個 C 源文件,也可以方便地利用 GCC 編譯、連接並生成可執行文件。例如,假設你有兩個源文件 main.c 和 factorial.c 兩個源文件,現在要編譯生成一個計算階乘的程序。
-----------------------
清單 factorial.c
-----------------------
#include <stdio.h>
#include <stdlib.h>
int factorial (int n)
{
if (n <= 1)
return 1;
else
return factorial (n - 1) * n;
}
-----------------------
-----------------------
清單 main.c
-----------------------
#include <stdio.h>
#include <stdlib.h>
int factorial (int n);
int main (int argc, char **argv)
{
int n;
if (argc < 2) {
printf ("Usage: %s n\n", argv [0]);
return -1;
}
else {
n = atoi (argv[1]);
printf ("Factorial of %d is %d.\n", n, factorial (n));
}
return 0;
}
-----------------------
利用如下的命令可編譯生成可執行文件,並執行程序:
$ gcc -o factorial main.c factorial.c
$ ./factorial 5
Factorial of 5 is 120.
GCC 可同時用來編譯 C 程序和 C++ 程序。一般來說,C 編譯器通過源文件的後綴名來判斷是 C 程序還是 C++ 程序。在 Linux 中,C 源文件的後綴名為 .c,而 C++ 源文件的後綴名為 .C 或 .cpp。
但是,gcc 命令只能編譯 C++ 源文件,而不能自動和 C++ 程序使用的庫連接。因此,通常使用 g++ 命令來完成 C++ 程序的編譯和連接,該程序會自動調用 gcc 實現編譯。假設我們有一個如下的 C++ 源文件(hello.C):
#include <iostream.h>
void main (void)
{
cout << "Hello, world!" << endl;
}
則可以如下調用 g++ 命令編譯、連接並生成可執行文件:
$ g++ -o hello hello.C
$ ./hello
Hello, world!
1.7.2 gcc/egcs 的主要選項
表 1-3 gcc 命令的常用選項
選項 解釋
-ansi 只支持 ANSI 標準的 C 語法。這一選項將禁止 GNU C 的某些特色,
例如 asm 或 typeof 關鍵詞。
-c 只編譯並生成目標文件。
-DMACRO 以字元串「1」定義 MACRO 宏。
-DMACRO=DEFN 以字元串「DEFN」定義 MACRO 宏。
-E 只運行 C 預編譯器。
-g 生成調試信息。GNU 調試器可利用該信息。
-IDIRECTORY 指定額外的頭文件搜索路徑DIRECTORY。
-LDIRECTORY 指定額外的函數庫搜索路徑DIRECTORY。
-lLIBRARY 連接時搜索指定的函數庫LIBRARY。
-m486 針對 486 進行代碼優化。
-o FILE 生成指定的輸出文件。用在生成可執行文件時。
-O0 不進行優化處理。
-O 或 -O1 優化生成代碼。
-O2 進一步優化。
-O3 比 -O2 更進一步優化,包括 inline 函數。
-shared 生成共享目標文件。通常用在建立共享庫時。
-static 禁止使用共享連接。
-UMACRO 取消對 MACRO 宏的定義。
-w 不生成任何警告信息。
-Wall 生成所有警告信息。
#DEMO#
MiniGUI 的編譯選項
1.7.3 gdb
GNU 的調試器稱為 gdb,該程序是一個互動式工具,工作在字元模式。在 X Window 系統中,
有一個 gdb 的前端圖形工具,稱為 xxgdb。gdb 是功能強大的調試程序,可完成如下的調試
任務:
* 設置斷點;
* 監視程序變數的值;
* 程序的單步執行;
* 修改變數的值。
在可以使用 gdb 調試程序之前,必須使用 -g 選項編譯源文件。可在 makefile 中如下定義
CFLAGS 變數:
CFLAGS = -g
運行 gdb 調試程序時通常使用如下的命令:
gdb progname
在 gdb 提示符處鍵入help,將列出命令的分類,主要的分類有:
* aliases:命令別名
* breakpoints:斷點定義;
* data:數據查看;
* files:指定並查看文件;
* internals:維護命令;
* running:程序執行;
* stack:調用棧查看;
* statu:狀態查看;
* tracepoints:跟蹤程序執行。
鍵入 help 後跟命令的分類名,可獲得該類命令的詳細清單。
#DENO#
1.7.4 gdb 的常用命令
表 1-4 常用的 gdb 命令
命令 解釋
break NUM 在指定的行上設置斷點。
bt 顯示所有的調用棧幀。該命令可用來顯示函數的調用順序。
clear 刪除設置在特定源文件、特定行上的斷點。其用法為:clear FILENAME:NUM。
continue 繼續執行正在調試的程序。該命令用在程序由於處理信號或斷點而
導致停止運行時。
display EXPR 每次程序停止後顯示表達式的值。表達式由程序定義的變數組成。
file FILE 裝載指定的可執行文件進行調試。
help NAME 顯示指定命令的幫助信息。
info break 顯示當前斷點清單,包括到達斷點處的次數等。
info files 顯示被調試文件的詳細信息。
info func 顯示所有的函數名稱。
info local 顯示當函數中的局部變數信息。
info prog 顯示被調試程序的執行狀態。
info var 顯示所有的全局和靜態變數名稱。
kill 終止正被調試的程序。
list 顯示源代碼段。
make 在不退出 gdb 的情況下運行 make 工具。
next 在不單步執行進入其他函數的情況下,向前執行一行源代碼。
print EXPR 顯示表達式 EXPR 的值。
1.7.5 gdb 使用範例
-----------------
清單 一個有錯誤的 C 源程序 bugging.c
-----------------
#include <stdio.h>
#include <stdlib.h>
static char buff [256];
static char* string;
int main ()
{
printf ("Please input a string: ");
gets (string);
printf ("\nYour string is: %s\n", string);
}
-----------------
上面這個程序非常簡單,其目的是接受用戶的輸入,然後將用戶的輸入列印出來。該程序使用了
一個未經過初始化的字元串地址 string,因此,編譯並運行之後,將出現 Segment Fault 錯誤:
$ gcc -o test -g test.c
$ ./test
Please input a string: asfd
Segmentation fault (core mped)
為了查找該程序中出現的問題,我們利用 gdb,並按如下的步驟進行:
1.運行 gdb bugging 命令,裝入 bugging 可執行文件;
2.執行裝入的 bugging 命令;
3.使用 where 命令查看程序出錯的地方;
4.利用 list 命令查看調用 gets 函數附近的代碼;
5.唯一能夠導致 gets 函數出錯的因素就是變數 string。用 print 命令查看 string 的值;
6.在 gdb 中,我們可以直接修改變數的值,只要將 string 取一個合法的指針值就可以了,為
此,我們在第 11 行處設置斷點;
7.程序重新運行到第 11 行處停止,這時,我們可以用 set variable 命令修改 string 的取值;
8.然後繼續運行,將看到正確的程序運行結果。
#DEMO#
1.7.6 其他程序/庫工具
strip:
nm:
size:
string:
1.7.7 創建和使用靜態庫
創建一個靜態庫是相當簡單的。通常使用 ar 程序把一些目標文件(.o)組合在一起,成為一個單獨的庫,然後運行 ranlib,以給庫加入一些索引信息。
1.7.8 創建和使用共享庫
特殊的編譯和連接選項
-D_REENTRANT 使得預處理器符號 _REENTRANT 被定義,這個符號激活一些宏特性。
-fPIC 選項產生位置獨立的代碼。由於庫是在運行的時候被調入,因此這個
選項是必需的,因為在編譯的時候,裝入內存的地址還不知道。如果
不使用這個選項,庫文件可能不會正確運行。
-shared 選項告訴編譯器產生共享庫代碼。
-Wl,-soname -Wl 告訴編譯器將後面的參數傳遞到連接器。而 -soname 指定了
共享庫的 soname。
# 可以把庫文件拷貝到 /etc/ld.so.conf 中列舉出的任何目錄中,並以
root 身份運行 ldconfig;或者
# 運行 export LD_LIBRARY_PATH='pwd',它把當前路徑加到庫搜索路徑中去。
1.7.9 使用高級共享庫特性
1. ldd 工具
ldd 用來顯示執行文件需要哪些共享庫, 共享庫裝載管理器在哪裡找到了需要的共享庫.
2. soname
共享庫的一個非常重要的,也是非常難的概念是 soname——簡寫共享目標名(short for shared object name)。這是一個為共享庫(.so)文件而內嵌在控制數據中的名字。如前面提到的,每一個程序都有一個需要使用的庫的清單。這個清單的內容是一系列庫的 soname,如同 ldd 顯示的那樣,共享庫裝載器必須找到這個清單。
soname 的關鍵功能是它提供了兼容性的標准。當要升級系統中的一個庫時,並且新庫的 soname 和老的庫的 soname 一樣,用舊庫連接生成的程序,使用新的庫依然能正常運行。這個特性使得在 Linux 下,升級使用共享庫的程序和定位錯誤變得十分容易。
在 Linux 中,應用程序通過使用 soname,來指定所希望庫的版本。庫作者也可以通過保留或者改變 soname 來聲明,哪些版本是相互兼容的,這使得程序員擺脫了共享庫版本沖突問題的困擾。
查看/usr/local/lib 目錄,分析 MiniGUI 的共享庫文件之間的關系
3. 共享庫裝載器
當程序被調用的時候,Linux 共享庫裝載器(也被稱為動態連接器)也自動被調用。它的作用是保證程序所需要的所有適當版本的庫都被調入內存。共享庫裝載器名字是 ld.so 或者是 ld-linux.so,這取決於 Linux libc 的版本,它必須使用一點外部交互,才能完成自己的工作。然而它接受在環境變數和配置文件中的配置信息。
文件 /etc/ld.so.conf 定義了標准系統庫的路徑。共享庫裝載器把它作為搜索路徑。為了改變這個設置,必須以 root 身份運行 ldconfig 工具。這將更新 /etc/ls.so.cache 文件,這個文件其實是裝載器內部使用的文件之一。
可以使用許多環境變數控制共享庫裝載器的操作(表1-4+)。
表 1-4+ 共享庫裝載器環境變數
變數 含義
LD_AOUT_LIBRARY_PATH 除了不使用 a.out 二進制格式外,與 LD_LIBRARY_PATH 相同。
LD_AOUT_PRELOAD 除了不使用 a.out 二進制格式外,與 LD_PRELOAD 相同。
LD_KEEPDIR 只適用於 a.out 庫;忽略由它們指定的目錄。
LD_LIBRARY_PATH 將其他目錄加入庫搜索路徑。它的內容應該是由冒號
分隔的目錄列表,與可執行文件的 PATH 變數具有相同的格式。
如果調用設置用戶 ID 或者進程 ID 的程序,該變數被忽略。
LD_NOWARN 只適用於 a.out 庫;當改變版本號是,發出警告信息。
LD_PRELOAD 首先裝入用戶定義的庫,使得它們有機會覆蓋或者重新定義標准庫。
使用空格分開多個入口。對於設置用戶 ID 或者進程 ID 的程序,
只有被標記過的庫才被首先裝入。在 /etc/ld.so.perload 中指定
了全局版本號,該文件不遵守這個限制。
4. 使用 dlopen
另外一個強大的庫函數是 dlopen()。該函數將打開一個新庫,並把它裝入內存。該函數主要用來載入庫中的符號,這些符號在編譯的時候是不知道的。比如 Apache Web 伺服器利用這個函數在運行過程中載入模塊,這為它提供了額外的能力。一個配置文件控制了載入模塊的過程。這種機制使得在系統中添加或者刪除一個模塊時,都不需要重新編譯了。
可以在自己的程序中使用 dlopen()。dlopen() 在 dlfcn.h 中定義,並在 dl 庫中實現。它需要兩個參數:一個文件名和一個標志。文件名可以是我們學習過的庫中的 soname。標志指明是否立刻計算庫的依賴性。如果設置為 RTLD_NOW 的話,則立刻計算;如果設置的是 RTLD_LAZY,則在需要的時候才計算。另外,可以指定 RTLD_GLOBAL,它使得那些在以後才載入的庫可以獲得其中的符號。
當庫被裝入後,可以把 dlopen() 返回的句柄作為給 dlsym() 的第一個參數,以獲得符號在庫中的地址。使用這個地址,就可以獲得庫中特定函數的指針,並且調用裝載庫中的相應函數。
⑤ gcc編譯文件時找不到指定函數怎麼辦
通常找不到指定函數不是因為編譯參數問題。而是你 g.cpp 中在include f.h的時候沒有使用: extern "C" { #include"f.h" } 因為C語言和cpp的編譯過程中的函數名稱修飾規則是不一樣的。當cpp引用C庫的時候必須告訴編譯器,哪些函數是C函數
⑥ LINUX下如何用G++編c++,給一個詳細的實例就好
參見這個地鍵耐襪址:http://hi..com/sohu2000000/blog/item/84f56021275b27a94723e861.html
G++ 中文使用教程
=====================================================================
簡介 gcc and g++分別是GNU的c & c++編譯器 gcc/g++在執行編譯工作的時候,總共需要4步
1.預處理,生成.i的文件[預處理器cpp]
2.將預處理後的文件不轉換成匯編語言,生成文件.s[編譯器egcs]
3.有匯編變為目標代碼(機畝芹器代碼)生成.o的文件[匯編器as]
4.連接目標代碼,生成可執行程序[鏈接器ld]
操作指南 [參數詳解]
-x language filename
設定文件所使用的語言,使後綴名無效,對以後的多個有效.也就是根
據約定C語言的後綴名稱是.c的,而C++的後綴名是.C或者.cpp,如果
你很個性,決定你的C代碼文件的後綴名是.pig 哈哈,那你就要用這
個參數,這個參數對他後面的文件名都起作用,除非到了下一個參數
的使用。
可以使用的參數嗎有下面的這些
`c', `objective-c', `c-header', `c++', `cpp-output',
`assembler', and `assembler-with-cpp'.
看到英文,應該可以理解的。
例子用法:
gcc -x c hello.pig
-x none filename
關掉上一個選項,也就是讓gcc根據文件名後綴,自動識別文件類型
例子用法:
gcc -x c hello.pig -x none hello2.c
-c
只激活稿激預處理,編譯,和匯編,也就是他只把程序做成obj文件
例子用法:
gcc -c hello.c
他將生成.o的obj文件
-S
只激活預處理和編譯,就是指把文件編譯成為匯編代碼。
例子用法
gcc -S hello.c
他將生成.s的匯編代碼,你可以用文本編輯器察看
-E
只激活預處理,這個不生成文件,你需要把它重定向到一個輸出文件里
面.
例子用法:
gcc -E hello.c > pianoapan.txt
gcc -E hello.c | more
慢慢看吧,一個hello word 也要與處理成800行的代碼
-o
制定目標名稱,預設的時候,gcc 編譯出來的文件是a.out,很難聽,如果
你和我有同感,改掉它,哈哈
例子用法
gcc -o hello.exe hello.c (哦,windows用習慣了)
gcc -o hello.asm -S hello.c
-pipe
使用管道代替編譯中臨時文件,在使用非gnu匯編工具的時候,可能有些問
題
gcc -pipe -o hello.exe hello.c
-ansi
關閉gnu c中與ansi c不兼容的特性,激活ansi c的專有特性(包括禁止一
些asm inline typeof關鍵字,以及UNIX,vax等預處理宏,
-fno-asm
此選項實現ansi選項的功能的一部分,它禁止將asm,inline和typeof用作
關鍵字。
-fno-strict-prototype
只對g++起作用,使用這個選項,g++將對不帶參數的函數,都認為是沒有顯式
的對參數的個數和類型說明,而不是沒有參數.
而gcc無論是否使用這個參數,都將對沒有帶參數的函數,認為城沒有顯式說
明的類型
-fthis-is-varialble
就是向傳統c++看齊,可以使用this當一般變數使用.
-fcond-mismatch
允許條件表達式的第二和第三參數類型不匹配,表達式的值將為void類型
-funsigned-char
-fno-signed-char
-fsigned-char
-fno-unsigned-char
這四個參數是對char類型進行設置,決定將char類型設置成unsigned char(前
兩個參數)或者 signed char(後兩個參數)
-include file
包含某個代碼,簡單來說,就是便以某個文件,需要另一個文件的時候,就可以
用它設定,功能就相當於在代碼中使用#include<filename>
例子用法:
gcc hello.c -include /root/pianopan.h
-imacros file
將file文件的宏,擴展到gcc/g++的輸入文件,宏定義本身並不出現在輸入文件
中
-Dmacro
相當於C語言中的#define macro
-Dmacro=defn
相當於C語言中的#define macro=defn
-Umacro
相當於C語言中的#undef macro
-undef
取消對任何非標准宏的定義
-Idir
在你是用#include"file"的時候,gcc/g++會先在當前目錄查找你所制定的頭
文件,如果沒有找到,他回到預設的頭文件目錄找,如果使用-I制定了目錄,他
回先在你所制定的目錄查找,然後再按常規的順序去找.
對於#include<file>,gcc/g++會到-I制定的目錄查找,查找不到,然後將到系
統的預設的頭文件目錄查找
-I-
就是取消前一個參數的功能,所以一般在-Idir之後使用
-idirafter dir
在-I的目錄裡面查找失敗,講到這個目錄裡面查找.
-iprefix prefix
-iwithprefix dir
一般一起使用,當-I的目錄查找失敗,會到prefix+dir下查找
-nostdinc
使編譯器不再系統預設的頭文件目錄裡面找頭文件,一般和-I聯合使用,明確
限定頭文件的位置
-nostdin C++
規定不在g++指定的標准路經中搜索,但仍在其他路徑中搜索,.此選項在創建
libg++庫使用
-C
在預處理的時候,不刪除注釋信息,一般和-E使用,有時候分析程序,用這個很
方便的
-M
生成文件關聯的信息。包含目標文件所依賴的所有源代碼
你可以用gcc -M hello.c來測試一下,很簡單。
-MM
和上面的那個一樣,但是它將忽略由#include<file>造成的依賴關系。
-MD
和-M相同,但是輸出將導入到.d的文件裡面
-MMD
和-MM相同,但是輸出將導入到.d的文件裡面
-Wa,option
此選項傳遞option給匯編程序;如果option中間有逗號,就將option分成多個選
項,然後傳遞給會匯編程序
-Wl.option
此選項傳遞option給連接程序;如果option中間有逗號,就將option分成多個選
項,然後傳遞給會連接程序.
-llibrary
制定編譯的時候使用的庫
例子用法
gcc -lcurses hello.c
使用ncurses庫編譯程序
-Ldir
制定編譯的時候,搜索庫的路徑。比如你自己的庫,可以用它制定目錄,不然
編譯器將只在標准庫的目錄找。這個dir就是目錄的名稱。
-O0
-O1
-O2
-O3
編譯器的優化選項的4個級別,-O0表示沒有優化,-O1為預設值,-O3優化級別最
高
-g
只是編譯器,在編譯的時候,產生調試信息。
-gstabs
此選項以stabs格式聲稱調試信息,但是不包括gdb調試信息.
-gstabs+
此選項以stabs格式聲稱調試信息,並且包含僅供gdb使用的額外調試信息.
-ggdb
此選項將盡可能的生成gdb的可以使用的調試信息.
-static
此選項將禁止使用動態庫,所以,編譯出來的東西,一般都很大,也不需要什麼
動態連接庫,就可以運行.
-share
此選項將盡量使用動態庫,所以生成文件比較小,但是需要系統由動態庫.
-traditional
試圖讓編譯器支持傳統的C語言特性
GNU 的調試器稱為 gdb,該程序是一個互動式工具,工作在字元模式。在 X Window 系統中,有一個 gdb 的
前端圖形工具,稱為 xxgdb。gdb 是功能強大的調試程序,可完成如下的調試任務:
* 設置斷點;
* 監視程序變數的值;
* 程序的單步執行;
* 修改變數的值。
在可以使用 gdb 調試程序之前,必須使用 -g 選項編譯源文件。可在 makefile 中如下定義 CFLAGS 變數:
CFLAGS = -g
運行 gdb 調試程序時通常使用如下的命令:
gdb progname
在 gdb 提示符處鍵入help,將列出命令的分類,主要的分類有:
* aliases:命令別名
* breakpoints:斷點定義;
* data:數據查看;
* files:指定並查看文件;
* internals:維護命令;
* running:程序執行;
* stack:調用棧查看;
* statu:狀態查看;
* tracepoints:跟蹤程序執行。
鍵入 help 後跟命令的分類名,可獲得該類命令的詳細清單。
#DENO#
gdb 的常用命令
表 1-4 常用的 gdb 命令
命令 解釋
break NUM 在指定的行上設置斷點。
bt 顯示所有的調用棧幀。該命令可用來顯示函數的調用順序。
clear 刪除設置在特定源文件、特定行上的斷點。其用法為:clear FILENAME:NUM。
continue 繼續執行正在調試的程序。該命令用在程序由於處理信號或斷點而
導致停止運行時。
display EXPR 每次程序停止後顯示表達式的值。表達式由程序定義的變數組成。
file FILE 裝載指定的可執行文件進行調試。
help NAME 顯示指定命令的幫助信息。
info break 顯示當前斷點清單,包括到達斷點處的次數等。
info files 顯示被調試文件的詳細信息。
info func 顯示所有的函數名稱。
info local 顯示當函數中的局部變數信息。
info prog 顯示被調試程序的執行狀態。
info var 顯示所有的全局和靜態變數名稱。
kill 終止正被調試的程序。
list 顯示源代碼段。
make 在不退出 gdb 的情況下運行 make 工具。
next 在不單步執行進入其他函數的情況下,向前執行一行源代碼。
print EXPR 顯示表達式 EXPR 的值。
1.8.5 gdb 使用範例
-----------------
清單 一個有錯誤的 C 源程序 bugging.c
-----------------
#include
#include
static char buff [256];
static char* string;
int main ()
{
printf ("Please input a string: ");
gets (string);
printf ("\nYour string is: %s\n", string);
}
-----------------
上面這個程序非常簡單,其目的是接受用戶的輸入,然後將用戶的輸入列印出來。該程序使用了一個未經過初
始化的字元串地址 string,因此,編譯並運行之後,將出現 Segment Fault 錯誤:
$ gcc -o test -g test.c
$ ./test
Please input a string: asfd
Segmentation fault (core mped)
為了查找該程序中出現的問題,我們利用 gdb,並按如下的步驟進行:
1.運行 gdb bugging 命令,裝入 bugging 可執行文件;
2.執行裝入的 bugging 命令;
3.使用 where 命令查看程序出錯的地方;
4.利用 list 命令查看調用 gets 函數附近的代碼;
5.唯一能夠導致 gets 函數出錯的因素就是變數 string。用 print 命令查看 string 的值;
6.在 gdb 中,我們可以直接修改變數的值,只要將 string 取一個合法的指針值就可以了,為此,我們在第
11 行處設置斷點;
7.程序重新運行到第 11 行處停止,這時,我們可以用 set variable 命令修改 string 的取值;
8.然後繼續運行,將看到正確的程序運行結果。
⑦ 求問mac下怎麼用g++編譯連接c++,最好能夠詳細一點(配圖),新手不是很懂
用Xcode就行了尺嫌呀,直接在裡面編碼,調試,運行。
用terminal就用陵祥手指令編譯,鏈接,宴碰運行。指令前面幾位都回答了。
⑧ c++如何編譯啊 ~
以Linux系統為例:
1、在連網的情況下,在終端中使用root超級用戶許可權輸入以下命令:
sudo apt-get install g++
並回車即可安裝C++編譯器g++。
2、安裝完畢,即可開始新建我們的一個C++工程了。下面以一個hello工程為例,簡單地介紹如何編譯一個 C++工程。
3、登錄Linux系統,打開終端,在當前目錄下使用mkdir命令新建一個hello的目錄;然後使用cd hello進入hello目錄中,並使用vi工具新建hello.h、hello.cpp、main.cpp、makefile四個文件。四個文件的內容分別如下:
1. hello.h文件
#ifndef HELLO_H_
#define HELLO_H_
class Hello {
public:
void print();
};
#endif
2. hello.cpp文件
#include "hello.h"
#include <iostream>
using namespace std;
void Hello::print() {
cout<<"Hello, welcome to Redhat Linux os!"<<endl;
}
3. main.cpp文件
#include "hello.h"
#include <iostream>
using namespace std;
int main() {
Hello h;
h.print();
return 0;
}
注意:這三個文件要以空白行結束,否則編譯時會有警告信息。
4. makefile文件
# this is a makefile of the c++ project hello
# the standard c++ compiler in the Redhat linux is g++
# written by young on June 27th, 2009
TARGET = .
CC = g++
CFLAGS = -g
CFLAGC = -c
MAINC = main.cpp
HELLO = hello.cpp
OBJ = hello.o
INCLUDE = -I$(TARGET)
EXEC = $(TARGET)/main
all: $(EXEC)
$(EXEC): $(OBJ) $(MAINC)
$(CC) $(CFLAGS) $(OBJ) $(MAINC) $(INCLUDE) -o $@
rm -f $(OBJ)
@echo "<<<<<< $@ is created successfully! >>>>>>"
$(OBJ): $(HELLO)
$(CC) $(CFLAGC) $(HELLO) -o $@
clean:
rm -f $(EXEC)
注意: makefile文件中的命令行(紅色字體)一定要以Tab建開頭,否則編譯通不過。
寫好makefile文件後,即可編譯工程。在終端中輸入make命令,回車後將顯示如下信息:
g++ -c hello.cpp -o hello.o
g++ -g hello.o main.cpp -I. -o main
rm -f hello.o
<<<<<< main is created successfully! >>>>>>
這些信息說明工程已被正確編譯,當前目錄下將生成一個main的可執行文件。
同樣,你也可以不使用makefile文件,而直接在終端上輸入以下兩行命令:
g++ -c hello.cpp -o hello.o
g++ -g hello.o main.cpp -I. -o main
也可以編譯這個工程。
使用ls -l命令查看當前目錄下的所有文件,確實有一個main文件。
在終端中輸入./main,即可運行程序。
⑨ [100分求解]:Dev-C++編譯.c文件時提示"源文件未編譯"無法運行 而把後綴改成.cpp後正常運行
原因:設置錯誤導致。解決方法:
如下參考:
1.首先,打開dev-c++,點擊菜單欄中的「工具」,點擊「編譯選項」,打開編輯選項對話框。
⑩ 在windows下用g++編譯程序的時候我每次都是輸入g++ xxx.cpp -g -Wall這樣很麻煩,能否用批處理實現
g++ %1 -g -Wall