make target, unmake target? - makefile

Since make knows all dependencies to make a target, it knows (almost) all intermediate artefacts. Is there a make version that can 'rollback', or 'unmake' a target?
(I know it removes targets created by implicit rules)

Most Makefiles provide the clean target, which removes all generated files. Additionally, autoconf-automake systems offer distclean, which also removes the files generated by configure.
These are no automatic targets, however; the makefile generation system gives a list of generated files to make. In general, make doesn't keep track which files it generated, so it can't distinguish between genuine source files (which are dependencies) and intermediate files (which are also dependencies). Even the leaf nodes of the dependency graph can't be used for distinguishment, because stamp files often have no dependencies as well.

Related

Make bazel rerun only actions depneding on modified go std package

I am interested in relinking a bazel project after modifying (and compiling) go's standard library.
Building the project with no cache takes a long time, and I need to do this modification and build multiple times successively, meaning it needs to happen as quickly as possible.
My bazel project builds many packages but ends up with one final binary that is relevant for these purposes.
I tried to just modify the file in usr/local/go/src and delete only the final binary from bazel's output path. This didn't make bazel rerun any actions (even though they depend on a .go file that was supposedly modified).
How could I then make the minimal amount of actions run again so that my modification applies to the final binary?
More specifically, how can I recompile a specific (standard library) package and then only relink the binary instead of also recompiling it and its dependencies.

What are the differences between make clean, make clobber, make distclean, make mrproper and make realclean?

I don't always write make files but when I do I like to try and write them well. Trying to make the interface consistent with what other developers might expect is always a struggle. What I am looking for is a summary of all the common make something cleaner (GNU) make targets.
What are the commonly found cleaning make targets?
When is each target normally used?
How does each target compare to others?
I have worked with a system using make clean, make clobber and make mrproper before. Those got steadily more extream with; make clean only tidying up temporaries, make clobber getting rid of most configuration and make mrproper almost going back to a just checked out state. Is that the normal order of things? Should make mrproper always remove the generated binaries and shared libraries for deployment?
Reading around suggests that make distclean tidies things up to the point of being ready to make a distribution package. I would imagine that leaves behind some automatically generated version tagging files, file manifests and shared libraries but possibly strips out temporary files that you would not want archived?
make realclean was completely new to me when I spied it on the GNU Make Goals manual page. As it is listed with distclean and clobber I would guess it had similar effects. Have I never come across it as it is a historical artifact or just quite specific to a set of projects I have to worked on?
Sorry, that is is a bit rambling. I have found various questions and answers that compare one target to the other but none that seemed to give a good overview.
Trying to form my own answer based on some research. I think the approximate order of severity is; mostlyclean, clean, maintainer-clean, mrproper, distclean and finally clobber (which is combined distclean and uninstall).
make clean
make clean is the most basic level. It cleans up most generated files but not anything that records configuration. GNU Make Manual's Goals page states:
Delete all files that are normally created by running make.
Further, the GNU Make Manual's Standard Targets page stages:
Delete all files in the current directory that are normally created by building the program. Also delete files in other directories if they are created by this makefile. However, don’t delete the files that record the configuration. Also preserve files that could be made by building, but normally aren’t because the distribution comes with them. There is no need to delete parent directories that were created with ‘mkdir -p’, since they could have existed anyway.
Delete .dvi files here if they are not part of the distribution.
make mostlyclean
make mostlyclean is the only gentler form of clean I have found, it behaves like clean but leaves behind files that would take a long time to compile and do not often need to be regenerated.
The GNU Make Manual's Standard Targets page stages:
Like ‘clean’, but may refrain from deleting a few files that people normally don’t want to recompile. For example, the ‘mostlyclean’ target for GCC does not delete libgcc.a, because recompiling it is rarely necessary and takes a lot of time.
make distclean
make distclean is the first step up from the basic make clean on many GNU Make systems. It seems to be pseudonymous or at least very similar to with make realclean and make clobber in many, but not all cases. It will delete everything that make clean does and remove the configuration.
In the Linux system this is one step beyond make mrpropper, see the section below for details.
I am not sure if the name implies that things are being made clean enough for distribution (the forming of a tar archive) or that the process is returning them to the state equal to what was distributed (just as things were immediately after unpacking a tar archive).
GNU Make Manual's Goals page states:
Any of these targets might be defined to delete more files than ‘clean’ does. For example, this would delete configuration files or links that you would normally create as preparation for compilation, even if the makefile itself cannot create these files.
Further, the GNU Make Manual's Standard Targets page stages:
Delete all files in the current directory (or created by this makefile) that are created by configuring or building the program. If you have unpacked the source and built the program without creating any other files, ‘make distclean’ should leave only the files that were in the distribution. However, there is no need to delete parent directories that were created with ‘mkdir -p’, since they could have existed anyway.
make uninstall
make uninstall will uninstall software installed via make install or one of the install-* variants. This is similar to part of the behaviour to make clobber on some systems but make uninstall should not touch the build area as make clobber will.
The GNU Make Manual's Standard Targets page stages:
Delete all the installed files—the copies that the ‘install’ and ‘install-*’ targets create.
This rule should not modify the directories where compilation is done, only the directories where files are installed.
make maintainer-clean
make maintainer-clean seems to be one step back from the more common make distclean. It deletes almost everything apart from the configuration. This makes it very similar to make clean.
The GNU Make Manual's Standard Targets page stages:
Delete almost everything that can be reconstructed with this Makefile. This typically includes everything deleted by distclean, plus more: C source files produced by Bison, tags tables, Info files, and so on.
It is also highlighted that this is not a commonly used target as it is for a specific set of users:
The ‘maintainer-clean’ target is intended to be used by a maintainer of the package, not by ordinary users.
make mrproper
make mrproper seems to be a Linux Kernel version of make distclean or make clobber.
that stops short of removing backup and patch files. It does everything that the make clean target does and strips out configuration.
I believe the name comes from a cleaning product known in the USA as Mr. Clean and the UK as Flash (which is why I had not heard of the product as named). Linus Torvalds being Finnish-American was presumably familiar with the Mr. Propper brand name.
The Linux Kernel Makefile states:
# Cleaning is done on three levels.
# make clean Delete most generated files
# Leave enough to build external modules
# make mrproper Delete the current configuration, and all generated files
# make distclean Remove editor backup files, patch leftover files and the like
make clobber
make clobber gets a mention on the Wikipedia article for Clobbering too. That also states that it is more severe than make clean, possibly one that even uninstalls the software. It is possible a combination of make uninstall and make distclean.
There is no single source for make clean levels. As things have evolved over time terminology and behaviour is inconsistent. The above is the best I have managed to piece together so far.

CMake - Build custom build paths for different configurations

I have a project whose make process generates different build artifacts for each configuration, e.g. if initiated with make a=a0 b=b0 it would build object files into builds/a0.b0, generate a binary myproject.a0.b0, and finally update an ambiguous executable link to point to the most recently built project ln -s myproject.a0.b0 myproject. For this project, this is a useful feature mainly because:
It separates the object files for different configurations (so when I rebuild in another configuration I don't have to recompile every single source with new defines and configurations set, (unfortunately) a very common procedure).
It retains the binaries for each configuration (so it's not required to rebuild to use a different configuration if it has already been built).
It makes a copy (or link) to the last built binary which is useful in testing.
Right now this is implemented in an ugly decades-old non-portable Makefile. I'd like to reproduce the same behavior in CMake to allow easier building on other platforms but I have not been able to reproduce it in any reasonable manner. It seems like adding targets with add_library/executable, but doing this for each possible permutation of input parameters seems wrong. And I'm not sure I could get the utilization correct, allowing make, make a=a0, make b=b0 a=a0 as opposed to what specifying a cmake target would require: make myproject-a0.b0.
Is this possible to do in cmake? Namely:
Specify the build directory based on input parameters.
Accept the parameters as make arguments which can be left out (defaulted) to select the appropriate target at the level of the makefile (so it's not required to rerun cmake for a new configuration).

How does Makefile know that a file changed and then recompile it?

Just out of curiosity, how does Makefile know that a file changed (and then recompile it)? Is it up to make? Is it up to the compiler? If so, is it language dependent?
It looks at the file time-stamp - simple as that. If a dependency is newer that the target, the target is rebuilt.
Make works by inspecting information about files, not their contents.
Make works out dependencies between targets and their dependencies, and then looks to see whether the files exist. If they do, it asks the operating system for the time and date the file was last modified. This is the 'timestamp' for this purpose, although the term can have other meanings.
If a target file either does not exist, or exists and is earlier than its dependent file, then Make rebuilds the target from the dependent by applying a rule.
If the dependent does not exist, Make signals an error.
A consequence of this is that you can force a rebuild by deleting the target, or by 'touching' the dependent to make it later than the target. You can avoid a rebuild by 'touching' the target. Touching simply updates the timestamp to now.

Building different targets in different folders - Xcode

I have two targets in the same xcode project, as bundle plugins, and I want the executable files within the binary to have the same name for both targets.
Is there a way I can either:
A) Define the executable file for each binary without affecting the .bundle name (or first target overwrites the second target as they're building).
B) Build both files in their own folder.
They are in the same project, so the build end-results are automatically placed in the same folder. One overwrites the other, as the .bundle name always ends up the same (because I want the same executable name). They share a lot of code, so they are in the same project, to build everything again at once, to make sure everything always has the latest code across all versions.
Would anybody know a way of doing this? I tried various options in the build settings. Or would anybody maybe have any "build phase" workaround ideas? Please don't ignore that the executable name needs to be the same for all binaries.
Thanks in advance!
I created a project for each slightly different built, with flags in the build settings for each target making each target distinct (with use of macros in the actual code).
Regarding in ensuring code is always the up-to-date, partially shared, code for each build/project, they share the source code by adding it to the project, without selecting the "copy to project folder" option. Annoying workaround, but it'll do until I work something better out...
Why don't you use targets with different names? Or a script after build, that copies the target to a different name?
This should copy each target to a unique name after build, without each build overwriting the other. (If things are linear)

Resources