win gcc,g++ 用法總結

slef:  直接寫個  .bat文件 (windows下)
content:
  goto skip_comments
  rem echo %1    //print  second argument

  添加動態鏈接庫文件 msvcr120d.dll 到編譯
  1.先加入了-LF:\wincode\ege\JuanYueYinYue   -L[path] , 要不然會找不到 msvcr120d.dll 鏈接庫文件, 因爲沒有去 那個目錄下找唄
  2.加入 -lmsvcr120d  表示鏈接 msvcr120d.dll  , 其實在本程序 鏈接該庫文件 根本沒用, 呵呵
  :skip_comments
  g++ %1 resource.h -lgraphics -lgdi32 -limm32 -lmsimg32 -lole32 -loleaut32 -lwinmm -luuid  -LF:\wincode\ege\JuanYueYinYue -lmsvcr120d -mwindows  

1.windows下gcc(mingw32)編譯連接 GTK+ && MySQL


下載LOFTER客戶端
1.下載MySQL(http://www.mysql.com/downloads/mysql/)
    安裝 注意把 Client C API library 選項勾上,安裝的是C語言API的庫文件


2.下載GTK+(all-in-one bundles)(http://ftp.gnome.org/pub/gnome/binaries/win32/gtk+/2.24/gtk+-bundle_2.24.10-20120208_win32.zip)
   解壓到任意目錄
   把<安裝目錄>/bin 添加到環境變量 PATH
   打開cmd,輸入:gtk-demo 測試OK

3.下載mingw(http://sourceforge.net/projects/mingw/files/Installer/mingw-get-inst/mingw-get-inst-20120426/mingw-get-inst-20120426.exe/download)
   安裝(下載速度奇慢!)
   把<安裝目錄>/bin 添加到環境變量 PATH
   打開cmd,輸入:gcc -v 測試OK

4.gcc編譯參數
    mysql參數:
        -I<安裝目錄>/include      表示搜索頭文件的目錄,注意:是大寫的i
        -L<安裝目錄>/lib             表示搜索庫文件的目錄(網上有說是xxx/lib/debug,或許是因爲版本不同,我那個目錄裏沒有libmysql.lib)
        -llibmysql                         表示需要的庫文件名爲libmysql.lib(在LInux下是-lmysqlclient,表示的是libmysqlclient.so文件,把前面的lib三個字母省略了,這和win下的gcc有點不一樣,win的gcc需要加lib,否則會提示找不到文件),注意:是小寫的L表示

    gtk+參數:
        打開cmd,輸入:pkg-config --cflags --libs gtk+-2.0,將顯示內容保存(因爲Linux下可以直接用``進行命令引用,但是我沒學過bat腳本,不知道用什麼符號--總之不是``...索性全複製出來)

     最後在cmd下用gcc編譯時 把上面兩列參數都加上吧windows下gcc(mingw32)編譯連接 GTK+  MySQL - ke_nux - 編程爲了生活,生活爲了編程,最好是寫個makefile文件,注意:用mingw的make要把<mingw安裝目錄>/bin下的mingw32-make.exe改成make.exe,否則cmd說找不到命令.

5.注意:
    (1)c源文件要加上:
        #inlcude <winsock.h>
        網上有說要加: #pragma comment(lib, "libmysql.lib") 但那是在VC上,gcc不是這樣用的,會提示:"warning: ignoring #pragma comment" .其實加參數 -libmysql是一樣的效果.不過不知用gcc怎麼在c源碼中直接關聯.
    (2)運行生成的exe文件時要把<mysql安裝目錄>/lib/libmysql.dll拷到當前文件(就是可執行文件所在的目錄),或者你索性拷去c:\windows\system32(64位的拷去c:\windows\system !!! 32位的拷到c:\windows\system也沒什麼問題),就跟玩遊戲少dx的dll動態鏈接庫文件一樣哈windows下gcc(mingw32)編譯連接 GTK+  MySQL - ke_nux - 編程爲了生活,生活爲了編程
    (3)若是64位的win7不建議裝64位的mysql...要是你不信可以試一下,會跟我一樣死的很慘的...不過折騰了兩天還是把問題解決了哈,就是32位編譯器和64位庫文件的關係,還有32位的可執行文件和64位的動態鏈接庫文件之間的關係,其實用32位的替換一下就行嘍...

2.gcc, g++ 用法

簡單的GCC用法
總的來說,gcc應該是一個編譯器。但整套的gcc環境並不是由gcc構成的,它是由多個包所組成的,這些包的互相作用產生了gcc的開發環境。其中,有一些包是你開發應用程序所必備的基本包,離開這些包你將無法正常使用gcc。

    gcc開發環境包括如下幾大包:

    binary                         基本包   提供基本的彙編器,連接器等
    gcc                            基本包   各種語言的編譯器,包括C,C++,Ada,Java等 
    Win32api,mingwi-runtime/glibc  基本包   系統函數庫 
    make/automake                  需要包   管理項目編譯的程序 
    gdb                            附加包   調試程序 

一. 常用編譯命令選項 
假設源程序文件名爲test.c1. 無選項編譯鏈接 
用法:#gcc test.c 
作用:將test.c預處理、彙編、編譯並鏈接形成可執行文件。這裏未指定輸出文件,默認輸出爲a.out。編譯成功後可以看到生成了一個a.out的文件。在命令行輸入./a.out 執行程序。./表示在當前目錄,a.out爲可執行程序文件名。

2. 選項 -o 
用法:#gcc test.c -o test 
作用:將test.c預處理、彙編、編譯並鏈接形成可執行文件test。-o選項用來指定輸出文件的文件名。輸入./test執行程序。

3. 選項 -E <大寫,注意>
用法:#gcc -E test.c -o test.i
作用:將test.c預處理輸出test.i文件。

4. 選項 -S <大寫,注意>
用法:#gcc -S test.i 
作用:將預處理輸出文件test.i彙編成test.s文件。

5. 選項 -c 
用法:#gcc -c test.s 
作用:將彙編輸出文件test.s編譯輸出test.o文件。

6. 無選項鍊接 
用法:#gcc test.o -o test 
作用:將編譯輸出文件test.o鏈接成最終可執行文件test。輸入./test執行程序。

7. 選項-O 
用法:#gcc -O1 test.c -o test 
作用:使用編譯優化級別1編譯程序。級別爲1~3,級別越大優化效果越好,但編譯時間越長。輸入./test執行程序。

二. 多源文件的編譯方法

如果有多個源文件,基本上有兩種編譯方法: 
[假設有兩個源文件爲test.c和testfun.c]

1. 多個文件一起編譯 
用法:#gcc testfun.c test.c -o test 
作用:將testfun.c和test.c分別編譯後鏈接成test可執行文件。 
2. 分別編譯各個源文件,之後對編譯後輸出的目標文件鏈接。 
用法: 
#gcc -c testfun.c //將testfun.c編譯成testfun.o 
#gcc -c test.c //將test.c編譯成test.o 
#gcc  testfun.o test.o -o test //將testfun.o和test.o鏈接成test

以上兩種方法相比較,第一中方法編譯時需要所有文件重新編譯,而第二種方法可以只重新編譯修改的文件,未修改的文件不用重新編譯。

三. gcc的常用編譯參數

    同VC,TC等編譯器不同,gcc其實是可以很方便的在提示符下編譯程序的。gcc在提示符下編譯程序,並沒有如同VC那樣的冗長而晦澀的編譯參數。相反,卻有着比VC更靈活且簡短的參數。

    不得不承認,不懂gcc編譯參數的人,確實會損失一些gcc的強大功能。所以,我下面簡單介紹一下gcc的一些基本編譯參數。這裏,我以C編譯器爲例。

    注意:gcc的編譯參數是區分大小寫的。 

    編譯二進制代碼 
    gcc -c yours.c -o yours.o 
    使用這段指令,gcc將會把yours.c編譯成yours.o的二進制代碼。其中,yours.o就類似於VC,TC中的.obj文檔。


    編譯最簡單的小程序 
    gcc -o yours yours.c 
    通過這條指令,gcc將會把yours.c源代碼編譯成名爲yours的可執行程序。當然,您也可以將yours.c改成我們剛纔介紹的yours.o文件。這樣,gcc將使用編譯剛纔編譯好的二進制文檔來鏈接程序。這裏,格式的特點是,-o 後面是一串文件列表,第一個參數是所編譯程序的文件名,從第二個開始,就是您編譯和連接該可執行程序所需要的二進制文檔或者源代碼。


    編譯時將自己的頭文件目錄設爲默認頭文件目錄 
    gcc -I”Your_Include_Files_Document_Path” -c yours.c -o yours.o 
    這條指令中的-I參數將會把Your_Include_Files_Document_Path添加到你默認的頭文件目錄中。這樣您將可以使用 #include <your_include.h>來導入頭文件。


    編譯時使用自己的靜態庫存放目錄 
    gcc -L”Your_Lib_Files_Document_Path” -o yours yours.o 
    這條指令將會讓gcc在連接時除了在默認Lib存放目錄中搜索指定的靜態庫以外,還會在Your_Lib_Files_Document_Path中搜索。


    編譯時使用靜態連接庫 
    gcc -lyour_lib -o yours yours.o 
    這條指令將會讓gcc在連接時把 libyour_lib.a中您所用到的函數連接到可執行程序中。此處注意,gcc所使用的靜態連接庫是lib*.a格式的。在連接時,只且僅需要提供*的內容就可以了。


    編譯時使用優化 
    gcc -O2 -c yours.c -o yours.o 
    使用優化方式編譯程序,其中除了-O2以外,還有-O3 -O1等等。他們代表不同的優化等級。最常用的,是-O2優化。當然,還有針對特殊CPU的優化,這裏就不介紹了。


    編譯時顯示所有錯誤和警告信息 
    gcc -Wall -c yours.c -o yours.o 
    gcc在默認情況下,將對一些如變量申請未使用這樣的問題或者申請了沒有給予初始值的問題忽略。但是,如果使用了-Wall參數,編輯器將列出所有的警告信息。這樣,您就可以知道您的代碼中有多少可能會在其他操作系統下出錯的地方了。(用這個指令看看你的代碼有多少地方寫的不怎麼合適。)


    編譯連接時,加入調試代碼 
    gcc -g -o yours yours.c 
    正如同VC有debug編譯模式一樣,gcc也有debug模式。添加了-g 參數編譯的可執行程序比普通程序略爲大一些,其中添加了一些調試代碼。這些代碼將被gdb所支持。


    連接時縮小代碼體積 
    gcc -s -o yours yours.o 
    因爲有人說Visual-MinGW生成的代碼小,於是研究了一下它的編譯參數,發現release模式的編譯參數就加了這一項。貌似編譯後的代碼的確縮小了很多。

    反彙編 
    gcc -S yours.c 
    用這個指令能把C語言變成彙編語言,不過不是常見的Intel語法,而是AT&T語法。兩者的語法有很大的區別。


    獲得幫助 
    gcc --help 
    這條指令從意思上就能看出,獲得gcc的幫助信息。如果您有什麼特殊需要,也許這個指令能幫上點小忙。


    總結:

    gcc的編譯參數是可以組合起來的,如:

    gcc yours.c -o yours -Wall -s -O2

------------------------------------------------------------------------------

MinGW搭建開發環境 
    MinGW是Minimalistic GNU for Windows 的縮寫。它是一個建立在GCC和binutils 項目上的編譯器系統。和其他GCC的移植版相比,它可以說是最接近Win32的一個了。因爲,MinGW幾乎支持所有的Win32 API,這也是MinGW的特色之一。它所連接的程序,不需要任何第三方庫就可以運行了。在某種程度上看,MinGW更像是VC的替代品。

    MinGW可以從http://www.mingw.org上獲得。

    要安裝MinGW有兩種方案:

    第一種方案:手動安裝

    到http://sourceforge.net/project/下載以下幾個壓縮包。考慮到文件的更新,此處只寫出文件的主要部分,省去文件的版本和更新日期(注:帶有src表示源代碼)。

    gcc-core:C語言編譯器,推薦使用最新的。 
    gcc-g++:C++語言編譯器,版本同上。(可選) 
    binutils:MinGW的彙編器和連接器等基礎工具。 
    mingw32-make:Make工具,用以管理你的項目。 
    gdb:MinGW調試器。 
    win32api:win32的API函數頭文件和連接庫 
    mingw-runtime:MinGW的運行時庫

    把以上的壓縮包解壓到一個目錄中,如C:\MinGW。

    注:MinGW還包括一個MSYM(Minimal SYStem)。這個工具是用來模仿Unix Shell,它可以把Unix上的命令轉換成Windows命令,如果習慣Unix可以下載這個工具。

    把MinGW的目錄 C:\MinGW\bin 添加進%PATH%環境變量中,可以在系統屬性那裏永久設置,或者建一個bat文件,寫入以下字符: 
    set Path=%PATH%;C:\MinGW\bin 
    然後進入DOS運行這個bat文件即可。

    最後在MS-DOS環境下運行: 
    gcc -v 
    如果顯示一段GCC的版本信息,說明你安裝的MinGW能正常工作了。 

    第二種方案:自動安裝

    到http://sourceforge.net/project/下載MinGW-x.x.x.exe。安裝過程它會自動從網上下載相應的文件,並自動配置好環境。

------------------------------------------------------------------------------

MinGW的使用
這部分將給出MinGW 下gcc/g++開發程序詳細例子。在討論例子使用之前,我們需要對MinGW安裝後的結果做個小小的改動。進入MinGW 的安裝目錄,如C:\MinGW,找到bin 目錄下mingw32-make.exe,將其更名爲make.exe(完成該改動後可以直接使用make來操作makefile)。
這裏開始正式討論MinGW的使用,分爲5 個步驟:(假設在D:\project 下開發,後續本節中文件建立均在該目錄下操作)
本節將會分別創建三個文件:cmnd.bat, makefile, main.cpp。

第一步建立 MinGW的gcc/g++的自動搜索路徑BAT 文件
創建一個文本文件,輸入以下方框內的內容:
set path=C:\mingw\bin;%PATH%;
cmd
保存好後,把文件名字改爲:cmnd.bat

第二步創建makefile
創建一個文本文件,輸入以下方框內的內容(可從本文中拷貝粘貼):
# makefile for MinGW Hello World Test
# @copyright 2007/05/01 by zenf
CC = g++
AR = ar
LD = ld
RM = del
#RM = rm -rf
MV = MOVE /Y
CP = copy
C++FLAGS = -g -Wno-deprecated -Wall -Werror -I.
OBJ_LIST = $(subst .cpp,.o,$(wildcard *.cpp))
TARGET = main.exe
all: depend.dep $(TARGET)
$(TARGET): $(OBJ_LIST)
$(CC) -o $(TARGET) $(OBJ_LIST) -mconsole
main.exe
clean:
$(RM) *.o *.obj *.tmp *.exe *.dep *.s
depend.dep:
$(CC) -M $(C++FLAGS) $(wildcard *.cpp) > $@
-include depend.*
.cpp.o :
$(CXX) -c $(C++FLAGS) $<
%.dir:%
$(MAKE) -C $< $(DEBUG_MAKE)
保存好後,把文件名字改爲: makefile (注:沒有後綴)

第三步建立 main.cpp
創建一個文本文件,輸入以下方框內的內容:
#include <iostream>
using namespace std;
int main(int argc, char* argv[])
{
cout << "hello world"<<endl;
cout << "----------------------------" << endl;
cout << "filename=" << __FILE__ << " line="<< __LINE__ << endl;
cout << "time="<< __TIME__ << " date="<< __DATE__ << endl;
cout << "funname="<< __func__ << endl;
cout << "----------------------------" << endl;
return 0;
}
保存好後,把文件名字改爲: main.cpp
說明:main.cpp示例中的__FILE__, __LINE__, __func__等幾個宏,對嵌入式軟件開發的debug非常幫助。

第四步編譯運行console模式
雙擊第一步中建立的cmnd.bat,進入command模式,輸入make 回車,make自動調用makefile編譯main.cpp,並且自動運行編譯後的結果main.exe,輸出如下結果:
D:\project >make
g++ -c -g -Wno-deprecated -Wall -Werror -I. main.cpp
g++ -o main.exe main.o -mconsole
main.exe
hello world
----------------------------
filename=main.cpp line=17
time=11:19:23 date=May 1 2007
funname=main
----------------------------

第五步編譯運行windows 模式
編輯main.cpp,修改爲如下的代碼內容:
#include <windows.h>
intWINAPI WinMain (HINSTANCE hInstance,
HINSTANCE hPrevInstance,
PSTR szCmdLine,
int iCmdShow)
{
MessageBox (NULL, "Hello World, My Dear", "Hello Demo", MB_OK);
return (0);
}
同時把第二步驟的makefile 一行內容修正(把-mconsole改爲-mwindows)
$(CC) -o $(TARGET) $(OBJ_LIST) –mconsole
修改爲:
$(CC) -o $(TARGET) $(OBJ_LIST) –mwindows
運行make 如同第四步。

詳細的MinGW的說明和使用,參考http://www.mingw.org/docs.shtml
  1. gcc 編譯 dll 庫文件
這兩天用CB(Code::Blocks)寫個小程序,要編譯出DLL供VB(6)使用。CB使用mingw-gcc作爲編譯器,在庫文件的產出上跟VC、VS之類的IDE略有不同。

由於C語言的基礎知識不是太好,尤其對編譯環節更是知之甚少。結果,試了幾次,導出的DLL中的函數總是無法被調用。

用VB加載時總是提示"DLL調用約定錯誤",百度之瞭解到VB只能調用適配__stdcall約定(這也是其他語言也能調用C的默認方式)的函數。

於是在源文件中的函數前加上__stdcall,導出後又提示"找不到DLL入口點foo in mydll.dll",搜索得知可能是導出函數的名字有問題。

打開DLL Export Viewer,載入mydll.dll,發現函數變成了"foo@4"。

網上的說法是使用__stdcall的副作用,可以用extern "C"來避免,於是又加上extern "C",結果依舊。

還有人說可以用DEF文件來控制導出的函數名,不過我也沒查到具體該怎麼加入到編譯過程中。

不斷google&baidu之後,發現gcc可以在鏈接階段通過指定--kill-at參數來消除這種情況。於是,緊接着又瞭解了下gcc的使用方法,嘗試幾次後終於成功了。

在這不得不吐槽部分人寫的技術博客,很多問題就是隻言片語帶過,讓人看得雲裏霧裏。我覺得人可以說錯話,但是起碼要把自己的意思表達清楚,不然胡亂湊出一篇誤人誤己。

這裏編寫個簡單例子來說明下具體是如何操作的:

建立DLL項目,結構如下:

test/
----mydll.h
----mydll.c
頭文件:mydll.h

#ifndef __MYDLL_H__
#define __MYDLL_H__

#ifdef BUILD_DLL
  #define DLL_EXPORT __declspec(dllexport)
#else
  #define DLL_EXPORT __declspec(dllimport)
#endif

#ifdef __cplusplus
extern "C" {
#endif
  DLL_EXPORT int __stdcall foo(int x);
#ifdef __cplusplus
}
#endif

#endif // __MYDLL_H__
C文件:mydll.c

#include "mydll.h"

DLL_EXPORT int __stdcall foo(int x) {
    return x;
}
如果你安裝了Code::Blocks(和MinGW),那麼創建環境變量:

MINGW_HOME=C:\Program Files\CodeBlocks\MinGW
PATH=%MINGW_HOME%\bin;%PATH%
打開命令行,進入我們的項目路徑中:

d:\test>
#執行編譯命令
d:\test>mingw32-gcc -c -DBUILD_DLL mydll.c
#執行鏈接命令,生成mydll.dll和靜態庫文件libmydll.a
d:\test>mingw32-gcc -shared -o mydll.dll mydll.o -Wl,--kill-at,--out-implib,libmydll.a
Creating library file: libmydll.a
以上,就是我們生成DLL的全過程了。

接下來,打開VB我們來驗證下:

Private Declare Function foo Lib "d:\test\mydll.dll" (ByVal x As Integer) As Integer

Private Sub Form_Load()
    Debug.Print foo(10)
End Sub
運行OK,立即窗口輸出10。

用Python測試下:

>>> import ctypes
>>> mydll = ctypes.windll.LoadLibrary("d:\\test\\mydll.dll")
>>> print mydll.foo(10)
10
>>>
好,也沒問題,那麼證明結果上是正確的。

當然,由於本人水平較低,文章中肯定有描述不正確的地方,各位大神如果如果看到還請不吝指教。

參考文檔:

http://baike.baidu.com/view/2814224.htm

http://baike.baidu.com/view/1276580.htm?fr=aladdin

http://blog.sina.com.cn/s/blog_4b02b8d001000avi.html
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章