Closed wisonye closed 1 year ago
What is the name of the AUR package you grabbed for LLVM?
What is the name of the AUR package you grabbed for LLVM?
llvm 15.0.7-2
llvm-libs 15.0.7-2
But not from AUR
, installed via pacman
:)
Can you try some other version of those libraries?
What is the name of the AUR package you grabbed for LLVM?
Remove version 15 and install version 14, doesn't help a bit:
N wison | /home/wison pacman --sync --search llvm14-lib | rg llvm14-libs
# extra/llvm14-libs 14.0.6-3 [installed]
I wison | /home/wison
N wison | /home/wison pacman --sync --search llvm14 | rg llvm14
# extra/llvm14 14.0.6-3 [installed]
# extra/llvm14-libs 14.0.6-3 [installed]
I wison | /home/wison
I wison | /home/wison pacman --sync --search clang14 | rg clang14
# extra/clang14 14.0.6-1 [installed]
Exactly the same compile error:
I wison | /home/wison/temp cd c3c/
I wison | /home/wison/temp/c3c mkdir build && cd build
I wison | /home/wison/temp/c3c/build cmake ..
# -- The C compiler identification is GNU 12.2.1
# -- The CXX compiler identification is GNU 12.2.1
# -- Detecting C compiler ABI info
# -- Detecting C compiler ABI info - done
# -- Check for working C compiler: /usr/bin/cc - skipped
# -- Detecting C compile features
# -- Detecting C compile features - done
# -- Detecting CXX compiler ABI info
# -- Detecting CXX compiler ABI info - done
# -- Check for working CXX compiler: /usr/bin/c++ - skipped
# -- Detecting CXX compile features
# -- Detecting CXX compile features - done
# C3C version: 0.4.117
# -- Found CURL: /usr/lib/libcurl.so (found version "8.0.1")
# -- Performing Test HAVE_FFI_CALL
# -- Performing Test HAVE_FFI_CALL - Success
# -- Found FFI: /usr/lib/libffi.so
# -- Performing Test Terminfo_LINKABLE
# -- Performing Test Terminfo_LINKABLE - Success
# -- Found Terminfo: /usr/lib/libtinfo.so
# -- Found ZLIB: /usr/lib/libz.so (found version "1.2.13")
# -- Found LibXml2: /usr/lib/libxml2.so (found version "2.10.3")
# -- Found LLVM 14.0.6
# -- Using LLVMConfig.cmake in: /usr/lib/llvm14/lib/cmake/llvm
# -- Libraries located in: /usr/lib/llvm14/lib
# CMake Error at /usr/lib/llvm14/lib/cmake/llvm/LLVM-Config.cmake:138 (message):
# Target X86 is not in the set of libraries.
# Call Stack (most recent call first):
# /usr/lib/llvm14/lib/cmake/llvm/LLVM-Config.cmake:263 (llvm_expand_pseudo_components)
# CMakeLists.txt:152 (llvm_map_components_to_libnames)
#
#
# -- Configuring incomplete, errors occurred!
N wison | /home/wison/temp/c3c/build cmake -DLLVM_DIR=/usr/lib/llvm14/lib/cmake/llvm/ ..
# C3C version: 0.4.117
# -- Found LLVM 14.0.6
# -- Using LLVMConfig.cmake in: /usr/lib/llvm14/lib/cmake/llvm/
# -- Libraries located in: /usr/lib/llvm14/lib
# CMake Error at /usr/lib/llvm14/lib/cmake/llvm/LLVM-Config.cmake:138 (message):
# Target X86 is not in the set of libraries.
# Call Stack (most recent call first):
# /usr/lib/llvm14/lib/cmake/llvm/LLVM-Config.cmake:263 (llvm_expand_pseudo_components)
# CMakeLists.txt:152 (llvm_map_components_to_libnames)
BTW, one thing that needs to be improved is definitely the compiler toolchain
across the different platforms.
I think zig cc
really does a good job with this: Single static link executable, download and it works out of the box!
I use zig cc
for my C game project, just download a 133MB
single executable and it works very well like magic (no cmake/gmake/make/llvm
need to be installed), maybe you should think about having it in C3
(embedded the entire compiler into c3c
), that will be a huge forever game changer:)
I think I saw a 15.0.7-3 version. That's the one I was thinking about. I removed support for LLVM 14 fairly recently.
I use zig cc for my C game project, just download a 133MB single executable and it works very well like magic (no cmake/gmake/make/llvm need to be installed), maybe you should think about having it in C3 (embedded the entire compiler into c3c), that will be a huge forever game changer:)
There are already precompiled executables: https://github.com/c3lang/c3c/releases/tag/untagged-a3c680b43c8d0212a837 that clock in around 30 Mb. Those contain everything already.
Unfortunately GitHub only has Windows on x64, Ubuntu and MacOS on x64 for CI, so those are the ones that get built. Getting even more ready would be very nice, but would require setting up and host another build machine which can run all targets in virtual machines. That's not done yet and hopefully I'll get some contributors to work on.
Theoretically one could use Zig CC or a similar custom toolchain to cross compile for other platforms, but it would involve compiling the entire LLVM as well, so there's a bit extra work there. For Windows there is actually a separate project building LLVM that is part of the C3 project.
Theoretically one could use Zig CC or a similar custom toolchain to cross compile for other platforms, but it would involve compiling the entire LLVM as well, so there's a bit extra work there. For Windows there is actually a separate project building LLVM that is part of the C3 project.
Yup, you're right, that takes extra work or even a lot of work to achieve. I do really interested in C3
project, maybe I can help in the future, but just busy at this moment, as it's currently still school holiday in New Zealand:) Busy teaching my boy and my wife to write their first game by C + raylib
.
Also, I need to make a comparison by using C/Rust/Zig: implement the same game by each programming language, then show them the difference and become a reference for them to choose their final programming language to dive deep.... nowadays, it's not easy to become husband and a dad .....:)
BTW, I try to compare the executable size, so I run the following command to compile the release version of helloworld:
./c3c -Os+ -g0 compile ../resources/testfragments/helloworld.c3
strip helloworld
But still around 249KB
for a simple hello world program, anything I'm missing?:)
I was wondering why zig
and zig cc
are able to compile out such small size executables (around 9~18KB
for .zig
and around 5~50KB
for .c
), if you know something about what's happening under the hood, plz share back, I love those details:)
For zig
compile .zig
file, click
Here is simple hello world of Zig
:
const std = @import("std");
pub fn main() void {
std.debug.print("\n>>> Hello world.", .{});
}
Build and run in zig
zig build-exe temp.zig && ./temp
Cross-compilation
-O ReleaseSmall
means RELEASE build and SMALL binary size (stripped)
optimization :
# Linux MUSL (Intel and ARM64)
zig build-exe temp.zig -O ReleaseSmall -target x86_64-linux-musl --name x86_64-linux-musl
zig build-exe temp.zig -O ReleaseSmall -target aarch64-linux-musl --name aarch64-linux-musl
# Liunx GLIBC (Intel and ARM64)
zig build-exe temp.zig -O ReleaseSmall -target x86_64-linux-gnu --name x86_64-linux-gnu
zig build-exe temp.zig -O ReleaseSmall -target aarch64-linux-gnu --name aarch64-linux-gnu
# MacOS (Intel and ARM64/M1/M2)
zig build-exe temp.zig -O ReleaseSmall -target x86_64-macos-none --name x86_64-macos-none
zig build-exe temp.zig -O ReleaseSmall -target aarch64-macos-none --name aarch64-macos-none
Executable format:
file aarch64-linux-musl
# aarch64-linux-musl: ELF 64-bit LSB executable, ARM aarch64, version 1 (SYSV), statically linked, stripped
file x86_64-linux-musl
# x86_64-linux-musl: ELF 64-bit LSB executable, x86-64, version 1 (SYSV), statically linked, stripped
file aarch64-linux-gnu
# aarch64-linux-gnu: ELF 64-bit LSB executable, ARM aarch64, version 1 (SYSV), statically linked, stripped
file x86_64-linux-gnu
# x86_64-linux-gnu: ELF 64-bit LSB executable, x86-64, version 1 (SYSV), statically linked, stripped
file aarch64-macos-none
# aarch64-macos-none: Mach-O 64-bit executable arm64
file x86_64-macos-none
# x86_64-macos-none: Mach-O 64-bit executable x86_64
So, here is the size difference:
ls -lht
# 8.5K aarch64-linux-musl*
# 8.5K x86_64-linux-musl*
# 8.5K aarch64-linux-gnu*
# 8.5K x86_64-linux-gnu*
# 50K aarch64-macos-none*
# 18K x86_64-macos-none*
For zig cc
compile .c
file
Here is simple hellow world of C
:
#include <stdio.h>
int main(void) {
printf("\n>>> Hello world");
return 0;
}
Build and run by zig cc
zig cc -o temp_c -std=c11 -Os -DNDEBUG temp.c && strip temp_c && ./temp_c
Cross-compilation
# Linux MUSL (Intel and ARM64)
zig cc -o c_x86_64-linux-musl -std=c11 -Os -DNDEBUG temp.c -target x86_64-linux-musl
zig cc -o c_aarch64-linux-musl -std=c11 -Os -DNDEBUG temp.c -target aarch64-linux-musl
# Liunx GLIBC (Intel and ARM64)
zig cc -o c_x86_64-linux-gnu -std=c11 -Os -DNDEBUG temp.c -target x86_64-linux-gnu
zig cc -o c_aarch64-linux-gnu -std=c11 -Os -DNDEBUG temp.c -target aarch64-linux-gnu
# MacOS (Intel and ARM64/M1/M2)
zig cc -o c_x86_64-macos-none -std=c11 -Os -DNDEBUG temp.c -target x86_64-macos-none
zig cc -o c_aarch64-macos-none -std=c11 -Os -DNDEBUG temp.c -target aarch64-macos-none
Executable format:
file c_aarch64-linux-musl
# c_aarch64-linux-musl: ELF 64-bit LSB executable, ARM aarch64, version 1 (SYSV), statically linked, with debug_info, not stripped
file c_x86_64-linux-musl
# c_x86_64-linux-musl: ELF 64-bit LSB executable, x86-64, version 1 (SYSV), statically linked, with debug_info, not stripped
file c_aarch64-linux-gnu
# c_aarch64-linux-gnu: ELF 64-bit LSB executable, ARM aarch64, version 1 (SYSV), dynamically linked, interpreter /lib/ld-linux-aarch64.so.1, for GNU/Linux 2.0.0, with debug_info, not stripped
file c_x86_64-linux-gnu
# c_x86_64-linux-gnu: ELF 64-bit LSB executable, x86-64, version 1 (SYSV), dynamically linked, interpreter /lib64/ld-linux-x86-64.so.2, for GNU/Linux 2.0.0, with debug_info, not stripped
file c_aarch64-macos-none
# c_aarch64-macos-none: Mach-O 64-bit executable arm64
file c_x86_64-macos-none
# c_x86_64-macos-none: Mach-O 64-bit executable x86_64
So, here is the size difference:
ls -lht
# 32K c_aarch64-linux-musl*
# 21K c_x86_64-linux-musl*
# 5.8K c_aarch64-linux-gnu*
# 5.0K c_x86_64-linux-gnu*
# 49K c_aarch64-macos-none*
# 16K c_x86_64-macos-none*
Zig aggressively only compiles (and checks!) code that is traceable from the main method. To get that, use --strip-unused when compiling C3. This will behave somewhat similar but it is not yet deleting things like names for unused enums, which means the data piles up a bit anyway. --strip-unused was created as I was working on general visibility rules, and changes later happened to improve what it could do but it was clearly not completely done. See #760 to track that issue.
Also, on linux I believe Zig compiles print to a syscall, which is why it's very slim as opposed to C3 which always goes by way of libc. On macOS it's mandatory to use libc, so that's partly why Zig is bigger there.
All in all, size is something I want to work on. There is a slight tension between that and introspection data, as the latter claims more space than one might hope. But it's possible to reduce what's currently there and #760 will track that.
Also, on linux I believe Zig compiles print to a syscall, which is why it's very slim as opposed to C3 which always goes by way of libc. On macOS it's mandatory to use libc, so that's partly why Zig is bigger there.
All in all, size is something I want to work on. There is a slight tension between that and introspection data, as the latter claims more space than one might hope. But it's possible to reduce what's currently there and #760 will track that.
Thanks for the detailed explanation, that's exactly what I want to know. I know some people don't care about the size (as XXKB doesn't affect anything at all), but I'm the one that cares about the quality and what's the best we can do, I'm that kind of person :)
You can test the dev branch, it strips more, but the static initializers for the temp allocator and registering printf functions are making code being tracked as "live" even though it is not used. That's the curse of static initialization. Avoiding it is... a bit difficult and would require a new feature. Adding a "disable static initializers" flag would be easy though.
Zig aggressively only compiles (and checks!) code that is traceable from the main method. To get that, use --strip-unused when compiling C3. This will behave somewhat similar but it is not yet deleting things like names for unused enums, which means the data piles up a bit anyway. --strip-unused was created as I was working on general visibility rules, and changes later happened to improve what it could do but it was clearly not completely done. See #760 to track that issue.
Sorry for the late reply, family time, I will be more free time when the kid goes back to school:)
Ok, --strip-unused
seems to work, strip more (88KB
helloworld on M2), love to see that happen :)
But one thing confuses me, I don't know why:
If I re-run the c3c
with the (yesterday compiled object files (.o)), it always shows the error below (no matter how many times to try):
c3c --strip-unused -Os+ -g0 compile ../resources/testfragments/helloworld.c3
2:
3: extern fn void printf(char *str, ...);
4:
5: fn void main()
^^^^
(/Users/wison/temp/c3c/resources/testfragments/helloworld.c3:5:9) Error: Missing main forwarding function '@main_to_void_main'.
But if I do rm -rf ./*.o; rm -rf helloworld
then re-run the same command again, it works...
You can test the dev branch, it strips more, but the static initializers for the temp allocator and registering printf functions are making code being tracked as "live" even though it is not used. That's the curse of static initialization. Avoiding it is... a bit difficult and would require a new feature. Adding a "disable static initializers" flag would be easy though.
Trying on the dev
branch, but that surprised error shows again after a clean cmake --build ./
:
I wison | /Users/wison/temp/c3c/build ls -lht
total 351312
drwxr-xr-x@ 19 wison staff 608B 13 Apr 09:18 CMakeFiles/
-rwxr-xr-x@ 1 wison staff 171M 13 Apr 09:18 c3c*
-rw-r--r--@ 1 wison staff 161K 13 Apr 09:18 libminiz.a
-rw-r--r--@ 1 wison staff 72K 13 Apr 09:18 libc3c_wrappers.a
-rw-r--r--@ 1 wison staff 2.0K 13 Apr 09:17 cmake_install.cmake
-rw-r--r--@ 1 wison staff 90K 13 Apr 09:17 Makefile
-rw-r--r--@ 1 wison staff 24K 13 Apr 09:17 CMakeCache.txt
drwxr-xr-x@ 3 wison staff 96B 13 Apr 09:17 lib/
I wison | /Users/wison/temp/c3c/build ./c3c --version
C3 Compiler Version (pre-alpha): 0.5.0
Installed directory: /Users/wison/temp/c3c/build/
LLVM version: 16.0.1
LLVM default target: arm64-apple-darwin22.3.0
I wison | /Users/wison/temp/c3c/build c3c -Os+ -g0 compile ../resources/testfragments/helloworld.c3
2:
3: extern fn void printf(char *str, ...);
4:
5: fn void main()
^^^^
(/Users/wison/temp/c3c/resources/testfragments/helloworld.c3:5:9) Error: Missing main forwarding function '@main_to_void_main'.
But if I run the it again, it works....why?:)
N wison | /Users/wison/temp/c3c/build ./c3c --strip-unused -Os+ -g0 compile ../resources/testfragments/helloworld.c3
Program linked to executable 'helloworld'.
I wison | /Users/wison/temp/c3c/build ls -lht helloworld
-rwxr-xr-x@ 1 wison staff 95K 13 Apr 09:21 helloworld*
N wison | /Users/wison/temp/c3c/build ./c3c -Os+ -g0 compile ../resources/testfragments/helloworld.c3
Program linked to executable 'helloworld'.
I wison | /Users/wison/temp/c3c/build ls -lht helloworld
-rwxr-xr-x@ 1 wison staff 320K 13 Apr 09:22 helloworld*
But the dev
version compiles a bigger size (95KB
) than the master
(88KB
) which should NOT be like that, right?:)
Even bigger without --strip-unused
(320KB
) than the master
(249KB)
, just let you know:)
That is indeed odd. The usual reason this is seen is if you compile with "nostdlib". These are macro definitions and so are not part of the compilation. If the main method is compatible with C main, so for example if your main is fn int main()
then the macro isn't necessary. The reason it worked differently ought to be one of those (no stdlib or int main()
/ void main()
)
With #767 I've tried it again and the binary is now 14KB down from 64KB.
On MacOS --strip-unused is down to less than 9 kb for x86. It might be possible to strip it down further, but I'll leave it at that for now. I'll keep monitoring this and try to reduce it further.
In regards to the AUR package, did you make any progress?
@wisonye can I close this issue?
I'm the author of the AUR package and I'm not really sure what the exact issue is. This was the only related thread that I could find, hoping someone more well versed in Cmake sees this.
Also, since I'm not using Arch Linux anymore, I'm going to disown the package. Maybe someone can pick it up and maintain it in my place.
I was looking into the AUR, because I wanted to try it. After a full day I found that there are several issues to make it compile in ArchLinux.
I am starting an Ubuntu chroot container to compile c3c inside. I think this puzzle can be solved, but it is not easy at all, and probably is better to wait until the llvm ArchLinux package gets updated.
@OdnetninI what version is AUR's LLVM at? Because I think the lowest supported by the compiler right now is 15 (It's testing with 15-18 with 18 being LLVM nightly) LLVM being released in Sept 2022, and while I maintained support for pre 15 and 15+ for quite a while, there is a problem with LLVM 15 having quite different IR output, forcing me to maintain two sets of tests. Otherwise I would have supported older versions as well.
@lerno Right now, in Arch Repositories we have LLVM 14 and 15, and AUR has 9 and 17. However, version 15 is flagged out of date since March. If they are not updating it is because they are having issues....
15-17 would be fine, but it needs lld libraries for linking as well. The problem with many of the LLVM builds is that many LLVM maintainers take upon themselves to curate the contents of the libraries. So someone might come up with the idea that say the x86 cross compilation is unimportant for everyone and deliberately exclude it from the compilation. So now no-one can use those libraries for x86 cross compilation.
The problem is so big that I choose to set up a repo that just grabs LLVM from source and compiles it for MSVC and uploads those binaries.
I think the best approach is really that: grab a docker image for each Linux distribution, compile LLVM from source and upload it as a static library with everything included as a single blob. It can be uploaded as a binary and then downloading that could be part of the CMake process basically.
But... we're not there yet. It just seems like the best way of handling this since everyone using LLVM seems to have this problem with messed up LLVM binaries.
I just compiled it in ArchLinux. I am going to create a new PKGBUILD file and test it again. If it works, I will upload it to the AUR. Unfortunately, the ArchLinux llvm setup is so broken that it was easier to download the deb packages and unpack them.
The package is available: https://aur.archlinux.org/packages/c3c-git
I just tested it on a clean install, an everything seems to work.
@OdnetninI that's fantastic, so does this mean it works with aur now? Can you update the README.md with instructions?
Yes, AUR works now.
I tested it on my machine and inside a new ArchLinux container. However, if anyone wants to test it and give feedback, I am here :)
I'll close this then.
Build from source
Install via AUR (
paru
)Could anyone plz give me help, many thanks :)