首页 > 系统相关 >分享实用工具源码--实现Windows IDE中查看Linux下编译信息

分享实用工具源码--实现Windows IDE中查看Linux下编译信息

时间:2023-09-04 15:33:00浏览次数:44  
标签:include addr int 实用工具 argv char 源码 Linux IDE


作者:fbysss
关键字: 实用工具源码  Windows下查看Linux编译信息
一、背景:本人写C程序不多,更不用说Linux下了。偶然一个机会,接了个这样的活,vi我用的还马马虎虎,但程序超过一千行,看起来就有些眼花了。于是只好在VC下编写代码,ftp传到Linux服务器,再用gcc编译,出错了再到VC下修改,再上传,如此这般,颇为费劲。Linux图形界面下安装一个C的开发工具?还是算了,我的Linux是虚拟机,在本机上使用Shell我都用的SecureCRT,就是不想切换来切换去。那有什么方式能更自动化一点呢?似乎没有比较贴心的方案,犹豫再三,花了一个下午写了这个工具,完全满足了自己的要求。在此分享给大家,希望对读者有所帮助。
二、设计思路:在Linux下运行一个守护进程,Windows下提供一个客户端供IDE调用,传递gcc命令行、文件名、文件内容(最开始考虑用ftp,后来一不做二不休,想让一切更简单些,索性把文件内容也通过Socket传过去了。)
三、源代码:
1.Linux下守护程序compileDaemon.c

#include <stdio.h>
#include <stdlib.h>
#include <errno.h>
#include <string.h>
#include <sys/types.h>
#include <netinet/in.h>
#include <sys/socket.h>
#include <sys/wait.h>
#include <unistd.h>
#include <arpa/inet.h>
#include <sys/time.h>
#include <sys/types.h>
#include <netdb.h>
#include <pthread.h>
#include <sys/stat.h>
/*******************************************************
文件名:compileDaemon.c
功能:Windows下查看Linux下编译信息--Linux下编译守护程序
编写人:fbysss
blog:blog.csdn.net/fbysss
email:[email protected]
********************************************************/
#define SPLIT  "###SPLIT###"
#define BUFLEN 1024*128
#define THREAD_NUM 1
pthread_mutex_t sock_mutex;
pthread_cond_t sock_cond;
#define MAXSIZE 512
#define resultFile "compile.log"
/**
所需参数:shellCommand,由client传递
包括gcc +参数  里面包含c源程序和目标文件名
*/
/********处理每个连接*******/
void * dealEachConn(void * arg)
{ char buf[MAXSIZE];
 char recvBuf[BUFLEN];
 //int filesize;//实际上没有使用。
 FILE * fdSrcFile;
 char cmdLine[MAXSIZE]={0};
 int len;
 
 char * recvBufHead;
 char * recvBufP;
 char  filepath[256];
 char compileStr[1024]={0}; 
 struct stat file_stat;
 int each_conn_fd=(int) arg; 
 len = recv(each_conn_fd, recvBuf, BUFLEN, 0);
 if (len < 0)
 {
  perror("nothing recieved.");
  return;
 }
 recvBufHead = recvBuf;
 recvBufP = recvBuf; 
 sprintf(cmdLine,"%s",recvBufP);
 recvBufP+=strlen(cmdLine);
 recvBufP++;//字符串结束符
 recvBufP+=strlen(SPLIT);
 //得到文件名
 sprintf(filepath,"%s",recvBufP);
 printf("filepath :%s/n",filepath);
 recvBufP+=strlen(filepath);
 recvBufP++;//字符串结束符
 recvBufP+=strlen(SPLIT); 
 
 //写文件
 fdSrcFile = fopen(filepath,"w");
 fwrite(recvBufP,len-(recvBufP-recvBufHead)-1,1,fdSrcFile);
 fclose(fdSrcFile);
 printf("file total %d bytes writed,/n",len-(recvBufP-recvBufHead));
 //组装命令行
 strcat(cmdLine," 2>&1|tee ");
 strcat(cmdLine,resultFile);
 printf("commandLine is:%s/n",cmdLine);
 system(cmdLine);
 FILE * fd = fopen(resultFile,"r");
 while(fgets(buf, MAXSIZE, fd)!=NULL)
 {
  strcat(compileStr,buf);
 }
 printf("compileStr is:%s/n",compileStr);
 int rtValue = send(each_conn_fd, compileStr, strlen(compileStr), 0);
 fclose(fd);
 close(each_conn_fd);
}
//启动一个线程
void startThreadPro(void * proc,void *arg)
{
 /* initialize */
    pthread_t* arr_pid = (pthread_t*)malloc(sizeof(pthread_t) * THREAD_NUM);
    pthread_mutex_init(&sock_mutex, NULL);
    pthread_cond_init(&sock_cond, NULL);
 printf("create thread a proc .../n");
 pthread_create(&arr_pid, NULL, proc, arg);
}
/**************************主程序*******************************/
int main(int argc, char **argv)
{
    int each_conn_fd;
 int sockfd;
    socklen_t len;
    struct sockaddr_in my_addr, their_addr;
    unsigned int myport, lisnum;
 /*****************************************初始化*****************************************/    if (argv[1])
        myport = atoi(argv[1]);
    else
        myport = 4444;
    if (argv[2])
        lisnum = atoi(argv[2]);
    else
        lisnum = 2;
    if ((sockfd = socket(PF_INET, SOCK_STREAM, 0)) == -1) {
        perror("socket");
        exit(1);
    }
    bzero(&my_addr, sizeof(my_addr));
    my_addr.sin_family = PF_INET;
    my_addr.sin_port = htons(myport);
    if (argv[3])//第三个参数为ip地址,指定绑定到哪个ip地址上。
        my_addr.sin_addr.s_addr = inet_addr(argv[3]);
    else
        my_addr.sin_addr.s_addr = INADDR_ANY;
/*******************************端口绑定bind**************************************************/
    if (bind(sockfd, (struct sockaddr *) &my_addr, sizeof(struct sockaddr))
        == -1) {
        perror("bind");
        exit(1);
    }
/***********************************侦听*****************************************************/
    if (listen(sockfd, lisnum) == -1) {
        perror("listen");
        exit(1);
    }
    while (1) {//while 1   //循环侦测客户端连接          
        len = sizeof(struct sockaddr);
        if ((each_conn_fd =
             accept(sockfd, (struct sockaddr *) &their_addr,//通过accept能够取得跟服务器连接的客户机地址their_addr,返回new_fd
                    &len)) == -1) {
   if (errno == EINTR){//避免信号对accept的影响 
    continue;
   }
            perror("accept");
            exit(errno);
        } else
  {
            printf("server: got connection from ip:%s, port: %d, socketfd: %d/n",
                   inet_ntoa(their_addr.sin_addr),
                   ntohs(their_addr.sin_port), each_conn_fd);
   
  }
  /* 开始处理每个新连接上的数据收发 */
 startThreadPro(dealEachConn,(void*)each_conn_fd);
    }//end while
 printf("start to close main socket.../n");
    close(sockfd);
    return 0;
}


2.Windows下客户端程序compileClient.c

#include "winsock.h"
#include "stdio.h"
/*******************************************************
文件名:compileClient.c
功能:Windows下查看Linux下编译信息--Windows 客户端
编写人:fbysss
blog:blog.csdn.net/fbysss
email:[email protected]
********************************************************/
#define BUFLEN 1024*128//这里一定要足够大。考虑到能够传送一般的c文件
#define LENGTH128 128
#define SPLIT  "###SPLIT###"
#define resultFile "compile.log"
void SocketError(char * call)
{
    fprintf(stderr," WinSock Error# function: %s, error code:%ld/n",call,WSAGetLastError());
}
/**
argv[1]:server ip
argv[2]:server port
argv[3]:send command
argv[4]:send file dir
argv[5]:send filename
*/
main(int argc,char ** argv)
{
    int index;
 int iRes,iPort,iTmp;
 char * rt;
    SOCKET sockfd;
    SOCKADDR_IN sin;
    WSADATA wsad;
    WORD wVersionReq;
 FILE * fp;
 FILE * fdSrcFile ;
 int sendLen;
    char sendBuf[BUFLEN]={0};
    char recvBuf[BUFLEN]={0};
 char * sdBufHead = sendBuf;
 char * sdBufferP = sendBuf;
 char filename[LENGTH128];
 char buf[LENGTH128]={0};
  if(argc<5)
  {
   fprintf(stderr,"Usage:winLinuxGcc <host> <port> <commandStr> <dir> <filename>/n");
   return -1;
  }
  if(inet_addr(argv[1])==INADDR_NONE)
  {
   fprintf(stderr,"Wrong ip :/n");
   return -1;
  }
  iPort=0;
  iPort=atoi(argv[2]);
  sin.sin_addr.s_addr=inet_addr(argv[1]);
  sin.sin_family=PF_INET;
  sin.sin_port=htons(iPort);
  if(iPort<=0)
  {
   fprintf(stderr,"must specify a number for port/n");
   return -1;
  }
  wVersionReq=MAKEWORD(1,1);
  iRes=WSAStartup(wVersionReq,&wsad);
  if(iRes!=0)
  {
   SocketError("WSAStartup()");
   return -1;
  }
   sockfd=socket(PF_INET,SOCK_STREAM,0);
  if(sockfd==INVALID_SOCKET)
  {
   SocketError("socket()");
   return -1;
  }
  iTmp=sizeof(sin);
  fprintf(stderr,"WinSock Client Start....../n");
  if(connect(sockfd,(LPSOCKADDR)&sin,iTmp)==SOCKET_ERROR)
  {
   SocketError("connect()");
   closesocket(sockfd);
   WSACleanup();
   return -1;
  }
  //printf("debug1/n");
  strcpy(sdBufferP,argv[3]);//命令行
  //写分隔符
  sdBufferP+=strlen(argv[3]); 
  sdBufferP++;//字符串结束符
  memcpy(sdBufferP,SPLIT,strlen(SPLIT));
  sdBufferP+=strlen(SPLIT);
  //写文件名
  memcpy(sdBufferP,argv[5],strlen(argv[5]));
  sdBufferP+=strlen(argv[5]);
  //写分隔符
  sdBufferP++;  
  memcpy(sdBufferP,SPLIT,strlen(SPLIT));
  sdBufferP+=strlen(SPLIT);
  //写文件内容
  strcpy(filename,argv[4]);
  strcat(filename,"//");
  strcat(filename,argv[5]);
  printf("debug:filename is:%s/n",filename);
  fdSrcFile = fopen(filename,"r");
  if(fdSrcFile<0)
  {
   perror("open file error:");
  }
  rt="1";
  index = 0;
  while(rt!=NULL)
  //while(rt!=NULL)
  { memset(buf,0,LENGTH128);
   index ++;
   rt=fgets(buf, LENGTH128, fdSrcFile);   
   memcpy(sdBufferP,buf,strlen(buf));    
   sdBufferP+=strlen(buf);
   
  }  sendLen = sdBufferP - sdBufHead;//计算发包长度
  iRes=send(sockfd,sendBuf,sendLen,0);
  if(iRes==SOCKET_ERROR)
  {
   SocketError("send()");
   closesocket(sockfd);
   WSACleanup();
   return -1;
  }  fp =fopen(resultFile,"a+b");
  if(fp==NULL)
   return -1;
  //读取返回的编译信息
  iRes=recv(sockfd,recvBuf,BUFLEN,0);
  while(iRes!=SOCKET_ERROR&&iRes!=0)
  {
   printf("Received %d bytes,Data:/n------------------/n%s/n------------------/n",iRes,recvBuf);
   fwrite(recvBuf,sizeof(char),iRes,fp);//写日志文件
   iRes=recv(sockfd,recvBuf,BUFLEN,0);
  }
  fclose(fp);
  closesocket(sockfd);
  WSACleanup();
  return 0;
}

四.编译运行守护程序

  • 上传compileDaemon到Linux;
  • 在Linux shell下,运行gcc -o compileDaemon compileDaemon.c编译程序;
  • 再输入./compileDaemon 4444 1,运行成功,进入守护监听状态。

五.客户端与VC集成配置


  • 首先建立一个工程,winLinuxGcc,加入文件compileClient.c,build之后,生成winLinuxGcc.exe。
  • tools->customize..-tools ,添加Menu Contents,输入 LinuxGCC,command输入winLinuxGcc.exe,Arguments输入<host> <port> "gcc -o ttt $(FileName)$(FileExt)" $(FileDir) $(FileName)$(FileExt)  (注意:<host> <port>请根据实际情况进行修改),并选中Use Output Window

    分享实用工具源码--实现Windows IDE中查看Linux下编译信息_windows


  • 任意打开一个需要在Linux下编译的程序,点击菜单tools,可以看到增加了一个菜单项“LinuxGcc”,点击该菜单,即可可以看到IDE下方输出窗口中的编译信息。
  • 分享实用工具源码--实现Windows IDE中查看Linux下编译信息_windows_02

 

六、结束语:

  • 本程序是针对GCC编写的, 客户端的第三个参数可以根据实际情况进行灵活配置。可以完全把Linux命令行格式放置到客户端,这样,不仅仅是gcc,其他编译器也可以适用(服务端稍作改动即可)。
  • 另外,除了VC,Editplus、UtraEdit以及其他可加入扩展命令的IDE同样适用本工具。进一步,不仅仅是C语言,其他语言,同样可以采用本工具来达到类似效果。
  • 局限性:本工具的编写主要是出于“背景”所述原因,满足的需求有限,并不能完成真正意义的交互调试,我不过是抛砖引玉,希望这样的尝试,能给大家带来更多启示,如果有人能把gdb的交互调试也在vc下实现了,那必定很酷。



标签:include,addr,int,实用工具,argv,char,源码,Linux,IDE
From: https://blog.51cto.com/u_16245757/7351239

相关文章

  • 直播带货源码,iOS 获取图片主题色
    直播带货源码,iOS获取图片主题色 -(void)getMostColorFormImage:(UIImage*)image{  WEAKSELF  [imagegetPaletteImageColorWithMode:ALL_MODE_PALETTEwithCallBack:^(PaletteColorModel*recommendColor,NSDictionary*allModeColorDic,NSError*error){   ......
  • 直播源码,自定义progressBar样式
    直播源码,自定义progressBar样式1、layout中xml布局如下: <RelativeLayout  android:layout_height="16dp"  android:layout_width="match_parent">  <ProgressBar    style="?android:attr/progressBarStyleHorizontal"    android......
  • 百度上传下载控件源码
    ​ 我们平时经常做的是上传文件,上传文件夹与上传文件类似,但也有一些不同之处,这次做了上传文件夹就记录下以备后用。首先我们需要了解的是上传文件三要素:1.表单提交方式:post(get方式提交有大小限制,post没有)2.表单的enctype属性:必须设置为multipart/form-data.3.表单必须......
  • 一口气用Python写了13个小游戏(附源码)
    今天给大家分享13个游戏源码,可以自己复现玩玩,研究下里面的编程逻辑,对学习编程(特别是初学者)应该会有很大帮助。1、吃金币源码分享:importosimportcfgimportsysimportpygameimportrandomfrommodulesimport*'''游戏初始化'''definitGame():#初始化pygame,设......
  • Linux安装IDEA
    下载idea.tar.gz(具体版本号就不写了)解压:sudotar-zxvfidea.tar.gz直接运行bin目录下的idea.sh即可:cdbinsudo./idea.sh如果有可视化界面,可以创建一个桌面图标,在桌面新建文件idea.desktop,然后输入以下内容[DesktopEntry]Version=2021.1Type=Application......
  • 实用工具篇!分享8款办公黑科技软件,用了再也离不开
    在现代办公环境中,科技的发展不仅改变了我们的工作方式,还带来了许多实用工具,让我们的工作更加高效和便捷。今天给大家分享X款办公黑科技软件,这些软件一旦使用,你会发现再也离不开它们。 1.思维导图软件——Gitmind Gitmind是一款免费思维导图软件,支持团队实时协作,可实现多人同......
  • 【腾讯云 Cloud Studio 实战训练营】使用在线编程的方式用Nuxt3开发一个后台管理系统(
    前言大家好,我是刘明,开源技术爱好者,十年创业老兵。CSDN近期联合腾讯云、Coding、CloudStudio组织了【腾讯云CloudStudio实战训练营活动】,苦于前些日子一直在备考注册会计师,没有很好的体验CloudStudio的云IDE产品。现在考试结束了,体验了一把云IDE,不禁感慨云端开发原来可以这么......
  • 全开源风车im源码(前端uniapp可发布H5及app/后端java含视频搭建教程)
    互联网彻底改变了我们的沟通方式,电子邮件是迄今为止采用最快的通信形式。不到二十年前,还没有多少人听说过它。现在,我们中的许多人都用电子邮件而不是写信,甚至打电话给别人,世界各地的人们每天发送数十亿封电子邮件。源码:ms.jstxym.top但有时甚至电子邮件也不够快。您可能不知道您......
  • 基于微信小程序的图书馆座位预约系统设计与实现-计算机毕业设计源码+LW文档
    选题意义: 该系统可以监测到图书馆座位的使用情况,便于学生查询图书馆的分布、座位多少、是否空闲等基本数据。学生可以通过手机或者计算机等终端进行座位预约,方便快捷。对于占座现象,学生可以通过系统进行反馈,方便图书馆管理人员及时处理。基于微信小程序的图书馆座位预约系统的使......
  • 忻州二手车交易系统的设计与实现-计算机毕业设计源码+LW文档
    一、选题的目的和意义: 本课题拟开发一个基于java的忻州二手车交易系统,开发的主要目标是通过忻州二手车交易系统,提供有用的信息数据,为购买者提供可靠的二手车信息,对推动二手车交易市场的发展具有积极有效的促进作用。随着计算机互联网的发展,信息技术应用到各个领域,尤其是电子商务......