从Cygwin中取出MinGW for GCC
Cygwin内含MinGW,于是就把原有的MinGW卸载了。但是由于某种原因(原因在最后介绍)gcc在Windows命令行下就不起作用了(运行后并不产生编译结果),即使Path设置正确。
采用掩蔽DLL的方法。将gcc放置于一个新建的文件夹,并运行,会出现缺失DLL,逐个加上这些DLL后能执行通过,但结果仍是无法产生输出文件。估计仍是有相关的DLL没有被链入。但是使用Dependency Walker也无法发现(显然在执行而言,装入文件夹的这些DLL已经足够了)。这些DLL是:
cygwin1.dll
cygintl-8.dll
cygiconv-2.dll
于是就想通过暴力方法找到这个缺失的DLL,想法很简单,就是逐个装入Cygwin的bin文件夹下的那些DLL,直到gcc执行能输出编译结果为止,这样最后装入的那个DLL有很大的可能是唯一缺失的那个DLL。Cygwin下的DLL毛毛多,当然得用程序实现,结果发现那个依赖的DLL是cygintl-3.dll。
这个程序工具选取,编译和执行也很有讲究。如果继续用那个cygwin下的gcc会有诸多不便。于是用VC,但其中用了cygwin下的一些命令,例如ls,因为其输出结果比dir要规整。因为system命令中cd是不起作用的,最终生成文件要放在那个装有待测gcc.exe的文件夹中,这个文件夹放在Cygwin/mingw下。具体代码贴在最后。
现在讲一下产生这个问题的真正原因。这个原因很可笑,是因为存在另一个应用,它也用到了cygwin相关的dll,但版本较旧。而它的bin文件夹又在%PATH%中,而新加的bin(包括Cygwin本身的bin)都在它之后。估计DLL的搜寻也是从%PATH%中依次进行的,于是链入的都是旧版本的,从而导致错误。这样一来看来刚才的这些抽取工作都是不必要的。郁闷。
采用掩蔽DLL的方法。将gcc放置于一个新建的文件夹,并运行,会出现缺失DLL,逐个加上这些DLL后能执行通过,但结果仍是无法产生输出文件。估计仍是有相关的DLL没有被链入。但是使用Dependency Walker也无法发现(显然在执行而言,装入文件夹的这些DLL已经足够了)。这些DLL是:
cygwin1.dll
cygintl-8.dll
cygiconv-2.dll
于是就想通过暴力方法找到这个缺失的DLL,想法很简单,就是逐个装入Cygwin的bin文件夹下的那些DLL,直到gcc执行能输出编译结果为止,这样最后装入的那个DLL有很大的可能是唯一缺失的那个DLL。Cygwin下的DLL毛毛多,当然得用程序实现,结果发现那个依赖的DLL是cygintl-3.dll。
这个程序工具选取,编译和执行也很有讲究。如果继续用那个cygwin下的gcc会有诸多不便。于是用VC,但其中用了cygwin下的一些命令,例如ls,因为其输出结果比dir要规整。因为system命令中cd是不起作用的,最终生成文件要放在那个装有待测gcc.exe的文件夹中,这个文件夹放在Cygwin/mingw下。具体代码贴在最后。
现在讲一下产生这个问题的真正原因。这个原因很可笑,是因为存在另一个应用,它也用到了cygwin相关的dll,但版本较旧。而它的bin文件夹又在%PATH%中,而新加的bin(包括Cygwin本身的bin)都在它之后。估计DLL的搜寻也是从%PATH%中依次进行的,于是链入的都是旧版本的,从而导致错误。这样一来看来刚才的这些抽取工作都是不必要的。郁闷。
- #include <stdio.h>
- #define DLLNAMEBUFSIZE 128
- #define DLLNAMEBUFSIZE 128
- #define CMDBUFSIZE 256
- #define RECVBUFSIZE 256
- typedef struct _DllInfo DllInfo;
- struct _DllInfo
- {
- char fileName[DLLNAMEBUFSIZE];
- DllInfo *pNext;
- };
- DllInfo *g_pDllList;
- DllInfo *g_pDllListTail;
- void ParseDllFileNames(FILE *fDl)
- {
- DllInfo *pDll;
- char dllNameBuf[DLLNAMEBUFSIZE];
- g_pDllListTail=g_pDllList = 0;
- while (!feof(fDl))
- {
- int n = fscanf(fDl, "%s/n", dllNameBuf);
- if (n == 0)
- {
- break;
- }
- //printf("%s/n", dllNameBuf);
- pDll = (DllInfo*)malloc(sizeof(DllInfo));
- strcpy(pDll->fileName, dllNameBuf + strlen("../bin/"));
- pDll->pNext = 0;
- if (g_pDllList==0)
- {
- g_pDllListTail=g_pDllList=pDll;
- }
- else
- {
- g_pDllListTail->pNext = pDll;
- g_pDllListTail = pDll;
- }
- }
- }
- int CheckFileExistence()
- {
- char recvbuf[RECVBUFSIZE];
- char *pszCmd = "..//bin//ls a.exe > result.txt";
- char *pszTarget = "a.exe";
- FILE *f;
- printf("%s/n", pszCmd);
- system(pszCmd);
- f = fopen("result.txt", "rb");
- if (!f)
- {
- return 0;
- }
- fgets(recvbuf, RECVBUFSIZE, f);
- if (0 == strncmp(recvbuf, pszTarget, strlen(pszTarget)))
- {
- return 1;
- }
- else
- {
- printf("return 0/n");
- return 0;
- }
- }
- void TryAddingDlls()
- {
- DllInfo *pDll = g_pDllList;
- char *pCmdCpl = "gcc.exe a.c";
- for ( ; pDll; pDll = pDll->pNext)
- {
- char *pszDllName = pDll->fileName;
- char cmd[CMDBUFSIZE];
- sprintf(cmd, "copy ..//bin//%s .", pszDllName);
- printf("%s/n", cmd);
- system(cmd);
- printf("%s/n", pCmdCpl);
- system(pCmdCpl);
- if (CheckFileExistence())
- {
- printf(":gcc works after %s being added./n", pszDllName);
- break;
- }
- }
- }
- int main(void)
- {
- FILE *fDl = 0;
- char *pCmd = "..//bin//ls ../bin/*.dll > dllfilelist.txt";
- printf("%s/n", pCmd);
- system(pCmd);
- fDl = fopen("dllfilelist.txt", "r");
- if (!fDl)
- {
- printf(": Error opening the list file./n");
- return 0;
- }
- ParseDllFileNames(fDl);
- fclose(fDl);
- printf(": Parsing DLL names OK./n");
- TryAddingDlls();
- return 0;
- }
enjoy every minute of an appless, googless and oracless life