顯示具有 MinGW 標籤的文章。 顯示所有文章
顯示具有 MinGW 標籤的文章。 顯示所有文章

2024年4月1日 星期一

Cygwin vs MinGW vs Msys

Quote Cygwin、Msys、MinGW、Msys2的區別與聯繫_msys2和mingw-CSDN博客

區別:
  • Cygwin是類比 POSIX 系統,源碼移植 Linux 應用到 Windows 下
  • MinGW 是用於開發 Windows 應用的開發環境。
  • Msys
  • Msys2

聯繫:
  • 均提供了部分 Linux 下的應用,多跑在 Windows 上
  • MinGW 作為 Cygwin 下的軟體包,可以在 Cygwin 上運行

Cygwin,原 Cygnus 出品(已被紅帽收購),目前是 RedHat 名下的專案。 專案的目的是提供運行於 Windows 平臺的類 Unix 環境(以 GNU 工具為代表),為了達到這個目的,Cygwin 提供了一套抽象層 dll,用於將部分 Posix 調用轉換成 Windows 的 API 調用,實現相關功能。 這裡面最典型的,最基本的類比層就是那個 cygwin1.dll。 除此之外,隨著Linux系統的發展壯大,目前的 Cygwin 已經不僅僅提供POSIX相容,因此也順帶多了更多類比層的依賴關係。

Cygwin 的目錄結構基本照搬了 linux 的樣子,但同時,也相容了 Windows 的許多功能:大部分應用使用 Unix 風格的路徑,Windows的盤符通過類似掛載點的方式提供給 Cygwin 使用;Cygwin 中既可以運行 Cygwin 的應用(依賴模擬層),又可以運行 Windows 應用,而傳遞給應用的路徑會經過它的類比層變換,以此保證程式運行不會出錯。

由於它的類比層實現了相當良好的 Posix 相容,人們試著將許多重要的 Linux/BSD 應用移植到了Cygwin下,使得Cygwin越來越大,功能也越來越豐富,以至於目前很多人直接把將Linux應用移植到Windows平臺的任務都交給了Cygwin(當然,這種移植並非原生)。 事實上,Cygwin誕生之初,本就是想通過GCC編譯出Windows應用來,因為bootstrap GCC而順帶搞了一坨別的東西過來,最後發展到現在的。

小結:Cygwin是運行於Windows平臺的POSIX“子系統”,提供Windows下的類Unix環境,並提供將部分 Linux 應用“移植”到Windows平臺的開發環境的一套軟體。 按照我經常開玩笑的話來講,Cygwin 基本上就是傳說中的 GNU/NT 系統(對照 GNU/Linux,GNU/BSD,GNU/HURD)。



MinGW, Minimalist GNU for Windows,開發原生(32位) Windows 應用的開發環境。 它主要提供了針對 win32 應用的 GCC、GNU binutils 等工具,以及對等於 Windows SDK(的子集)的頭文件和用於 MinGW 版本 linker 的庫檔(so、a等,而不是 VC 的 lib)。

MinGW 能夠替代 cl 用於編譯不包含 MFC 的、以 WinSDK 為主的 Windows 應用,並且編譯出來的應用不依賴於第三方的模擬層支援,其運行時為大部分 Windows 標配的 msvcrt(故稱原生 Windows 應用)。 除此之外,MinGW 也支援 GCC 支援的其他語言。

因為這些原因,MinGW 被許多 Linux 上發展起來的開發工具選擇為 Windows 版本的預設編譯器,例如 CodeBlocks,例如 DevC++。

小結,MinGW 是用於進行 Windows 應用開發的 GNU 工具鏈(開發環境),它的編譯產物一般是原生 Windows 應用,雖然它本身不一定非要運行在 Windows 系統下(是的 MinGW 工具鏈也存在於 Linux、BSD 甚至 Cygwin 下)。



MSYS,由於 MinGW 本身僅代表工具鏈,而在 Windows 下,由於那個shi一樣的cmd,以及配套的命令行工具不夠齊全(也不舒服),因此,MinGW 開發者從曾經比較舊的 Cygwin 創建了一個分支,也用於提供類 Unix 環境。 但與 Cygwin 的大而全不同,MSYS 是衝著小巧玲瓏的目標去的,所以整套 MSYS 以及 MinGW,主要以基本的 Linux 工具為主,大小在 200M 左右,並且沒有多少擴展能力。

MSYS 是用於輔助 Windows 版 MinGW 進行命令行開發的配套軟體包,提供了部分 Unix 工具以使得 MinGW 的工具使用起來方便一些。 如果不喜歡龐大的 Cygwin,而且使用不多,可以試試。 不過喜歡完整體驗、不在乎磁碟佔用等等,還是推薦 Cygwin 而不是 MSYS。



MinGW-w64,前面提到的MinGW,是針對32位 Windows 應用開發的。 而且由於版本問題,不能很好的支援較新的 Windows API。 MinGW-W64 則是新一代的 MinGW,支援更多的 API,支援 64 位應用開發,甚至支援 32 位 host 編譯 64 位應用以及反過來的“交叉”編譯。 除此之外,它本身也有 32 位和 64 位不同版本,其它與 MinGW 相同。



MSYS2,由於 MinGW 萬年不更新,MSYS 更是,Cygwin的許多新功能 MSYS 沒有同步過來,於是 Alex 等人建立了新一代的 MSYS 專案。 仍然是 fork 了 Cygwin(較新版),但有個更優秀的包管理員 pacman,有活躍的開發者跟使用者組,有大量預編譯的軟體包(雖然肯定沒有Cygwin多)...... 對於不喜歡龐大的 Cygwin 的使用者而言,推薦試試 msys2。

2015年4月20日 星期一

用MinGW編譯DLL

原文: http://october388.blogspot.tw/2009/04/mingwdll.html

testdll.h:
#ifndef TESTDLL_H
#define TESTDLL_H

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

#ifdef __cplusplus
extern "C" {
#endif

DLLAPI float funadd(float a, float b);

#ifdef __cplusplus
}
#endif

#endif


testmain.c:#include
#include "testdll.h"

int main(void)
{
float a,b,c;

    a=1.0;
    b=2.0;
    c=funadd(a,b);
    
    printf("%f \n",c);
    getchar();    
}


testdll.c:
#include "testdll.h"

float funadd(float a, float b)
{
    return (a+b);
}


gcc -c -DDLL_EXPORT (-fPIC) testdll.cPS : 會產生testdll.o的檔案...還有x86平台,-fPIC會忽略

gcc -shared -o testdll.dll testdll.o -Wl,--output-def,testdll.def,--out-implib,testdll.lib
PS : 產生三個檔案:
testdll.dll:也就是程式執行時載入的dll檔 
testdll.def:若有需要和VC編譯器連結,這個檔會需要
testdll.lib:export library,用來連結主程式,這樣主程式才能知道找哪個dll,那個dll裡有哪些函式跟參數....

gcc -c testmain.cPS : 用來使用dll的主程式,會產生一個testmain.o的檔案

gcc -static -o test.exe testmain.o -L. -ltestdllPS : 會讓主程式和export library(testdll.lib)靜態連結起來,產生test.exe的可執行檔


由於dll和主程式都是用MinGW產生的,所以可以簡化上面的步驟,不過上面的解說,可以對執行檔組成了解多一些,以下舉兩個例子

方法一:
gcc -shared -o testdll.dll testdll.c
PS : -shared是linker的參數,這裡直接產生testdll.dll

gcc -c testmain.c

PS : -c:只編譯不連結,產生testmain.o

gcc -o test.exe testmain.o testdll.dll

PS : 我也不知給什麼規則,反正MinGW搞得定這個testdll.dll就對了

方法二:
gcc -shared -o testdll.dll testdll.c
gcc -o test.exe testmain.c -L. -ltestdll

PS : -l:unix環境裡,會找libtestdll.a(-static) 或 libtestdll.so(-shared),在函式庫名稱的命名上,前面一定要有lib

不過MinGW對於這個慣例,放寬許多,來讓熟悉windows的人習慣
for (-static) : 會找libtestdll.a 或 testdll.lib
for (-shared) : 會找libtestdll.so . testdll.dll 或 libtestdll.dll

希望看完之後是感覺"條條道路通羅馬",而不是給它一整個亂...

這裡又牽扯出另一個疑問,那就是MinGW的make,它對於字尾規則和函式庫的處理,是否有加上這些擴充,有空在研究好了

PS:MinGW的官方網站,有提供一個Shell,叫MSYS,之前發現MinGW和MSYS都有自己的make,MinGW的make叫mingw32-make.exe,MSYS的make叫make.exe,其中MSYS的make是unix style,不能分辨'\',組成的路徑字串(windows是用'\',組成路徑字串),也許這兩個make除了這個區別,還包括了字尾規則和函式庫處理的差異...


testdll.h的補充說明:
關於DLL_EXPORT 的定義,應該要在編譯testdll.c時定義,來分別dllimport和dllexport,不過我沒加,也沒錯誤,我不知道MinGW有沒有支援__declspec(dllimport)和__declspec(dllexport) 這些關鍵字...

關於extern "C" {},如果使用gcc,且souce code的附檔名是.c,會有錯誤,不過__cplusplus沒有定義,會避開...
如果附檔名是.cpp,或gcc改g++,則__cplusplus會定義,就會使函數的Name Mangling使用C的形式(簡單的那一種),常看到...

這裡的紀錄,主要都是看了別人的文章,試出來的...我盡量有系統性,不過最好還是參考相關主要說明文件