From 7d36af563f01ef4a3f89590f3001052af183a6ea Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?S=C3=A9bastien=20Marie?= Date: Sun, 21 May 2017 18:45:26 +0200 Subject: [PATCH 01/56] add motivation section --- text/0000-target-extension.md | 141 ++++++++++++++++++++++++++++++++++ 1 file changed, 141 insertions(+) create mode 100644 text/0000-target-extension.md diff --git a/text/0000-target-extension.md b/text/0000-target-extension.md new file mode 100644 index 00000000000..b428dd6ddd0 --- /dev/null +++ b/text/0000-target-extension.md @@ -0,0 +1,141 @@ +- Feature Name: `target extension` +- Start Date: 2017-05-21 +- RFC PR: +- Rust Issue: + +# Summary +[summary]: #summary + +Extend Rust target specification to follow more closely LLVM triple specification. + +# Motivation +[motivation]: #motivation + +[LLVM triple](http://llvm.org/docs/LangRef.html#target-triple) specification is +more precise than the current [Rust +target](https://github.com/rust-lang/rust/blob/7ac844ffb850a73b98cd47cbdec909d1f03c7987/src/librustc_back/target/mod.rs#L228) +specification we have. + +In particular, Rust target definition is missing for: +- optional OS version +- optional environment version + + +Rust language is aimed to be used on different operating systems following +themself there own rules. In particular, each operating systems have proper way +to deal with breaking changes: if Linux tends to forbid breaking changes by +policy, all others systems doesn't have such rule. As Rust language tend to be +a stable language, having a stable way to describe breaking changes on the OS +would be very valuable and could become necessary as time passes. + +LLVM deals with such changes on OS by having a different triple per OS version, +like for the following triples: + +- `x86_64-apple-darwin16.0.0` +- `x86_64-unknown-freebsd12.0` +- `x86_64-unknown-freebsd11.0` +- `i386-unknown-openbsd5.8` +- `x86_64-unknown-netbsd7.99` + + +As examples, considers the following changes in several operating systems (some +are ABI changes, others API changes) and how a crate like `libc` would have to +deal with them. Please note that some are quite old but could be considered as +representative of something that already occurred in the past. + +- OpenBSD 5.5 does a big breaking changes in order to be compatible with + [year 2038](https://www.openbsd.org/faq/upgrade55.html#time_t): it switchs + from a signed 32 bit counter to signed 64 bit time type. + See [commit message](http://cvsweb.openbsd.org/cgi-bin/cvsweb/src/sys/sys/_types.h?rev=1.6&content-type=text/x-cvsweb-markup) + and [diff on types](http://cvsweb.openbsd.org/cgi-bin/cvsweb/src/sys/sys/_types.h.diff?r1=1.5&r2=1.6) + +- OpenBSD 6.2 (upcoming) changes `si_addr` type (`char *` to `void *`) in + `siginfo_t` structure. + See [commit message](http://cvsweb.openbsd.org/cgi-bin/cvsweb/src/sys/sys/siginfo.h?rev=1.12&content-type=text/x-cvsweb-markup) + and [diff on sys/siginfo.h](http://cvsweb.openbsd.org/cgi-bin/cvsweb/src/sys/sys/siginfo.h.diff?r1=1.11&r2=1.12). + +- FreeBSD 10 changes the `cap_rights_t` type from `uint64_t` to a structure + that they can extend in the future in a backward compatible way. + See [commit R255129](https://svnweb.freebsd.org/base?view=revision&revision=255219). + +- FreeBSD 11 changes signature of `psignal()` to align to POSIX 2008 + (`unsigned int` to `int` argument). + See [commit R300997](https://svnweb.freebsd.org/base?view=revision&revision=300997) + and [diff on signal.h](https://svnweb.freebsd.org/base/head/include/signal.h?r1=300997&r2=300996&pathrev=300997). + +- FreeBSD 12 (upcoming) removes `setkey()`, `encrypt()`, `des_setkey()` and + `des_cipher()` functions. + See [commit R306651](https://svnweb.freebsd.org/base?view=revision&revision=306651) + and [diff of unistd.h](https://svnweb.freebsd.org/base/head/include/unistd.h?r1=306651&r2=306650&pathrev=306651). + +- FreeBSD 12 (upcoming) adds a new member `fb_memattr` in the middle of the + structure `fb_info` (public under `sys/fbio.h`). + See [commit R306555](https://svnweb.freebsd.org/base?view=revision&revision=306555) + and [diff of sys/fbio.h](https://svnweb.freebsd.org/base/head/sys/sys/fbio.h?r1=306555&r2=306554&pathrev=306555). + +- NetBSD 7.99 (upcoming 8) adds a new member `mnt_lower` in the middle of + the structure `mount` (public under `sys/mount.h`). + See [commit message](http://cvsweb.netbsd.org/bsdweb.cgi/src/sys/sys/mount.h?rev=1.221&content-type=text/x-cvsweb-markup) + and [diff of sys/mount.h](http://cvsweb.netbsd.org/bsdweb.cgi/src/sys/sys/mount.h.diff?r1=1.220&r2=1.221). + +- NetBSD 7.99 (upcoming 8) changes signature of `scandir()` function to conforms to `IEEE + Std 1003.1-2008` (`const void *` to `const struct dirent **`). + See [commit message](http://cvsweb.netbsd.org/bsdweb.cgi/src/include/dirent.h?rev=1.36&content-type=text/x-cvsweb-markup&sortby=date) + and [diff to dirent.h](http://cvsweb.netbsd.org/bsdweb.cgi/src/include/dirent.h.diff?r1=1.35&r2=1.36&sortby=date). + +- DragonFly 1.4 switchs `ino_t` from 32 bits to 64 bits. + See [commit message](http://gitweb.dragonflybsd.org/dragonfly.git/commit/f91a71dd15504ebdb04387d0822771ef145b25f9?f=sys/sys/types.h) + and [diff to sys/types.h](http://gitweb.dragonflybsd.org/dragonfly.git/blobdiff/6f1e2b382f6c2ba9b43a1fc106ba998b45499eea..f91a71dd15504ebdb04387d0822771ef145b25f9:/sys/sys/types.h) + + +In the current situation, `libc` crate has no way to deal in a stable way with +these changes. It could only support two incompatible OS version together by +only defining the common subset. + +Additionnally, in order to switch `libc` from one OS version to another, it +would be required to do a breaking change at `libc` level (incrementing major +version of `libc` itself) which is undesirable. + + +The purpose of extending Rust `Target` type to follow LLVM Triple definition is +to be able to deal with such changes at Rust language level. As the target will +be able to make distinction between particular OS or environment version, it +would be possible to export the information in the same way we export +`target_os`, `target_arch`, `target_endian` or `target_pointer_width`. + +This way, a crate like `libc` could export raw bindings of platform +specifically for the targeted version. + + +# Detailed design +[design]: #detailed-design + +This is the bulk of the RFC. Explain the design in enough detail for somebody familiar +with the language to understand, and for somebody familiar with the compiler to implement. +This should get into specifics and corner-cases, and include examples of how the feature is used. + +# How We Teach This +[how-we-teach-this]: #how-we-teach-this + +What names and terminology work best for these concepts and why? +How is this idea best presented—as a continuation of existing Rust patterns, or as a wholly new one? + +Would the acceptance of this proposal change how Rust is taught to new users at any level? +How should this feature be introduced and taught to existing Rust users? + +What additions or changes to the Rust Reference, _The Rust Programming Language_, and/or _Rust by Example_ does it entail? + +# Drawbacks +[drawbacks]: #drawbacks + +Why should we *not* do this? + +# Alternatives +[alternatives]: #alternatives + +What other designs have been considered? What is the impact of not doing this? + +# Unresolved questions +[unresolved]: #unresolved-questions + +What parts of the design are still TBD? From 3b1362a633db82651656ba1edc88c0a956ab7390 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?S=C3=A9bastien=20Marie?= Date: Sun, 21 May 2017 18:52:54 +0200 Subject: [PATCH 02/56] motivation: add link to LLVM Triple definition of getXXXVersion --- text/0000-target-extension.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/text/0000-target-extension.md b/text/0000-target-extension.md index b428dd6ddd0..2439e6d4297 100644 --- a/text/0000-target-extension.md +++ b/text/0000-target-extension.md @@ -17,8 +17,8 @@ target](https://github.com/rust-lang/rust/blob/7ac844ffb850a73b98cd47cbdec909d1f specification we have. In particular, Rust target definition is missing for: -- optional OS version -- optional environment version +- optional [OS version](https://github.com/llvm-mirror/llvm/blob/343e535d9c38cf57173ace6597380752a18a6a67/include/llvm/ADT/Triple.h#L315) +- optional [environment version](https://github.com/llvm-mirror/llvm/blob/343e535d9c38cf57173ace6597380752a18a6a67/include/llvm/ADT/Triple.h#L303) Rust language is aimed to be used on different operating systems following From 9333fa0007bf55ad6312326aaa496b825b23ec78 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?S=C3=A9bastien=20Marie?= Date: Sun, 21 May 2017 19:02:46 +0200 Subject: [PATCH 03/56] motivation: missing dot --- text/0000-target-extension.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/text/0000-target-extension.md b/text/0000-target-extension.md index 2439e6d4297..d0b3a5a8648 100644 --- a/text/0000-target-extension.md +++ b/text/0000-target-extension.md @@ -22,7 +22,7 @@ In particular, Rust target definition is missing for: Rust language is aimed to be used on different operating systems following -themself there own rules. In particular, each operating systems have proper way +themself there own rules.In particular, each operating systems have proper way to deal with breaking changes: if Linux tends to forbid breaking changes by policy, all others systems doesn't have such rule. As Rust language tend to be a stable language, having a stable way to describe breaking changes on the OS @@ -47,7 +47,7 @@ representative of something that already occurred in the past. [year 2038](https://www.openbsd.org/faq/upgrade55.html#time_t): it switchs from a signed 32 bit counter to signed 64 bit time type. See [commit message](http://cvsweb.openbsd.org/cgi-bin/cvsweb/src/sys/sys/_types.h?rev=1.6&content-type=text/x-cvsweb-markup) - and [diff on types](http://cvsweb.openbsd.org/cgi-bin/cvsweb/src/sys/sys/_types.h.diff?r1=1.5&r2=1.6) + and [diff on types](http://cvsweb.openbsd.org/cgi-bin/cvsweb/src/sys/sys/_types.h.diff?r1=1.5&r2=1.6). - OpenBSD 6.2 (upcoming) changes `si_addr` type (`char *` to `void *`) in `siginfo_t` structure. From 82ec48b5b35ad146a8f6e8b6096ab3b2bd8073c9 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?S=C3=A9bastien=20Marie?= Date: Sun, 21 May 2017 19:06:30 +0200 Subject: [PATCH 04/56] motivation: rephrasing --- text/0000-target-extension.md | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/text/0000-target-extension.md b/text/0000-target-extension.md index d0b3a5a8648..90f89ff0244 100644 --- a/text/0000-target-extension.md +++ b/text/0000-target-extension.md @@ -16,7 +16,8 @@ more precise than the current [Rust target](https://github.com/rust-lang/rust/blob/7ac844ffb850a73b98cd47cbdec909d1f03c7987/src/librustc_back/target/mod.rs#L228) specification we have. -In particular, Rust target definition is missing for: +In particular, the following elements are missing from the Rust target +definition: - optional [OS version](https://github.com/llvm-mirror/llvm/blob/343e535d9c38cf57173ace6597380752a18a6a67/include/llvm/ADT/Triple.h#L315) - optional [environment version](https://github.com/llvm-mirror/llvm/blob/343e535d9c38cf57173ace6597380752a18a6a67/include/llvm/ADT/Triple.h#L303) From c071d61bef5ef192f809e8e93f25997d21bd730c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?S=C3=A9bastien=20Marie?= Date: Sun, 21 May 2017 19:14:45 +0200 Subject: [PATCH 05/56] motivation: typo --- text/0000-target-extension.md | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/text/0000-target-extension.md b/text/0000-target-extension.md index 90f89ff0244..604e6636e12 100644 --- a/text/0000-target-extension.md +++ b/text/0000-target-extension.md @@ -23,7 +23,7 @@ definition: Rust language is aimed to be used on different operating systems following -themself there own rules.In particular, each operating systems have proper way +them self there own rules.In particular, each operating systems have proper way to deal with breaking changes: if Linux tends to forbid breaking changes by policy, all others systems doesn't have such rule. As Rust language tend to be a stable language, having a stable way to describe breaking changes on the OS @@ -45,7 +45,7 @@ deal with them. Please note that some are quite old but could be considered as representative of something that already occurred in the past. - OpenBSD 5.5 does a big breaking changes in order to be compatible with - [year 2038](https://www.openbsd.org/faq/upgrade55.html#time_t): it switchs + [year 2038](https://www.openbsd.org/faq/upgrade55.html#time_t): it switches from a signed 32 bit counter to signed 64 bit time type. See [commit message](http://cvsweb.openbsd.org/cgi-bin/cvsweb/src/sys/sys/_types.h?rev=1.6&content-type=text/x-cvsweb-markup) and [diff on types](http://cvsweb.openbsd.org/cgi-bin/cvsweb/src/sys/sys/_types.h.diff?r1=1.5&r2=1.6). @@ -84,7 +84,7 @@ representative of something that already occurred in the past. See [commit message](http://cvsweb.netbsd.org/bsdweb.cgi/src/include/dirent.h?rev=1.36&content-type=text/x-cvsweb-markup&sortby=date) and [diff to dirent.h](http://cvsweb.netbsd.org/bsdweb.cgi/src/include/dirent.h.diff?r1=1.35&r2=1.36&sortby=date). -- DragonFly 1.4 switchs `ino_t` from 32 bits to 64 bits. +- DragonFly 1.4 switches `ino_t` from 32 bits to 64 bits. See [commit message](http://gitweb.dragonflybsd.org/dragonfly.git/commit/f91a71dd15504ebdb04387d0822771ef145b25f9?f=sys/sys/types.h) and [diff to sys/types.h](http://gitweb.dragonflybsd.org/dragonfly.git/blobdiff/6f1e2b382f6c2ba9b43a1fc106ba998b45499eea..f91a71dd15504ebdb04387d0822771ef145b25f9:/sys/sys/types.h) @@ -93,7 +93,7 @@ In the current situation, `libc` crate has no way to deal in a stable way with these changes. It could only support two incompatible OS version together by only defining the common subset. -Additionnally, in order to switch `libc` from one OS version to another, it +Additionally, in order to switch `libc` from one OS version to another, it would be required to do a breaking change at `libc` level (incrementing major version of `libc` itself) which is undesirable. From b7744dd32aa3b57ebdc3dca3d55ca1522edf5571 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?S=C3=A9bastien=20Marie?= Date: Sun, 21 May 2017 19:16:02 +0200 Subject: [PATCH 06/56] motivation: add some bold --- text/0000-target-extension.md | 18 +++++++++--------- 1 file changed, 9 insertions(+), 9 deletions(-) diff --git a/text/0000-target-extension.md b/text/0000-target-extension.md index 604e6636e12..71962fb4c5a 100644 --- a/text/0000-target-extension.md +++ b/text/0000-target-extension.md @@ -44,47 +44,47 @@ are ABI changes, others API changes) and how a crate like `libc` would have to deal with them. Please note that some are quite old but could be considered as representative of something that already occurred in the past. -- OpenBSD 5.5 does a big breaking changes in order to be compatible with +- **OpenBSD 5.5** does a big breaking changes in order to be compatible with [year 2038](https://www.openbsd.org/faq/upgrade55.html#time_t): it switches from a signed 32 bit counter to signed 64 bit time type. See [commit message](http://cvsweb.openbsd.org/cgi-bin/cvsweb/src/sys/sys/_types.h?rev=1.6&content-type=text/x-cvsweb-markup) and [diff on types](http://cvsweb.openbsd.org/cgi-bin/cvsweb/src/sys/sys/_types.h.diff?r1=1.5&r2=1.6). -- OpenBSD 6.2 (upcoming) changes `si_addr` type (`char *` to `void *`) in +- **OpenBSD 6.2** (upcoming) changes `si_addr` type (`char *` to `void *`) in `siginfo_t` structure. See [commit message](http://cvsweb.openbsd.org/cgi-bin/cvsweb/src/sys/sys/siginfo.h?rev=1.12&content-type=text/x-cvsweb-markup) and [diff on sys/siginfo.h](http://cvsweb.openbsd.org/cgi-bin/cvsweb/src/sys/sys/siginfo.h.diff?r1=1.11&r2=1.12). -- FreeBSD 10 changes the `cap_rights_t` type from `uint64_t` to a structure +- **FreeBSD 10** changes the `cap_rights_t` type from `uint64_t` to a structure that they can extend in the future in a backward compatible way. See [commit R255129](https://svnweb.freebsd.org/base?view=revision&revision=255219). -- FreeBSD 11 changes signature of `psignal()` to align to POSIX 2008 +- **FreeBSD 11** changes signature of `psignal()` to align to POSIX 2008 (`unsigned int` to `int` argument). See [commit R300997](https://svnweb.freebsd.org/base?view=revision&revision=300997) and [diff on signal.h](https://svnweb.freebsd.org/base/head/include/signal.h?r1=300997&r2=300996&pathrev=300997). -- FreeBSD 12 (upcoming) removes `setkey()`, `encrypt()`, `des_setkey()` and +- **FreeBSD 12** (upcoming) removes `setkey()`, `encrypt()`, `des_setkey()` and `des_cipher()` functions. See [commit R306651](https://svnweb.freebsd.org/base?view=revision&revision=306651) and [diff of unistd.h](https://svnweb.freebsd.org/base/head/include/unistd.h?r1=306651&r2=306650&pathrev=306651). -- FreeBSD 12 (upcoming) adds a new member `fb_memattr` in the middle of the +- **FreeBSD 12** (upcoming) adds a new member `fb_memattr` in the middle of the structure `fb_info` (public under `sys/fbio.h`). See [commit R306555](https://svnweb.freebsd.org/base?view=revision&revision=306555) and [diff of sys/fbio.h](https://svnweb.freebsd.org/base/head/sys/sys/fbio.h?r1=306555&r2=306554&pathrev=306555). -- NetBSD 7.99 (upcoming 8) adds a new member `mnt_lower` in the middle of +- **NetBSD 7.99** (upcoming 8) adds a new member `mnt_lower` in the middle of the structure `mount` (public under `sys/mount.h`). See [commit message](http://cvsweb.netbsd.org/bsdweb.cgi/src/sys/sys/mount.h?rev=1.221&content-type=text/x-cvsweb-markup) and [diff of sys/mount.h](http://cvsweb.netbsd.org/bsdweb.cgi/src/sys/sys/mount.h.diff?r1=1.220&r2=1.221). -- NetBSD 7.99 (upcoming 8) changes signature of `scandir()` function to conforms to `IEEE +- **NetBSD 7.99** (upcoming 8) changes signature of `scandir()` function to conforms to `IEEE Std 1003.1-2008` (`const void *` to `const struct dirent **`). See [commit message](http://cvsweb.netbsd.org/bsdweb.cgi/src/include/dirent.h?rev=1.36&content-type=text/x-cvsweb-markup&sortby=date) and [diff to dirent.h](http://cvsweb.netbsd.org/bsdweb.cgi/src/include/dirent.h.diff?r1=1.35&r2=1.36&sortby=date). -- DragonFly 1.4 switches `ino_t` from 32 bits to 64 bits. +- **DragonFly 1.4** switches `ino_t` from 32 bits to 64 bits. See [commit message](http://gitweb.dragonflybsd.org/dragonfly.git/commit/f91a71dd15504ebdb04387d0822771ef145b25f9?f=sys/sys/types.h) and [diff to sys/types.h](http://gitweb.dragonflybsd.org/dragonfly.git/blobdiff/6f1e2b382f6c2ba9b43a1fc106ba998b45499eea..f91a71dd15504ebdb04387d0822771ef145b25f9:/sys/sys/types.h) From bb235600b113e93e6ae09c0e932082ed0737a5a8 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?S=C3=A9bastien=20Marie?= Date: Mon, 22 May 2017 09:30:41 +0200 Subject: [PATCH 07/56] populate parts with ideas (will need phrasing) --- text/0000-target-extension.md | 81 +++++++++++++++++++++++++++++++++++ 1 file changed, 81 insertions(+) diff --git a/text/0000-target-extension.md b/text/0000-target-extension.md index 71962fb4c5a..e88c0b9125c 100644 --- a/text/0000-target-extension.md +++ b/text/0000-target-extension.md @@ -74,6 +74,9 @@ representative of something that already occurred in the past. See [commit R306555](https://svnweb.freebsd.org/base?view=revision&revision=306555) and [diff of sys/fbio.h](https://svnweb.freebsd.org/base/head/sys/sys/fbio.h?r1=306555&r2=306554&pathrev=306555). +- **FreeBSD ?** wants to switch `ino_t` from 32 bits to 64 bits. + See [Status Update and Call for Testing](https://lists.freebsd.org/pipermail/freebsd-fs/2017-April/024684.html). + - **NetBSD 7.99** (upcoming 8) adds a new member `mnt_lower` in the middle of the structure `mount` (public under `sys/mount.h`). See [commit message](http://cvsweb.netbsd.org/bsdweb.cgi/src/sys/sys/mount.h?rev=1.221&content-type=text/x-cvsweb-markup) @@ -115,6 +118,65 @@ This is the bulk of the RFC. Explain the design in enough detail for somebody fa with the language to understand, and for somebody familiar with the compiler to implement. This should get into specifics and corner-cases, and include examples of how the feature is used. + + +### Language level: what the user will see ? + +- new `target_os_version` and `target_env_version` attributes +- new operators to deal with symbol (string) comparaison +- examples + - `#[cfg(all(target_os="openbsd", target_os_version < "5.5")]` + - `#[cfg(all(target_os="openbsd", target_os_version >= "5.5")]` + - `#[cfg(all(target_os="freebsd", target_os_version >= "10", target_os_version < "12")]` + - `#[cfg(all(target_os="freebsd", any(target_os_version = "10", target_os_version = "11"))]` + + +### Syntax level + +- operators to compare versions in attribute + +- behaviour + - numeric comparaison + - "2" < "10" : true + - able to deal with any number of "." inside the symbol: + - "2" < "2.0" : true + - "3" < "2.0" : false + - "2.0" < "2.0" : false + - "10.0" < "10.0.1" : true + + +See `libsyntax/attr.rs`, `libsyntax/config.rs`, `libsyntax/parse/parser.rs` +(unsure about these files for now). + + +### Backend level + +- additional members in `Target` + - `target_os_version: String` (could be empty: "") + - `target_env_version: String` (could be empty: "") + +- drawbacks: it requires a new target per OS version +- add a flexible code to easily create new target (with just + `target_os_version` changing) + +See `librustc_back/target/`. + +### Session level + +- populate and export the new attributes in the default build configuration + +See `librustc/session/config.rs`. + + +### Workflow with new OS release + +- when a new OS release occurs + - adds to `libc` any changes (using `target_os_version` if required) + - adds a new target specification + - remove target of any unsupported OS version + + + # How We Teach This [how-we-teach-this]: #how-we-teach-this @@ -131,12 +193,31 @@ What additions or changes to the Rust Reference, _The Rust Programming Language_ Why should we *not* do this? +- additional complexity in attributes for conditional compilation +- number of targets will grow a lot + - not all targets will be testable (requires a particular OS version for + running testsuite) + - will require to deprecate unsupported OS version (for example OpenBSD + officially support only the 2 last releases) + # Alternatives [alternatives]: #alternatives What other designs have been considered? What is the impact of not doing this? +- using `target_os` with the version inside. it would require to duplicate all + `libc` code (for only small differencies) at each release. + +- statu quo: while no fundamental breaking changes occurs at OS level, no need + to do anything. Disclosure: FreeBSD switchs to ino64 could occurs soon. + + # Unresolved questions [unresolved]: #unresolved-questions What parts of the design are still TBD? + +- partial implementation with no additional operator at syntax level. It + requires to explicitly list all affected OS/env version on changes. Doable if + the list of supported OS/env version is controlled in some way. + From 21ffe8b05f8b4e1aedf74c5241a8de0c49c3a6a5 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?S=C3=A9bastien=20Marie?= Date: Mon, 22 May 2017 09:32:34 +0200 Subject: [PATCH 08/56] headers at level 2 --- text/0000-target-extension.md | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/text/0000-target-extension.md b/text/0000-target-extension.md index e88c0b9125c..81520d1d347 100644 --- a/text/0000-target-extension.md +++ b/text/0000-target-extension.md @@ -120,7 +120,7 @@ This should get into specifics and corner-cases, and include examples of how the -### Language level: what the user will see ? +## Language level: what the user will see ? - new `target_os_version` and `target_env_version` attributes - new operators to deal with symbol (string) comparaison @@ -131,7 +131,7 @@ This should get into specifics and corner-cases, and include examples of how the - `#[cfg(all(target_os="freebsd", any(target_os_version = "10", target_os_version = "11"))]` -### Syntax level +## Syntax level - operators to compare versions in attribute @@ -149,7 +149,7 @@ See `libsyntax/attr.rs`, `libsyntax/config.rs`, `libsyntax/parse/parser.rs` (unsure about these files for now). -### Backend level +## Backend level - additional members in `Target` - `target_os_version: String` (could be empty: "") @@ -161,14 +161,14 @@ See `libsyntax/attr.rs`, `libsyntax/config.rs`, `libsyntax/parse/parser.rs` See `librustc_back/target/`. -### Session level +## Session level - populate and export the new attributes in the default build configuration See `librustc/session/config.rs`. -### Workflow with new OS release +## Workflow with new OS release - when a new OS release occurs - adds to `libc` any changes (using `target_os_version` if required) From 3863b7e5fd4f9ad306da97ced81d4ba64ba8cda3 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?S=C3=A9bastien=20Marie?= Date: Mon, 22 May 2017 09:39:20 +0200 Subject: [PATCH 09/56] typo --- text/0000-target-extension.md | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/text/0000-target-extension.md b/text/0000-target-extension.md index 81520d1d347..1812d84e637 100644 --- a/text/0000-target-extension.md +++ b/text/0000-target-extension.md @@ -134,7 +134,6 @@ This should get into specifics and corner-cases, and include examples of how the ## Syntax level - operators to compare versions in attribute - - behaviour - numeric comparaison - "2" < "10" : true @@ -209,7 +208,7 @@ What other designs have been considered? What is the impact of not doing this? `libc` code (for only small differencies) at each release. - statu quo: while no fundamental breaking changes occurs at OS level, no need - to do anything. Disclosure: FreeBSD switchs to ino64 could occurs soon. + to do anything. Disclosure: FreeBSD switch to ino64 could occurs soon. # Unresolved questions From 1e43d8b9b74054ddf968f112bd4115c8d42574fe Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?S=C3=A9bastien=20Marie?= Date: Mon, 22 May 2017 09:53:53 +0200 Subject: [PATCH 10/56] provide explicit examples about "common subset" --- text/0000-target-extension.md | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/text/0000-target-extension.md b/text/0000-target-extension.md index 1812d84e637..9798f59ca3d 100644 --- a/text/0000-target-extension.md +++ b/text/0000-target-extension.md @@ -94,11 +94,14 @@ representative of something that already occurred in the past. In the current situation, `libc` crate has no way to deal in a stable way with these changes. It could only support two incompatible OS version together by -only defining the common subset. +only defining the common subset. Depending the breaking part, it could result +removed feature in rustc (removing `si_addr` for OpenBSD would break stack +overflow detection), or even breaking rustc itself (removing `ino_t` for +FreeBSD). Additionally, in order to switch `libc` from one OS version to another, it would be required to do a breaking change at `libc` level (incrementing major -version of `libc` itself) which is undesirable. +version of `libc` itself) which is undesirable for this purpose. The purpose of extending Rust `Target` type to follow LLVM Triple definition is From 5cd75e950852efb8f5295b39afd6cab33b907d99 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?S=C3=A9bastien=20Marie?= Date: Mon, 22 May 2017 10:58:56 +0200 Subject: [PATCH 11/56] add reference to lang/rust diff for freebsd ino64 --- text/0000-target-extension.md | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/text/0000-target-extension.md b/text/0000-target-extension.md index 9798f59ca3d..79518eedf13 100644 --- a/text/0000-target-extension.md +++ b/text/0000-target-extension.md @@ -75,7 +75,8 @@ representative of something that already occurred in the past. and [diff of sys/fbio.h](https://svnweb.freebsd.org/base/head/sys/sys/fbio.h?r1=306555&r2=306554&pathrev=306555). - **FreeBSD ?** wants to switch `ino_t` from 32 bits to 64 bits. - See [Status Update and Call for Testing](https://lists.freebsd.org/pipermail/freebsd-fs/2017-April/024684.html). + See [Status Update and Call for Testing](https://lists.freebsd.org/pipermail/freebsd-fs/2017-April/024684.html), + and [diff on lang/rust (ports tree)](https://github.com/FreeBSDFoundation/freebsd/blob/bc50a841851470d98cf1c219b261133536aa7ee8/ports.patch#L402). - **NetBSD 7.99** (upcoming 8) adds a new member `mnt_lower` in the middle of the structure `mount` (public under `sys/mount.h`). From eed9c151f92424fd01ddcab42150d592f83c151f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?S=C3=A9bastien=20Marie?= Date: Mon, 22 May 2017 17:29:06 +0200 Subject: [PATCH 12/56] add a warning: only ideas for now --- text/0000-target-extension.md | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/text/0000-target-extension.md b/text/0000-target-extension.md index 79518eedf13..f654fa8db3d 100644 --- a/text/0000-target-extension.md +++ b/text/0000-target-extension.md @@ -22,9 +22,9 @@ definition: - optional [environment version](https://github.com/llvm-mirror/llvm/blob/343e535d9c38cf57173ace6597380752a18a6a67/include/llvm/ADT/Triple.h#L303) -Rust language is aimed to be used on different operating systems following -them self there own rules.In particular, each operating systems have proper way -to deal with breaking changes: if Linux tends to forbid breaking changes by +Rust language is aimed to be used on different operating systems following them +self there own rules. In particular, each operating systems have proper way to +deal with breaking changes: if Linux tends to forbid breaking changes by policy, all others systems doesn't have such rule. As Rust language tend to be a stable language, having a stable way to describe breaking changes on the OS would be very valuable and could become necessary as time passes. @@ -122,7 +122,7 @@ This is the bulk of the RFC. Explain the design in enough detail for somebody fa with the language to understand, and for somebody familiar with the compiler to implement. This should get into specifics and corner-cases, and include examples of how the feature is used. - +**INCOMPLETE PART: only ideas are presented here for now** ## Language level: what the user will see ? From 7e6374c4289739c4cff6daada144c61b1bb4f9d0 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?S=C3=A9bastien=20Marie?= Date: Mon, 22 May 2017 18:56:22 +0200 Subject: [PATCH 13/56] provide a complete example --- text/0000-target-extension.md | 25 +++++++++++++++++++++++++ 1 file changed, 25 insertions(+) diff --git a/text/0000-target-extension.md b/text/0000-target-extension.md index f654fa8db3d..eaead66e9eb 100644 --- a/text/0000-target-extension.md +++ b/text/0000-target-extension.md @@ -135,6 +135,31 @@ This should get into specifics and corner-cases, and include examples of how the - `#[cfg(all(target_os="freebsd", any(target_os_version = "10", target_os_version = "11"))]` +Here an complete (and simple) example. In OpenBSD 6.2, the structure `siginfo_t` +changed: + +```rust +pub struct siginfo_t { + pub si_signo: ::c_int, + pub si_code: ::c_int, + pub si_errno: ::c_int, + + #[cfg(target_os_version < "6.2")] + pub si_addr: *mut ::c_char, + #[cfg(target_os_version >= "6.2")] + pub si_addr: *mut ::c_void, + + #[cfg(target_pointer_width = "32")] + __pad: [u8; 112], + #[cfg(target_pointer_width = "64")] + __pad: [u8; 108], +} +``` + +With this code, it is possible to target `x86_amd64-unknown-openbsd6.1` **and** +`x86_amd64-unknown-openbsd6.2`. + + ## Syntax level - operators to compare versions in attribute From 76fc5ffc3ce99cbc0f329f0c171bc08ef62ec761 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?S=C3=A9bastien=20Marie?= Date: Mon, 22 May 2017 19:01:02 +0200 Subject: [PATCH 14/56] compare with current libc --- text/0000-target-extension.md | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/text/0000-target-extension.md b/text/0000-target-extension.md index eaead66e9eb..018348fa791 100644 --- a/text/0000-target-extension.md +++ b/text/0000-target-extension.md @@ -157,7 +157,11 @@ pub struct siginfo_t { ``` With this code, it is possible to target `x86_amd64-unknown-openbsd6.1` **and** -`x86_amd64-unknown-openbsd6.2`. +`x86_amd64-unknown-openbsd6.2`, whereas with [current libc +code](https://github.com/rust-lang/libc/blob/6ddc76a27e0678c04ec7337591f8a0e36c065664/src/unix/bsd/netbsdlike/openbsdlike/mod.rs#L106) +only version before 6.1 is possible, and switching to the other version would +be a breaking changes in `libc` (and we would lost OpenBSD 6.1 supported +version). ## Syntax level From 6ab7f908846804c01926a52892c66e708a618498 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?S=C3=A9bastien=20Marie?= Date: Tue, 23 May 2017 08:09:10 +0200 Subject: [PATCH 15/56] breaking change in --target --- text/0000-target-extension.md | 18 ++++++++++++++++++ 1 file changed, 18 insertions(+) diff --git a/text/0000-target-extension.md b/text/0000-target-extension.md index 018348fa791..7ece8b20ba0 100644 --- a/text/0000-target-extension.md +++ b/text/0000-target-extension.md @@ -218,8 +218,25 @@ How is this idea best presented—as a continuation of existing Rust patterns, o Would the acceptance of this proposal change how Rust is taught to new users at any level? How should this feature be introduced and taught to existing Rust users? + +Modifying the `Target` struct is a low-level change by itself. + +From a developer perspective, it adds a new attributes for conditional +compilation. + +For projects using Rust (mozilla in mind), it changes the `--target` argument +for several existing targets in a breaking way: some targets will disappears +(`x86_64-unknown-openbsd`) in favor of others targets +(`x86_64-unknown-openbsd6.0` and `x86_64-unknown-openbsd6.1` at time of +writing). But it reflects better the reality: OpenBSD 6.0 is different than +OpenBSD 6.1. + + What additions or changes to the Rust Reference, _The Rust Programming Language_, and/or _Rust by Example_ does it entail? +- _Rust Reference_: mentioning new attributes in conditional compilation attribute section. + + # Drawbacks [drawbacks]: #drawbacks @@ -232,6 +249,7 @@ Why should we *not* do this? - will require to deprecate unsupported OS version (for example OpenBSD officially support only the 2 last releases) + # Alternatives [alternatives]: #alternatives From a1b309ba1ae1c587a225c6f8d095f06bc69f0025 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?S=C3=A9bastien=20Marie?= Date: Tue, 23 May 2017 11:02:20 +0200 Subject: [PATCH 16/56] language level --- text/0000-target-extension.md | 42 +++++++++++++++++++++++++++-------- 1 file changed, 33 insertions(+), 9 deletions(-) diff --git a/text/0000-target-extension.md b/text/0000-target-extension.md index 7ece8b20ba0..b8af6e739e2 100644 --- a/text/0000-target-extension.md +++ b/text/0000-target-extension.md @@ -126,17 +126,38 @@ This should get into specifics and corner-cases, and include examples of how the ## Language level: what the user will see ? -- new `target_os_version` and `target_env_version` attributes -- new operators to deal with symbol (string) comparaison -- examples - - `#[cfg(all(target_os="openbsd", target_os_version < "5.5")]` - - `#[cfg(all(target_os="openbsd", target_os_version >= "5.5")]` - - `#[cfg(all(target_os="freebsd", target_os_version >= "10", target_os_version < "12")]` - - `#[cfg(all(target_os="freebsd", any(target_os_version = "10", target_os_version = "11"))]` +At language level, new attributes for conditional compilation would be added: +- `target_os_version` +- `target_env_version` -Here an complete (and simple) example. In OpenBSD 6.2, the structure `siginfo_t` -changed: +There could be empty (""). + +```rust +extern { + // encrypt() function doesn't exist in freebsd12 + + #[cfg(all(target_os="freebsd", target_os_version != "12"))] + pub fn encrypt(block *mut ::c_char, flag ::c_int) -> ::c_int; +} +``` + + +Additionally, in order to simplify matching for several versions, new operators +to doing comparaison would be added too. + +```rust +extern { + // encrypt() function doesn't exist anymore starting with freebsd12 + + #[cfg(all(target_os="freebsd", target_os_version < "12"))] + pub fn encrypt(block *mut ::c_char, flag ::c_int) -> ::c_int; +} +``` + + +Another complete (and simple) example. In OpenBSD 6.2, the structure +`siginfo_t` changed: ```rust pub struct siginfo_t { @@ -144,6 +165,8 @@ pub struct siginfo_t { pub si_code: ::c_int, pub si_errno: ::c_int, + // A type correction occured in 6.2. + // Before it was a `char *` and now it is a `void *`. #[cfg(target_os_version < "6.2")] pub si_addr: *mut ::c_char, #[cfg(target_os_version >= "6.2")] @@ -193,6 +216,7 @@ See `libsyntax/attr.rs`, `libsyntax/config.rs`, `libsyntax/parse/parser.rs` See `librustc_back/target/`. + ## Session level - populate and export the new attributes in the default build configuration From 011dfb6b24a46aa02dc7f8fbb73824dec686f9a1 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?S=C3=A9bastien=20Marie?= Date: Tue, 23 May 2017 11:06:56 +0200 Subject: [PATCH 17/56] language level. rephrasing --- text/0000-target-extension.md | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/text/0000-target-extension.md b/text/0000-target-extension.md index b8af6e739e2..3bddd12e15a 100644 --- a/text/0000-target-extension.md +++ b/text/0000-target-extension.md @@ -156,7 +156,7 @@ extern { ``` -Another complete (and simple) example. In OpenBSD 6.2, the structure +Another complete (and simple) example: in OpenBSD 6.2, the structure `siginfo_t` changed: ```rust @@ -179,10 +179,10 @@ pub struct siginfo_t { } ``` -With this code, it is possible to target `x86_amd64-unknown-openbsd6.1` **and** -`x86_amd64-unknown-openbsd6.2`, whereas with [current libc +It would be possible to target `x86_amd64-unknown-openbsd6.1` **and** +`x86_amd64-unknown-openbsd6.2` whereas with [current libc code](https://github.com/rust-lang/libc/blob/6ddc76a27e0678c04ec7337591f8a0e36c065664/src/unix/bsd/netbsdlike/openbsdlike/mod.rs#L106) -only version before 6.1 is possible, and switching to the other version would +only one version is possible, and switching from one to the other version would be a breaking changes in `libc` (and we would lost OpenBSD 6.1 supported version). From 4cf558f49eb601aac5010e21d63f27152ebd48c4 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?S=C3=A9bastien=20Marie?= Date: Tue, 23 May 2017 11:25:51 +0200 Subject: [PATCH 18/56] some elements about attribute --- text/0000-target-extension.md | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/text/0000-target-extension.md b/text/0000-target-extension.md index 3bddd12e15a..54c768d1e00 100644 --- a/text/0000-target-extension.md +++ b/text/0000-target-extension.md @@ -137,7 +137,7 @@ There could be empty (""). extern { // encrypt() function doesn't exist in freebsd12 - #[cfg(all(target_os="freebsd", target_os_version != "12"))] + #[cfg(all(target_os="freebsd", not(target_os_version="12")))] pub fn encrypt(block *mut ::c_char, flag ::c_int) -> ::c_int; } ``` @@ -189,6 +189,10 @@ version). ## Syntax level +The addition of new operators in attribute is a syntax extension. + + + - operators to compare versions in attribute - behaviour - numeric comparaison From 27a340d5010cd5141d5b6a314cf2b5f3aae2aee8 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?S=C3=A9bastien=20Marie?= Date: Tue, 23 May 2017 17:24:51 +0200 Subject: [PATCH 19/56] syntax: operators vs predicates --- text/0000-target-extension.md | 35 ++++++++++++++++++++++++++++++++--- 1 file changed, 32 insertions(+), 3 deletions(-) diff --git a/text/0000-target-extension.md b/text/0000-target-extension.md index 54c768d1e00..f93f2977bf3 100644 --- a/text/0000-target-extension.md +++ b/text/0000-target-extension.md @@ -191,8 +191,6 @@ version). The addition of new operators in attribute is a syntax extension. - - - operators to compare versions in attribute - behaviour - numeric comparaison @@ -203,11 +201,39 @@ The addition of new operators in attribute is a syntax extension. - "2.0" < "2.0" : false - "10.0" < "10.0.1" : true - See `libsyntax/attr.rs`, `libsyntax/config.rs`, `libsyntax/parse/parser.rs` (unsure about these files for now). + +Alternatively, using new predicates instead of modifying deeply the syntax. +Semantics would be the same has operators (numeric comparaison, dealing with +any number of "." inside the symbol). + +```rust +pub struct siginfo_t { + pub si_signo: ::c_int, + pub si_code: ::c_int, + pub si_errno: ::c_int, + + // A type correction occured in 6.2. + // Before it was a `char *` and now it is a `void *`. + #[cfg(gt(target_os_version, "6.2"))] + pub si_addr: *mut ::c_char, + #[cfg(ge("6.2", target_os_version))] + pub si_addr: *mut ::c_void, + + #[cfg(target_pointer_width = "32")] + __pad: [u8; 112], + #[cfg(target_pointer_width = "64")] + __pad: [u8; 108], +} +``` + +See `libsyntax/attr.rs`. + + + ## Backend level - additional members in `Target` @@ -299,3 +325,6 @@ What parts of the design are still TBD? requires to explicitly list all affected OS/env version on changes. Doable if the list of supported OS/env version is controlled in some way. +- additional operators for attribute diverges a lot from current syntax + - currently only `#[cfg(name)]` or `#[cfg(name=value)]` + `any()`, `all()` and `not()` + - does adding predicates like `gt(n1,n2,...)` and `ge(n1,n2,...)` would be more straightful ? From b581eb49e24566aaadae22ad0ffa3f407e8cbed0 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?S=C3=A9bastien=20Marie?= Date: Tue, 23 May 2017 17:27:03 +0200 Subject: [PATCH 20/56] proper header with true space --- text/0000-target-extension.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/text/0000-target-extension.md b/text/0000-target-extension.md index f93f2977bf3..252e72d0339 100644 --- a/text/0000-target-extension.md +++ b/text/0000-target-extension.md @@ -124,7 +124,7 @@ This should get into specifics and corner-cases, and include examples of how the **INCOMPLETE PART: only ideas are presented here for now** -## Language level: what the user will see ? +## Language level: what the user will see ? At language level, new attributes for conditional compilation would be added: @@ -187,7 +187,7 @@ be a breaking changes in `libc` (and we would lost OpenBSD 6.1 supported version). -## Syntax level +## Syntax level The addition of new operators in attribute is a syntax extension. From 86e3d1378bf20bca383984dd4ddbe6d7016559c8 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?S=C3=A9bastien=20Marie?= Date: Tue, 23 May 2017 17:30:48 +0200 Subject: [PATCH 21/56] use of template for target argument (cli) ? --- text/0000-target-extension.md | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/text/0000-target-extension.md b/text/0000-target-extension.md index 252e72d0339..8e574f8652b 100644 --- a/text/0000-target-extension.md +++ b/text/0000-target-extension.md @@ -241,6 +241,10 @@ See `libsyntax/attr.rs`. - `target_env_version: String` (could be empty: "") - drawbacks: it requires a new target per OS version + - **XXX** does it possible to autodetect ? + - some targets tagged as "template" + - if the provided `target` name match the template, complete it + - add a flexible code to easily create new target (with just `target_os_version` changing) From 2dd80ee4d3713012e288cb92f938271546d1eca0 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?S=C3=A9bastien=20Marie?= Date: Tue, 23 May 2017 17:31:39 +0200 Subject: [PATCH 22/56] add XXX --- text/0000-target-extension.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/text/0000-target-extension.md b/text/0000-target-extension.md index 8e574f8652b..b251012ec95 100644 --- a/text/0000-target-extension.md +++ b/text/0000-target-extension.md @@ -189,7 +189,7 @@ version). ## Syntax level -The addition of new operators in attribute is a syntax extension. +The addition of new operators in attribute is a syntax extension (**XXX** maybe too invasive). - operators to compare versions in attribute - behaviour @@ -206,7 +206,7 @@ See `libsyntax/attr.rs`, `libsyntax/config.rs`, `libsyntax/parse/parser.rs` -Alternatively, using new predicates instead of modifying deeply the syntax. +**XXX** Alternatively, using new predicates instead of modifying deeply the syntax. Semantics would be the same has operators (numeric comparaison, dealing with any number of "." inside the symbol). From db2994edf38bf27bf6fd0b5cae462be41158fb68 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?S=C3=A9bastien=20Marie?= Date: Tue, 23 May 2017 17:34:01 +0200 Subject: [PATCH 23/56] syntax: operators vs predicates --- text/0000-target-extension.md | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/text/0000-target-extension.md b/text/0000-target-extension.md index b251012ec95..5fc489d2d19 100644 --- a/text/0000-target-extension.md +++ b/text/0000-target-extension.md @@ -144,7 +144,7 @@ extern { Additionally, in order to simplify matching for several versions, new operators -to doing comparaison would be added too. +to doing comparaison would be added too (**XXX** operator or predicate ?). ```rust extern { @@ -152,6 +152,9 @@ extern { #[cfg(all(target_os="freebsd", target_os_version < "12"))] pub fn encrypt(block *mut ::c_char, flag ::c_int) -> ::c_int; + + #[cfg(all(target_os="freebsd", gt(target_os_version, "12")))] + pub fn encrypt(block *mut ::c_char, flag ::c_int) -> ::c_int; } ``` From 84577f7c50d19e1e1da1bd9a3b58d403e8c23ba7 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?S=C3=A9bastien=20Marie?= Date: Thu, 25 May 2017 07:00:39 +0200 Subject: [PATCH 24/56] freebsd ino64 branch has been commited. mentioned by @dumbbell --- text/0000-target-extension.md | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/text/0000-target-extension.md b/text/0000-target-extension.md index 5fc489d2d19..beefc5aabb5 100644 --- a/text/0000-target-extension.md +++ b/text/0000-target-extension.md @@ -74,8 +74,10 @@ representative of something that already occurred in the past. See [commit R306555](https://svnweb.freebsd.org/base?view=revision&revision=306555) and [diff of sys/fbio.h](https://svnweb.freebsd.org/base/head/sys/sys/fbio.h?r1=306555&r2=306554&pathrev=306555). -- **FreeBSD ?** wants to switch `ino_t` from 32 bits to 64 bits. - See [Status Update and Call for Testing](https://lists.freebsd.org/pipermail/freebsd-fs/2017-April/024684.html), +- **FreeBSD 12** wants to switch `ino_t` from 32 bits to 64 bits. + See [commit R318736](https://svnweb.freebsd.org/base?view=revision&revision=318736), + [diff on types](https://svnweb.freebsd.org/base/head/sys/sys/_types.h?r1=307756&r2=318736), + the [Status Update and Call for Testing](https://lists.freebsd.org/pipermail/freebsd-fs/2017-April/024684.html), and [diff on lang/rust (ports tree)](https://github.com/FreeBSDFoundation/freebsd/blob/bc50a841851470d98cf1c219b261133536aa7ee8/ports.patch#L402). - **NetBSD 7.99** (upcoming 8) adds a new member `mnt_lower` in the middle of @@ -320,7 +322,7 @@ What other designs have been considered? What is the impact of not doing this? `libc` code (for only small differencies) at each release. - statu quo: while no fundamental breaking changes occurs at OS level, no need - to do anything. Disclosure: FreeBSD switch to ino64 could occurs soon. + to do anything. Note that FreeBSD 12 will be released with such changes. # Unresolved questions From c28d3aef7cba007de7d1b5c4531b87d39d6ae046 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jean-S=C3=A9bastien=20P=C3=A9dron?= Date: Fri, 26 May 2017 23:12:17 +0200 Subject: [PATCH 25/56] text/0000-target-extension.md: Fix some grammar issues --- text/0000-target-extension.md | 44 +++++++++++++++++------------------ 1 file changed, 22 insertions(+), 22 deletions(-) diff --git a/text/0000-target-extension.md b/text/0000-target-extension.md index beefc5aabb5..ae9f81c7946 100644 --- a/text/0000-target-extension.md +++ b/text/0000-target-extension.md @@ -22,10 +22,10 @@ definition: - optional [environment version](https://github.com/llvm-mirror/llvm/blob/343e535d9c38cf57173ace6597380752a18a6a67/include/llvm/ADT/Triple.h#L303) -Rust language is aimed to be used on different operating systems following them -self there own rules. In particular, each operating systems have proper way to +Rust language is aimed to be used on different operating systems following themselves +their own rules. In particular, each operating systems have proper way to deal with breaking changes: if Linux tends to forbid breaking changes by -policy, all others systems doesn't have such rule. As Rust language tend to be +policy, all others systems doesn't have such rule. As Rust language tends to be a stable language, having a stable way to describe breaking changes on the OS would be very valuable and could become necessary as time passes. @@ -39,14 +39,14 @@ like for the following triples: - `x86_64-unknown-netbsd7.99` -As examples, considers the following changes in several operating systems (some +As examples, consider the following changes in several operating systems (some are ABI changes, others API changes) and how a crate like `libc` would have to deal with them. Please note that some are quite old but could be considered as representative of something that already occurred in the past. - **OpenBSD 5.5** does a big breaking changes in order to be compatible with [year 2038](https://www.openbsd.org/faq/upgrade55.html#time_t): it switches - from a signed 32 bit counter to signed 64 bit time type. + from a signed 32 bit counter to a signed 64 bit time type. See [commit message](http://cvsweb.openbsd.org/cgi-bin/cvsweb/src/sys/sys/_types.h?rev=1.6&content-type=text/x-cvsweb-markup) and [diff on types](http://cvsweb.openbsd.org/cgi-bin/cvsweb/src/sys/sys/_types.h.diff?r1=1.5&r2=1.6). @@ -85,7 +85,7 @@ representative of something that already occurred in the past. See [commit message](http://cvsweb.netbsd.org/bsdweb.cgi/src/sys/sys/mount.h?rev=1.221&content-type=text/x-cvsweb-markup) and [diff of sys/mount.h](http://cvsweb.netbsd.org/bsdweb.cgi/src/sys/sys/mount.h.diff?r1=1.220&r2=1.221). -- **NetBSD 7.99** (upcoming 8) changes signature of `scandir()` function to conforms to `IEEE +- **NetBSD 7.99** (upcoming 8) changes signature of `scandir()` function to conform to `IEEE Std 1003.1-2008` (`const void *` to `const struct dirent **`). See [commit message](http://cvsweb.netbsd.org/bsdweb.cgi/src/include/dirent.h?rev=1.36&content-type=text/x-cvsweb-markup&sortby=date) and [diff to dirent.h](http://cvsweb.netbsd.org/bsdweb.cgi/src/include/dirent.h.diff?r1=1.35&r2=1.36&sortby=date). @@ -97,8 +97,8 @@ representative of something that already occurred in the past. In the current situation, `libc` crate has no way to deal in a stable way with these changes. It could only support two incompatible OS version together by -only defining the common subset. Depending the breaking part, it could result -removed feature in rustc (removing `si_addr` for OpenBSD would break stack +only defining the common subset. Depending on the breaking part, it could result +in removed feature in rustc (removing `si_addr` for OpenBSD would break stack overflow detection), or even breaking rustc itself (removing `ino_t` for FreeBSD). @@ -109,7 +109,7 @@ version of `libc` itself) which is undesirable for this purpose. The purpose of extending Rust `Target` type to follow LLVM Triple definition is to be able to deal with such changes at Rust language level. As the target will -be able to make distinction between particular OS or environment version, it +be able to distinguish between particular OS or environment versions, it would be possible to export the information in the same way we export `target_os`, `target_arch`, `target_endian` or `target_pointer_width`. @@ -146,7 +146,7 @@ extern { Additionally, in order to simplify matching for several versions, new operators -to doing comparaison would be added too (**XXX** operator or predicate ?). +to doing comparison would be added too (**XXX** operator or predicate?). ```rust extern { @@ -188,7 +188,7 @@ It would be possible to target `x86_amd64-unknown-openbsd6.1` **and** `x86_amd64-unknown-openbsd6.2` whereas with [current libc code](https://github.com/rust-lang/libc/blob/6ddc76a27e0678c04ec7337591f8a0e36c065664/src/unix/bsd/netbsdlike/openbsdlike/mod.rs#L106) only one version is possible, and switching from one to the other version would -be a breaking changes in `libc` (and we would lost OpenBSD 6.1 supported +be a breaking change in `libc` (and we would lose OpenBSD 6.1 supported version). @@ -198,7 +198,7 @@ The addition of new operators in attribute is a syntax extension (**XXX** maybe - operators to compare versions in attribute - behaviour - - numeric comparaison + - numeric comparison - "2" < "10" : true - able to deal with any number of "." inside the symbol: - "2" < "2.0" : true @@ -212,7 +212,7 @@ See `libsyntax/attr.rs`, `libsyntax/config.rs`, `libsyntax/parse/parser.rs` **XXX** Alternatively, using new predicates instead of modifying deeply the syntax. -Semantics would be the same has operators (numeric comparaison, dealing with +Semantics would be the same as operators (numeric comparison, dealing with any number of "." inside the symbol). ```rust @@ -246,7 +246,7 @@ See `libsyntax/attr.rs`. - `target_env_version: String` (could be empty: "") - drawbacks: it requires a new target per OS version - - **XXX** does it possible to autodetect ? + - **XXX** is it possible to autodetect ? - some targets tagged as "template" - if the provided `target` name match the template, complete it @@ -284,14 +284,14 @@ How should this feature be introduced and taught to existing Rust users? Modifying the `Target` struct is a low-level change by itself. -From a developer perspective, it adds a new attributes for conditional +From a developer perspective, it adds a new attribute for conditional compilation. -For projects using Rust (mozilla in mind), it changes the `--target` argument -for several existing targets in a breaking way: some targets will disappears +For projects using Rust (Mozilla in mind), it changes the `--target` argument +for several existing targets in a breaking way: some targets will disappear (`x86_64-unknown-openbsd`) in favor of others targets (`x86_64-unknown-openbsd6.0` and `x86_64-unknown-openbsd6.1` at time of -writing). But it reflects better the reality: OpenBSD 6.0 is different than +writing). But it reflects better the reality: OpenBSD 6.0 is different from OpenBSD 6.1. @@ -319,9 +319,9 @@ Why should we *not* do this? What other designs have been considered? What is the impact of not doing this? - using `target_os` with the version inside. it would require to duplicate all - `libc` code (for only small differencies) at each release. + `libc` code (for only small differences) at each release. -- statu quo: while no fundamental breaking changes occurs at OS level, no need +- status quo: while no fundamental breaking changes occur at OS level, no need to do anything. Note that FreeBSD 12 will be released with such changes. @@ -334,6 +334,6 @@ What parts of the design are still TBD? requires to explicitly list all affected OS/env version on changes. Doable if the list of supported OS/env version is controlled in some way. -- additional operators for attribute diverges a lot from current syntax +- additional operators for attribute diverge a lot from current syntax - currently only `#[cfg(name)]` or `#[cfg(name=value)]` + `any()`, `all()` and `not()` - - does adding predicates like `gt(n1,n2,...)` and `ge(n1,n2,...)` would be more straightful ? + - would adding predicates like `gt(n1,n2,...)` and `ge(n1,n2,...)` be more straightforward? From e39e9e7cf5a8ef566f20c458c68cd71fca871c77 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?S=C3=A9bastien=20Marie?= Date: Sat, 27 May 2017 15:25:06 +0200 Subject: [PATCH 26/56] use predicates instead of operators --- text/0000-target-extension.md | 76 ++++++++++++++--------------------- 1 file changed, 31 insertions(+), 45 deletions(-) diff --git a/text/0000-target-extension.md b/text/0000-target-extension.md index beefc5aabb5..fefe8e92e0e 100644 --- a/text/0000-target-extension.md +++ b/text/0000-target-extension.md @@ -145,17 +145,14 @@ extern { ``` -Additionally, in order to simplify matching for several versions, new operators -to doing comparaison would be added too (**XXX** operator or predicate ?). +Additionally, in order to simplify matching for several versions, new predicates +to doing version comparaison would be added too. ```rust extern { // encrypt() function doesn't exist anymore starting with freebsd12 - #[cfg(all(target_os="freebsd", target_os_version < "12"))] - pub fn encrypt(block *mut ::c_char, flag ::c_int) -> ::c_int; - - #[cfg(all(target_os="freebsd", gt(target_os_version, "12")))] + #[cfg(all(target_os="freebsd", version_lt(target_os_version, "12")))] pub fn encrypt(block *mut ::c_char, flag ::c_int) -> ::c_int; } ``` @@ -172,9 +169,9 @@ pub struct siginfo_t { // A type correction occured in 6.2. // Before it was a `char *` and now it is a `void *`. - #[cfg(target_os_version < "6.2")] + #[cfg(version_lt(target_os_version, "6.2"))] pub si_addr: *mut ::c_char, - #[cfg(target_os_version >= "6.2")] + #[cfg(version_ge(target_os_version, "6.2"))] pub si_addr: *mut ::c_void, #[cfg(target_pointer_width = "32")] @@ -194,46 +191,39 @@ version). ## Syntax level -The addition of new operators in attribute is a syntax extension (**XXX** maybe too invasive). +The addition of new predicates in attribute is a syntax extension. -- operators to compare versions in attribute -- behaviour - - numeric comparaison - - "2" < "10" : true - - able to deal with any number of "." inside the symbol: - - "2" < "2.0" : true - - "3" < "2.0" : false - - "2.0" < "2.0" : false - - "10.0" < "10.0.1" : true +It permits to easily make a piece of code available to a range version. -See `libsyntax/attr.rs`, `libsyntax/config.rs`, `libsyntax/parse/parser.rs` -(unsure about these files for now). +Predicates would be: +- `version_eq()` : equal +- `version_lt()` : less-than +- `version_le()` : less-or-equal +- `version_gt()` : greater-than +- `version_ge()` : greater-or-equal +The choice of an explicit name is to unhidden that the comparaison is done on +strings with a specific format (`major.minor.micro`). -**XXX** Alternatively, using new predicates instead of modifying deeply the syntax. -Semantics would be the same has operators (numeric comparaison, dealing with -any number of "." inside the symbol). +Having a predicate instead of an operator (`version_lt()` vs `<`) avoid a too +intrusive syntax's modification too. -```rust -pub struct siginfo_t { - pub si_signo: ::c_int, - pub si_code: ::c_int, - pub si_errno: ::c_int, - // A type correction occured in 6.2. - // Before it was a `char *` and now it is a `void *`. - #[cfg(gt(target_os_version, "6.2"))] - pub si_addr: *mut ::c_char, - #[cfg(ge("6.2", target_os_version))] - pub si_addr: *mut ::c_void, +- behaviour + - numeric comparaison + - `version_lt("2", "10")` : true - #[cfg(target_pointer_width = "32")] - __pad: [u8; 112], - #[cfg(target_pointer_width = "64")] - __pad: [u8; 108], -} -``` + - able to deal with any number of "." inside the symbol: + - `version_lt("3", "2.0")` : false + - `version_lt("2.0", "2.0")` : false + - `version_lt("10.0", "10.0.1")` : true + + - LLVM assumes "2" to be equivalent to "2.0.0" + - `version_eq("2", "2.0")` : true + + - allow more than 2 arguments in the predicate + - `version_le("3", "4", "5")` : true See `libsyntax/attr.rs`. @@ -330,10 +320,6 @@ What other designs have been considered? What is the impact of not doing this? What parts of the design are still TBD? -- partial implementation with no additional operator at syntax level. It +- partial implementation with no additional predicate at syntax level. It requires to explicitly list all affected OS/env version on changes. Doable if the list of supported OS/env version is controlled in some way. - -- additional operators for attribute diverges a lot from current syntax - - currently only `#[cfg(name)]` or `#[cfg(name=value)]` + `any()`, `all()` and `not()` - - does adding predicates like `gt(n1,n2,...)` and `ge(n1,n2,...)` would be more straightful ? From 2d83358d2f51524fe381beff762c4aa4c2342751 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?S=C3=A9bastien=20Marie?= Date: Sun, 28 May 2017 14:19:09 +0200 Subject: [PATCH 27/56] rephrasing --- text/0000-target-extension.md | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/text/0000-target-extension.md b/text/0000-target-extension.md index fefe8e92e0e..b875b70da66 100644 --- a/text/0000-target-extension.md +++ b/text/0000-target-extension.md @@ -145,8 +145,9 @@ extern { ``` -Additionally, in order to simplify matching for several versions, new predicates -to doing version comparaison would be added too. +Additionally, in order to simplify conditional compilation when changes are +accross several versions, new predicates would be added too in order to do +version comparaison. ```rust extern { From 263a8753835f8e0b3c49a849ecb5dfe9b99efb60 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?S=C3=A9bastien=20Marie?= Date: Sun, 28 May 2017 14:20:21 +0200 Subject: [PATCH 28/56] move session part upper --- text/0000-target-extension.md | 13 ++++++++----- 1 file changed, 8 insertions(+), 5 deletions(-) diff --git a/text/0000-target-extension.md b/text/0000-target-extension.md index b875b70da66..b2c0d3246e2 100644 --- a/text/0000-target-extension.md +++ b/text/0000-target-extension.md @@ -230,6 +230,14 @@ See `libsyntax/attr.rs`. +## Session level + +- populate and export the new attributes in the default build configuration + +See `librustc/session/config.rs`. + + + ## Backend level - additional members in `Target` @@ -247,11 +255,6 @@ See `libsyntax/attr.rs`. See `librustc_back/target/`. -## Session level - -- populate and export the new attributes in the default build configuration - -See `librustc/session/config.rs`. ## Workflow with new OS release From a052b3f60581da4ced133d867ec85273bc9796d3 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?S=C3=A9bastien=20Marie?= Date: Sat, 17 Jun 2017 07:10:08 +0200 Subject: [PATCH 29/56] syntax level: make examples for behavior --- text/0000-target-extension.md | 25 ++++++++++++++----------- 1 file changed, 14 insertions(+), 11 deletions(-) diff --git a/text/0000-target-extension.md b/text/0000-target-extension.md index 48bd1c493fd..625a0098d55 100644 --- a/text/0000-target-extension.md +++ b/text/0000-target-extension.md @@ -210,20 +210,23 @@ strings with a specific format (`major.minor.micro`). Having a predicate instead of an operator (`version_lt()` vs `<`) avoid a too intrusive syntax's modification too. +```rust +#[cfg(version_lt("2", "10"))] +println!("numeric comparaison: 2 < 10"); -- behaviour - - numeric comparison - - `version_lt("2", "10")` : true - - able to deal with any number of "." inside the symbol: - - `version_lt("3", "2.0")` : false - - `version_lt("2.0", "2.0")` : false - - `version_lt("10.0", "10.0.1")` : true +#[cfg(version_lt("3", "2.0")] +println!("able to deal with any number of '.': 3 < 2.0 (false)"); +#[cfg(version_lt("2.0", "2.0")] +println!("able to deal with any number of '.': 2.0 < 2.0 (false)"); +#[cfg(version_lt("10.0", "10.0.1")] +println!("able to deal with any number of '.':10.0 < 10.0.1"); - - LLVM assumes "2" to be equivalent to "2.0.0" - - `version_eq("2", "2.0")` : true +#[cfg(version_eq("2", "2.0")] +println!("LLVM assumes \"2\" to be equivalent to \"2.0.0\"); - - allow more than 2 arguments in the predicate - - `version_le("3", "4", "5")` : true +#[cfg(version_le("3", "4", "5")] +println!("allow more than 2 arguments in the predicate: 3 <= 4 <= 5"); +``` See `libsyntax/attr.rs`. From 3cebfe2cedc2ead6fefdab03f78dad805b1a344c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?S=C3=A9bastien=20Marie?= Date: Sat, 17 Jun 2017 07:20:11 +0200 Subject: [PATCH 30/56] move "session level" after "backend level" --- text/0000-target-extension.md | 27 +++++++++++++-------------- 1 file changed, 13 insertions(+), 14 deletions(-) diff --git a/text/0000-target-extension.md b/text/0000-target-extension.md index 625a0098d55..c9e68737562 100644 --- a/text/0000-target-extension.md +++ b/text/0000-target-extension.md @@ -120,11 +120,6 @@ specifically for the targeted version. # Detailed design [design]: #detailed-design -This is the bulk of the RFC. Explain the design in enough detail for somebody familiar -with the language to understand, and for somebody familiar with the compiler to implement. -This should get into specifics and corner-cases, and include examples of how the feature is used. - -**INCOMPLETE PART: only ideas are presented here for now** ## Language level: what the user will see ? @@ -194,7 +189,8 @@ version). The addition of new predicates in attribute is a syntax extension. -It permits to easily make a piece of code available to a range version. +It permits to easily make a piece of code available to a range version. It is a +facility to manipulate the new attributes defined at language level. Predicates would be: @@ -231,13 +227,6 @@ println!("allow more than 2 arguments in the predicate: 3 <= 4 <= 5"); See `libsyntax/attr.rs`. -## Session level - -- populate and export the new attributes in the default build configuration - -See `librustc/session/config.rs`. - - ## Backend level @@ -258,7 +247,7 @@ See `librustc_back/target/`. -## Workflow with new OS release +### Workflow with new OS release - when a new OS release occurs - adds to `libc` any changes (using `target_os_version` if required) @@ -267,6 +256,16 @@ See `librustc_back/target/`. +## Session level + +At the session level, rustc should populate and export the new attributes +(values taken from targeted backend) in the default build configuration. + + +See `librustc/session/config.rs`. + + + # How We Teach This [how-we-teach-this]: #how-we-teach-this From 8efe83e89fe676b1e9f3c1a09ac00f5a2b774a3c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?S=C3=A9bastien=20Marie?= Date: Sat, 17 Jun 2017 07:23:45 +0200 Subject: [PATCH 31/56] How We Teach This: place TODO and cleanup --- text/0000-target-extension.md | 10 ++++------ 1 file changed, 4 insertions(+), 6 deletions(-) diff --git a/text/0000-target-extension.md b/text/0000-target-extension.md index c9e68737562..e3d8040f19b 100644 --- a/text/0000-target-extension.md +++ b/text/0000-target-extension.md @@ -230,6 +230,8 @@ See `libsyntax/attr.rs`. ## Backend level +**TODO** + - additional members in `Target` - `target_os_version: String` (could be empty: "") - `target_env_version: String` (could be empty: "") @@ -269,12 +271,7 @@ See `librustc/session/config.rs`. # How We Teach This [how-we-teach-this]: #how-we-teach-this -What names and terminology work best for these concepts and why? -How is this idea best presented—as a continuation of existing Rust patterns, or as a wholly new one? - -Would the acceptance of this proposal change how Rust is taught to new users at any level? -How should this feature be introduced and taught to existing Rust users? - +**TODO** Modifying the `Target` struct is a low-level change by itself. @@ -292,6 +289,7 @@ OpenBSD 6.1. What additions or changes to the Rust Reference, _The Rust Programming Language_, and/or _Rust by Example_ does it entail? - _Rust Reference_: mentioning new attributes in conditional compilation attribute section. +- **TODO** # Drawbacks From d833447f6e5a7db40844c7b4cd73b2f0fe9e72b8 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?S=C3=A9bastien=20Marie?= Date: Sat, 17 Jun 2017 07:24:59 +0200 Subject: [PATCH 32/56] drawbacks: explain why deprecating --- text/0000-target-extension.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/text/0000-target-extension.md b/text/0000-target-extension.md index e3d8040f19b..b47e6628908 100644 --- a/text/0000-target-extension.md +++ b/text/0000-target-extension.md @@ -302,7 +302,7 @@ Why should we *not* do this? - not all targets will be testable (requires a particular OS version for running testsuite) - will require to deprecate unsupported OS version (for example OpenBSD - officially support only the 2 last releases) + officially support only the 2 last releases) to limit the number of targets # Alternatives From 11b46b7bcc1a4ebe7c49a3723efd32fe972905a3 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?S=C3=A9bastien=20Marie?= Date: Sat, 17 Jun 2017 07:26:18 +0200 Subject: [PATCH 33/56] mention rust issue for FreeBSD12 breaking changes --- text/0000-target-extension.md | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/text/0000-target-extension.md b/text/0000-target-extension.md index b47e6628908..510b3f25e3c 100644 --- a/text/0000-target-extension.md +++ b/text/0000-target-extension.md @@ -314,7 +314,8 @@ What other designs have been considered? What is the impact of not doing this? `libc` code (for only small differences) at each release. - status quo: while no fundamental breaking changes occur at OS level, no need - to do anything. Note that FreeBSD 12 will be released with such changes. + to do anything. Note that FreeBSD 12 will be released with such changes (see + [issue #42681](https://github.com/rust-lang/rust/issues/42681)). # Unresolved questions From 94f08aac14f15eb8359fa7d9eda822af402b2c1d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?S=C3=A9bastien=20Marie?= Date: Mon, 26 Jun 2017 09:07:56 +0200 Subject: [PATCH 34/56] backend level --- text/0000-target-extension.md | 67 ++++++++++++++++++++++++++--------- 1 file changed, 51 insertions(+), 16 deletions(-) diff --git a/text/0000-target-extension.md b/text/0000-target-extension.md index 510b3f25e3c..94907c7932c 100644 --- a/text/0000-target-extension.md +++ b/text/0000-target-extension.md @@ -230,32 +230,67 @@ See `libsyntax/attr.rs`. ## Backend level -**TODO** +### Target structure -- additional members in `Target` - - `target_os_version: String` (could be empty: "") - - `target_env_version: String` (could be empty: "") +At the backend level, the `Target` structure gains two new members: -- drawbacks: it requires a new target per OS version - - **XXX** is it possible to autodetect ? - - some targets tagged as "template" - - if the provided `target` name match the template, complete it +- `target_os_version: String` +- `target_env_version: String` -- add a flexible code to easily create new target (with just - `target_os_version` changing) +to represent the (possibly empty) versions of the OS and environment. -See `librustc_back/target/`. +### Implication on targets number + +It should be noted it will implied a new target per OS version (for each +architecture), as soon as a breaking change occurs (new target required), or on +each major release (as it could be more simple for the end user to know which +target to use). + +As example, FreeBSD has currently 3 targets (one per supported architecture: +`x86_64`, `i686` and `aarch64`). If we want to be able to express targets for 3 +releases (two currently supported and one upcoming), the number of target will +grow to 9 targets. + + +### Version tracking per OS + +The exact way to tracking the OS version (creating a new target) should be done +per OS, because OS has different expectations regarding breaking changes +between versions. +As example, FreeBSD keep ABI/API accross minor versions, and a breaking change +should only occur at major version (but not necessary). +So, the targets should be (for `x86_64` architecture): +- `x86_64-unknown-freebsd10` (currently supported) +- `x86_64-unknown-freebsd11` (currently supported) +- `x86_64-unknown-freebsd12` (in development) -### Workflow with new OS release +At the opposite, OpenBSD only release major versions (even if expressed with +two digits versions), and a breaking change could occur at each version: +- `x86_64-unknown-openbsd6.0` (currently supported) +- `x86_64-unknown-openbsd6.1` (currently supported) +- `x86_64-unknown-openbsd6.2` (in development) -- when a new OS release occurs - - adds to `libc` any changes (using `target_os_version` if required) - - adds a new target specification - - remove target of any unsupported OS version +### Default OS version for a target + +It could be noted that the current unversioned target (like +`x86_64-unknown-openbsd`) could be still used as an alias of some versioned +target. + +If so, the semantic have to be defined (tracking the oldest or most recent +supported version). + +Keeping the unversioned target would avoid a breaking change in command-line. +But the change could be useful too as it permits to downstream to be aware that +targeting particular OS version (FreeBSD 11 for example) could result unusable +binary for others OS versions (FreeBSD 12). + + + +See `librustc_back/target/`. ## Session level From 5cd0f4487d17dc9ee04a6e1a41a5e111a766d7ca Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?S=C3=A9bastien=20Marie?= Date: Mon, 26 Jun 2017 09:13:55 +0200 Subject: [PATCH 35/56] backend level: typo & rephrasing --- text/0000-target-extension.md | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/text/0000-target-extension.md b/text/0000-target-extension.md index 94907c7932c..d524a23cab8 100644 --- a/text/0000-target-extension.md +++ b/text/0000-target-extension.md @@ -249,15 +249,15 @@ target to use). As example, FreeBSD has currently 3 targets (one per supported architecture: `x86_64`, `i686` and `aarch64`). If we want to be able to express targets for 3 -releases (two currently supported and one upcoming), the number of target will +releases (two currently supported and one upcoming), the number of targets will grow to 9 targets. ### Version tracking per OS The exact way to tracking the OS version (creating a new target) should be done -per OS, because OS has different expectations regarding breaking changes -between versions. +per OS, because OS has different expectations regarding when a breaking change +could occur accross versions. As example, FreeBSD keep ABI/API accross minor versions, and a breaking change should only occur at major version (but not necessary). From 41d891b9dae5b9cdac6cab0b33b60ec3594e4dd6 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?S=C3=A9bastien=20Marie?= Date: Mon, 26 Jun 2017 09:39:41 +0200 Subject: [PATCH 36/56] drawbacks / alternatives --- text/0000-target-extension.md | 37 +++++++++++++++++++++-------------- 1 file changed, 22 insertions(+), 15 deletions(-) diff --git a/text/0000-target-extension.md b/text/0000-target-extension.md index d524a23cab8..401378e21fa 100644 --- a/text/0000-target-extension.md +++ b/text/0000-target-extension.md @@ -268,7 +268,7 @@ So, the targets should be (for `x86_64` architecture): - `x86_64-unknown-freebsd12` (in development) At the opposite, OpenBSD only release major versions (even if expressed with -two digits versions), and a breaking change could occur at each version: +two digits version), and a breaking change could occur at each version: - `x86_64-unknown-openbsd6.0` (currently supported) - `x86_64-unknown-openbsd6.1` (currently supported) - `x86_64-unknown-openbsd6.2` (in development) @@ -313,7 +313,7 @@ Modifying the `Target` struct is a low-level change by itself. From a developer perspective, it adds a new attribute for conditional compilation. -For projects using Rust (Mozilla in mind), it changes the `--target` argument +For projects using Rust (Firefox in mind), it changes the `--target` argument for several existing targets in a breaking way: some targets will disappear (`x86_64-unknown-openbsd`) in favor of others targets (`x86_64-unknown-openbsd6.0` and `x86_64-unknown-openbsd6.1` at time of @@ -330,27 +330,34 @@ What additions or changes to the Rust Reference, _The Rust Programming Language_ # Drawbacks [drawbacks]: #drawbacks -Why should we *not* do this? +At language level, it adds additional complexity for defining new predicates +for manipulating version numbers. -- additional complexity in attributes for conditional compilation -- number of targets will grow a lot - - not all targets will be testable (requires a particular OS version for - running testsuite) - - will require to deprecate unsupported OS version (for example OpenBSD - officially support only the 2 last releases) to limit the number of targets +At backend level, the number of targets will grow a lot. It means that not all +targets will be testable (too much required ressources and it would require a +particular OS version for testing too). + +It will require to regulary deprecate old targets (for unsupported OS version) +in order to not keep too much old stuff. The end-user has still the possibility +to use flexible target using external JSON file for these targets, if the +corresponding code for this particular version is still in `libc` crate. # Alternatives [alternatives]: #alternatives -What other designs have been considered? What is the impact of not doing this? +The more simple approch is to use `target_os` with the OS version inside +(`freebsd12`). But it would require to duplicate all `libc` code (for only +small differences) at each release. Having a separated attribute is more simple. -- using `target_os` with the version inside. it would require to duplicate all - `libc` code (for only small differences) at each release. +Having only parts of the current RFC is also possible: new predicates at +language level are only a way simplify code expression. -- status quo: while no fundamental breaking changes occur at OS level, no need - to do anything. Note that FreeBSD 12 will be released with such changes (see - [issue #42681](https://github.com/rust-lang/rust/issues/42681)). +But without some way to express breaking changes existence at OS level, Rust is +unable to targeting simultaneous several OS version. Regarding +[issue #42681](https://github.com/rust-lang/rust/issues/42681) for FreeBSD 12, +it means Rust should either deprecating older FreeBSD versions support (whereas +FreeBSD itself still support them) or not supporting FreeBSD 12. # Unresolved questions From fb78f3d0f73519d9a475aaa570ab85d87b00461c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?S=C3=A9bastien=20Marie?= Date: Mon, 26 Jun 2017 09:42:04 +0200 Subject: [PATCH 37/56] predicates are at syntax level --- text/0000-target-extension.md | 14 ++++++++------ 1 file changed, 8 insertions(+), 6 deletions(-) diff --git a/text/0000-target-extension.md b/text/0000-target-extension.md index 401378e21fa..aab51e0d586 100644 --- a/text/0000-target-extension.md +++ b/text/0000-target-extension.md @@ -330,7 +330,7 @@ What additions or changes to the Rust Reference, _The Rust Programming Language_ # Drawbacks [drawbacks]: #drawbacks -At language level, it adds additional complexity for defining new predicates +At syntax level, it adds additional complexity for defining new predicates for manipulating version numbers. At backend level, the number of targets will grow a lot. It means that not all @@ -350,8 +350,10 @@ The more simple approch is to use `target_os` with the OS version inside (`freebsd12`). But it would require to duplicate all `libc` code (for only small differences) at each release. Having a separated attribute is more simple. -Having only parts of the current RFC is also possible: new predicates at -language level are only a way simplify code expression. +Having only parts of the current RFC is also possible: new predicates at syntax +level are only a way simplify code expression. It would requires to explicitly +list all affected OS/env version on changes. It is doable if the list of +supported/OS/env versions is controlled in some way. But without some way to express breaking changes existence at OS level, Rust is unable to targeting simultaneous several OS version. Regarding @@ -363,8 +365,8 @@ FreeBSD itself still support them) or not supporting FreeBSD 12. # Unresolved questions [unresolved]: #unresolved-questions +**TODO** + What parts of the design are still TBD? -- partial implementation with no additional predicate at syntax level. It - requires to explicitly list all affected OS/env version on changes. Doable if - the list of supported OS/env version is controlled in some way. +- unversioned target for CLI From e358690df6b7886ecbfb505ee8b216a29aff349f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?S=C3=A9bastien=20Marie?= Date: Mon, 26 Jun 2017 09:53:39 +0200 Subject: [PATCH 38/56] unresolved --- text/0000-target-extension.md | 18 ++++++++---------- 1 file changed, 8 insertions(+), 10 deletions(-) diff --git a/text/0000-target-extension.md b/text/0000-target-extension.md index aab51e0d586..c4d38ef1518 100644 --- a/text/0000-target-extension.md +++ b/text/0000-target-extension.md @@ -239,6 +239,7 @@ At the backend level, the `Target` structure gains two new members: to represent the (possibly empty) versions of the OS and environment. +See `librustc_back/target/`. ### Implication on targets number @@ -283,14 +284,14 @@ target. If so, the semantic have to be defined (tracking the oldest or most recent supported version). +It could be convenient thing for compiler users, but any serious work should +rely on versioned OS target (as compiling for one target version could mean +unusable binary on other OS version). + Keeping the unversioned target would avoid a breaking change in command-line. But the change could be useful too as it permits to downstream to be aware that -targeting particular OS version (FreeBSD 11 for example) could result unusable -binary for others OS versions (FreeBSD 12). - - +targeting particular OS doesn't mean the binary will work on other version. -See `librustc_back/target/`. ## Session level @@ -365,8 +366,5 @@ FreeBSD itself still support them) or not supporting FreeBSD 12. # Unresolved questions [unresolved]: #unresolved-questions -**TODO** - -What parts of the design are still TBD? - -- unversioned target for CLI +As unresolved-question, the question about the unversioned target on +command-line is open. Does it makes sens to have it or not ? From 768be76d7bded9b12eaf709945c46fa950d6809c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?S=C3=A9bastien=20Marie?= Date: Mon, 26 Jun 2017 10:19:10 +0200 Subject: [PATCH 39/56] how-we-teach-this --- text/0000-target-extension.md | 26 +++++++++++++------------- 1 file changed, 13 insertions(+), 13 deletions(-) diff --git a/text/0000-target-extension.md b/text/0000-target-extension.md index c4d38ef1518..2332f13396c 100644 --- a/text/0000-target-extension.md +++ b/text/0000-target-extension.md @@ -307,25 +307,25 @@ See `librustc/session/config.rs`. # How We Teach This [how-we-teach-this]: #how-we-teach-this -**TODO** +If modifying the `Target` struct is a low-level change by itself, the current +RFC proposes it in order to change an implicit paradigm in targets (the +targeting OS will be stable accross version, which is false). -Modifying the `Target` struct is a low-level change by itself. +With the RFC, Rust become able to express this lack of stability on the OS, in +a stable way. In a sens, it extents the ability of Rust to targets several OS +by refining to targets several OS version. -From a developer perspective, it adds a new attribute for conditional -compilation. - -For projects using Rust (Firefox in mind), it changes the `--target` argument -for several existing targets in a breaking way: some targets will disappear -(`x86_64-unknown-openbsd`) in favor of others targets -(`x86_64-unknown-openbsd6.0` and `x86_64-unknown-openbsd6.1` at time of -writing). But it reflects better the reality: OpenBSD 6.0 is different from -OpenBSD 6.1. +From downstream perspective, it permits to use Rust to target several OS +versions whereas the versions are incompatibles. +From Rust developer perspective, it adds a new attributes for conditional +compilation. -What additions or changes to the Rust Reference, _The Rust Programming Language_, and/or _Rust by Example_ does it entail? +Regarding documentation, additions have to be done on: - _Rust Reference_: mentioning new attributes in conditional compilation attribute section. -- **TODO** +- **TODO**: mentioning new predicates +- **TODO**: mentioning targets (by OS version) # Drawbacks From 0cda58a326bbd0f945f077990f0f99c45417d899 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?S=C3=A9bastien=20Marie?= Date: Mon, 26 Jun 2017 10:44:57 +0200 Subject: [PATCH 40/56] documentation, rustup, rustc --- text/0000-target-extension.md | 17 ++++++++++++----- 1 file changed, 12 insertions(+), 5 deletions(-) diff --git a/text/0000-target-extension.md b/text/0000-target-extension.md index 2332f13396c..43dfc56bf2b 100644 --- a/text/0000-target-extension.md +++ b/text/0000-target-extension.md @@ -319,13 +319,15 @@ From downstream perspective, it permits to use Rust to target several OS versions whereas the versions are incompatibles. From Rust developer perspective, it adds a new attributes for conditional -compilation. +compilation, and extent the syntax with new predicates in convenient way. -Regarding documentation, additions have to be done on: +Regarding documentation, additions have to be done on _Rust Reference_ in order +to mention new attributes in conditional compilation attribute section, with +related new predicates. -- _Rust Reference_: mentioning new attributes in conditional compilation attribute section. -- **TODO**: mentioning new predicates -- **TODO**: mentioning targets (by OS version) +Visible changes should also occur on main rust-lang.org site on pages about +rustc distribution: rustup will be able to distribute binaries for more +platforms (per OS version), or about platform support. # Drawbacks @@ -343,6 +345,11 @@ in order to not keep too much old stuff. The end-user has still the possibility to use flexible target using external JSON file for these targets, if the corresponding code for this particular version is still in `libc` crate. +Projects using Rust with binary distribution will have to update in order to +cover a more important number of platforms. In particular rustc itself (with +and without rustup). It will mean more ressources to build more targets. But +the resulting binaries will work on all targets. + # Alternatives [alternatives]: #alternatives From a04877432233436e43f113f4084b89778105e3fc Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?S=C3=A9bastien=20Marie?= Date: Mon, 26 Jun 2017 10:55:43 +0200 Subject: [PATCH 41/56] Specifics compilations options --- text/0000-target-extension.md | 14 ++++++++++++++ 1 file changed, 14 insertions(+) diff --git a/text/0000-target-extension.md b/text/0000-target-extension.md index 43dfc56bf2b..f8b78a5a8bd 100644 --- a/text/0000-target-extension.md +++ b/text/0000-target-extension.md @@ -241,6 +241,20 @@ to represent the (possibly empty) versions of the OS and environment. See `librustc_back/target/`. + +### Specifics compilations options + +It could be noted that some platforms could require additionnal compilation +options, like macOS and `-mmacosx-version-min` for specifying the minimal +version (it affects e.g. dynamic library loader). + +No additional changes is required for this support: `TargetOptions` structure +already contains array for such options: `pre_link_args`, `late_link_args` and +`post_link_args`. + +Having a per version target permits to have different options per target. + + ### Implication on targets number It should be noted it will implied a new target per OS version (for each From 54102815ea42290c8bf0e89ac7869f479f9f7e1f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?S=C3=A9bastien=20Marie?= Date: Mon, 26 Jun 2017 11:01:42 +0200 Subject: [PATCH 42/56] complete motivation with elements for windows --- text/0000-target-extension.md | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/text/0000-target-extension.md b/text/0000-target-extension.md index f8b78a5a8bd..6534e8ef620 100644 --- a/text/0000-target-extension.md +++ b/text/0000-target-extension.md @@ -117,6 +117,14 @@ This way, a crate like `libc` could export raw bindings of platform specifically for the targeted version. +It also has been mentioned in +[pre-rfc discussion](https://internals.rust-lang.org/t/pre-rfc-target-extension-dealing-with-breaking-changes-at-os-level/5289/11), +that it could be benefical to some others OS (like Windows) to have versioned +targets too: for the end-user "knowing what version he is targeting means he can +decide what symbols he can link to normally, and what symbols he has to +dynamically load, and what fallbacks he has to implement." + + # Detailed design [design]: #detailed-design From 215f5eecb847c7f100861d27c53147e6129c249f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?S=C3=A9bastien=20Marie?= Date: Tue, 27 Jun 2017 08:39:15 +0200 Subject: [PATCH 43/56] Related previous discussions --- text/0000-target-extension.md | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/text/0000-target-extension.md b/text/0000-target-extension.md index 6534e8ef620..34a308e8a35 100644 --- a/text/0000-target-extension.md +++ b/text/0000-target-extension.md @@ -391,9 +391,19 @@ unable to targeting simultaneous several OS version. Regarding it means Rust should either deprecating older FreeBSD versions support (whereas FreeBSD itself still support them) or not supporting FreeBSD 12. +A possible alternative is to replace `libc` with runtime detection of system +interface. But it isn't suitable for cross-building. + # Unresolved questions [unresolved]: #unresolved-questions As unresolved-question, the question about the unversioned target on command-line is open. Does it makes sens to have it or not ? + + +# Related previous discussions +[discussions]: #previous-discussions + +- [libc#7570: How to deal with breaking changes on platform ?](https://github.com/rust-lang/libc/issues/570) +- [Rust Internals: Pre-RFC: target extension (dealing with breaking changes at OS level)](https://internals.rust-lang.org/t/pre-rfc-target-extension-dealing-with-breaking-changes-at-os-level/5289) From d245235bd5038248861d112e47b1944cce181d87 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?S=C3=A9bastien=20Marie?= Date: Tue, 27 Jun 2017 08:42:24 +0200 Subject: [PATCH 44/56] alternative: rust-bindgen --- text/0000-target-extension.md | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/text/0000-target-extension.md b/text/0000-target-extension.md index 34a308e8a35..7940ec6c9e1 100644 --- a/text/0000-target-extension.md +++ b/text/0000-target-extension.md @@ -391,8 +391,9 @@ unable to targeting simultaneous several OS version. Regarding it means Rust should either deprecating older FreeBSD versions support (whereas FreeBSD itself still support them) or not supporting FreeBSD 12. -A possible alternative is to replace `libc` with runtime detection of system -interface. But it isn't suitable for cross-building. +A possible alternative is to replace `libc` with FFI bindings generation at +compile-time (using [rust-bindgen](https://github.com/servo/rust-bindgen) for +example). But it isn't suitable for cross-building. # Unresolved questions From c2de7b5b0077c7c53f46f169ac385bb4479a3488 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?S=C3=A9bastien=20Marie?= Date: Tue, 27 Jun 2017 12:02:16 +0200 Subject: [PATCH 45/56] update date for submission --- text/0000-target-extension.md | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/text/0000-target-extension.md b/text/0000-target-extension.md index 7940ec6c9e1..3d81c83cf23 100644 --- a/text/0000-target-extension.md +++ b/text/0000-target-extension.md @@ -1,7 +1,7 @@ - Feature Name: `target extension` -- Start Date: 2017-05-21 -- RFC PR: -- Rust Issue: +- Start Date: 2017-06-27 +- RFC PR: (leave this empty) +- Rust Issue: (leave this empty) # Summary [summary]: #summary From 02fb3bff4aee59d147dbd47dff3feac752088ab6 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?S=C3=A9bastien=20Marie?= Date: Tue, 4 Jul 2017 19:41:09 +0200 Subject: [PATCH 46/56] mention MSVC environment version --- text/0000-target-extension.md | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/text/0000-target-extension.md b/text/0000-target-extension.md index 3d81c83cf23..7aa1979b214 100644 --- a/text/0000-target-extension.md +++ b/text/0000-target-extension.md @@ -94,6 +94,15 @@ representative of something that already occurred in the past. See [commit message](http://gitweb.dragonflybsd.org/dragonfly.git/commit/f91a71dd15504ebdb04387d0822771ef145b25f9?f=sys/sys/types.h) and [diff to sys/types.h](http://gitweb.dragonflybsd.org/dragonfly.git/blobdiff/6f1e2b382f6c2ba9b43a1fc106ba998b45499eea..f91a71dd15504ebdb04387d0822771ef145b25f9:/sys/sys/types.h) +- **MSVC 2015** has several breaking changes. + See [Visual C++ change history 2003 - 2015](https://msdn.microsoft.com/en-us/library/bb531344.aspx), + in particular section about *C Runtime* and *STL* breaking changes. + In particular: some functions like [gets](https://msdn.microsoft.com/en-us/library/2029ea5f.aspx) + or [`_cgets`](https://msdn.microsoft.com/en-us/library/3197776x.aspx) have been + removed. In order to conform to C++11, old names for type traits from an earlier + version of the C++ draft standard have been remamed. + This one is an example of environment version. + In the current situation, `libc` crate has no way to deal in a stable way with these changes. It could only support two incompatible OS version together by From c91ac07cefdb93ecf764f0ae65a0cda26774eab7 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?S=C3=A9bastien=20Marie?= Date: Sun, 9 Jul 2017 13:58:30 +0200 Subject: [PATCH 47/56] Runtime detection --- text/0000-target-extension.md | 17 +++++++++++++++++ 1 file changed, 17 insertions(+) diff --git a/text/0000-target-extension.md b/text/0000-target-extension.md index 7aa1979b214..d78db8bb2c1 100644 --- a/text/0000-target-extension.md +++ b/text/0000-target-extension.md @@ -385,6 +385,8 @@ the resulting binaries will work on all targets. # Alternatives [alternatives]: #alternatives +## Simply appending the version in the target name + The more simple approch is to use `target_os` with the OS version inside (`freebsd12`). But it would require to duplicate all `libc` code (for only small differences) at each release. Having a separated attribute is more simple. @@ -400,6 +402,21 @@ unable to targeting simultaneous several OS version. Regarding it means Rust should either deprecating older FreeBSD versions support (whereas FreeBSD itself still support them) or not supporting FreeBSD 12. +## Runtime detection + +Runtime detection is already in use for [Android](https://github.com/rust-lang/rust/blob/13157c4ebcca735a0842bd03c3dad1de7c429f9f/src/libstd/sys/unix/android.rs#L70-L93). +It has the advantage to permit rustc to target *several* OS with the same binary. + +It is based on OS version detection (with symbol existence for example) and on +providing fallback or alternative for function calls. + +But it couldn't cover all aspects of ABI breaking, specially changes in +structures (member size or offset change). It would require to replace +structure's member access by function calls doing runtime detection, adding an +overhead. + +## Dynamic bindings generation + A possible alternative is to replace `libc` with FFI bindings generation at compile-time (using [rust-bindgen](https://github.com/servo/rust-bindgen) for example). But it isn't suitable for cross-building. From d75be58f08340f88928ecb31dd069159e4f8bc97 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?S=C3=A9bastien=20Marie?= Date: Tue, 11 Jul 2017 12:42:39 +0200 Subject: [PATCH 48/56] explain how to remove the overhead --- text/0000-target-extension.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/text/0000-target-extension.md b/text/0000-target-extension.md index d78db8bb2c1..283fff37c41 100644 --- a/text/0000-target-extension.md +++ b/text/0000-target-extension.md @@ -412,8 +412,8 @@ providing fallback or alternative for function calls. But it couldn't cover all aspects of ABI breaking, specially changes in structures (member size or offset change). It would require to replace -structure's member access by function calls doing runtime detection, adding an -overhead. +structure's member access by function calls doing runtime detection. The +possible overhead could be removed by using lazy detection and caching. ## Dynamic bindings generation From 7d5b56b9833fa54ce0354e3f64af7a4e98ab90bb Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?S=C3=A9bastien=20Marie?= Date: Sat, 12 Aug 2017 08:34:49 +0200 Subject: [PATCH 49/56] alternative: adding cfg attribute using build.rs --- text/0000-target-extension.md | 15 +++++++++++++++ 1 file changed, 15 insertions(+) diff --git a/text/0000-target-extension.md b/text/0000-target-extension.md index 283fff37c41..eba1260332f 100644 --- a/text/0000-target-extension.md +++ b/text/0000-target-extension.md @@ -421,6 +421,21 @@ A possible alternative is to replace `libc` with FFI bindings generation at compile-time (using [rust-bindgen](https://github.com/servo/rust-bindgen) for example). But it isn't suitable for cross-building. +## Adding cfg attribute using build.rs + +It is possible to do some compile time detection (or using cargo feature) to +select a particular OS version in `libc`. It has been [proposed for resolving +the FreeBSD 12 ABI issue](https://github.com/rust-lang/libc/pull/721). + +With such code, the `libc` code is right regarding the selected version. + +The drawback is such detection is fragile, and crosscompilation more complex +(it requires cargo feature usage). + +Additionally, a larger problem is mixing code with different OS version would +be possible (no error at compile time): for example using libstd from rustup +targeting one version, and using with crate locally compiled for another +version. It would produce bad code and crash could occurs at runtime. # Unresolved questions [unresolved]: #unresolved-questions From a1d759bf5acdb22be8734f50e4272a94ef9d826f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?S=C3=A9bastien=20Marie?= Date: Fri, 13 Apr 2018 06:51:20 +0200 Subject: [PATCH 50/56] Restrict the RFC to BSD OS while in motivation section, update some historical points (some OS version are released now) --- text/0000-target-extension.md | 20 ++++++++++---------- 1 file changed, 10 insertions(+), 10 deletions(-) diff --git a/text/0000-target-extension.md b/text/0000-target-extension.md index eba1260332f..d539cc76732 100644 --- a/text/0000-target-extension.md +++ b/text/0000-target-extension.md @@ -8,6 +8,8 @@ Extend Rust target specification to follow more closely LLVM triple specification. +The underlined purpose is to allow Rust compiler to target more easily BSD OS version. + # Motivation [motivation]: #motivation @@ -50,7 +52,7 @@ representative of something that already occurred in the past. See [commit message](http://cvsweb.openbsd.org/cgi-bin/cvsweb/src/sys/sys/_types.h?rev=1.6&content-type=text/x-cvsweb-markup) and [diff on types](http://cvsweb.openbsd.org/cgi-bin/cvsweb/src/sys/sys/_types.h.diff?r1=1.5&r2=1.6). -- **OpenBSD 6.2** (upcoming) changes `si_addr` type (`char *` to `void *`) in +- **OpenBSD 6.2** changes `si_addr` type (`char *` to `void *`) in `siginfo_t` structure. See [commit message](http://cvsweb.openbsd.org/cgi-bin/cvsweb/src/sys/sys/siginfo.h?rev=1.12&content-type=text/x-cvsweb-markup) and [diff on sys/siginfo.h](http://cvsweb.openbsd.org/cgi-bin/cvsweb/src/sys/sys/siginfo.h.diff?r1=1.11&r2=1.12). @@ -64,17 +66,17 @@ representative of something that already occurred in the past. See [commit R300997](https://svnweb.freebsd.org/base?view=revision&revision=300997) and [diff on signal.h](https://svnweb.freebsd.org/base/head/include/signal.h?r1=300997&r2=300996&pathrev=300997). -- **FreeBSD 12** (upcoming) removes `setkey()`, `encrypt()`, `des_setkey()` and +- **FreeBSD 12** removes `setkey()`, `encrypt()`, `des_setkey()` and `des_cipher()` functions. See [commit R306651](https://svnweb.freebsd.org/base?view=revision&revision=306651) and [diff of unistd.h](https://svnweb.freebsd.org/base/head/include/unistd.h?r1=306651&r2=306650&pathrev=306651). -- **FreeBSD 12** (upcoming) adds a new member `fb_memattr` in the middle of the +- **FreeBSD 12** adds a new member `fb_memattr` in the middle of the structure `fb_info` (public under `sys/fbio.h`). See [commit R306555](https://svnweb.freebsd.org/base?view=revision&revision=306555) and [diff of sys/fbio.h](https://svnweb.freebsd.org/base/head/sys/sys/fbio.h?r1=306555&r2=306554&pathrev=306555). -- **FreeBSD 12** wants to switch `ino_t` from 32 bits to 64 bits. +- **FreeBSD 12** switchs `ino_t` from 32 bits to 64 bits. See [commit R318736](https://svnweb.freebsd.org/base?view=revision&revision=318736), [diff on types](https://svnweb.freebsd.org/base/head/sys/sys/_types.h?r1=307756&r2=318736), the [Status Update and Call for Testing](https://lists.freebsd.org/pipermail/freebsd-fs/2017-April/024684.html), @@ -126,12 +128,10 @@ This way, a crate like `libc` could export raw bindings of platform specifically for the targeted version. -It also has been mentioned in -[pre-rfc discussion](https://internals.rust-lang.org/t/pre-rfc-target-extension-dealing-with-breaking-changes-at-os-level/5289/11), -that it could be benefical to some others OS (like Windows) to have versioned -targets too: for the end-user "knowing what version he is targeting means he can -decide what symbols he can link to normally, and what symbols he has to -dynamically load, and what fallbacks he has to implement." +It should be noted that if this motivation section presents globally the +underlined problem of breaking changes in OS, which could be present in a large +broad of OS, the RFC will focus on a fewer set of OS. The RFC will target only +BSD systems where breaking changes are part of the process OS developpment. # Detailed design From 8bbae5e828cde3166f71819238960e9e3ec6eabf Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?S=C3=A9bastien=20Marie?= Date: Fri, 13 Apr 2018 08:10:40 +0200 Subject: [PATCH 51/56] Remove predicates from the RFC. Only mention them as solution of possible drawbacks (long enumeration of versions). --- text/0000-target-extension.md | 79 +++++------------------------------ 1 file changed, 10 insertions(+), 69 deletions(-) diff --git a/text/0000-target-extension.md b/text/0000-target-extension.md index d539cc76732..5db2cd51385 100644 --- a/text/0000-target-extension.md +++ b/text/0000-target-extension.md @@ -157,20 +157,6 @@ extern { ``` -Additionally, in order to simplify conditional compilation when changes are -accross several versions, new predicates would be added too in order to do -version comparaison. - -```rust -extern { - // encrypt() function doesn't exist anymore starting with freebsd12 - - #[cfg(all(target_os="freebsd", version_lt(target_os_version, "12")))] - pub fn encrypt(block *mut ::c_char, flag ::c_int) -> ::c_int; -} -``` - - Another complete (and simple) example: in OpenBSD 6.2, the structure `siginfo_t` changed: @@ -182,9 +168,9 @@ pub struct siginfo_t { // A type correction occured in 6.2. // Before it was a `char *` and now it is a `void *`. - #[cfg(version_lt(target_os_version, "6.2"))] + #[cfg(not(any(target_os_version = "6.2", target_os_version = "6.3"))] pub si_addr: *mut ::c_char, - #[cfg(version_ge(target_os_version, "6.2"))] + #[cfg(any(target_os_version = "6.2", target_os_version = "6.3"))] pub si_addr: *mut ::c_void, #[cfg(target_pointer_width = "32")] @@ -202,49 +188,6 @@ be a breaking change in `libc` (and we would lose OpenBSD 6.1 supported version). -## Syntax level - -The addition of new predicates in attribute is a syntax extension. - -It permits to easily make a piece of code available to a range version. It is a -facility to manipulate the new attributes defined at language level. - -Predicates would be: - -- `version_eq()` : equal -- `version_lt()` : less-than -- `version_le()` : less-or-equal -- `version_gt()` : greater-than -- `version_ge()` : greater-or-equal - -The choice of an explicit name is to unhidden that the comparaison is done on -strings with a specific format (`major.minor.micro`). - -Having a predicate instead of an operator (`version_lt()` vs `<`) avoid a too -intrusive syntax's modification too. - -```rust -#[cfg(version_lt("2", "10"))] -println!("numeric comparaison: 2 < 10"); - -#[cfg(version_lt("3", "2.0")] -println!("able to deal with any number of '.': 3 < 2.0 (false)"); -#[cfg(version_lt("2.0", "2.0")] -println!("able to deal with any number of '.': 2.0 < 2.0 (false)"); -#[cfg(version_lt("10.0", "10.0.1")] -println!("able to deal with any number of '.':10.0 < 10.0.1"); - -#[cfg(version_eq("2", "2.0")] -println!("LLVM assumes \"2\" to be equivalent to \"2.0.0\"); - -#[cfg(version_le("3", "4", "5")] -println!("allow more than 2 arguments in the predicate: 3 <= 4 <= 5"); -``` - -See `libsyntax/attr.rs`. - - - ## Backend level ### Target structure @@ -350,11 +293,10 @@ From downstream perspective, it permits to use Rust to target several OS versions whereas the versions are incompatibles. From Rust developer perspective, it adds a new attributes for conditional -compilation, and extent the syntax with new predicates in convenient way. +compilation. Regarding documentation, additions have to be done on _Rust Reference_ in order -to mention new attributes in conditional compilation attribute section, with -related new predicates. +to mention new attributes in conditional compilation attribute section. Visible changes should also occur on main rust-lang.org site on pages about rustc distribution: rustup will be able to distribute binaries for more @@ -364,8 +306,12 @@ platforms (per OS version), or about platform support. # Drawbacks [drawbacks]: #drawbacks -At syntax level, it adds additional complexity for defining new predicates -for manipulating version numbers. +Do not providing a simple way to target a range of versions (for example, "from +version 12 to current version") could imply a long enumeration of version, that +could only grow with time. But two things has to be noted: first it could help +to limit the number of supported and tested versions ; secondly, the fact this +particular RFC doesn't require such construct do not forbid to propose a new +RFC later, once the necessity of such mecanism would be more evident (or not). At backend level, the number of targets will grow a lot. It means that not all targets will be testable (too much required ressources and it would require a @@ -391,11 +337,6 @@ The more simple approch is to use `target_os` with the OS version inside (`freebsd12`). But it would require to duplicate all `libc` code (for only small differences) at each release. Having a separated attribute is more simple. -Having only parts of the current RFC is also possible: new predicates at syntax -level are only a way simplify code expression. It would requires to explicitly -list all affected OS/env version on changes. It is doable if the list of -supported/OS/env versions is controlled in some way. - But without some way to express breaking changes existence at OS level, Rust is unable to targeting simultaneous several OS version. Regarding [issue #42681](https://github.com/rust-lang/rust/issues/42681) for FreeBSD 12, From 0ea6b56929c8a0307f425b9b7bf9ce246f03533e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?S=C3=A9bastien=20Marie?= Date: Fri, 13 Apr 2018 08:12:21 +0200 Subject: [PATCH 52/56] FreeBSD 12 is partially supported under FreeBSD 12, libc uses FreeBSD 11 compat ABI. It limits `ino_t` to 32 bits (and uses truncation for not representable ino_t on 32 bits). --- text/0000-target-extension.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/text/0000-target-extension.md b/text/0000-target-extension.md index 5db2cd51385..6a67bd44774 100644 --- a/text/0000-target-extension.md +++ b/text/0000-target-extension.md @@ -341,7 +341,7 @@ But without some way to express breaking changes existence at OS level, Rust is unable to targeting simultaneous several OS version. Regarding [issue #42681](https://github.com/rust-lang/rust/issues/42681) for FreeBSD 12, it means Rust should either deprecating older FreeBSD versions support (whereas -FreeBSD itself still support them) or not supporting FreeBSD 12. +FreeBSD itself still support them) or only partially supporting FreeBSD 12. ## Runtime detection From a925b057f4eb78303a67fba3e691e0803f95f5b3 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?S=C3=A9bastien=20Marie?= Date: Fri, 13 Apr 2018 08:34:14 +0200 Subject: [PATCH 53/56] Explicit a bit the rustup support --- text/0000-target-extension.md | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/text/0000-target-extension.md b/text/0000-target-extension.md index 6a67bd44774..124cd137cfa 100644 --- a/text/0000-target-extension.md +++ b/text/0000-target-extension.md @@ -300,7 +300,9 @@ to mention new attributes in conditional compilation attribute section. Visible changes should also occur on main rust-lang.org site on pages about rustc distribution: rustup will be able to distribute binaries for more -platforms (per OS version), or about platform support. +platforms (per OS version), or about platform support. If only one version is +distributed (what it is expected), the binary will be runnable only on one +particular OS version (but will be able to produce binary for another version). # Drawbacks From 2fbad3500a92ace8fe5d457bb64daad071cd0be7 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?S=C3=A9bastien=20Marie?= Date: Sat, 14 Apr 2018 11:44:45 +0200 Subject: [PATCH 54/56] add a "migration path" section --- text/0000-target-extension.md | 112 ++++++++++++++++++++++++++++++++++ 1 file changed, 112 insertions(+) diff --git a/text/0000-target-extension.md b/text/0000-target-extension.md index 124cd137cfa..63b1984735f 100644 --- a/text/0000-target-extension.md +++ b/text/0000-target-extension.md @@ -278,6 +278,118 @@ See `librustc/session/config.rs`. +## Migration path + +FreeBSD will be taken as example for the migration path. But it would apply for +others BSD OS. + +Currently, `rustc` has 3 known targets regarding FreeBSD: + +- `aarch64-unknown-freebsd` +- `i686-unknown-freebsd` +- `x86_64-unknown-freebsd` + +Assuming we want to support FreeBSD 10 and FreeBSD 11 (current supported +production releases), and FreeBSD 12 (upcoming release), the following steps +will need consideration. + + +### Extending Target definition + +- add `target_os_version` and `target_env_version` in `Target` definition. The + default value for all existing targets (including FreeBSD) will be `""` + (empty string). + +- make `rustc` to export new `target_os_version` and `target_env_version` attributes. + +- make `cargo` to export new `TARGET_OS_VERSION` and `TARGET_ENV_VERSION` + environment variables. + +At this point: + +- it should be no impact. the underline mecanism is implemented but nothing use + it. + +### Add new targets specifically for FreeBSD 10, 11 and 12 + +- add new targets, by duplicating the target code (using a function for simplicity): + - FreeBSD 10 + - `aarch64-unknown-freebsd10` + - `i686-unknown-freebsd10` + - `x86_64-unknown-freebsd10` + + - FreeBSD 11 + - `aarch64-unknown-freebsd11` + - `i686-unknown-freebsd11` + - `x86_64-unknown-freebsd11` + + - FreeBSD 12 + - `aarch64-unknown-freebsd12` + - `i686-unknown-freebsd12` + - `x86_64-unknown-freebsd12` + +- in these new targets, only `llvm_target` and `target_os_version` will be changed + +At this point: + +- the `freebsd` target is still build and distributed. `freebsd10`, `freebsd11` + and `freebsd12` are available for use using usual `--target` argument of + `rustc`. there is still no changes in the Rust ecosystem. +- the number of targets will grow: for FreeBSD: from 3 to 12 targets. +- no changes in `libc`. the four targets are as functional as before and all + uses the same libc code (at this point, there is no specific code using + `target_os_version`). +- the generated code for versioned `freebsdXX` could be different as the LLVM + backend is now aware of the targeted version. +- downstream projects could technically start using versioned targets (the code + is still the same), but it would not be recommanded for now or only for testing. + +### Specific changes for FreeBSD 12 could start to occurs + +- changes libc to produce different code if `target_os_version="12"`, + specifically regarding struct changes that occured in FreeBSD 12. + +At this point: + +- when explicitly targeting `freebsd12`, the produced code will have different + structure and functions. The produced binary targets FreeBSD 12, and will not + work on FreeBSD 11 (due to the use of breaking changes that occured in FreeBSD + 12). + +### Smoothly remove unversioned Target for FreeBSD + +- replace the Target `freebsd` (unversioned) by an alias on `freebsd11`. It + ensures that all FreeBSD targets will have `target_os_version` sets to a + specific version. +- alternatively, more complex code could be used for the alias: + - on a FreeBSD host: `freebsd` will point to the host version + - on any other host: `freebsd` will point to predefined default version + +At this point: + +- *some code could break*. for example, library path will be + `i686-unknown-freebsd11` instead of `i686-unknown-freebsd`. +- it is a transition period: downstream projects should start using versioned + Target. For example, Rust infrastructure should stop building `freebsd` but + `freebsd11`, and rustup should distribute this specific version (`freebsd11` + has been taken only as example). +- as transition period, it should be long enought. + +### Completely remove unversioned Target for FreeBSD + +- remove the alias `freebsd` +- only keeping `freebsd10`, `freebsd11` and `freebsd12` targets + +At this point: + +- *some code could break*. Any downstream projects still using unversioned + target will break. +- this step isn't strictly necessary. an unversioned target `freebsd` could + have sens too. But care will be need when the alias will move (from + `freebsd11` to `freebsd12` for example). Removing it let downstream projects to + deal themself with such transition. + + # How We Teach This [how-we-teach-this]: #how-we-teach-this From f8ba3bd62fc25786dcf6f7564739d5e53edee3df Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?S=C3=A9bastien=20Marie?= Date: Sat, 14 Apr 2018 12:01:24 +0200 Subject: [PATCH 55/56] some changes in migration path --- text/0000-target-extension.md | 33 ++++++++++++++++++++------------- 1 file changed, 20 insertions(+), 13 deletions(-) diff --git a/text/0000-target-extension.md b/text/0000-target-extension.md index 63b1984735f..9a550a93e17 100644 --- a/text/0000-target-extension.md +++ b/text/0000-target-extension.md @@ -312,7 +312,7 @@ At this point: ### Add new targets specifically for FreeBSD 10, 11 and 12 -- add new targets, by duplicating the target code (using a function for simplicity): +- add new targets, by duplicating the target code (using a function): - FreeBSD 10 - `aarch64-unknown-freebsd10` - `i686-unknown-freebsd10` @@ -332,7 +332,7 @@ At this point: At this point: -- the `freebsd` target is still build and distributed. `freebsd10`, `freebsd11` +- the `freebsd` target is still built and distributed. `freebsd10`, `freebsd11` and `freebsd12` are available for use using usual `--target` argument of `rustc`. there is still no changes in the Rust ecosystem. - the number of targets will grow: for FreeBSD: from 3 to 12 targets. @@ -341,8 +341,13 @@ At this point: `target_os_version`). - the generated code for versioned `freebsdXX` could be different as the LLVM backend is now aware of the targeted version. -- downstream projects could technically start using versioned targets (the code - is still the same), but it would not be recommanded for now or only for testing. +- downstream projects could start using versioned targets (the code is still + the same), but it would not be recommanded for production, but only for + testing. +- tests should be done to ensure the compatibility of the ecosystem with + versioned targets as it could break some assumption: for example, library + path will be `i686-unknown-freebsd11` instead of `i686-unknown-freebsd` in + `freebsd11` target. ### Specific changes for FreeBSD 12 could start to occurs @@ -355,6 +360,8 @@ At this point: structure and functions. The produced binary targets FreeBSD 12, and will not work on FreeBSD 11 (due to the use of breaking changes that occured in FreeBSD 12). +- the rest of the Rust ecosystem (still using `freebsd` as default build + target) is unaffected by these changes. ### Smoothly remove unversioned Target for FreeBSD @@ -362,18 +369,18 @@ At this point: ensures that all FreeBSD targets will have `target_os_version` sets to a specific version. - alternatively, more complex code could be used for the alias: - - on a FreeBSD host: `freebsd` will point to the host version - - on any other host: `freebsd` will point to predefined default version + - on a FreeBSD host: `freebsd` will point to the host version. + - on any other host: `freebsd` will point to predefined default version. At this point: -- *some code could break*. for example, library path will be - `i686-unknown-freebsd11` instead of `i686-unknown-freebsd`. +- *some code could break*. it will only concern untested code from the previous + steps. - it is a transition period: downstream projects should start using versioned - Target. For example, Rust infrastructure should stop building `freebsd` but - `freebsd11`, and rustup should distribute this specific version (`freebsd11` - has been taken only as example). -- as transition period, it should be long enought. + Target. For example, Rust infrastructure should stop building `freebsd` in + favor of `freebsd11`, and rustup should distribute this specific version too + (`freebsd11` has been taken only as example). +- as transition period, it should be long enough. ### Completely remove unversioned Target for FreeBSD @@ -383,7 +390,7 @@ At this point: At this point: - *some code could break*. Any downstream projects still using unversioned - target will break. + target will break (as the target has been removed). - this step isn't strictly necessary. an unversioned target `freebsd` could have sens too. But care will be need when the alias will move (from `freebsd11` to `freebsd12` for example). Removing it let downstream projects to From bf221e79044b448141f6eacfb4c39ba3ea699704 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?S=C3=A9bastien=20Marie?= Date: Sat, 14 Apr 2018 12:05:51 +0200 Subject: [PATCH 56/56] migration path: use in production --- text/0000-target-extension.md | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/text/0000-target-extension.md b/text/0000-target-extension.md index 9a550a93e17..36c74e61b15 100644 --- a/text/0000-target-extension.md +++ b/text/0000-target-extension.md @@ -377,9 +377,9 @@ At this point: - *some code could break*. it will only concern untested code from the previous steps. - it is a transition period: downstream projects should start using versioned - Target. For example, Rust infrastructure should stop building `freebsd` in - favor of `freebsd11`, and rustup should distribute this specific version too - (`freebsd11` has been taken only as example). + Target for production code. For example, Rust infrastructure should stop + building `freebsd` in favor of `freebsd11`, and rustup should distribute this + specific version too (`freebsd11` has been taken only as example). - as transition period, it should be long enough. ### Completely remove unversioned Target for FreeBSD