2 ms·
I don't see why it can't be a part of the language, since the language implementation requires that the notion of compilation configuration exists and even C/C+
by duped 5y ago
I don't see why it can't be a part of the language, since the language implementation requires that the notion of compilation configuration exists and even C/C++ has a specific language construct to check for it (through the preprocessor).
> If I build libfoo with -Dexclude_feature_bar which just drops 2 source modules from the library build, how can the language express that?
By expressing within the language that the library can be configured with an optional `exclude_feature_bar` flag. Then downstream dependencies can express they require importing libfoo configured with exclude_feature_bar.
At least in Rust where the compilation unit is a crate, crates must express what their compile options are, and dependents express that they require specific compile options from their dependencies. You could argue this isn't a property of the language, but I would argue it is since it's so tightly coupled to the language implementation (despite living in a config file, that file is required to build anything)
Since C and C++ eschew this fundamental requirement of packaging software and pass the buck to the library authors to figure out a way to describe available configuration options, there's no standard way to do this, and dependency management becomes quite difficult. That doesn't mean that other language authors can't solve the problem. And it plays into what the original comment said, which is that managing dependencies in C/C++ is abysmal.
- PaulDavisThe1st 5y agoSo let's take one of my canonical examples. libfftw (Fastest Fourier Transform in the West) can be built with at least the two following critical options: 1. use double or float for computation 2. thread-safe or not The result is 4 possible versions of libfftw: double + thread-unsafe float + thread-unsafe double + thread-safe float + thread-safe What aspects of rust's crate design will allow me, developer of an application that uses libfftw, to define which of these I want to use? How many crates will I have installed in order to switch between any of them?
- duped 5y agoSo we're in agreement that the C and C++ languages cannot express compilation requirements. I'm saying this is a reason why dependency management in these languages is hard. Any language depending on C/C++ will not be able to magically fix the lack of module semantics, just like they can't magically fix use-after-frees across FFI. However, if fftw was wrapped in a Rust crate, the manifest can express those using features in the Cargo.toml file [1] which can be read in a build.rs[2] script which would provide the proper configurations to libfftw at build time for all dependents that specify which options it needs. In this model you won't need more than one crate installed for libfftw, since the crate expresses everything needed. Crates are not static collections of object files like C/C++ libraries. [1] https://doc.rust-lang.org/cargo/reference/features.html https://doc.rust-lang.org/cargo/reference/features.html [2] https://doc.rust-lang.org/cargo/reference/build-scripts.html https://doc.rust-lang.org/cargo/reference/build-scripts.html
- PaulDavisThe1st 5y agoYes, we agree that the actual languages named C and C++ cannot express compilation requirements. As far as I can tell, neither does Rust as a language. It just so happens that Rust has (thus far) settled on a single build system (Cargo) which (like most other build systems) has a way to express them (and a very expressive one at that, since it is written using Rust itself). This doesn't seem that different from projects that use build systems that express all their compilation requirements, with the difference that the build system uses a different language (e.g. Python). The crate design you've described works as long as all your dependencies are wrapped in a "crate" of the correct type (in the current case of Rust, a Cargo crate). But is it even close to realistic to imagine that there will be correct "crate-like" encapsulations of every C/C++ library, thus enabling them to be used seamlessly from each language with a "crate-like" system? I don't know, maybe this is genuinely likely, at least for Rust. To me, having to assume that the hundreds of millions of lines of code that already exist must be and will be wrapped in a crate-like system seems like a bad bet, and I'd rather have a build system that doesn't require this to be true for me to use any pre-existing code. The model you are describing for crates seems to also break down for 3rd party non-open-source libraries, where (re)compilation as part of the build process for my own application is not an option. In such cases, it's hard to see how proprietary developers would be content with anything other than "a static collection of object files" for their licensable libraries. But maybe I'm wrong about that too.
- PaulDavisThe1st 5y ago> since the language implementation requires that the notion of compilation configuration exists This is not true for most languages. I can use a build system that has its own options, and in the build specification I can say: if (defined (build_option1)): sources += source_file1 else sources += source_file2 The compiler and linker have no idea that there is any choice between the two source files, or that the build time option exists. The two files can each provide the same functionality (e.g. hand-coded SIMD asm, but for different target systems); nothing in the language knows anything about this.
- duped 5y agoThis is a rather outdated model for languages, for example the .NET CLR, Rust, Go, NodeJS, Python (and I believe the JVM?) all have module semantics or language specifications that describe how compilation units find each other, and the compiler () is responsible for mapping source files to import statements. The compiler is what is responsible for deciding which file is compiled and how it is configured to do so. () or de facto standard build tool like Cargo But that said the example is a little contrived since you wouldn't use a compile configuration to exclude a source file in most languages that have more flushed out module structures than C
- PaulDavisThe1st 5y agoI am not sure what interpreted languages would have to do with "compilation units", but perhaps I'm missing something. The example comes specifically from the build system for Ardour, where we have hand-written assembler and will incorporate different files into build depending on the target (SIMD) architecture and expected runtime environment. I would not call that contrived. I have no doubt at all that Cargo can handle many, even the majority, of projects of a certain scale. I have very strong doubts that a build system so centered on a particular language and with so many assumptions about how things are written and built can work for all projects. It's a problem when the build system falls down on the most demanding stuff, because it leads to people building "meta-build systems" around it, and we've seen how that turned out in the past.