Date: Wed, 13 Mar 2024 10:05:57 +0000
Hi,
On Tue, 2024-03-12 at 13:31 +0200, Andrei Grosu via Std-Proposals
wrote:
> The proposal is simple: constexpr support for the filesystem API.
>
> The need comes from writing a build system in (modern) C++.
> If there is support for compile-time access to the filesystem , it
> would be , in my opinion, the key missing piece for a build system
> implemented in modern C++.
> Without that you would have to depend on code generation , but with
> it , there is not much missing to build a fully featured build system
> in C++ itself.
I think you failed to sell the motivation of this, but I can think of
use cases where #embed "string literal" could potentially show its
limitations in the future.
#embed does work great for its intended purpose of embedding self-
contained resources into executables. But given that #embed exposes the
contents as a constant expression, I think it can be reasonable
foreseen that it will not only be used for efficiently embedding huge
resources into executables, but for example to efficiently generate
APIs and/or runtime validation code from protocol specifications. Some
(most?) of the popular protocol specification formats are not self-
contained and can refer to other files. Some of these rely on code
generation to translate these specifications into safe C++ APIs and/or
to runtime validation code, but in the future they could switch to
#embed and reflection/reification to do the same, once we get there.
I think it's not entirely unreasonable to want embed-like functionality
that works on a "treeish" instead of "blob" (in git speak), and allow
the compilers to map directory trees to these treeish objects exposed
within the program in an implementation-defined way (not unlike how
#include and import mappings are also implementation-defined). This
shouldn't be based on std::filesystem for concerns already raised, but
I think the idea has merit.
Maybe it is a bit too early though, and first we will need to see how
#embed pans out. I can imagine pure #embed-based patterns dealing with
non-selfcontained formats, but they might require boilerplate and
repetition and/or they are inefficient. It's also possible that there
is a pattern with #embed that just works well for the purpose.
>
> Is this a question of compiler complexity , to enable constexpr
> filesystem access ? It is not clear to me if there are other factors
> at play.
>
> Can anyone ‘in the know’ share some insights why it might or might
> not be feasable ?
I think it's feasible, I think a lot of concerns are around these
points:
* restrictions on the FS access (shouldn't just expose the build
machine's FS as is)
* Which parts of FS semantics that are important (do we want directory
listing, various file metadata, file types as in regular, symlink,
block device...)
* confusing runtime and compile time std::filesystem behavior
I don't think that any of this couldn't be solved. IMO a feature like
this:
* just shouldn't use anything like std::filesystem, fopen, ifstream,
etc...
* compilers shouldn't expose the whole of the host FS, only parts that
are explicitly specified by compiler options. This doesn't make this
not worthy of standardizing, just like #include and import (and
#embed!) was worthy of standardizing. All compilers have flags to
specifiy include directories and import mappings. Not sure how #embed
works in this regard.
* should be built from bottom up, probably on top of #embed (and
std::embed maybe?), only adding features that are obviously needed. I
wouldn't even add listing directories at first, unless there is a
compelling use case. I think a `std::embed(constant_expression)` alone
would go a long way.
Cheers,
Lénárd
On Tue, 2024-03-12 at 13:31 +0200, Andrei Grosu via Std-Proposals
wrote:
> The proposal is simple: constexpr support for the filesystem API.
>
> The need comes from writing a build system in (modern) C++.
> If there is support for compile-time access to the filesystem , it
> would be , in my opinion, the key missing piece for a build system
> implemented in modern C++.
> Without that you would have to depend on code generation , but with
> it , there is not much missing to build a fully featured build system
> in C++ itself.
I think you failed to sell the motivation of this, but I can think of
use cases where #embed "string literal" could potentially show its
limitations in the future.
#embed does work great for its intended purpose of embedding self-
contained resources into executables. But given that #embed exposes the
contents as a constant expression, I think it can be reasonable
foreseen that it will not only be used for efficiently embedding huge
resources into executables, but for example to efficiently generate
APIs and/or runtime validation code from protocol specifications. Some
(most?) of the popular protocol specification formats are not self-
contained and can refer to other files. Some of these rely on code
generation to translate these specifications into safe C++ APIs and/or
to runtime validation code, but in the future they could switch to
#embed and reflection/reification to do the same, once we get there.
I think it's not entirely unreasonable to want embed-like functionality
that works on a "treeish" instead of "blob" (in git speak), and allow
the compilers to map directory trees to these treeish objects exposed
within the program in an implementation-defined way (not unlike how
#include and import mappings are also implementation-defined). This
shouldn't be based on std::filesystem for concerns already raised, but
I think the idea has merit.
Maybe it is a bit too early though, and first we will need to see how
#embed pans out. I can imagine pure #embed-based patterns dealing with
non-selfcontained formats, but they might require boilerplate and
repetition and/or they are inefficient. It's also possible that there
is a pattern with #embed that just works well for the purpose.
>
> Is this a question of compiler complexity , to enable constexpr
> filesystem access ? It is not clear to me if there are other factors
> at play.
>
> Can anyone ‘in the know’ share some insights why it might or might
> not be feasable ?
I think it's feasible, I think a lot of concerns are around these
points:
* restrictions on the FS access (shouldn't just expose the build
machine's FS as is)
* Which parts of FS semantics that are important (do we want directory
listing, various file metadata, file types as in regular, symlink,
block device...)
* confusing runtime and compile time std::filesystem behavior
I don't think that any of this couldn't be solved. IMO a feature like
this:
* just shouldn't use anything like std::filesystem, fopen, ifstream,
etc...
* compilers shouldn't expose the whole of the host FS, only parts that
are explicitly specified by compiler options. This doesn't make this
not worthy of standardizing, just like #include and import (and
#embed!) was worthy of standardizing. All compilers have flags to
specifiy include directories and import mappings. Not sure how #embed
works in this regard.
* should be built from bottom up, probably on top of #embed (and
std::embed maybe?), only adding features that are obviously needed. I
wouldn't even add listing directories at first, unless there is a
compelling use case. I think a `std::embed(constant_expression)` alone
would go a long way.
Cheers,
Lénárd
Received on 2024-03-13 10:06:07