简体   繁体   English

仅编译linux终端中已编辑的文件

[英]Compiling only edited files in linux terminal

I am making a project in Linux OS with a lot of .cpp and .h files and the problem is that every time I want to compile and run the project I have to compile everything, otherwise it doesn't work. 我在Linux操作系统中创建了一个包含大量.cpp.h文件的项目,问题是每次我想编译和运行项目时我都要编译所有内容,否则它不起作用。 For example: 例如:

g++ main.cpp test.cpp test2.cpp test3.cpp test1.h test2.h test3.h -o main g ++ main.cpp test.cpp test2.cpp test3.cpp test1.h test2.h test3.h -o main

Is there a way, when I only edit the main.cpp I do not have to re-compile everything like so 有没有办法,当我只编辑main.cpp时,我不必重新编译所有内容

g++ main.cpp -o main g ++ main.cpp -o main

I recommend using makefiles for this job as they are phenomenal in building dependencies. 我建议使用makefile来完成这项工作,因为它们在构建依赖项方面非常出色。

https://www.cs.umd.edu/class/fall2002/cmsc214/Tutorial/makefile.html https://www.cs.umd.edu/class/fall2002/cmsc214/Tutorial/makefile.html

If main.cpp uses code from test*.cpp, you can't just compile main.cpp. 如果main.cpp使用来自test * .cpp的代码,则不能编译main.cpp。 You can compile the individual files into object files using g++ -c test.cpp , and then link those files in with g++ main.cpp test.o test2.o test3.o -o main . 您可以使用g++ -c test.cpp将单个文件编译为目标文件,然后使用g++ main.cpp test.o test2.o test3.o -o main链接这些文件。 If you learn to use make , you can automate this process to only recompile object files when needed. 如果您学习使用make ,则可以将此过程自动化为仅在需要时重新编译目标文件。

Your header files should typically be #include d in your source files, so you don't need to explicitly give them on the command line. 您的头文件通常应该是源文件中的#include d,因此您无需在命令行上显式地提供它们。

Incremental compilation is pretty standard and an engineering best practice. 增量编译非常标准,是工程最佳实践。 However, to achieve incremental compilation (at least in a sane and sustainable way that will actually save you time), you need to use a build system that can keep track of dependencies and determine which targets / inputs have changed since the last invocation of the build system and that can automatically invoke the compiler to compile and link only the targets that actually require updating. 但是,要实现渐进式编译(至少以理智且可持续的方式实际节省您的时间),您需要使用构建系统来跟踪依赖关系并确定自上次调用之后哪些目标/输入已更改构建系统,它可以自动调用编译器来编译和链接实际需要更新的目标。

For choice of build system, I recommend looking into Gradle (very popular in opensource projects) or Bazel (Google's build system that was opensourced relatively recently, though it is less popular). 对于构建系统的选择,我建议研究Gradle (在开源项目中非常流行)或Bazel (谷歌的构建系统最近开源,虽然不太受欢迎)。 Historically, Make (and systems to automate Makefile generation such as Autoconf and CMake ) have been the common build systems, especially among C++ developers; 从历史上看, Make (以及自动生成Makefile的系统,如AutoconfCMake )一直是常见的构建系统,特别是在C ++开发人员中; however, these tools are declining in popularity and make for much more complicated build configurations as well as ease of shooting oneself in the foot compared to more modern build systems (for example, Gradle and Bazel have build configuration files that are portable across systems, whereas Makefiles make it relatively easy to inadvertently depend on OS-specific or compiler-specific details that render the build process non-portable. Make does have some very portable rules for avoiding portability issues, but great care must be used when designing makefiles to ensure that non-portable instructions are not used). 然而,与更现代的构建系统相比,这些工具的普及程度越来越低,并且使得构建配置更加复杂,并且易于在脚下拍摄(例如,Gradle和Bazel构建了可跨系统移植的配置文件,而Makefile使得无意中依赖于特定于操作系统或特定于编译器的细节使得构建过程变得不可移植相对容易.Make确实有一些非常便携的规则来避免可移植性问题,但在设计makefile时必须非常小心以确保不使用非便携式指令)。 For a more comprehensive list of C++ build systems, check out my C++ resources page. 有关更全面的C ++构建系统列表,请查看我的C ++资源页面。

As for how these build systems implement incremental builds under the hood; 至于这些构建系统如何实现增量构建; basically, they would compile each *.cpp file separately into its own *.o file and keep around the *.o file. 基本上,他们会将每个* .cpp文件分别编译成自己的* .o文件,并保留* .o文件。 Then each *.o file would be linked together to produce the final build output. 然后将每个* .o文件链接在一起以生成最终的构建输出。 Thus, only *.o files whose inputs are newer than the *.o file would be regenerated; 因此,只重新生成输入比* .o文件更新的* .o文件; similarly, only those libraries or executables whose *.o inputs are newer than the library or executable being generated would be recreated. 类似地,只有那些* .o输入比生成的库或可执行文件更新的库或可执行文件才会被重新创建。 In short, these build systems would do a fairly complex dependency analysis to figure out which files have changed / which targets to rebuild and would invoke g++ multiple times (not just once). 简而言之,这些构建系统将进行相当复杂的依赖性分析,以确定哪些文件已更改/要重建哪些目标,并将多次调用g ++(而不仅仅是一次)。 This is why I highly recommend automating it with a build system rather than attempting to perform it by hand. 这就是为什么我强烈建议使用构建系统自动化它而不是尝试手动执行它。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM