Linux学习笔记——例说makefile 增加宏定义

从学习C语言开始就慢慢开始接触makefile,查阅了很多的makefile的资料但总感觉没有真正掌握makefile,如果自己动手写一个makefile总觉得非常吃力。所以特意借助博客总结makefile的相关知识,通过例子说明makefile的具体用法。
    例说makefile分为以下几个部分,更多内容请参考【例说makefile索引博文】
    1.只有单个C文件  
    2.含有多个C文件   
    3.需要包括头文件路径
    4.增加宏定义
    5.增加系统共享库
    6.增加自定义共享库
    7.一个实际的例子


    【代码仓库】——makefile-example
    代码仓库位于bitbucket,可借助TortoiseHg(GUI工具)克隆代码或者在网页中直接下载zip包。
    【本例说明】

    本例将说明makefile文件中如何加入宏定义。

 

1.gcc复习
    宏定义使用前缀-D,在编译过程中可以把宏定义追加到CFLAG中。宏定义有两种相似的写法
    【第一种】-D DEFINES
    【第二种】-D DEFINES=CONDITION


2.源文件
    使用两种不同的方式,通过宏定义包裹打印功能,分别使用#ifdef和#if

#include <stdio.h>
#include <test-add.h>
#include <test-sub.h>
int main(void)
{
    int a = 3;
    int b = 2;
      
    printf("a=%d\n", a);
    printf("b=%d\n", b);
#ifdef TEST_ADD
    printf("a+b=%d\n", add(a,b));
#endif
#if TEST_SUB
    printf("a-b=%d\n", sub(a,b));
#endif
    return 0;
}

3.makefile
    请替换其中的[tab],并以代码仓库中的makefile文件为主。

# 指令编译器和选项
CC=gcc
CFLAGS=-Wall -std=gnu99
# 宏定义
DEFS = -DTEST_ADD -DTEST_SUB=1
CFLAGS += $(DEFS)
# 目标文件
   
TARGET=test
# 源文件
SRCS = test.c \
  ./test-add/test-add.c \
  ./test-sub/test-sub.c
# 头文件查找路径
INC = -I./test-add -I./test-sub
# 目标文件
OBJS = $(SRCS:.c=.o)
# 链接为可执行文件
$(TARGET):$(OBJS)
# @echo TARGET:$@
# @echo OBJECTS:$^
[tab]$(CC) -o $@ $^
clean:
[tab]rm -rf $(TARGET) $(OBJS)
# 连续动作,请清除再编译链接,最后执行
exec:clean $(TARGET)
[tab]@echo 开始执行
[tab]./$(TARGET)
[tab]@echo 执行结束
# 编译规则 $@代表目标文件 $< 代表第一个依赖文件
%.o:%.c
[tab]$(CC) $(CFLAGS) $(INC) -o $@ -c $<

4.具体说明

    【1】 makefile定义头文件的方法有两种

    【第一种】-D DEFINES

    【第二种】-D DEFINES=CONDITION


    【2】DEFS = -DTEST_ADD -DTEST_SUB=1
    为了说明问题,此处使用了两种不同的写法。此时两处打印功能均被执行


    【3】CFLAGS += $(DEFS)
    追加到CFLAGS中,此处需要强调CFLAGS只是一个变量,可以命名为任何合法的名称,只要在编译过程中引用该参数即可。
    $(CC) $(CFLAGS) $(INC) -o $@ -c $<

 

5.执行过程
    【编译和链接】
    make clean && make
    【控制台输出】
rm -rf test test.o ./test-add/test-add.o ./test-sub/test-sub.o
gcc -Wall -std=gnu99 -DTEST_ADD -DTEST_SUB=1 -I./test-add -I./test-sub -o test.o -c test.c
gcc -Wall -std=gnu99 -DTEST_ADD -DTEST_SUB=1 -I./test-add -I./test-sub -o test-add/test-add.o -c test-add/test-add.c
gcc -Wall -std=gnu99 -DTEST_ADD -DTEST_SUB=1 -I./test-add -I./test-sub -o test-sub/test-sub.o -c test-sub/test-sub.c
gcc -o test test.o test-add/test-add.o test-sub/test-sub.o
    从控制台的输出可以看出,在编译过程中加入了-D参数。
    【执行】
a=3
b=2
a+b=5
a-b=1    最终效果和预期完全相同,makefile得到的验证。


6.总结
    【1】增加宏定义的两个方法 -D DEFINES  和 -D DEFINES=CONDITION
    【2】宏定义追加到CFLAG之后

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/252921.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

Android基本组件是什么?

1、ImageView继承View组件,不单单用于显示图片,用 XML代码 编写的Drawable也可以显示出来。其中的XML属性 android:scaleType(设置图片如何缩放或移动以适应ImageView的大小) 有很多的属性值,如:matrix(使用矩形方式进行缩放)fitXY(对图片横向纵向缩放)center(图片放在ImageVie…

Java 运算符及优先级

运算符 分割符&#xff1a;  ,  ;  []  ()算数运算符&#xff1a;    -  *  /  %    --关系运算符&#xff1a;  >  <  >  <    !逻辑运算符&#xff1a;  !  &  |  ^  &&  ||赋值运算符&#xff1a; …

array sort - 2 : quick sort

递归实现&#xff1a; #include <stdio.h>int arr[10] {3, 2, 4, 1, 9, 7, 5, 6, 0, 8};void print_array(){ int i 0; for (i 0; i < 10; i) printf("arr[%d]:%d ", i, arr[i]); printf("\n");}void swap(int *i, int *j){ …

Linux C 读取文件夹下所有文件(包括子文件夹)的文件名

本文&#xff1a;http://www.cnblogs.com/xudong-bupt/p/3504442.html Linux C 下面读取文件夹要用到结构体struct dirent&#xff0c;在头#include <dirent.h>中&#xff0c;如下&#xff1a; #include <dirent.h> struct dirent {long d_ino; /* inode number 索…

报表工具实现单据套打

【摘要】 单据套打再也不用手动测量&#xff0c;反复调试了&#xff0c;报表工具实现单据套打&#xff0c;去乾学院看个究竟&#xff1a;报表工具实现单据套打!实际项目开发中&#xff0c;很多情况会涉及到单据的打印。即在一张印刷好的空白单据上&#xff0c;准确无误地打印上…

每隔10秒钟打印一个“Helloworld”

/*** 每隔10秒钟打印一个“Helloworld”*/ public class Test03 {public static void main(String[] args) throws InterruptedException {ThreadImp threadImp new ThreadImp();Thread thread1 new Thread(threadImp);thread1.start();} }class ThreadImp extends Thread {p…

C++ STL 优先队列

//优先队列//Priority_queue //STL#include<iostream>#include<cstdio>#include<cstdlib>#include<queue>using namespace std;struct cmp{ bool operator() (const int a,const int b) const{//用const定义的a,b是包裹着变量外衣的常数&#xff0c;不…

GDB调试core文件样例(如何定位Segment fault)

core dump又叫核心转储, 当程序运行过程中发生异常, 程序异常退出时, 由操作系统把程序当前的内存状况存储在一个core文件中, 叫core dump. (Linux中如果内存越界会收到SIGSEGV信号&#xff0c;然后就会core dump) 在程序运行的过程中&#xff0c;有的时候我们会遇到Segment fa…

管理信息系统的开发与管理

{% extendsmuban.html %} {% block head %}输入{% endblock %} {% block main %} <div><div class"form-group"><label for"question">标题</label><textarea class"form-control" cols"50" rows"2&q…

python11-28笔记(1.6-1.7)

1.6 多类型传值和冗余参数多类型传值&#xff1a;比如def fun(x,y)&#xff0c;定义2个形参定义一个元组t(1,2),如果把元组当做实参传入到函数中&#xff0c;会报错 如何将元组当做不同类型的参数传入到函数中fun(t) 代表传入的是元组或者这样调用fun((1,2))注意实参的个数要和…

session机制详解以及session的相关应用

session是web开发里一个重要的概念&#xff0c;在大多数web应用里session都是被当做现成的东西&#xff0c;拿来就直接用&#xff0c;但是一些复杂的web应用里能拿来用的session已经满足不了实际的需求&#xff0c;当碰到这样的情况时候我们需要更加深入的理解session的机制&am…

(转)Shell中获取字符串长度的七种方法

Shell中获取字符串长度的七种方法 原文&#xff1a;http://blog.csdn.net/jerry_1126/article/details/51835119 求字符串操作在shell脚本中很常用&#xff0c;下面归纳、汇总了求字符串的几种可能方法: 【方法一】:利用${#str}来获取字符串的长度 【方法二】:利用awk的length方…

linux下用core和gdb查询出现段错误的地方

有些时候我们在一段C代码的时候&#xff0c;由于对一个非法内存进行了操作&#xff0c;在程序运行的过程中&#xff0c;出现了"段错误"。呵呵&#xff0c;这种问题我想很多人会经常遇到。遇到这种问题是非常无语的&#xff0c;只是提示了"段错误"&#xff…

第一篇-Html标签中head标签,body标签中input系列,textarea和select标签

第十四周课程&#xff08;1-12章节&#xff09; HTML 裸体 CSS 穿华丽衣服 Javascript 动起来 一 HTML &#xff08;20个标签&#xff09; 1.我们的浏览器是socket客户端 2.一套规则&#xff0c;浏览器认识的规则 3.开发者&#xff1a; 学习html规则 开发后台程序&#xff1a…

opencv3.2.0 Cmake 3.8.0 + tdm-gcc-5.1.0-3

实测 tdm-gcc-5.1.0-3 tdm32-1 32位版本无法正确编译Opencv 3.2.0 会遇到诸多编译问题 解决办法 使用tdm-gcc-5.1.0-2 tdm64-1 64位版本转载于:https://www.cnblogs.com/fundou/p/6710209.html

什么是商品属性

一、什么是商品属性&#xff1a; Definition of Product Attributes A product attribute is a characteristic that defines a particular product and will affect a consumers purchase decision. Product attributes can be tangible (or physical in nature) or intangibl…

linux用户管理(1)----创建用户(adduser和useradd)和删除用户(userdel)

arm linux的系统用户管理&#xff1a; 1、删除root用户&#xff1a;deluser root2、删除tt用户:deluser tt3、建立root用户&#xff1a;adduser root4、修改用户密码&#xff1a;登录相应的用户后&#xff0c;用passwd来修改密码4、linux用户和密码的管理&#xff08;ftp&#…

前端性能优化之图像优化原理

前端性能优化中&#xff0c;图像的优化是非常重要的一环&#xff0c;为什么要说图像的优化呢&#xff0c;而不是我们常见的图片优化&#xff1f;因为这里的图像包括矢量图和位图&#xff0c;我们常说的图片优化是指位图的优化。这篇文章转载至奇舞周刊&#xff0c;大佬总结的非…

Lua开发学习4-普通循环和迭代器循环

说句实话&#xff0c;每当看到Lua代码&#xff0c;我都感觉是半个SQL代码&#xff0c;写起来还是感觉有点恐怖。 while循环&#xff1a; 与C#的while循环类似&#xff0c;没有什么好说的&#xff1b; --------Lua的while循环 while(condition)dostatementsend For循环 exp1为起…

什么是js的严格模式

设立严格模式的原因&#xff1a; - 消除Javascript语法的一些不合理、不严谨之处&#xff0c;减少一些怪异行为; - 消除代码运行的一些不安全之处&#xff0c;保证代码运行的安全&#xff1b; - 提高编译器效率&#xff0c;增加运行速度&#xff1b; - 为未来新版本的Javascrip…