make: Adding function for "no rule" targets - makefile

I have a Makefile which uses a lot of static files, for example:
/mystaticpath/somepath/official_gpl_package-0.1.2.tar.gz
I use this Makefile on several computers and I don't need all packages on all computers. (That's the whole point of make)
Anyway, what I would like to do is put everything in /mystaticpath on a centralized server and download the packages on demand.
In other words, whenever make encounters a missing source file ("no rule"-error), it should run a script and then try again afterwards. The script would need the name of the missing file as a parameter and would download the file from the centralized server, so from make's point of view, the script is an universal creator of everything that might be needed in /mystaticpath.
Does anybody know whether that is possible with make?

Your design makes the little hairs on the back of my neck stand up, but give this a try:
/mystaticpath/%:
retrieve_script $#

Related

Run several 'make' command at the same time?

(make noob here)
I did the following:
Configured a C++ project with CMake.
In one terminal tab, ran make to start building the whole project.
Got bored of waiting for the whole thing to build, figured I could
just make the subfolder I'm working on at the moment.
Without stopping the ongoing build in the first tab, opened a second tab and ran make from said subfolder.
Things looked pretty normal for a short while, then suddenly second tab started displaying build outputs related to the whole project, not only to the subfolder. I figured what I tried didn't work as I expected, so I CTRL-C'd the second tab.
That's when the weirdest happened: in the first tab the build output was mixed with lines coming form the specific folder I wanted to build. And the build went way past 100%, up to 128%!
My question is: what exactly does 'make' do when launched more than once at the same time?
Am I correct to think that the multiple make commands where somehow "merged" in the same process??
This is more a question about the makefiles that CMake creates and how they work. It's these makefiles which do things like track the percent complete, etc., not make itself. It's quite possible that by starting a second build in the same directory, you've messed up whatever facilities the CMake makefiles use to track progress.
The short answer is that no, it's not possible that one invocation of make will somehow "take over" or merge another invocation of make. As far as the make program is concerned they know nothing about each other. However since both are operating on the same filesystem, if one make writes files in a way that can confuse another make, you could see strange behaviors.
The cmake-generated makefiles are very complex; I've never actually tried to understand completely how they work. I've always thought it a shame that no one has tried to implement a CMake GNU Makefile generator in addition to the Unix Makefiles generator, that took full advantage of GNU make features. I'm sure the results would be easier to read and probably faster. But it seems unlikely this will ever happen; CMake users who care more about speed than portability are probably just switching to use Ninja as a generator.

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.

How to code a script to create a makefile

i'm new year and I need some answer. I searched on the web to some answer but i didn't found anything usefull. What am i searching is for a shell programms that when you execute it, create a Makefile with the binary name in arguments like :
./automakefile.sh hello .
Will build you a Makefile with a binary name called hello.
I hope you guys will help me, i'm counting on you <3
There is, unfortunately, no such magic command. If there was, we wouldn't need Makefiles to start with because the magic would most likely have been incorporated in the compiler.
There are several reasons why there isn't a command like that.
Given a random binary file, you can't generally say what programming language it was written in.
You also can't tell what source file were used to compile the binary file from, or where in the file hierarchy they are located (not just where they were located when the binary file was compiled last time, maybe on another system).
You don't know the dependencies between the source code files. Makefiles are primarily useful for keeping track of these (and compiler flags etc.), so that changing one single source file in a big project does not trigger a recompilation of everything.
You don't know what compiler to use, or what flags to pass to it. This is another thing a Makefile contains.
There are build tools available for making the creation of Makefiles easier, and for making them portable between systems on different architectures (the Makefiles that is, not necessarily the programs, that's down to the programmer). One such set of tool is GNU's autotools, another is CMake, and I'm sure there are others as well, but those are the ones I use.
Now you're facing another but similar problem, and that is that you still need to learn the syntax of, and writ,e your Makefile.am and configure.ac files (for the GNU tools), or your CMakeLists.txt files (for CMake).

How can I completely compile a bash project to be distributed?

I am trying to compile a bash project into a distributable binary. I tried shc, and it worked, except all my source statements were broken. I have numerous source statements to keep the code base cleaner, but they are broken when compiled with shc. How can I compile down my bash project so that instead of having a bunch of .sh files, the end user can just have one single file?
Shc is an obfuscator, not a compiler. At the end of the day, it still invokes /bin/sh or whatever, and feeds it your original script. It has not a slightest idea what your script actually does. If it needs an additional file to source, you have to supply it at an appropriate location.
You may want to investigate things like SHAR. Build anarchive, then compile it with shc if you want.
It sounds like all you're missing is a facility to expand all your source statements. That should be fairly easy to write if your codebase is fairly consistent in its use of those statements: just write a script to expand them inline and away you go.
Alternatively, just put all your scripts into a single Zip file or tarball and tell the user to extract the contents of that one file, or if even that is too much I'm sure you can imagine a way to encode the zipped contents of all the non-main files into a giant comment at the bottom of the main file, and have it extract what it needs before proceeding.
Or, you know, use the appropriate installer for your system. Build an RPM for RHEL or a Debian package or a Windows MSI or whatever....

How to Debug Following Fortran Program

I am trying to compile the following software so that I can step through and debug it. I am only a novice programmer and I am trying to understand how this whole makefile business works with Fortran. I know that there is a ton of literature on makefiles but I just need to insert a simple debug flag and I think if someone provided me with the answer to this question that would be the best way for me to learn.
So the program I am trying to compile, TINKER, is actually made up of several packages, located at http://dasher.wustl.edu/tinkerwiki/index.php/Main_Page. I would like to compile and debug JUST ONE specific executable, "analyze". I contacted the developer and received the following reply but I am still stuck...
Since TINKER has lots of small source code files, what we do is
compile each of the small files to an object file using the "-c" flag.
Then we put all of these object code files (ie, the ".o" files) into
an object library. Finally, we link each of the TINKER top level
programs, such as "analyze", against the object library. There is a
Makefile supplied with TINKER that does this. We also supply
individual scripts called "compile.make", "library.make" and
"link.make" for various CPU/compiler combinations that can be run in
order to perform the steps I describe above. To build a "debuggable"
executable, you just need to include the appropriate debug flags
(usually "-g") as part of the compile and link stages.
I am currently running OSX 10.6.8. If someone could show me which folders I cd into, what commands I enter that would be so great!
Thanks!
My follow up question (once I can figure out how to answer the above via command line will concern how to import the same procedure but using the Photran IDE - http://wiki.eclipse.org/PTP/photran/documentation/photran5#Starting_a_Project_with_a_Hand-Written_Makefile)
The directions are at http://dasher.wustl.edu/tinkerwiki/index.php/Main_Page#Installing_TINKER_on_your_Computer
Maybe out of date? g77 is obsolete -- it would be better to use gfortran.
The key steps: "The first step in building TINKER using the script files is to run the appropriate compile.make script for your operating system and compiler version. Next you must use a library.make script to create an archive of object code modules. Finally, run a link.make script to produce the complete set of TINKER executables. The executables can be renamed and moved to wherever you like by editing and running the ‘‘rename’’ script."
So cd to the directory for the Mac -- based on "we also provide machine-specific directories with three separate shell scripts to compile the source, build an object library, and link binary executables." Then run the command scripts. Probably ./compile.make. Look around for the directories ... you can probably figure it out from the names. Or search for the file "compile.make".
Or find someone local to you who knows more about programming.

Resources