[编译] 2、minGW gcc在windows搭建编译win32程序环境
2018-06-08 19:39
441 查看
1、普通下载一个MinGW程序、安装之后可以直接将MinGW目录拷贝到总工程的tool里面:
demo_mesh_common tree -L 2 . ├── app ├── bin ├── build ├── doc ├── sdk │ ├── alg │ ├── bsp │ ├── driver │ └── phy └── tool └── MinGW
2、参考学习在dos下使用gcc来编译,发现分步骤编译会报_alloca未定义的错误:
a.o:a.c:(.text+0x3f8): undefined reference to `_alloca'
猜测可能是有些库没有链接进来,于是搜索MinGW/lib/下的库:
F:\demo_mesh_common\tool\MinGW\lib>grep -rn "_alloc" Binary file libmingw32.a matches Binary file libmingwex.a matches Binary file libwldap32.a matches Binary file libdxerr8.a matches Binary file libdxerr9.a matches Binary file gcc/mingw32/3.4.5/libgcc.a matches Binary file librpcdce4.a matches Binary file libbfd.a matches Binary file libiberty.a matches
通过一个一个加进编译选项,最终发现:需要将gcc/mingw32/3.4.5/libgcc.a加入:
./MinGW/bin/ld -L"./MinGW/lib" -o a.exe a.o "./MinGW/lib/crt2.o" -lmingw32 -lkernel32 -lmsvcrt -luser32 -lwow32 -lwldap32 -lwin32k -lvfw32 -lmingw32 -lmingwex -lwldap32 -ldxerr8 -ldxerr9 -lrpcdce4 -lbfd -liberty -L"./MinGW/lib/gcc/mingw32/3.4.5" -lgcc
3、我测试的win32串口程序,在Git Bush(linux属性)的窗口中可以执行,但无数据,必须在win窗口中执行。
4、附录
makefile:
a.o:a.c ./MinGW/bin/gcc -c a.c B:a.o ./MinGW/bin/ld -L"./MinGW/lib" -o a.exe a.o "./MinGW/lib/crt2.o" -lmingw32 -lkernel32 -lmsvcrt -luser32 -lwow32 -lwldap32 -lwin32k -lvfw32 -lmingw32 -lmingwex -lwldap32 -ldxerr8 -ldxerr9 -lrpcdce4 -lbfd -liberty -L"./MinGW/lib/gcc/mingw32/3.4.5" -lgcc A: ./MinGW/bin/gcc -s -O2 a.c -mconsole
a.c:
#include <stdio.h> #include <stdlib.h> #include <windows.h> #include <string.h> #include <malloc.h> HANDLE hComm; OVERLAPPED m_ov; COMSTAT comstat; DWORD m_dwCommEvents; //如果在调用CreateFile创建句柄时指 //定了FILE_FLAG_OVERLAPPED标志,那么调用ReadFile和WriteFile对该句柄进 //行的操作就应该是重叠的;如果未指定 //重叠标志,则读写操作应该是同步的 //在同步执行时,函数直到操作完成后才返回。这意味着同步执行时线程会被阻塞,从 //而导致效率下降。在重叠执行时,即使操作还未完成,这两个函数也会立即返回,费 //时的I/O操作在后台进行 BOOL openport(char *portname)//打开一个串口 { hComm = CreateFile(portname, GENERIC_READ | GENERIC_WRITE, 0, 0, OPEN_EXISTING, FILE_FLAG_OVERLAPPED, 0); if (hComm == INVALID_HANDLE_VALUE) return FALSE; else return TRUE; } BOOL setupdcb(int rate_arg) { DCB dcb; int rate= rate_arg; memset(&dcb,0,sizeof(dcb)); //在一段内存块中填充某个给定的值,是对较大的结构//体或数组进行清零操作的一种最快方法 if(!GetCommState(hComm,&dcb))//获取当前DCB配置 { return FALSE; } /* -------------------------------------------------------------------- */ // set DCB to configure the serial port dcb.DCBlength = sizeof(dcb); /* ---------- Serial Port Config ------- */ dcb.BaudRate = rate; dcb.Parity = NOPARITY; dcb.fParity = 0; dcb.StopBits = ONESTOPBIT; dcb.ByteSize = 8; dcb.fOutxCtsFlow = 0; dcb.fOutxDsrFlow = 0; dcb.fDtrControl = DTR_CONTROL_DISABLE; dcb.fDsrSensitivity = 0; dcb.fRtsControl = RTS_CONTROL_DISABLE; dcb.fOutX = 0; dcb.fInX = 0; /* ----------------- misc parameters ----- */ dcb.fErrorChar = 0; dcb.fBinary = 1; dcb.fNull = 0; dcb.fAbortOnError = 0; dcb.wReserved = 0; dcb.XonLim = 2; dcb.XoffLim = 4; dcb.XonChar = 0x13; dcb.XoffChar = 0x19; dcb.EvtChar = 0; /* -------------------------------------------------------------------- */ // set DCB if(!SetCommState(hComm,&dcb)) { return FALSE; } else return TRUE; } //在用readfile和writefile读写串行口时,需要考虑超时问题, 读写串口的超时有两 //种:间隔超时和总超时, 写操作只支持总超时,而读操作两种超时均支持, 如果所有 //写超时参数均为0,那么就不使用写超时。 BOOL setuptimeout(DWORD ReadInterval,DWORD ReadTotalMultiplier,DWORD ReadTotalconstant,DWORD WriteTotalMultiplier,DWORD WriteTotalconstant) { COMMTIMEOUTS timeouts; timeouts.ReadIntervalTimeout=ReadInterval; //读间隔超时 timeouts.ReadTotalTimeoutConstant=ReadTotalconstant; //读时间系数 timeouts.ReadTotalTimeoutMultiplier=ReadTotalMultiplier; //读时间常量 timeouts.WriteTotalTimeoutConstant=WriteTotalconstant; // 写时间系数 timeouts.WriteTotalTimeoutMultiplier=WriteTotalMultiplier; //写时间常//量, 总超时的计算公式是:总超时=时间系数×要求读/写的字符数+时间常量 if(!SetCommTimeouts(hComm, &timeouts)) { return FALSE; } else return TRUE; } void ReceiveChar(){ BOOL bRead = TRUE; BOOL bResult = TRUE; DWORD dwError = 0; DWORD BytesRead = 0; char RXBuff; while(TRUE){ bResult = ClearCommError(hComm, &dwError, &comstat); // 在使用ReadFile 函数进行读操作前,应先使用ClearCommError函数清除错误 if(comstat.cbInQue==0)// COMSTAT结构返回串口状态信息 //本文只用到了cbInQue成员变量,该成员变量的值代表输入缓冲区的字节数 continue; if(bRead){ bResult = ReadFile(hComm, // Handle to COMM port串口的句柄 &RXBuff,// RX Buffer Pointer// 读入的数据存储的地址,即读入的数据将存//储在以该指针的值为首地址的一片内存区 1,// Read one byte要读入的数据的字节数, &BytesRead, // Stores number of bytes read, 指向一个DWORD//数值,该数值返回读操作实际读入的字节数 &m_ov); // pointer to the m_ov structure// 重叠操作时,该参数指向一个OVERLAPPED结构,同步操作时,该参数为NULL printf("%02X",RXBuff); if (!bResult){// 当ReadFile和WriteFile返回FALSE时,不一定就是操作失//败,线程应该调用GetLastError函数分析返回的结果 switch (dwError = GetLastError()){ case ERROR_IO_PENDING: bRead = FALSE; break; default:break; } }else{ bRead = TRUE; } } // close if (bRead) if (!bRead){ bRead = TRUE; bResult = GetOverlappedResult(hComm, // Handle to COMM port &m_ov, // Overlapped structure &BytesRead, // Stores number of bytes read TRUE); // Wait flag } } } BOOL WriteChar(BYTE* m_szWriteBuffer,DWORD m_nToSend){ BOOL bWrite = TRUE; BOOL bResult = TRUE; DWORD BytesSent = 0; HANDLE m_hWriteEvent; ResetEvent(m_hWriteEvent); if (bWrite){ m_ov.Offset = 0; m_ov.OffsetHigh = 0; // Clear buffer bResult = WriteFile(hComm, // Handle to COMM Port, 串口的句柄 m_szWriteBuffer, // Pointer to message buffer in calling finction // 即以该指针的值为首地址的nNumberOfBytesToWrite // 个字节的数据将要写入串口的发送数据缓冲区 m_nToSend, // Length of message to send, 要写入的数据的字节数 &BytesSent, // Where to store the number of bytes sent // 指向指向一个DWORD数值,该数值返回实际写入的字节数 &m_ov ); // Overlapped structure // 重叠操作时,该参数指向一个OVERLAPPED结构, // 同步操作时,该参数为NULL if (!bResult){ // 当ReadFile和WriteFile返回FALSE时,不一定就是操作失 //败,线程应该调用GetLastError函数分析返回的结果 DWORD dwError = GetLastError(); switch (dwError){ case ERROR_IO_PENDING: //GetLastError函数返回//ERROR_IO_PENDING。这说明重叠操作还未完成 // continue to GetOverlappedResults() BytesSent = 0; bWrite = FALSE; break; default:break; } } } // end if(bWrite) if (!bWrite){ bWrite = TRUE; bResult = GetOverlappedResult(hComm, // Handle to COMM port &m_ov, // Overlapped structure &BytesSent, // Stores number of bytes sent TRUE); // Wait flag // deal with the error code if (!bResult){ printf("GetOverlappedResults() in WriteFile()"); } } // end if (!bWrite) // Verify that the data size send equals what we tried to send if (BytesSent != m_nToSend){ printf("WARNING: WriteFile() error.. Bytes Sent: %d; Message Length: %d\n", BytesSent, strlen((char*)m_szWriteBuffer)); } return TRUE; } int main(void){ printf("open comport successsdsfds\n"); if(openport("com3")) printf("open comport success\n"); if(setupdcb(9600)) printf("setupDCB success\n"); if(setuptimeout(0,0,0,0,0)) //如果所有写超时参数均为0,那么就不使用写超时 printf("setuptimeout success\n"); PurgeComm(hComm, PURGE_RXCLEAR | PURGE_TXCLEAR | PURGE_RXABORT | PURGE_TXABORT); // 在读写串口之前,还要用PurgeComm()函数清空缓冲区 //PURGE_TXABORT 中断所有写操作并立即返回,即使写操作还没有完成。 //PURGE_RXABORT 中断所有读操作并立即返回,即使读操作还没有完成。 //PURGE_TXCLEAR 清除输出缓冲区 //PURGE_RXCLEAR 清除输入缓冲区 //WriteChar("please send data now",20); printf("received data:\n"); ReceiveChar( ); system("pause"); return 0; }
链接
- 学习在dos下使用gcc来编译:https://www.geek-share.com/detail/2645576360.html
@beautifulzzzz 智能硬件、物联网,热爱技术,关注产品 博客:http://blog.beautifulzzzz.com 园友交流群:414948975
相关文章推荐
- objective-c : windows下搭建环境并编译自己的第一个objective-c程序
- libpomelo+cocos2d-x 开发环境搭建(windows平台开发win32程序)
- Windows 7下使用GNU工具编译C/C++程序的环境搭建
- Windows环境下使用cmd面板手动编译c/c++程序
- Wireshark Windows编译环境搭建
- Windows下通过虚拟机搭建android的linux编译环境
- windows下搭建NDK+Cygwin编译环境…
- 交叉编译之二:linux环境搭建及下载程序
- Windows环境下搭建Cocos2d-x3.2环境并配置android交叉编译环境(转)
- protobuf windows java 环境搭建(编译出protobuf需要的jar包,解决编译时OutOfMemory的问题)
- Windows Objective C编译环境搭建
- windows环境VS2015编译TensorFlow C++程序完全攻略
- win32汇编环境搭建以及第一个程序
- Windows 使用dryrun 运行github上的Android程序之环境搭建
- 【Go】windows下搭建go语言编译环境
- 在Windows下使用CMake+MinGW搭建C/C++编译环境
- Windows下Qt编译环境搭建及编译命令 (转)
- 最新的IOS在windows环境下编译环境搭建记录
- 在 windows 环境下编译 Objective-C 程序
- Subline text3 配置java程序编译运行在subline控制台环境和windows控制台