Prefix an inherited Makefile target - makefile

My project's Makefile includes another makefile to which we do not want to make local modifications.
From it, we inherit a target called test.
How can I edit my own Makefile, to ensure a custom command gets run before the inherited make test target?
I get around this now by defining a new itest target, but I'd rather just be able to call make test.
include: other-project/rules.mk
.PHONY: itest
itest:
<my-command> $(MAKE) test

Just add a prerequisite:
include: other-project/rules.mk
test: itest
.PHONY: itest
itest:
<my-command>

Related

GNU Make does not include all auto-generated includes before executing dependent rule

My makefile makes use of auto-generated dependencies. To do this, I have in my top-level makefile something similar to:
# Makefile
include target1.deps
include target2.deps
all: target2.deps
cat $^
target2.deps: target1.deps
target1.deps:
echo "target2.deps:" > $#
echo " touch target2.deps" >> $#
Initially, target1.deps and target2.deps do not exist. When make is first instantiated, it parses the entire Makefile and searches for a way to generate these include files. After building them, it reinvokes itself, causing the Makefile to be reparsed and the include files to be included this time. At least, that's my understanding.
The issue is that when I run the above Makefile, Make first builds target1.deps, then executes the body of the all rule, never having built or included target2.deps. This causes cat to error: cat: target2.deps: No such file or directory
This seems like a contradiction to me. I explicitly tell Make that all depends on target2.deps, but it attempts to execute the rule before satisfying its prerequisites!
The intended behavior is that target1.deps should be built and included, then target2.deps should be built and included using the rule contained within target1.deps, and then all should be run. How do I achieve this?
Context: Since this is weirdly abstract, here's my goal: I have a target index.html, which gets generated from a template index.html.in, but I don't know anything about its dependencies. I need to find out (a) which files I need to create before building index.html and (b) which files index.html will depend on at runtime.
For example index.html includes some inline css that's pulled out of global.css - I need to therefore build global.css before building index.html. On the other hand, index.html links to about.html, so after I build index.html I want to also build about.html. I call the former "build dependencies" and the latter "runtime dependencies". So my makefile looks something like this:
include index.html.build_deps
include index.html.runtime_deps
all: index.html $(runtime_deps_index.html)
%.build_deps: %.in
./extract_build_deps %< -o %#
%.runtime_deps: %
./extract_runtime_deps %< -o %#
%: %.in
./compile_template %< -o $#
What I want to happen is for Make to follow these steps:
Build index.html.build_deps
Include index.html.build_deps
Build global.css (now a known prerequisite of index.html)
Build index.html
Build index.html.runtime_deps
Include index.html.runtime_deps
Build about.html (contained inside $(runtime_deps_index.html) included from index.html.runtime_deps)
Target all is reached
What actually happens:
Make sees that index.html.build_deps can be directly build from index.html.in; does so.
Make sees that index.html.runtime_deps can be built from index.html, can be built from index.html.in.
Make builds index.html. It errors because global.css hasn't yet been built.
If Make had included index.html.build_deps after building that, then it would be aware of the global.css dependency. But because it tries to build all include files before expanding any of them, it's unaware of the dependency. I want to add a dependency "index.html.runtime_deps depends on index.html.build_deps having been included, but I'm not sure how to specify such a dependency.
#Dario is correct. To be a bit more specific, these are the steps make will follow here:
Read the makefile.
Try to build target1.deps.
Find a target target1.deps and execute the recipe.
The recipe succeeds, but make observes that the file target1.deps still does not exist, so make doesn't mark the target as updated.
Try to build target2.deps.
There's a target for it that depends on target1.deps, which make already built, but there's no recipe for it so make doesn't mark target2.deps as updated (since it was never updated, as far as make can tell--it didn't run any recipe to update it).
So, make decides none of the included makefiles were actually updated and it won't re-exec.
Then make wants to build all; it sees that all depends on target2.deps but make already considered that target and decided it didn't need to be rebuilt, so now make is done with all its work.
You can run make -d and follow along with the decisions make takes.

Makefile target with makefile as dependency

I am currently working on a project where I have a couple applications in a parent folder that need to be rebuilt whenever the libraries contained in child folders are updated. The apps in the parent folder are built with a makefile, and the libraries are built with a separate makefile in the respective folder. This looks something like :
ParentDir
app1
app2
Makefile
libdir1
Makefile
libdir2
Makefile
I'm currently doing something like this for my makefile in the parent dir
all : app1 app2
libs = libdir1/lib1.a libdir2/lib2.a
.PHONY : $(libs)
$(all) : $(libs)
#do stuff to make the apps
libdir1/lib1.a :
$(MAKE) -c libdir1
libdir2/lib2.a :
$(MAKE) -c libdir2
My problem is, I don't want the apps in the parent dir's makefile to rebuild unless one of the makefiles it "depends" on are updated. I know that the reason this is happening currently is that I have my libs declared as PHONY ( so they always rebuild ), but that was the only way I could figure out to actually call the children makefiles.
So, what I want is for each app to build only when either of the libdirs makefile's would actually do something, and to call each libdir's makefile that would "do something" before building the app.
Thanks for your help in advance.
You should make a dummy dependency for the libraries so that their Makefiles are always processed. Here is a good example and explanation: http://owen.sj.ca.us/~rk/howto/slides/make/slides/makerecurs.html

Makefile, main function, ClassNotFound

I have a Java program, and write a makefile to compile it on Linux.
My project organized like this (Run.java is the main entry)
Program -
Src -
(package)adb.Bing_WebResults
Run.java
(package)adb.jsonModel
*.java
(package)adb.models
*.java
bin -
lib -
gson.jar
commons.jar
resource -
*.txt
This is my makefile:
# My project require 3 parameters from user input.
default: Run.class
Run.class: src/adb/Bing_WebResults/Run.java
javac -sourcepath src/ -classpath lib/*.jar -d bin/ src/adb/Bing_WebResults/*.java src/adb/jsonModels/*.java src/adb/models/*.java
run:
java -classpath bin/:lib/*.jar Run "$(ARG1)" "$(ARG2)" "$(ARG3)"
When I use "make run" command in Linux terminate, exception shows that "Could not find the main class: Run"
Are there something wrong with my makefile? Wrong path or something?
There are many things that could potentially be wrong, but the most apparent issues are the incorrect dependencies of the targets in your makefile.
First of all, the target run should have a dependency on Run.class. If you do make run then make looks at the target called run. In your makefile, this target does not have any dependencies defined, and it will execute the line java ... without checking whether the actual compiled class Run.class exists. As a consequence, if you do make run from a clean situation, your source code will not be compiled and the java command will fail because the compiled class is missing.
Your dependency of default on Run.class is incorrect as well, because Run.class will exist in the bin directory, not in the working directory. The line below mentions the target Run.class as well.
There are several ways to improve your makefile. See below an example of corrected code with some variables added to avoid repeated expressions. This approach is a matter of style and preference though.
BINDIR := bin
RUNCLASS := Run
RUNBINARY := $(BINDIR)/$(RUNCLASS).class
SRCDIR := src/adb/Bing_WebResults
RUNSRC := $(SRCDIR)/$(RUNCLASS).java
# Note: the default target below is superfluous at this moment
default: $(RUNBINARY)
$(RUNBINARY): $(RUNSRC)
javac -sourcepath src/ -classpath lib/*.jar -d $(BINDIR) $(SRCDIR)/*.java src/adb/jsonModels/*.java src/adb/models/*.java
run: $(RUNBINARY)
java -classpath $(BINDIR):lib/*.jar $(RUNCLASS) "$(ARG1)" "$(ARG2)" "$(ARG3)"
This works for me in a simplified, comparable setup -- it might work for you as well. Looking at the snippet you provided, there are most likely other dependencies or changes that need to be added to complete your makefile correctly. Potentially, you might have to add package information to your run command and dependency expressions, but that depends on your source code. Your post does not contain enough information to provide a complete solution.
P.S.: Do not forget to replace spaces by tabs if you copy this code to your own makefile.
At last you need to specify the package when running since you dont seem to have the main class in default package.
java -classpath bin com.example.Run arg1 arg2 ...
It turns out that two points should be noticed:
(1) Run is in a package, so it should be "adb.Bing_WebResults.Run.class" in makefile.
(2) external jar files should be concatenated by : (e.g. lib/a.jar: lib/b.jar)

How to copy files from the package to the main codebase?

I have got a plugin package to enhance the working of our product. This package contain some additional files and some modified main code-base repository files. But we can't directly merge this package with our code-base. Our target is to copy files from this package to the main code-base at the time of build. So we have to do some modifications in makefiles.
This package follows the similar directory hierarchy as that of the main code-base directory tree. What could be the best method to do so ? I'm thinking of creating some kind of script to do so. Would this be a good option ?
Without seeing any of your code, all I can suggest is creating a make target that will always get executed and putting it as part of the dependencies to your main code-base build. Something along these lines
final_target : other_dependencies copy_plugin_files
command_to_build_final_target
other_dependencies : source_files
command_to_build_other_dependencies
.PHONY : copy_plugin_files #this makes sure this will always execute
copy_plugin_files :
[insert script or cp command here to copy your plugin files]
If you need the plugin files copied first, then put the copy_plugin_files dependency before the other_dependencies after final_target.
If you need the plugin files to run through their own make process first, then put cd path/to/plugin && $(MAKE) as part of the recipe for your copy_plugin_files target.
Hope that helps!

How can I control the order in which make targets are executed?

Let's say I have a main target, exe which depends on three libs:
exe: LIB1.lib LIB2.lib LIB3.lib
and the lib targets have something like this:
LIB1: $(LIB1OBJECTS)
LIB2: $(LIB2OBJECTS)
LIB3: $(LIB3OBJECTS)
Giving that most of the time, make will be run with a -j flag, and I would like for LIB1 and LIB2 to be built in parallel, how can I make sure that LIB3 is always built after LIB2?
Make LIB3 dependent on LIB2.

Resources