【原创】支持同时生成多个main函数 makefile 模板
背景:
去年做项目的时候,由于有需要编译出多个可执行文件的需求,修改了Makefile使其支持生成多个结果(编译多个含有main函数的文件),但总觉得自己的实现不够完美。
今年又遇到这样需求的时候,可在网上找了一圈,发现没有找到能够同时编译得到多个结果的Makefile模板。
目录结构

可以发现,其中,seeker.c 以及 main.c 中都有 main函数,如果按照以往的编译方式,是会引起冲突的

如果将编译的文件写死而引起的不便又违背了make简洁的初衷,那么本人是怎么解决这样的问题的呢?
解决方法:
其实很简单,只需要
1.在包含main函数的.c文件中,头尾加上条件宏
2.在makefile中的编译规则中指定-D选项(条件编译)
这样一来,当make时,其他包含了main的宏由于条件编译而变成了空文件,自然便不会引起多重main函数编译冲突了。
源码:
以下是本人的makefile,希望各路大神批评指正。如果有更好的实现,请告知我,谢谢。
模板与demo的网址:https://gitee.com/schips/common_code_for_my_self/tree/master/makefile/makefile_for_apps
$ cat Makefile
# 添加所有的.c文件
SRCS = $(wildcard src/*.c)
OBJS = $(SRCS:.c = .o) # 指定 头文件目录
INCLUDES = -I ./inc # 指定库目录
LIBS = -L ./lib # 指定编译器
CC = gcc
# 指定编译选项(可选)
CCFLAGS = -g -Wall -O0 # 编译目标列表
OUTPUT1 = target1
OUTPUT2 = target2
# ...
OUTPUTLIST=$(OUTPUT1) $(OUTPUT2)
# 将 所有的目标作为一个列表,便于make clean
all : $(OUTPUTLIST) # 编译目标1
$(OUTPUT1) : $(OBJS)
@$(CC) $^ -o $@ $(INCLUDES) $(LIBS) -D_$(shell echo $(@)|tr a-z A-Z)_ $(OUTPUT2) : $(OBJS)
@$(CC) $^ -o $@ $(INCLUDES) $(LIBS) -D_$(shell echo $(@)|tr a-z A-Z)_ %.o : %.c
@$(CC) -c $< $(CCFLAGS) clean:
@rm $(OUTPUTLIST)
.PHONY:clean
注:红色的处只是为了使得宏与OUTPUTx的名字保持一致,且不是小写形式(习惯上,宏使用大写),这样一来就不需要修改过多的东西就很方便了。
其他:
项目中使用到的2个带有main函数的文件头部(文件最后一行都是 #endif)


【原创】支持同时生成多个main函数 makefile 模板的更多相关文章
- WPF点滴(1) Main 函数
应用程序的入口函数是main函数,在Console程序和Winform程序main函数都有清晰的定义,可以很容易找到,但是WPF的工程文件中却找不到main函数的定义,是WPF不需要main函数吗?N ...
- C++-main函数与命令行参数
1.main函数的概念 C语言中main函数称之为主函数 —个C程序是从main函数开始执行的 下面的main函数定义正确吗? //1 main(){ } //2 void main(){ } //3 ...
- JAVA之旅(五)——this,static,关键字,main函数,封装工具类,生成javadoc说明书,静态代码块
JAVA之旅(五)--this,static,关键字,main函数,封装工具类,生成javadoc说明书,静态代码块 周末收获颇多,继续学习 一.this关键字 用于区分局部变量和成员变量同名的情况 ...
- eclipse 中main()函数中的String[] args如何使用?通过String[] args验证账号密码的登录类?静态的主方法怎样才能调用非static的方法——通过生成对象?在类中制作一个方法——能够修改对象的属性值?
eclipse 中main()函数中的String[] args如何使用? 右击你的项目,选择run as中选择 run configuration,选择arguments总的program argu ...
- 【Go入门教程3】流程(if、goto、for、switch)和函数(多个返回值、变参、传值与传指针、defer、函数作为值/类型、Panic和Recover、main函数和init函数、import)
这小节我们要介绍Go里面的流程控制以及函数操作. 流程控制 流程控制在编程语言中是最伟大的发明了,因为有了它,你可以通过很简单的流程描述来表达很复杂的逻辑.Go中流程控制分三大类:条件判断,循环控制和 ...
- c语言main函数返回值、参数详解(返回值是必须的,0表示正常退出)
C语言Main函数返回值 main函数的返回值,用于说明程序的退出状态.如果返回0,则代表程序正常退出:返回其它数字的含义则由系统决定.通常,返回非零代表程序异常退出. 很多人甚至市面上的一些书籍,都 ...
- C++向main函数传递参数的方法(实例已上传至github)
通常情况下,我们定义的main函数都只有空形参列表: int main(){...} 然而,有时我们确实需要给mian传递实参,一种常见的情况是用户设置一组选项来确定函数所要执行的操作.例如,假定ma ...
- main函数的正确格式
main函数称之为主函数,一个C程序总是从main()函数开始执行的.在关于C语言的网贴和图书中,可以看到main函数的多种格式,这些格式,有的是正确的,有的是不正确的,为了避免错误,现归纳整理如下. ...
- 关于main函数的定义
很多人甚至市面上的一些书籍,都使用了void main( ),其实这是错误的.C/C++中从来没有定义过void main( ).C++之父Bjarne Stroustrup在他的主页上的FAQ中明 ...
随机推荐
- 网络威胁实时地图(CyberThread Real-time Map)
今天跟大家分享一下网络威胁实时地图(CyberThread Real-time Map),从地图上可以看出目前网络威胁情况数据. 点击打开网络威胁实时地图 可以点击demo on/off来看演示.可以 ...
- 修改 TeamViewer ID 的方法
TeamViewer 使用频繁后会被判定为商业用途,不可用.此软件的账号和设备mac地址绑定. 修改TeamViewer ID后可以重新开始使用.下述方法可以成功修改TeamViewer ID. 关闭 ...
- 【Python 11】汇率兑换4.0(函数)
1.案例描述 设计一个汇率换算程序,其功能是将美元换算成人民币,或者相反. 2.0增加功能:根据输入判断是人民币还是美元,进行相应的转换计算 3.0增加功能:程序可以一直运行,知道用户选择退出 4.0 ...
- python之sqlalchemy的使用
准备数据 from sqlalchemy.ext.declarative import declarative_base from sqlalchemy import Column from sqla ...
- javaScript判断手机型号
window.onload = function () { alert("1"); var u = navigator.userAgent; if (u.indexOf('Andr ...
- solr 7.7 搭建和搜索
最近做了个solr搜索的demo, 用的是solr7.7,之前网上好多文章搭建solr都是5.5+tomcat.. 自己摆弄了下,发现solr7.7和5.5 的部分文件夹有些改动,没有深究原理也就没有 ...
- spring boot 2.0 WebMvcConfigurerAdapter过时解决方法
第一种: @Configuration public class WebAppConfig implements WebMvcConfigurer{ @Bean public HandlerInter ...
- iOS开发基础-图片切换(1)
一.程序功能分析 1)点击左右箭头切换图片.序号.描述: 2)如果是首张图片,左边箭头失效: 3)如果是最后一张图片,右边箭头失效. 二.程序实现 定义确定图片位置.大小的常量: //ViewCont ...
- python之configparser模块详解--小白博客
configparse模块 一.ConfigParser简介 ConfigParser 是用来读取配置文件的包.配置文件的格式如下:中括号“[ ]”内包含的为section.section 下面为类似 ...
- 软件工程(FZU2015) 赛季得分榜,第一回合
SE_FZU目录:1 2 3 4 5 6 7 8 9 10 11 12 13 积分规则 积分制: 作业为10分制,练习为3分制:alpha30分: 团队项目分=团队得分+个人贡献分 个人贡献分: 个人 ...