[编译] 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;
}

链接

@beautifulzzzz
智能硬件、物联网,热爱技术,关注产品
博客:http://blog.beautifulzzzz.com
园友交流群:414948975

原文地址:https://www.cnblogs.com/zjutlitao/p/9157295.html

时间: 2024-10-04 18:33:17

[编译] 2、minGW gcc在windows搭建编译win32程序环境的相关文章

在Windows7上搭建Cocos2d-x win32开发环境

很多其它相关内容请查看本人博客:http://www.bokeyi.com/ll/category/cocos2d-x/ 建议:为了避免安全相关的问题,请以管理员权限执行全部的操作,当执行命令的时候,也要确保之前是以管理员权限打开了命令行窗体. 工具准备 搭建开发环境须要安装工具包含 Visual Studio 2013 (2012或2010也能够) python ---(本教程以python2.7.5版本号为例),下载地址:http://www.python.org/download/rele

在windows搭建react-native android 开发环境总结

1.安装必须的软件 1.Python 2    注意勾选 Add python.exe to Path,选项,这样就可以在安装完成后,不用手动去添加环境变量 安装完,打开cmd.exe,输入python,然后enter,如果能成功返回ptython的版本号等信息,则说明安装成功.   2.Node.js 安装完node之后,打开cmd.exe,输入node -v,如果返回node.jsben,则说明node.js,安装成功. 由于npm在国内的速度奇慢,建议使用淘宝代理,或者使用其他科学上网工具

TestLink学习一:Windows搭建Apache+MySQL+PHP环境

PHP集成开发环境有很多,如XAMPP.AppServ......只要一键安装就把PHP环境给搭建好了.但这种安装方式不够灵活,软件的自由组合不方便,同时也不利于学习.所以我还是喜欢手工搭建PHP开发环境,需要哪个模块自己安装就行了,或者那个软件需要升级,直接升级那个软件就行了,并不影响其他软件,非常方便. 安装环境:windowsXP 32 一.准备工作-下载所需软件 Apache  httpd-2.2.22-win32-x86-openssl-0.9.8t.msi PHP       php

windows搭建react natiive android环境及真机运行遇到的坑

第1步:安装最新版Java 下载安装JDK ,最好是Java Development Kit [JDK] 1.8或更高版本 官网地址:http://www.oracle.com/technetwork/java/javase/downloads/jdk8-downloads-2133151.html 配置环境 (不会的百度哦) 第2步:安装Android SDK 有两种方案,直接安卓android SDK或者Android Studio.Android Studio包含了运行和测试React N

Windows搭建Apache+MySQL+PHP环境

PHP集成开发环境有很多,如XAMPP.AppServ......只要一键安装就把PHP环境给搭建好了.但这种安装方式不够灵活,软件的自由组合不方便,同时也不利于学习.所以我还是喜欢手工搭建PHP开发环境,需要哪个模块自己安装就行了,或者那个软件需要升级,直接升级那个软件就行了,并不影响其他软件,非常方便. 安装环境:windowsXP 32 一.准备工作-下载所需软件 Apache  httpd-2.2.22-win32-x86-openssl-0.9.8t.msi PHP       php

在windows搭建jenkins測试环境

jenkins 搭建好开发环境必备之中的一个,简单易用,搭建測试平台非常有帮助,不知道的都能够了解一下 官网下载地址 http://jenkins-ci.org/ 我是下载window版本号的 安装有多种方式,我用了最简单的方式 直接解压文件,然后双击 setup.exe文件.选择安装路径安装,就这样安装完毕了 安装完毕 在浏览器上输入 http://127.0.0.1:8080/ 先新建一个项目.我如今仅仅针对maven 项目,所以我选了第二项.它还有非常多强大的功能,只是对我来说够用了 成功

Windows 搭建IIS+PHP+MySQL环境

准备工作: 1.php-7.2.25-Win32-VC15-x64,下载地址:http://windows.php.net/downloads/releases 2.mysql-installer-community-5.7.28.0,下载地址:https://downloads.mysql.com/archives/community/ 第一步 安装IIS 首先,右键单击右下角的WINDOWS徽标,点击设置-应用程序-程序和功能(或者是直接搜索控制面板点击程序和功能) 点击:启用或者关闭WIN

Windows搭建安装React Native环境配置

1.安装Java 这里需要注意对环境变量的设置,可以根据Java -version来检测一下,jdk最好是1.8以上 2.安装SDK 这里需要注意设置环境变量ANDROID_HOME:Android SDK Manager的位置 例如:(ANDROID_HOME=> E:\Android\sdk)设置环境变量PATH:例如:(PATH=> %ANDROID_HOME%\tools;%ANDROID_HOME%\platform-tools) 3.设置SDK 打开Android SDK Mana

在Windows下编译FFmpeg详细说明

MinGW:一个可自由使用和自由发布的Windows特定头文件和使用GNC工具集导入库的集合,允许你生成本地的Windows程序而不需要第三方C运行时 MinGW,即 Minimalist GNU For Windows.它是一些头文件和端口库的集合,该集合允许人们在没有第三方动态链接库的情况下使用 GCC产生 Windows32 程序. 开发 MinGW 是为了那些不喜欢工作在 Linux(FreeBSD) 操作系统而留在 Windows 的人提供一套符合 GNU 的 GNU 工作环境. 所以