简体   繁体   中英

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. For example:

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

g++ main.cpp -o main

I recommend using makefiles for this job as they are phenomenal in building dependencies.

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. 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 . If you learn to use make , you can automate this process to only recompile object files when needed.

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.

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). Historically, Make (and systems to automate Makefile generation such as Autoconf and CMake ) have been the common build systems, especially among C++ developers; 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). For a more comprehensive list of C++ build systems, check out my C++ resources page.

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. Then each *.o file would be linked together to produce the final build output. Thus, only *.o files whose inputs are newer than the *.o file would be regenerated; similarly, only those libraries or executables whose *.o inputs are newer than the library or executable being generated would be recreated. 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). This is why I highly recommend automating it with a build system rather than attempting to perform it by hand.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

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