[编译] 2、minGW gcc在windows搭建编译win32程序环境

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.cnblogs.com/personnel/p/4584819.html

@beautifulzzzz
智能硬件、物联网,热爱技术,关注产品
博客:http://blog.beautifulzzzz.com
园友交流群:414948975
[编译] 2、minGW gcc在windows搭建编译win32程序环境的更多相关文章
- vs编译在win xp电脑上运行的win32程序遇到的问题记录(无法定位程序输入点GetTickCount64于动态链接库KERNEL32.dll)
直接编译后运行,弹出提示框:不是有效的win32应用程序 像之前那样把msvcr110.dll复制过去依然报错: 这是因为vs2012编译的win32程序用到的系统函数在xp环境上对应不上.之前转载的 ...
- TestLink学习一:Windows搭建Apache+MySQL+PHP环境
PHP集成开发环境有很多,如XAMPP.AppServ......只要一键安装就把PHP环境给搭建好了.但这种安装方式不够灵活,软件的自由组合不方便,同时也不利于学习.所以我还是喜欢手工搭建PHP开发 ...
- 在windows搭建react-native android 开发环境总结
1.安装必须的软件 1.Python 2 注意勾选 Add python.exe to Path,选项,这样就可以在安装完成后,不用手动去添加环境变量 安装完,打开cmd.exe,输入py ...
- 在windows搭建jenkins測试环境
jenkins 搭建好开发环境必备之中的一个,简单易用,搭建測试平台非常有帮助,不知道的都能够了解一下 官网下载地址 http://jenkins-ci.org/ 我是下载window版本号的 安装有 ...
- Windows 搭建 Linux kernal0.11 环境
下载:http://www.oldlinux.org/Linux.old/bochs/ 安装bochs 运行 界面:
- 在Windows7上搭建Cocos2d-x win32开发环境
很多其它相关内容请查看本人博客:http://www.bokeyi.com/ll/category/cocos2d-x/ 建议:为了避免安全相关的问题,请以管理员权限执行全部的操作,当执行命令的时候, ...
- 于windows建筑物Cocos2d-x win32开发环境
这份文件是从cocos2d-x复制的官网.. . 在windows7上搭建COCOS2D-X开发环境并不难. 可是因为框架更新过快,非常多用户都有困难.我希望你们觉得这个教程实用. 建议:为了避 ...
- Windows下搭建Android NDK开发环境及命令行编译
首先说明本文内的相关安装操作参考<Pro Android C++ with the NDK>一书. 安装 Windows搭建Android NDK开发环境需要安装如下部分(同时需要配置对应 ...
- 在Windows下编译FFmpeg详细说明
MinGW:一个可自由使用和自由发布的Windows特定头文件和使用GNC工具集导入库的集合,允许你生成本地的Windows程序而不需要第三方C运行时 MinGW,即 Minimalist GNU F ...
随机推荐
- 【codelife 阿里技术文章分享——读后感】
目前看到的几篇比较有感触的文章,分别是: 前端Leader如何做好团队规划?阿里内部培训总结公开 ——>这里会有关于针对技术项目如何做规划的一些指导,非常有价值 程序员吃的是青春饭?本质上取 ...
- vue的搭建项目
请求的封装,先在src下面创建一个utils的文件夹,文件夹里面有ajax.js loading.js index.js to 1 请求的封装 ajax文件 需要引入的文件在后面 /* * [page ...
- 【scarletthln 关于算法的一点总结】
1. 分解问题的角度: fix 某一维度,尝试另一维度上的所有可能 a. 可能是array的(i, j)pointers, b. 可能是矩形的长与宽, c. 可能是tree的每一个subtree, ...
- 51单片机学习笔记(郭天祥版)(9)——IIC、EEPROM
IIC是两根线,单总线,只有一根数据线,发送数据和读取收据都是一根线,像我们之前学的AD.DA都是许多线,许多线的话,这样做系统可以少浪费资源,少浪费控制IO口的资源,这种并行的处理速度快.所以线越多 ...
- 【深度好文】多线程之WaitHandle-->派生EventWaitHandle事件构造-》AutoResetEvent、ManualResetEvent
AutoResetEvent/ManualResetEvent 都是继承自 EventWaitHandle ,EventWaitHandle继承自WaitHandle. 在讨论这个问题之前,我们先了解 ...
- spring Mongodb查询索引报错 java.lang.NumberFormatException: empty String
最近事情比较多,本篇文章算是把遇到的问题杂糅到一起了. 背景:笔者最近在写一个mongo查询小程序,由于建立索引时字段名用大写,而查询的时候用小写. 代码如下: db.getCollection(&q ...
- centos 上docker 运行出现/bin/sh: . not found
本人用的是Linux上的编译的....然后用了win上的编译命令 解决办法 : 用Linux上的编译命令..... CGO_ENABLED=0 GOOS=linux GOARCH=amd64 g ...
- CSS3网页动画
CSS3网页动画 概要:CSS3变形是一些效果的集合 如:平移.旋转.缩放.倾斜效果 每个效果都可以称为变形(transform)他们可以分别操控元素发生平移.旋转.缩放.倾斜等变化. 网页中能够实现 ...
- 桌面小部件Wight父类AppWidgetProvider的三个方法
onUpdate()这个方法会在每次更新App Widget的时候调用,数据更新的逻辑都写在这个方法里边.而且要注意的是:在用户添加小部件的时候,会首先调用这个方法,应该在这个方法里进行初始化操作,比 ...
- 基于百词斩和扇贝单词的背单词APP软件测试
概述 背单词APP是非常受大学生青睐的手机应用,但它的发展尚未成熟,存在一些缺陷.我们决定深入地分析一组典型的背单词APP:百词斩(A产品).扇贝单词(B产品),寻找当前背单词APP中的提升空间.下面 ...