(一)前言

我们刚开始学习linux c的时候,一般都是在一个c文件里面写完所有程序,然后用gcc编译这个c文件就好了,十分简单。

但是你有没有想过,如果我们希望将不同模块的代码放到不同的c文件,然后最后编译成一个程序,这个时候又应该怎么办呢?

有人会说,怎么用这么麻烦,直接放在一个c文件里面就好了。但是你总是要考虑一下现实情况的多变性,虽然同时编译很多个c文件不好,但是只会编译一个c文件显得你很LOW。

(二)例子

具一个现实当中简单的例子

比如说我们要编译如下程序,程序当中有两个c文件。以下程序都是我在之前的博客发过的,大家如果很在意代码的意思的话,可以在之前的博客里面找一找。

main.c

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#define MEM_PART "/proc/meminfo" #include "file.h" //用于存储内存信息的结构体
struct mem_info
{
char MemTotal[];
char MemFree[];
char MemAvailable[];
char Buffers[];
char Cached[];
}; typedef struct mem_info MEM_info,*pMEM_info; //按行读取/proc/meminfo中的信息,并保存到mem结构体中
int get_mem_info(pMEM_info mem)
{
char buffer[];
if(NULL==mem)
{
printf("\nget_mem_info:param null!\n");
return ;
}
memset(mem,,sizeof(MEM_info));
if(==get_file_line(buffer,MEM_PART,))//读取第一行
{
sscanf(buffer,"%*s %s",mem->MemTotal);
if(==get_file_line(buffer,MEM_PART,))//读取第二行
{ sscanf(buffer,"%*s %s",mem->MemFree);
if(==get_file_line(buffer,MEM_PART,))//读取第三行
{ sscanf(buffer,"%*s %s",mem->MemAvailable);
if(==get_file_line(buffer,MEM_PART,))//读取第四行
{ sscanf(buffer,"%*s %s",mem->Buffers);
if(==get_file_line(buffer,MEM_PART,))//读取第五行
{
sscanf(buffer,"%*s %s",mem->Cached);
return ;
} } } } } return ;
} int main()
{
char result[];
char result2[];
MEM_info mem; get_file_line(result,MEM_PART,); sscanf(result,"%*s %s",result2);
printf("\n%s\n",result);
printf("\n%s\n",result2); get_mem_info(&mem);
printf("\n%s %s %s %s %s\n",mem.MemTotal,mem.MemFree,mem.MemAvailable,mem.Buffers,mem.Cached); printf("\n%s\n",result); return ; }

file.c

#include <stdio.h>
#include <stdlib.h>
#include <sys/stat.h>
#include <sys/types.h>
#include <string.h>
#include <fcntl.h>
#define FILEBUFFER_LENGTH 5000
#define EMPTY_STR ""
//打开fileName指定的文件,从中读取第lineNumber行
//返回值:成功返回1,失败返回0
int get_file_line(char *result,char *fileName,int lineNumber)
{
FILE *filePointer;
int i=;
char buffer[FILEBUFFER_LENGTH];
char *temp; memset(buffer,'\0',FILEBUFFER_LENGTH*sizeof(char));
strcpy(buffer,EMPTY_STR); if((fileName==NULL)||(result==NULL))
{
return ;
} if(!(filePointer=fopen(fileName,"rb")))
{return ;} while((!feof(filePointer))&&(i<lineNumber))
{
if(!fgets(buffer,FILEBUFFER_LENGTH,filePointer))
{
return ;
}
i++;//差点又忘记加这一句了
} /* printf("\n%d\n",sizeof(*result));
if(strlen(buffer)>sizeof(*result))//不能够这么写,虽然fgets读取一行后会在末尾加上'\0',但是sizeof(result)得到的结果却是result本身类型的大小,所以不能够这么算。当静态数组传入函数时,在函数内部只能知道它是一个指针
{
return 0;
}*/ if(!=fclose(filePointer))
{
return ;
} if(!=strcmp(buffer,EMPTY_STR))
{
while(NULL!=(temp=strstr(buffer,"\n")))
{
*temp='\0';
} while(NULL!=(temp=strstr(buffer,"\r")))
{
*temp='\0';
} strcpy(result,buffer);
}else
{
strcpy(result,EMPTY_STR);
return ;
} return ;
}

file.h

#ifndef FILE_H_INCLUDED
#define FILE_H_INCLUDED
extern int get_file_line(char *result,char *fileName,int lineNumber);//result前少打一个*号,然后就出现段错误
#endif

从中可以看到,main.c要用到file.c中的函数,所以引用了file.h头文件。

如果我们在只编译main.c文件的话程序会报错,如图:

只有当同时编译main.c和file.c的时候程序才不会报错:

由此可见多文件编译的方法为:主文件要包含声明被引用文件函数的头文件,编译的时候主文件和被所有引用的文件要同时编译才可以。

这样的方法,在文件很少的时候还可以,在文件很多的时候就不怎么适用了。

当然,多个文件的编译还有其他方法,比如说makefile,不过如果你是一个一无所知的初学者的话,像codeblock这样的ide恐怕会更加让你觉得方便一些。

(三)具体方法

在codeblock当中编译多个文件十分简单,只要把所有相关联的文件添加到一个工程里面就够了。

使用codeblock编译实际上和命令行编译没有多大的区别,因为它实际上也是自动生成gcc 或g++命令行进行编译,无须我们手动费劲地输入命令行。codeblock本身不带编译器,使用的是我们系统本身已有的编译器。

(1)新建一个工程

新建工程的过程在上一篇的文章中已经说过,把main.c代码复制粘贴进去就成这样

(2)把file.c file.h文件复制到工程目录下。

(3)在codeblock界面当中点击工程名,选择add file,将file.c和file.h都添加进工程里面(选中两个文件后点击open)

然后出现以下界面

不用管太多,选择ok就好。

完成后的project界面就是如下这样子

(4)编译

点击build 编译成功

如图

我的codeblock编译产生的命令行是这样子的

gcc -Wall -g  -c /home/linfen/timer2/main.c -o obj/Debug/main.o
g++  -o bin/Debug/timer2 obj/Debug/file.o obj/Debug/main.o  -lrt -lpthread  /usr/local/lib/libgumbo.a /usr/lib/libpthread.a

但是你们自己编译的时候应该不会有-lrt -lpthread  /usr/local/lib/libgumbo.a /usr/lib/libpthread.a这个东西。本工程即使没有-lrt -lpthread  /usr/local/lib/libgumbo.a /usr/lib/libpthread.a也能正常编译(因为根本就没有用到那些库)。

之所以产生-lrt -lpthread  /usr/local/lib/libgumbo.a /usr/lib/libpthread.a与我自己对codeblock编译器的编译设定有关,目的是引用第三方库。不过,本工程并没有引用第三方库,所以有没有-lrt -lpthread  /usr/local/lib/libgumbo.a /usr/lib/libpthread.a都没有什么关系。

要想这方面了解更多可以继续看下一篇文章。

Linux c codeblock的使用(二):在工程中编译多个文件的更多相关文章

  1. ARC工程中添加非ARC文件

    转载自:http://blog.csdn.net/zhenweicao/article/details/16988543 分类: IOS2013-11-27 17:02 626人阅读 评论(0) 收藏 ...

  2. maven工程中防止mapper.xml文件被漏掉、未加载的方法

    maven工程中防止mapper.xml文件被漏掉.未加载的方法 就是在pom.xml文件中添加以下内容 <!-- 如果不添加此节点mybatis的mapper.xml文件都会被漏掉. --&g ...

  3. ios工程中加入.c/.cpp文件

    如果你在工程里拉入.c/.cpp文件就会导致工程报错, 现在有两种解决方式 1. 把.c文件的后缀全部改成.m的后缀 把.cpp文件的后缀改成.mm的后缀 2. 使用 工程名-Prefix.pch 并 ...

  4. 关于eclipse中MAVEN WEB工程中编译问题

    这几天是被java的环境搞疯了,我先是搭了一个spring+springmvc+mybatis的工程,在家里跑了一下,没有问题,把工程带到公司里用,却一直不能使用. 按常理来说,只要工程发生一点变化, ...

  5. iOS工程中的info.plist文件

    我们建立一个工程后,会在Supporting files下面看到一个"工程名-Info.plist"的文件,这个是对工程做一些运行期配置的文件,很重要,不能删除. 如果你在网上下载 ...

  6. CYUSB3014固件部分低版本工程在Eclipse中编译得到img文件时无效的解决方案

    最近在做基于我们AC6102开发板的UVC图像视频方案,下载了官方的an75779应用工程,但是倒入到FX3—SDK自带的Eclipse中后,却无法编译生成img文件,经过比对后确认是生成该文件的命令 ...

  7. iOS工程中的info.plist文件的完整研究

    原地址:http://blog.sina.com.cn/s/blog_947c4a9f0100zf41.html 们建立一个工程后,会在Supporting files下面看到一个"工程名- ...

  8. 转:在支持ARC工程中编译不支持ARC的文件

    转:http://blog.csdn.net/duxinfeng2010/article/details/8709697 实践总结:-fno-objc-arc 设置 解决了 旧代码中存在 releas ...

  9. CSharp工程中的几个文件

    以下基于.NET Framework4.6及.NET Core2.0 .csproj 用于配置项目信息,如: 程序集名称.类型 Framework版本 项目所包含的文件信息,如:cs.html.js. ...

随机推荐

  1. pywinauto简单操作写字板的例子

    前段时间写了做web程序界面自动化的简单例子,今天写一下windows gui程序界面自动化测例子吧. ps.咱中国人YinKaisheng封装的UIAutomation库也很好用,https://g ...

  2. Extundelete 数据恢复

    Extundelete 数据恢复 “rm -rf /*” 是我们经常使用的命令,操作不慎全盘接蹦,从删库到跑路,身为过来人的我们都经历过rm带来的痛苦. 不要慌,当我们有了Extundelete就可以 ...

  3. uirecorder 启动webdriver服务报错

    在安装好uirecorder后,执行起来是各种错误. 不是少这个就是缺那个,也是因为自己对自动化测试知识太匮乏. 导致刚开始走自动化测试绕了很多弯路,报个错都不知所措.后来才知道要多看ERROR后面的 ...

  4. go-switch特点

    程序中遇到有枚举分支逻辑时,需要用到 switch 代替多个 if else 判断. 学习过程遇到一些与C#不同点,记录下. 语法: switch expr { case x1 : //expr为x1 ...

  5. BZOJ 3473 字符串

    思路 广义SAM的题目,先全部插入,然后每个字符串在SAM上匹配,如果发现当前sz小于k(就是前缀不满足条件),就跳fail(找前缀的后缀,就是找子串)到满足条件为止,然后一个满足条件的节点,它的所有 ...

  6. Servlet使用注解配置URl提示404错误

    刚接触servlet 3.0,使用注释描述servlet @WebServlet(name="FirstServlet", urlPatterns="/FirstServ ...

  7. python cookbook 小结

    最近一直在看python cookbook.这本书主要讲的是python 语言的一些编程素材.正如它的名字一样,烹饪书.就好像再讲如何处理食材(各种类型的数据),然后再煮菜(算法).打个比方,煮菜随便 ...

  8. Python3环境搭建

    Python3环境搭建   Windows系统下安装Python3 Python3 下载 Python3 最新源码,二进制文档,新闻资讯等可以在 Python 的官网查看到: Python 官网:ht ...

  9. Linux之磁盘分区

    一.基础知识 1.磁盘分区 磁盘的分区主要分为基本分区(primary partion)和扩充分区(extension partion)两种,基本分区和扩充分区的数目之和不能大于四个.且基本分区可以马 ...

  10. react项目中页面跳转、刷新及获取网络状态

    // 页面跳转 window.location.href = 'http://speedtest.wangxiaotong.com/' // 页面刷新 window.location.reload() ...