On 3/17/23 9:20 AM, Nomura RH wrote:
> Hi,
>
> I am trying to add support for an embedded ARM compiler to Meson. I've ran
> into an issue with dependency files.
>
> From what I see, Meson forces the compiler to generate dependency files
> with a certain name by passing it a flag like gcc's '-MF' or a variation
> thereof, and this argument is defined in a compiler's
> 'get_dependency_gen_args() method'.
It's a bit simpler than that. The real purpose of
get_dependency_gen_args() is to accept a backend token representing the
depfile name, and then return the compiler arguments relevant to have
the compiler emit a depfile.
The depfile name itself is controlled by the depfile_for_object()
method, instead.
The ninja backend will write out the depfile_for_object() as the
`DEPFILE =` attribute of an object's build edge. This is interpreted as
a variable for the compiler meta-rule e.g. `c_COMPILER` can say that
`depfile = $DEPFILE`. Ninja doesn't care whether that is passed as a
command-line argument to the compiler, it just assumes that whatever the
build rule is, it produces this output file as an artifact.
As far as get_dependency_gen_args() goes, this is usually invoked in the
backend like this:
```
compiler.get_dependency_gen_args('$out', '$DEPFILE')
```
For the GNU mixin, with:
```
return ['-MD', '-MQ', outtarget, '-MF', outfile]
```
This says the compiler expects to generate a depfile by executing the
following ninja rule:
```
command = <...> -MD -MQ $out -MF $DEPFILE <...>
```
Which is filled in by compiler.get_exelist() + ['$ARGS'] +
compiler.get_compile_only_args() + ['$in']
blah blah blah.
At the end, ninja says this:
```
rule c_COMPILER
command = ccache cc $ARGS -MD -MQ $out -MF $DEPFILE -o $out -c $in
deps = gcc
depfile = $DEPFILE_UNQUOTED
description = Compiling C object $out
```
And since $DEPFILE is just a token it's overridden by each individual
build edge the same way $in and $out are. So get_dependency_gen_args()
really doesn't have to care about what the name is -- only where in the
command line it goes, or even, whether the compiler takes the name of
the depfile or else hardcodes the location and just wants a boolean
toggle -M to choose whether to produce it.
> Now, unfortunately the compiler I'm trying to support does not have such a
> functionality. It will always emit dependency files based on the outfile
> base name (i.e. if you compile foo.c to foo.c.obj, the depfile will be
> named foo.c.d, but the Ninja backend expects foo.c.obj.d).
So in this case, what I'd expect is you want to make sure that the default:
```
def depfile_for_object(self, objfile):
return objfile + '.' + self.get_depfile_suffix()
```
instead returns:
```
return os.path.splitext(objfile)[] + '.' + self.get_depfile_suffix()
```
And probably get_dependency_gen_args() just wants to drop the outfile
argument and simply return ['-MD'] or something? The cython compiler
just returns ['-M'] for comparison.
> Is this issue a deal breaker for Meson support of this compiler? Or is
> there some way to make Meson work around the compiler's behavior?
Although I don't think it's actually a problem in this case, I just want
to clarify that meson has no public API, and every part of the codebase
is internal functions which can be refactored in any way you the
contributor want to -- assuming that that refactor achieves some useful
goal such as "I think it looks better" or "I think it's easier to
maintain this way" or "I needed to do this in order to support a
specific compiler".
(Also assuming a core developer agrees with that reason, but it's hard
to disagree with a simple factual statement "it adds support for a
specific compiler".)
So you do not need to worry about "deal breakers". :) :)
..
However, unfortunately, you *may* have to worry about the fact that we
don't have developer docs for the internals. Please feel free to ask as
many questions as you like about how the current program structure fits
together, and we will be happy to provide guidance.
--
Eli Schwartz