Can we have multiple rules with same target? - makefile

Can we have multiple rules with same target? Here pre-requisites will change. I am using 3.82 make version. Where it will pick the length of the steam (% symbol match ) to determine which rule to pick among multiple conflicting pattern rules. Wtih 3.81 version it works fine as expected. But with 3.82 it is picking wrong rule.
Eg: - We have two rules below
$(TGTDIR)/$(TGT_EXAMPLES_UVM)/%: $(SRC_EXAMPLES_UVM)/%
$(copy_test)
$(TGTDIR)/$(TGT_EXAMPLES_UVM)/bug_fix/%: $(SRC_EXAMPLES_UVM)/common_src/%
$(copy_test)
SRC_EXAMPLES_UVM value is 'example/uvm'. Inside /uvm folder we have bug_fix/ folder with some files in it. Some files are common (i.e same name) in common_src/ & bug_fix/ folders. For those files make has to run first rule above. But in newer version 3.82 it is running second rule, to fix it i want to have a separate rule below for /bug_fix/ folder . Is this the right way to fix it? Because target will become same in this case ? I am new to make. Can Anyone please help?
$(TGTDIR)/$(TGT_EXAMPLES_UVM)/bug_fix/%: $(SRC_EXAMPLES_UVM)/bug_fix/%
$(copy_test)

Related

Make: Shall we give same targets for multiple rules?

I am pretty new to GNUmakefiles.
I am going to place two rules with same target patters as follows:
$(TGTSIP)/$(VERILOG_DIR)/src/%: $(TGTDDVAPI)/$(VERILOG_DIR)/%
$(test_file)
$(TGTSIP)/$(VERILOG_DIR)/src/%: $(TGTMODEL)/%
$(test_file)
i Mentioned above in makefiles. because for few files the pre-requisit will change.Build works fine as expected. But i am not very sure whether this is the right way of having such rules ? If this is not the right way . Could anyone share the best way how we can simplify this?
For more understanding i am trying to copy files from 2 different paths to one same location. In this case target is the path where we are copying and prerequisites are the different paths. How can we handle it in single rule?
Make does not object against multiple concurrent pattern rules with non-empty recipes. In fact, it's totally legit.
However, you should keep in mind that in this case the timestamps of the concurrent sources do not matter: if both patterns match directly (i.e. not by an implicit chaining) and with the same stem length then the first one always wins (and no warning issued). And then only the winner's timestamp will be compared against the target's one.
Therefore, it's possible that the target will not be updated by a source from the second directory (being shadowed by an old source from the first one). If it's okay for you (e.g. there's no conflict between the source dirs) then just do this.

Makefile: assume file is up to date for a specific target?

I'm using GNU Make to build graphs for a paper. I have two targets:
data which rebuilds the data/*.csv folder. This is very computationally expensive. (Also in terms of money.)
plot which rebuilds the plots from the data/ folder
Now, because of how expensive data is to compute, I committed the resulting files in git. I'd like to avoid changing them whenever possible. But when someone clones the git repository, it messes the mtime of the files, so make plot wants to rebuild data, even though they're already there.
That said, I don't want to remove the target dependency! If, for some reason, I recompute something in data, I want the plots to see that and to be able to rebuild themselves. Also, if one csv is missing, I want it to be computed.
I think ideally, what I want is to have a way to say "if these files are present, assume that they are up to date". Is there a way to do that in GNU Make?
Thanks to the comment of Renaud Pacalet, I used order-only dependencies to rewrite my rule like this:
data/%.csv: | source/%.py
...
Using this | allows make to never rebuild a CSV file already present.

add only certain rules for sonar scanner instead of excluding

Instead of excluding or ignore rules in sonar's property file, I'd like to have only a few certain rules for sonar to analyse, so I don't need to exclude a large number of rules out of 344 rules for c++. How can I do that? (I'm not adding customized rules)
I imageine the syntax would be: (in .properties file)
sonar.issue.include.multicriteria=***
sonar.issue.include.multicriteria.***.ruleKey=cpp:S984
....
EDIT:
1, I need to configure this in a CLI environment.
2, It's about one project, two rule sets. one rule sets for local use and the other one for CI/CD use.
You need to craft a Quality Profile that contains only your rules of interest, and then either make it the default profile for C++, or explicitly assign your project to it.
BTW, correctly setting exclusions in properties (versus through the UI) is quite tricky. I'm not sure about the correctness of the ruleKey field name, and you're probably missing another field in there, but your syntax seems to be on the right track.

How does make tell when a file hasn't been modified?

Make can tell if a file has been modified since the last make invocation. I guess it compares the files' modification times with the time they were last built. To do this it would have to store the latest times on disk, right?
Anyone know if and where or how it does that?
Thanks.
I guess you didn't look too hard to find an answer:
http://www.gnu.org/software/make/ If a target file is newer than all of its dependencies, then it is already up to date, and it does not need to be regenerated.
http://www.gnu.org/software/make/manual/html_node/Rule-Syntax.html The criterion for being out of date is specified in terms of the prerequisites, which consist of file names separated by spaces. [...] A target is out of date if it does not exist or if it is older than any of the prerequisites (by comparison of last-modification times). The idea is that the contents of the target file are computed based on information in the prerequisites, so if any of the prerequisites changes, the contents of the existing target file are no longer necessarily valid.
http://pubs.opengroup.org/onlinepubs/9699919799/utilities/make.html The make utility examines time relationships and shall update those derived files (called targets) that have modified times earlier than the modified times of the files (called prerequisites) from which they are derived.
It doesn't do that.
Instead, it compares the modification time of the target with the modification times of its dependencies. So when you have a rule
foo-sorted: foo; sort $< > $#
the modification times of foo-sorted and foo are compared.

Expressions in a build rule "Output Files"?

Can you include expressions in the "Output Files" section of a build rule in Xcode? Eg:
$(DERIVED_FILE_DIR)$(echo "/dynamic/dir")/$(INPUT_FILE_BASE).m
Specifically, when translating Java files with j2objc, the resulting files are saved in subfolders, based on the java packages (eg. $(DERIVED_FILE_DIR)/com/google/Class.[hm]). This is without using --no-package-directories, which I can't use because of duplicate file names in different packages.
The issue is in Output Files, because Xcode doesn't know how to search for the output file at the correct location. The default location is $(DERIVED_FILE_DIR)/$(INPUT_FILE_BASE).m, but I need to perform a string substitution to insert the correct path. However any expression added as $(expression) gets ignored, as it was never there.
I also tried to export a variable from the custom script and use it in Output Files, but that doesn't work either because the Output Files are transformed into SCRIPT_OUTPUT_FILE_X before the custom script is ran.
Unfortunately, Xcode's build support is pretty primitive (compared to say, make, which is third-odd years older :-). One option to try is splitting the Java source, so that the two classes with the same names are in different sub-projects. If you then use different prefixes for each sub-project, the names will be disambiguated.
A more fragile, but maybe simpler approach is to define a separate rule for the one of the two classes, so that it can have a unique prefix assigned. Then add an early build phase to translate it before any other Java classes, so the rules don't overlap.
For me, the second alternative does work (Xcode 7.3.x) - to a point.
My rule is not for Java, but rather for Google Protobuf, and I tried to maintain the same hierarchy (like your Java package hierarchy) in the generated code as in the source .proto files. Indeed files (.pb.cc and .pb.h) were created as expected, with their hierarchies, inside the Build/Intermediates/myProject.build/Debug/DerivedSources directory.
However, Xcode usually knows to continue and compile the generated output into the current target - but that breaks as it only looks for files in the actual ${DERIVED_FILE} - not within sub-directories underneath.
Could you please explain better "Output Files are transformed into SCRIPT_OUTPUT_FILE_X" ? I do not understand.

Resources