Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/cplusplus/156.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C++ 首先编译/生成上次修改的cpp文件_C++_Makefile - Fatal编程技术网

C++ 首先编译/生成上次修改的cpp文件

C++ 首先编译/生成上次修改的cpp文件,c++,makefile,C++,Makefile,当我处理cpp文件时,我经常需要更改该cpp文件引用的头文件。例如,假设我有三个文件: common-headerh [file referred to by both cpp files] file1.cpp file2.cpp 在我的make文件中,我的命令相当于: g++-std=c++0x file1.cpp file2.cpp 我希望有一个makefile自动重新排序编译顺序,以便首先编译最近修改的文件。换句话说,如果file1.cpp是最近修改的,我希望我的make文件执

当我处理cpp文件时,我经常需要更改该cpp文件引用的头文件。例如,假设我有三个文件:

common-headerh      [file referred to by both cpp files]
file1.cpp
file2.cpp
在我的make文件中,我的命令相当于: g++-std=c++0x file1.cpp file2.cpp

我希望有一个makefile自动重新排序编译顺序,以便首先编译最近修改的文件。换句话说,如果file1.cpp是最近修改的,我希望我的make文件执行以下操作:

g++ -std=c++0x file1.cpp file2.cpp
但是,如果最近修改了file2.cpp,我希望make文件执行以下操作:

g++ -std=c++0x file2.cpp file1.cpp
我如何以自动化的方式做到这一点?也欢迎针对特定IDE/构建环境的答案


**********背景**********

我有一个大型项目(编译大约需要7分钟),我的许多代码都驻留在头文件中的模板中[在上面的示例中是common header.h]。正如您所知,模板代码在没有引用的.cpp文件的情况下是无法编译的,更准确地说是无法编译的。假设我想在file2.cpp中添加一个新功能,最后用模板对其进行编码。这意味着我不得不将我的新代码放在common header.h中。自然,只有在编译file2.cpp时,才会编译这些新的代码位。但是,由于头文件已被修改,file1.cpp也需要重新编译。这很好,但假设我在commonheader.h中的新模板代码中有一个基本的输入错误。然后我必须等待整个file1.cpp在file2.cpp之前编译。但是,如果先编译file2.cpp,我将立即知道我的打字错误,而无需等待file1.cpp的编译

当然,一个快速的解决方案是手动重新编译file2.cpp。但是,所有错误修复都发生在头文件中:file2.cpp不是我的IDE中的焦点窗口。因此,我必须导航到引用公共头.h的正确cpp文件,然后从那里重新编译。更不用说我经常简单地混淆编译快捷方式和构建快捷方式,不得不中止构建,自然会分心。或者,我干脆放弃,去youtube等待整个构建,结果导致糟糕的生产率


感谢您的建议

没有像那样减少编译时间的灵丹妙药,特别是对于模板,这是唯一的通用方法。您应该考虑是否可以减少代码耦合,将头拆分为多个文件,以便更改不会影响整个项目。如果更改包含在所有位置的标题,则需要重新编译所有内容。您还可以尝试将当前正在修改的功能与整个项目文件分开移动,这样编译器就不必在进行更改时反复重新编译未更改的代码。另外,如果您可以选择使用预编译头。

我可以考虑使用bash脚本,例如:

ls -tr
这已经给出了从最近一次排序的文件夹中的文件,如果您有其他文件,您可以使用grep仅检索.cpp

有了它,您就可以生成g++命令了

如果在Makefile中的命令之前添加注释:

#replace
g++ -std=c++0x file1.cpp file2.cpp
然后使用sed,您可以找到订单,并将其替换为

NEWCMD=$( ls -tr your/directory | grep .cpp )
NEWCMD="g++ -std=c++0x $NEWCMD"
sed '/#replace/!b;n;c$NEWCMD' Makefile
您需要在Makefile之前运行它,但是Makefile允许一些bash,所以也许有一种方法可以将它放在那里,而不必调用sed


我还没有对此进行测试,但还无法发表评论:)

如何指导make构建您最感兴趣的文件

一个快速的解决方案是手动重新编译file2.cpp

而且自动总是更好,对吗?一个叫做make1的小脚本怎么样,比如说,
make1

#!/bin/sh
tgt=$(ls -t *.cpp | sed '1 s/\.cpp$/.o/; q')
make $tgt && make
当然,
$tgt
不需要是单个文件;可以是按时间顺序排列的所有文件


我在简化;源树可能在多个位置有对象。但是,如果可以枚举它们并按修改时间对它们进行排序,则可以确定“最有趣”的目标

我使用QT creator,我想我可以告诉它在生成文件之前做一些bash,但不是100%确定。为什么必须在头文件中定义
file2.cpp
所需的模板,而
file1.cpp
必须包含在头文件中?如果模板仅由
file2.cpp
所需,那么为什么必须将它们放在头文件中呢?你是对的,我过于简化了。实际上要复杂得多。通常,file1、file2、…、file20不使用模板,而是包含头。然后文件21,文件22。。。file25使用模板。只要有多个文件使用头文件,它就必须在头文件中(标准中是这样说的)。当然,您可以制作一个“实现头”——我已经使用过的优化——第二个头文件只包含在file21、…、file25中。然而,制作这样的实现头通常需要几个小时的代码重构——事实上,我正在寻找更简单的替代方案(因此我的问题)。听起来好像你有一个严重过度耦合的代码库,你正在寻找一种聪明的方法来抑制症状,而不是花时间去纠正根本的问题。不,我的系统是世界上最好的,是C++的错,它编译得很慢。当然,我的系统是好是坏与我最初发布的问题是不同的。我刚刚尝试了你的脚本,但我不明白它的作用:你能解释一下吗?我很难解码'1s/\.cpp$/.o/;q'
1
是一个地址;这意味着代码在输入的第一行(最新的文件)上运行
s/\.cpp$/.o/
是将文件名结尾的子字符串.cpp替换为.o的命令。结果将自动打印。然后
q
告诉sed退出。例如,要打印前5行,可以使用
s/\.cpp$/.o/;5q
。我在命令行中使用了您的解决方案,它似乎正在按照宣传的那样工作。我还没有把它制作成一个功能齐全的脚本[最好通过make]。谢谢