Add buck2 rules that implement CMake's configure_file() behavior. #1102
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
This adds a set of rules that implement CMake
configure_file()
semantics, significantly easing the burden of writing native buck builds for libraries whose native build systems are written in CMake (or other configure-like systems).Typically, such build systems will run a step before the build begins that determines values for all of the things it considers important. Then it will output a header file (or otherwise modify the build in some way, for example by adding preprocessor defines) that contains preprocessor defines, typedefs etc that contain definitions based on the values that were determined earlier.
Examples of popular libraries that depend on this kind of functionality are curl and nghttp2, but there are (very literally) thousands that someone could name. Implementing native buck builds for these libraries pretty much require rules such as those implemented in this PR.
There are two basic categories of meta-rules implemented in this PR, and then one "real" rule that does the actual work.
generic value rules hardcode values about your toolchain (or, really, anything at all) that would otherwise be computed by something like autoconf, configure, or CMake itself. For example, these systems may try to detect whether or not your toolchain has
ssize_t
defined, or the size of an integer. These systems do this by compiling small little programs and examining the output to determine what happened. This approach is flexible, but it is non-hermetic and necessarily requires a configure step. Hermetic build systems -- by definition -- know everything about the build environment. These rules do not have any outputs, and simply provide a way to encode the known values into build targets that can be used by the next category of rules: substitution rules.value rules are quite flexible. They support primitive types (int, bool, string) as well as list types, and even file types (so you can read the content of a file in a dynamic action and use the content as a value later). You can also join and concatenate values that are in previously computed list values, or spread across multiple such value targets. This can be useful, for example, when embedding file content in headers.
substitution rules define mappings between variable names that might appear in the substitution file, and values that were previously encoded in the form of value rules. To explain why this distinction is needed, consider two libraries, both of whom need to detect whether
ssize_t
exists on your system. One library expect its configured header file to have a line of the form:while the other may expect to have a line of the form:
Whether or not
ssize_t
exists is a universal truth, but the libraries expect to consume that information through different ways. So we need one set of rules (value rules) to encode the universally known values, and another set of rules (substitution rules) to define the library-specific mappings.Finally, we have the
cmake_configure_file
rule which accepts a list of substitutions and will perform the generation.