-
Notifications
You must be signed in to change notification settings - Fork 89
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
make: use pre-compiled newlib and libc++ #353
Conversation
lib/fetch-libc++.sh
Outdated
MIRRORS=(\ | ||
"https://www.cs.virginia.edu/~bjc8c/archive/tock"\ | ||
"https://alpha.mirror.svc.schuermann.io/files"\ | ||
) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I don't think we should be automatically downloading binaries from custom places.
What happens if these are replaced with something malicious?
What happens if this is updated or changed, it isn't tracked in git?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The sha256 hash is. If someone can replace the zip with something malicious and the same hash, maybe we accept defeat?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
What if we bump the newlib version and then delete the old one? That will break users who don't update as it's not checked into git.
It just seems risky and clunky to have these outside the repo. What is the benefit?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Hopefully we wouldn't delete from every mirror? I don't know why we would delete them.
The benefit is not having to not having to add ~150MB of zip files to the repo on every version update.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Hopefully we wouldn't delete from every mirror?
Hopefully not, but nothing stops that from happening.
The benefit is not having to not having to add ~150MB of zip files to the repo on every version update.
With git-lfs is that really an issue?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This all comes from a discussion we had where I thought the conclusion was pulling in a zip (like we've done with the riscv toolchain) was fine. https://github.com/tock/tock/blob/master/doc/wg/core/notes/core-notes-2023-09-22.md#libtock-c-newlib-updates
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
After another discussion I don't think we are eager to pay for github lfs when we have a decent (free, ready to go) solution. https://docs.github.com/en/billing/managing-billing-for-git-large-file-storage/about-billing-for-git-large-file-storage
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Happy to continue hosting this on my personal mirror. I can also add a mirror on our cluster web server at Princeton. I believe that, as long as we have a system that checks these URLs and complains if they're down, we should be able to maintain a good number of toolchain versions reliably before bandwidth / storage becomes an issue for us.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
FWIW here's a crude example of how we can use GitHub actions to periodically check whether our mirrors are still alive and the links still work: https://github.com/lschuermann/tock-mirrortest. We can add a step to the workflow that automatically opens an issue and tags the admins of the failing mirror, and potentially also a script that collects these links from the various Tock repos. Just need to make sure we don't over-engineer this too much. What do you think @bradjc @alevy?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
After another discussion I don't think we are eager to pay for github lfs when we have a decent (free, ready to go) solution. https://docs.github.com/en/billing/managing-billing-for-git-large-file-storage/about-billing-for-git-large-file-storage
Ah, I didn't realise GitHub charges for LFS
FWIW, GitHub actions supports executing Dockerfiles. We can create a manually started action that devs can use to generate these artifacts (and then copy them over to mirrors), without having to go through the process of getting Docker running on their system: https://docs.github.com/en/actions/creating-actions/creating-a-docker-container-action |
@@ -12,7 +12,7 @@ jobs: | |||
ci-format: | |||
strategy: | |||
matrix: | |||
os: [ubuntu-20.04] | |||
os: [ubuntu-22.04] |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Should we split this PR up more? A few of these changes could just go right in which would reduce the diff and make reverting any regressions easier
Configuration.mk
Outdated
# Library versions. | ||
NEWLIB_VERSION ?= 4.2.0.20211231 | ||
LIBCPP_VERSION ?= 12.2.0 |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Should we split this bump out as well
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think we might be able to split it up. We may also not want to do more work and review more PRs. I'm still trying to get it to work at all.
newlib/newlib-4.2.0.20211231.patch
Outdated
--- a/libtock-newlib-4.2.0.20211231/headers/ssp/string.h | ||
+++ b/libtock-newlib-4.2.0.20211231/headers/ssp/string.h | ||
@@ -36,7 +36,7 @@ | ||
|
||
__BEGIN_DECLS | ||
void *__memcpy_chk(void *, const void *, size_t, size_t); | ||
-void *__memmove_chk(void *, void *, size_t, size_t); | ||
+void *__memmove_chk(void *, const void *, size_t, size_t); | ||
void *__mempcpy_chk(void *, const void *, size_t, size_t); | ||
void *__memset_chk(void *, int, size_t, size_t); | ||
char *__stpcpy_chk(char *, const char *, size_t); | ||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Why do we need to patch newlib? What's the status of this, have you submitted it upstream?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
We get warnings without those changes.
Would newlib really not notice those warnings after multiple years? I assumed it's something we're doing differently or something they don't want to fix.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
That seems like an issue on our side then.
I suspect they don't see the warnings. If we want to keep this we should send a fix upstream. Otherwise this is how nothing ever gets fixed
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
If they use github, easy enough, but I'm not going to learn how newlib does things via mailing lists, unfortunately.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Not wanting to learn a new tool doesn't seem like a good excuse here.
Newlib is a maintained project so we should be sending all fixes and patches upstream. Otherwise we are stuck patching newlib for the foreseeable future. We also don't even know if this is the correct fix, by sending the change upstream we can get feedback from the maintainers about the fix. We shouldn't just punt on the right way to do things because it might be a little harder
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@bradjc FWIW I can volunteer to relay patches upstream, if you don't want to use mailing lists. Would need to dig into this issue first, though.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Please do!
Warning we get:
CC ../../libtock/udp.c
In file included from ../../lib/libtock-newlib-4.3.0.20230120/arm/arm-none-eabi/include/string.h:180,
from ../../libtock/udp.c:1:
../../lib/libtock-newlib-4.3.0.20230120/arm/arm-none-eabi/include/ssp/string.h:39:7: warning: mismatch in argument 2 type of built-in function '__memmove_chk'; expected 'const void *' [-Wbuiltin-declaration-mismatch]
39 | void *__memmove_chk(void *, void *, size_t, size_t);
| ^~~~~~~~~~~~~
Based on -Wbuiltin-declaration-mismatch
, the glibc definition:
https://github.com/bminor/glibc/blob/2e0c0ff95ca0e3122eb5b906ee26a31f284ce5ab/include/string.h#L189
extern void *__memmove_chk (void *__dest, const void *__src, size_t __len,
size_t __destlen) __THROW;
versus newlib:
void *__memmove_chk(void *, void *, size_t, size_t);
And I suppose we haven't seen this before because we've been using the headers provided by the user's compiler.
Ok next status update. libc++
In both error cases the errors seem to propagate from the headers (not our compiled libraries). It's possible that gcc 11.2 is just not the version to use. I think I will try with a newer gcc source next. |
Next finding: building libc++ 13.2 with 10.3 compiler on riscv doesn't work:
|
With libc++ 12.3, c++ apps compile with gcc 13.2, but with gcc 10.3 we get the same(-ish) header errors as with libc++ 11.2. Last chance for a one-size-fits-all option i think is libc++ 10.5. |
Ok I think things are back to a working state. The make file now chooses which versions of newlib and libc++ to use based on the versions of the toolchains in use (both arm and riscv independently). Also the packaging for the built archives is cleaner without so much of our own manual file choosing, now we just use Next up I need to figure out dockerfiles for different versions of libc++ and see if I can get a gcc 13 version. Although I can't find any linux distros that have |
@@ -1,7 +1,6 @@ | |||
#include <stdbool.h> | |||
#include <stdint.h> | |||
#include <stdio.h> | |||
#include <assert.h> |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I don't understand this change. Why can we no longer include assert.h? I can't figure out anything that changed from previous versions of newlib.
Without this change we get:
CC main.c
In file included from main.c:4:
../../../../../lib/libtock-newlib-4.3.0.20230120/arm/arm-none-eabi/include/assert.h:39:6: warning: redundant redeclaration of '__assert' [-Wredundant-decls]
39 | void __assert (const char *, int, const char *)
| ^~~~~~~~
In file included from ../../../../../lib/libtock-newlib-4.3.0.20230120/arm/arm-none-eabi/include/sys/reent.h:458,
from ../../../../../lib/libtock-newlib-4.3.0.20230120/arm/arm-none-eabi/include/stdio.h:60,
from main.c:2:
../../../../../lib/libtock-newlib-4.3.0.20230120/arm/arm-none-eabi/include/assert.h:39:6: note: previous declaration of '__assert' with type 'void(const char *, int, const char *)'
39 | void __assert (const char *, int, const char *)
| ^~~~~~~~
../../../../../lib/libtock-newlib-4.3.0.20230120/arm/arm-none-eabi/include/assert.h:41:6: warning: redundant redeclaration of '__assert_func' [-Wredundant-decls]
41 | void __assert_func (const char *, int, const char *, const char *)
| ^~~~~~~~~~~~~
../../../../../lib/libtock-newlib-4.3.0.20230120/arm/arm-none-eabi/include/assert.h:41:6: note: previous declaration of '__assert_func' with type 'void(const char *, int, const char *, const char *)'
41 | void __assert_func (const char *, int, const char *, const char *)
| ^~~~~~~~~~~~~
LD build/cortex-m0/cortex-m0.elf
assert.h specifically doesn't have an include guard.
fb6414c
to
7794f20
Compare
Ok this is ready. It would be great to make a decision one way or another on this. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Changes look good, and this seems to work on NixOS for ARM and RISC-V. I'll follow this up with some changes to the shell.nix
file, such that we no longer build a custom compiler and libc there.
10c0c7e
to
5370b36
Compare
support any version, package with `make install`
Causes conflicts with already included items
new folder where we store precompiled libraries. includes fetch scripts to pull from remote
no newlib riscv by default
5370b36
to
df5b9b8
Compare
aa882f7
aa882f7
to
27b5991
Compare
I fixed the CI failures of this PR in 22f8a73 (change Both the |
Hooray, thanks! |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Assuming this is good to merge, as it's been previously added to the merge queue already.
!!! Woo! |
make: use pre-compiled newlib and libc++
Follow up to #343.
This restructures the newlib and libc++ handling to create .zip files which can be stored remotely and fetched when users want to build libtock-c apps. This removes the need to store the compiled libraries in the repo.
This also updates the versions of the two libraries.
Since we now ship our own newlib we no longer need the user's system to include one. This makes compiling riscv much easier and we enable that by default now.
New features compared to current approach
Some lingering questions
<assert.>
now gives a warning due to redefined things. This is because assert gets pulled in twice (once in the reent.h checks and once in the main.c file). I have no idea why this is an issue now and wasn't before, as nothing in this area of newlib seems to have changed. It seems like it should have been an issue before as well.Testing
Please try this branch out. It should work as a user (libtock-c developer).
I haven't done a FULL end-to-end test of the newlib and libc++ generation (it takes forever and is toolchain dependent). I want to do that, but others can look at this in the meantime.