Date: Tue, 29 Oct 2024 11:32:51 -0400
Just in case it's not clear to everyone, one big limitation of
compile_commands.json is that it does not distinguish between flags you
need to build a library correctly and flags you need to parse a library
interface interface correctly.
One would reasonably expect that modules would allow "private" include
directories and preprocessor definitions that do not need to be propagated
to downstream projects. They do, but the compile commands used to build
BMIs do not distinguish between -DMYPROJECT_PRIVATE=1 and
-DMYPROJECT_YOU_NEED_THIS_TOO=1. They are both just flags sorted in
whatever order.
A richer format would provide metadata needed to make that distinction.
There are alternatives that have been considered, like inventing flags that
include propagation semantics, but in my opinion we are due to clarify this
interop layer in the ecosystem anyway.
Bret
On Tue, Oct 29, 2024, 10:50 Ben Boeckel via SG15 <sg15_at_[hidden]>
wrote:
> On Tue, Oct 29, 2024 at 15:49:20 +0200, Boris Kolpackov wrote:
> > Ben Boeckel <ben.boeckel_at_[hidden]> writes:
> >
> > > I suspect compile commands will still be *useful* for simple things
> like
> > > `clang-tidy` (when the build is using a compatible `clang` compiler),
> but
> > > not if one is doing things like `clang-tidy` on a `gcc` build (as
> > > `clang-tidy` would need to discover how to make its own BMIs instead
> of the
> > > `gcc`-flavored BMIs the build is going to use.
> >
> > If the compilation database also includes the command lines for
> > compiling all the BMIs used by a project, then a tool could
> > conceivably figure out how to build its own BMI versions. We
> > have a mode like this in build2: dump BMI command lines for
> > dependencies but other TUs only for this project.
>
> This does not work in general. Just because you have the command line
> does not mean you understand which modules are allowed to be imported.
> Let's say you have a multi-config build (as CMake supports) where there
> are commands for release and debug. How is one supposed to understand
> which command is for which configuration and align them with consumers
> using the same configuration?
>
> Also, tools like `clangd` that provide completion should not offer
> modules that are not importable from the TU in question. Yes, there
> exists module X in the build, but just knowing the command lines
> provides no indication that it lives in a library that *links to* the
> library the current TU is in, so doing autocompletion for it is counter
> productive.
>
> > > I still don't know what a command line would look like for such a
> > > thing though.
> >
> > My current thinking is that a header command line should be derived
> > from a library/executable to which it belongs (at least in build2
> > headers are prerequisites of libraries/executables so we can
> > establish this relationship). And "derive" probably would mean
> > "as if we compiled an imaginary TU of this library/executable".
>
> Yes, the issue is that `INTERFACE` in CMake means "for my consumers but
> *not* for me". And (today) `INTERFACE` libraries cannot have `PUBLIC`
> visibility rules, so any command for the target would not have those
> flags. Hence making a target that links to the target and generating
> commands as-if from that instead. It's probably isomorphic to what
> you're doing, just in CMake semantics instead. We can work on that once
> we have modules working.
>
> --Ben
> _______________________________________________
> SG15 mailing list
> SG15_at_[hidden]
> https://lists.isocpp.org/mailman/listinfo.cgi/sg15
>
compile_commands.json is that it does not distinguish between flags you
need to build a library correctly and flags you need to parse a library
interface interface correctly.
One would reasonably expect that modules would allow "private" include
directories and preprocessor definitions that do not need to be propagated
to downstream projects. They do, but the compile commands used to build
BMIs do not distinguish between -DMYPROJECT_PRIVATE=1 and
-DMYPROJECT_YOU_NEED_THIS_TOO=1. They are both just flags sorted in
whatever order.
A richer format would provide metadata needed to make that distinction.
There are alternatives that have been considered, like inventing flags that
include propagation semantics, but in my opinion we are due to clarify this
interop layer in the ecosystem anyway.
Bret
On Tue, Oct 29, 2024, 10:50 Ben Boeckel via SG15 <sg15_at_[hidden]>
wrote:
> On Tue, Oct 29, 2024 at 15:49:20 +0200, Boris Kolpackov wrote:
> > Ben Boeckel <ben.boeckel_at_[hidden]> writes:
> >
> > > I suspect compile commands will still be *useful* for simple things
> like
> > > `clang-tidy` (when the build is using a compatible `clang` compiler),
> but
> > > not if one is doing things like `clang-tidy` on a `gcc` build (as
> > > `clang-tidy` would need to discover how to make its own BMIs instead
> of the
> > > `gcc`-flavored BMIs the build is going to use.
> >
> > If the compilation database also includes the command lines for
> > compiling all the BMIs used by a project, then a tool could
> > conceivably figure out how to build its own BMI versions. We
> > have a mode like this in build2: dump BMI command lines for
> > dependencies but other TUs only for this project.
>
> This does not work in general. Just because you have the command line
> does not mean you understand which modules are allowed to be imported.
> Let's say you have a multi-config build (as CMake supports) where there
> are commands for release and debug. How is one supposed to understand
> which command is for which configuration and align them with consumers
> using the same configuration?
>
> Also, tools like `clangd` that provide completion should not offer
> modules that are not importable from the TU in question. Yes, there
> exists module X in the build, but just knowing the command lines
> provides no indication that it lives in a library that *links to* the
> library the current TU is in, so doing autocompletion for it is counter
> productive.
>
> > > I still don't know what a command line would look like for such a
> > > thing though.
> >
> > My current thinking is that a header command line should be derived
> > from a library/executable to which it belongs (at least in build2
> > headers are prerequisites of libraries/executables so we can
> > establish this relationship). And "derive" probably would mean
> > "as if we compiled an imaginary TU of this library/executable".
>
> Yes, the issue is that `INTERFACE` in CMake means "for my consumers but
> *not* for me". And (today) `INTERFACE` libraries cannot have `PUBLIC`
> visibility rules, so any command for the target would not have those
> flags. Hence making a target that links to the target and generating
> commands as-if from that instead. It's probably isomorphic to what
> you're doing, just in CMake semantics instead. We can work on that once
> we have modules working.
>
> --Ben
> _______________________________________________
> SG15 mailing list
> SG15_at_[hidden]
> https://lists.isocpp.org/mailman/listinfo.cgi/sg15
>
Received on 2024-10-29 15:33:05