Makefile的效率--如何才能让make执行时,效率高,执行快呢

ccyuki_ 2015-06-05 03:27:03
我们现在弄一个项目,使用了一个Makefile,但是编译要长达30分钟;
怎么样才能把这个Makefile的编译效率提高呢???
没注意数执行了多少条编译命令,但是它可能一共也就执行了30条左右的命令,每条都要等上一会儿,
执行make操作以后,输出的单条命令,基本长这样

g++ -g -O2 -std=gnu++11 -Isrc -Isrc/calcCenter -Isrc/datasources -Isrc/datasources/CTP -Isrc/datasources/CTP/foreign -Isrc/datasources/HB -Isrc/datasources/HB/foreign -Isrc/datasources/IB -Isrc/datasources/IB/foreign -Isrc/datasources/RTS -Isrc/datasources/RTS/foreign -Isrc/datasources/SP -Isrc/datasources/SP/foreign -Isrc/datasources/TT -Isrc/factory -Isrc/iniparser -Isrc/model -Isrc/odb -Isrc/quickfix -Isrc/socket -Isrc/state_define -Isrc/state_machine -Isrc/util -Isrc/zeromq -Iinclude -I/usr/include/python2.7 -MMD -c -o src/fix_datasources_router.o src/fix_datasources_router.cpp


从昨天开始看陈皓的跟我一起写Makefile,刚刚看完了,知道似乎“shell函数”“隐含规则”会有影响,但是我用不进去

我的项目结构:
---project
----include
---quick
----src
---module1
---.....cpp .h
---module2
....包括.cpp 和.h文件
----makefile


---------------------------------------------------------------------------------------
付上我的Makefile文件,求大神指导
--------------------------------------------------------------------------------------

####################################################
# Generic makefile - 万能Makefile
# for compiling and linking C++ projects on Linux
# Author: George Foot Modified:Jackie Lee
####################################################
### Customising
#
# Adjust the following if necessary; EXECUTABLE is the target
# executable's filename, and LIBS is a list of libraries to link in
# (e.g. alleg, stdcx, iostr, etc). You can override these on make's
# command line of course, if you prefer to do it that way.
#
#
#编译odb模块
#$(shell python src/odb/odbCompile.py)
# 可执行文件名
EXECUTABLE := lsad

exclude_dirs := svn doc .svn

#dirs_src := $(shell find ./src -maxdepth 10 -type d)
#适配Linux下svn。
dirs_src := $(shell find ./src -type d ! -path "*.svn*")
dirs_src := $(basename $(patsubst ./%,%,$(dirs_src)))
dirs_src := $(filter-out $(exclude_dirs),$(dirs_src))

#dirs_lib := $(shell find ./lib -maxdepth 10 -type d)
dirs_lib := $(shell find ./lib -type d ! -path "*.svn*")
dirs_lib := $(basename $(patsubst ./%,%,$(dirs_lib)))
dirs_lib := $(filter-out $(exclude_dirs),$(dirs_lib))

#dirs_include := $(shell find ./include -maxdepth 10 -type d)
dirs_include := $(shell find ./include -type d ! -path "*.svn*")
dirs_include := $(basename $(patsubst ./%,%,$(dirs_include)))
dirs_include := $(filter-out $(exclude_dirs),$(dirs_include))

# 动态库目录
LIBDIR:=$(dirs_lib)
# 动态库文件名
LIBS := log4cplus rt pthread rt ev mysqlpp python2.7
LIBS += quickfix quickttfix

LIBS += thostmduserapi thosttraderapi rtsapi securitymduserapi securitytraderapi
#thostmduserapi, thosttraderapi : CTP的lib
#rtsapi : RTS的lib
#securitymduserapi securitytraderapi: 华宝 CTP的lib

LIBS += odb-mysql odb-boost boost_date_time odb
#odb依赖的lib

# 头文件目录
INCLUDES:=$(dirs_src) $(dirs_include) /usr/include/python2.7
# 除了当前目录外,其他的源代码文件目录
SRCDIR:=$(dirs_src) $(dirs_include)
#
# # Now alter any implicit rules' variables if you like, e.g.:

# 避免clean子目录操作同名,加上_clean_前缀 -std=gnu++11 -Wall -Wunreachable-code -Wshadow -Wpointer-arith -Winline -Wnon-virtual-dtor
# -Wunknown-pragmas -Wunused-function -Wunused-label -Wunused-value -Wunused-variable -Wl,-Map,lsad.map
CC:=g++
#CFLAGS := -g -O2 -Wextra -Wunreachable-code -Wpointer-arith -std=gnu++11 -DMYSQLPP_MYSQL_HEADERS_BURIED
CFLAGS := -g -O2 -std=gnu++11
CPPFLAGS := $(CFLAGS)
CPPFLAGS += $(addprefix -I,$(INCLUDES))
CPPFLAGS += -MMD

#-std=gnu++11
#
# # The next bit checks to see whether rm is in your djgpp bin
# # directory; if not it uses del instead, but this can cause (harmless)
# # `File not found' error messages. If you are not using DOS at all,
# # set the variable to something which will unquestioningly remove
# # files.
#

RM-F := rm -f


# # You shouldn't need to change anything below this point.
#
SRCS := $(wildcard *.cpp) $(wildcard $(addsuffix /*.cpp, $(SRCDIR)))
OBJS := $(patsubst %.cpp,%.o,$(SRCS))
DEPS := $(patsubst %.o,%.d,$(OBJS))
MISSING_DEPS := $(filter-out $(wildcard $(DEPS)),$(DEPS))
MISSING_DEPS_SOURCES := $(wildcard $(patsubst %.d,%.cpp,$(MISSING_DEPS)))


.PHONY : all deps objs clean cleanall rebuild info odb

all: $(EXECUTABLE)

#当表结构改变时,重新编译odb
odb:
@/usr/bin/env python src/odb/odbCompile.py

deps : $(DEPS)

objs : $(OBJS)

clean :
@$(RM-F) $(DEPS)
@$(RM-F) $(OBJS)
@$(RM-F) src/odb/odb_tables-odb*

cleanall: clean
@$(RM-F) $(EXECUTABLE)
@$(RM-F) src/odb/odb_tables.sql

rebuild: cleanall all
ifneq ($(MISSING_DEPS),)
$(MISSING_DEPS) :
@$(RM-F) $(patsubst %.d,%.o,$@)
endif
-include $(DEPS)
$(EXECUTABLE) : $(OBJS)
$(CC) -o $(EXECUTABLE) $(OBJS) $(addprefix -L,$(LIBDIR)) $(addprefix -l,$(LIBS)) -DDATABASE_MYSQL

info:
@echo "[dirs_lib]" $(dirs_lib)
@echo "[dirs_src]" $(dirs_src)
@echo "[dirs_include]" $(dirs_include)
@echo "[LIBS]" $(LIBS)
@echo "[LIBDIR]" $(LIBDIR)
@echo "[INCLUDES]" $(INCLUDES)
@echo "[SRCS]" $(SRCS)
@echo "[OBJS]" $(OBJS)
@echo "[DEPS]" $(DEPS)
@echo "[MISSING_DEPS]" $(MISSING_DEPS)
@echo "[MISSING_DEPS_SOURCES]" $(MISSING_DEPS_SOURCES)

...全文
646 10 打赏 收藏 转发到动态 举报
AI 作业
写回复
用AI写文章
10 条回复
切换为时间正序
请发表友善的回复…
发表回复
ccyuki_ 2015-06-12
  • 打赏
  • 举报
回复
解决啦,原因是我单条命令搜索头文件里-I/include....好多目录,不停查找,拖慢了速度; 把代码#include ""改成了相对路径,去除了Makefile的-I参数;速度提升了一半 然后参考上面小伙伴说的mak -jN速度又提升了几分钟; 时间成功从30分钟压缩到6分钟
码到功成 2015-06-08
  • 打赏
  • 举报
回复
引用 5 楼 zhxianbin的回复:
make -jN 可以加快编译速度
赞同,楼主可以参考linux内核怎么的启用多线程make的
ccyuki_ 2015-06-08
  • 打赏
  • 举报
回复
引用 4 楼 z1073071892 的回复:
[quote=引用 3 楼 nswcfd 的回复:] 建议先把所有的编译命令记录下来(比如把make的输出重定向),看看单独跑所有编译命令用多少时间,这大概就能判断慢是慢在编译上,还是满在make自己的解析和判断上。
是单条命令本身就慢[/quote] 我知道是因为单条命令所包含的目录太多了,需要不停的进出查找头文件导致的,但是不知道怎么去解决它
zhxianbin 2015-06-08
  • 打赏
  • 举报
回复
make -jN 可以加快编译速度
ccyuki_ 2015-06-08
  • 打赏
  • 举报
回复
引用 3 楼 nswcfd 的回复:
建议先把所有的编译命令记录下来(比如把make的输出重定向),看看单独跑所有编译命令用多少时间,这大概就能判断慢是慢在编译上,还是满在make自己的解析和判断上。
是单条命令本身就慢
ccyuki_ 2015-06-08
  • 打赏
  • 举报
回复
使用了make -jN,错误的原因是内存不足,加了交换区,但是没感觉到变快,我从top里看,有的make线程执行了5分钟 目前为止........
ccyuki_ 2015-06-08
  • 打赏
  • 举报
回复
引用 7 楼 psc928624742 的回复:
[quote=引用 5 楼 zhxianbin的回复:]make -jN 可以加快编译速度
赞同,楼主可以参考linux内核怎么的启用多线程make的[/quote] 我使用make -jN会报错的
nswcfd 2015-06-05
  • 打赏
  • 举报
回复
建议先把所有的编译命令记录下来(比如把make的输出重定向),看看单独跑所有编译命令用多少时间,这大概就能判断慢是慢在编译上,还是满在make自己的解析和判断上。
ccyuki_ 2015-06-05
  • 打赏
  • 举报
回复
引用 1 楼 todo9351 的回复:
建议: 1 makefile 更名为Makefile 2 使用递归编译的方式写Makefile, 方便后续扩展和维护 make -C .xxxxxx 3 可以将各个 module 封装为 lib,后续即使没有对应 module 的源码可以编出主程序,如果只是修改部分代码的话,编一次N快 4 LINUX服务器要好。
我的目前状况: 1.是Makefile 2.3.应该属于一样吧?就是各个模块分的清楚。可是我这个项目的结构我感觉分不清楚呢 4.现在就是在vagrant上跑了一台64位的虚拟机,写程序 现在这个Makefile也可以在改动部分代码的时候,只编译修改那部分吖。 它慢在哪呢
todo9351 2015-06-05
  • 打赏
  • 举报
回复
建议: 1 makefile 更名为Makefile 2 使用递归编译的方式写Makefile, 方便后续扩展和维护 make -C .xxxxxx 3 可以将各个 module 封装为 lib,后续即使没有对应 module 的源码可以编出主程序,如果只是修改部分代码的话,编一次N快 4 LINUX服务器要好。
对“info make”的翻译整理,不是一个纯粹的语言翻译版本,其中对GNU make的一些语法和用法进行了一些详细分析和说明,也加入了一些个人的观点和实践总结。 本书的所有的例子都可以在支持V3.8版本的GNU make的系统中正确执行。 中文于册 伪目标 强制目标(没有命令或依赖的规则) 空目标文件 的特殊目标 多目标 多规则目标 静态模式 静态模式规则的语法 静态模式和隐含规则 双冒号规则 自动产生依赖 第五章:规则的命令 为规则书写命令 命令回显 命令的执行 并发执行命令 命令执行的错误 中断的执行 的递归执行 变量 变量和递归 命令行选项和递归 选项 定义命令包 第六章 中的变量 使用变量 变量的引用 两种变量定义(赋值) 归展开式变量 直接展开式变量 定义一个空格 ”操作符 变量的高级用法 变量的替换引用 变量的套嵌引用 变量取值 如何设置变量 追加变量值 指示符 多行定义 系统环境变量 目标指定变量 模式指定变量 第七章 的条件执行 的条件判断 个例子 条件判断的基本语法 标记测试的条件语句 笫八章:的内嵌函数 的函数 年月日 中文于册 函数的调用语法 文本夂理函数 文件名处理函数 函数 函数 西数 函数 函数 函数 西数 的控制函数 第九章:执行 执行 指定 文件 指定终极日标 替代命令的执行 防止特定文件重建 替换变量定义 使用 进行编译测试 的命令行选项 第十章: 的隐含规则 使用隐含规则 隐含规则的使用 的隐含规则一览 隐含变量 代表命令的变量 命令参数的变量 隐含规则链 模式规 模式规则介绍 模式规则示例 自动化变量 年月日 中文于册 模式的匹配 万用规则 重建内嵌隐含规则 缺省规则 后缀规则 隐含规则搜索算法 笫十一章:使用更新静态库文件 更新静态库文件 库成员作为目标 静态库的更新 更新静态庠的符号索引表 静态库的注意享项 静态库的后缀规则 第十二章: 的特点 的一些特点 源自 的特点 源自其他版本的特点 自身的特点 第十三章和其它版本的兼容 不兼容性 第十四章 的约定 书写约定 基本的约定 规则命令行的约定 代表命令变量 安装目录变量 的标准目标名 安装命令分类 第十五章的常见错误信息 产生的错误信息 附录:关键字索引 可识别的指示符 函数 的自动化变量 环境变量 后序 年月日 中文于册 关于本书 本文瑾献给所有热爱 的程序员!本中文文档版权所有 本文比较完整的讲述 工具,涵盖 的用法、语法。同重 讨论如何为一个工程编写 作为一个程序员, 工具的使用以及编 写 是必嚅的。系统、详细讲述的中文资料比较少,出于对广大中文 的支持,本人在工作之余,花了个多月间完成对“ 的翻译整理,完成 这个中文版手册。夲书不是一个纯粹的语言翻译版本,其中对 的一些语法 和用法根据我个人的工作经验进行了一些详细分析和说明,也加入了一些个人的观点和 实践总结。本书的所有的例子都可以在支持版本的 的系统中正确执行。 由于个人水平限制,本文在一些地方存在描述不准确之处。恳请大家在阅读过程中 提出您宝贵的意见,也是对我个人的帮助。我的个人电子邯箱地址: 非常愿意和大家交流!共同学习 阅读本书之前,读者应该对 的工具链和 的一些常用编程工具有一定的 了解。诸如: 等;同在书写 ,需要能够进行一些 基本的编程。这些工具是维护一个工程的基础。如果大家对这些工具的用法不是 很熟悉,可参考项目资料 阅读本文的几点建议: 如果之前你对 没有了解、当前也不想深入的学习 的读 者。可只阅读本文各章节前半部分的内容(作为各章节的基础知识) 如果你已经对 比较熟悉,你更霄要关心此版本的新增特点、功能、 和之前版本不兼容之处;也可以作为开发过程过程的参考手册。 之前你对 没有概念、或者刚开始接触,本身又想成为一个 下 的专业程序员,那么建议:完整学习本文的各个章节,包括了基础知识和高级 用法、技巧。它会为你在 下的工程开发、工程管理提供非常有用的帮助。 此中文文档当前版本 本文的所有勘误和最新版本可在主 页 上获取!! 谢谢! 徐海兵 年月日 中文于册 第一章:概述 概既述 环境下的程序员如果不会侠用 来构建和管理自己的工程,应该 不能算是一个合柊的专业程序员,至少不能称得上是程序员。在 )环 境下侠用 的 工具能够比较容易的构建一个属于你自己的工程,整个工程的 编译只需要一个命令就可以完成编译、连接以至于最后的执行。不过这需要我们投入 些间去完成一个或者多个称之为 文件的编写。此文件正是 正常工作 的基础 所要完成的 文件描述了整个工程的编译、连接等规则。其中包括:工程 中的哪些源文件需要编译以及如何编译、需要创建那些库文件以及如何创建这些库文 件、如何最后产生我们想要得可执行文件。尽管看起来可能是很复杂的事情,但是为工 程编写
Make命令   在make命令后不仅可以出现宏定义,还可以跟其他命令行参数,这些参数指定了需要编译的目标文件。其标准形式为:   target1 [target2 …]:[:][dependent1 …][;commands][#…]   [(tab) commands][#…]   方括号中间的部分表示可选项。Targets和dependents当中可以包含字符、数字、句点和"/"符号。除了引用,commands中不能含有"#",也不允许换行。   在通常的情况下命令行参数中只含有一个冒号":",此command序列通常和makefile文件中某些定义文件间依赖关系的描述行有关。如果与目标相关连的那些描述行指定了相关的command序列,那么就执行这些相关的command命令,即使在分号和(tab)后面的aommand字段甚至有可能是NULL。如果那些与目标相关连的行没有指定command,那么将调用系统默认的目标文件生成规则。   如果命令行参数中含有两个冒号"::",则此的command序列也许会和makefile中所有描述文件依赖关系的行有关。此执行那些与目标相关连的描述行所指向的相关命令。同还将执行build-in规则。   如果在执行command命令返回了一个非"0"的出错信号,例如makefile文件中出现了错误的目标文件名或者出现了以连字符打头的命令字符串,make操作一般会就此终止,但如果make后带有"-i"参数,则make将忽略此类出错信号。   Make命本身可带有四种参数:标志、宏定义、描述文件名和目标文件名。其标准形式为:   Make [flags] [macro definitions] [targets]   Unix系统下标志位flags选项及其含义为:   -f file  指定file文件为描述文件,如果file参数为"-"符,那么描述文件指向标准输入。如果没有"-f"参数,则系统将默认当前目录下名为makefile或者名为Makefile的文件为描述文件。在linux中, GNU make 工具在当前工作目录中按照GNUmakefilemakefileMakefile的顺序搜索 makefile文件。   -i   忽略命令执行返回的出错信息。   -s   沉默模式,在执行之前不输出相应的命令行信息。   -r   禁止使用build-in规则。   -n   非执行模式,输出所有执行命令,但并不执行。   -t   更新目标文件。   -q   make操作将根据目标文件是否已经更新返回"0"或非"0"的状态信息。   -p   输出所有宏定义和目标文件描述。   -d   Debug模式,输出有关文件和检测间的详细信息。   linux下make标志位的常用选项与Unix系统中稍有不同,下面我们只列出了不同部分:   -c dir   在读取 makefile 之前改变到指定的目录dir。   -I dir   当包含其他 makefile文件,利用该选项指定搜索目录。   -h   help文挡,显示所有的make选项。   -w   在处理 makefile 之前和之后,都显示工作目录。   通过命令行参数中的target ,可指定make要编译的目标,并且允许同定义编译多个目标,操作按照从左向右的顺序依次编译target选项中指定的目标文件。如果命令行中没有指定目标,则系统默认target指向描述文件中第一个目标文件。

23,216

社区成员

发帖
与我相关
我的任务
社区描述
Linux/Unix社区 应用程序开发区
社区管理员
  • 应用程序开发区社区
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧