GCC linking wrong libpthread for build.rs - rust

I'm attempting to cross-compile from Linux (NixOS) to Windows and encountering some frustrations.
There seem to be two parts that together are breaking the build:
Code in my Rust project requires multithreading, and as such requires a version of libpthread for Windows.
To build properly, I need a build.rs file. For some reason, Rust requires a version of libpthread for Linux for that.
What's the problem? Well, the build.rs has to be built with regular GCC and not MinGW because it needs to execute on my system. But for some reason, GCC is attempting to link to the Windows libpthread library instead of the system one, and as such is failing with an error about not supporting the library format.
(Failed) Alternatives
If I remove the build.rs, the project builds fine. Unfortunately, I need it for full functionality.
If I remove the Windows version of libpthread the build.rs builds and runs correctly, but MinGW fails with a missing library error when building the rest of the project.
Solution Paths?
Either I have to figure out why GCC's linking to the wrong version of libpthread, or I have to disable -lpthread entirely for the build.rs. I have no idea why it would need pthreads, considering for testing I stripped it down to only fn main() {}.
I have no idea where to start on either of these, and I've already spent a couple of days getting the problem down to this. I'd appreciate some help!

Related

Clang huge compilation?

Good Morning.
I am compiling Clang, following the instructions here Getting Started: Building and Running Clang
I am on linux and the compilation goes smoothly. But I think I am missing out something...
I want to compile ONLY clang, not all the related libraries. The option -DLLVM_ENABLE_PROJECTS=clang seems doing what I want (check LLVM_ENABLE_PROJECTS here)
If I use the instructions written there, I can compile, but I think I am compiling too much....a build directory of 70GB seems too much to me...
I tried to download the official debian source and compile the debian package (same source code! just using the "debian way" to create a package from official debian source), just to compare...The compilation goes smoothly, is very fast, and the build directory is much much smaller...as I expected...
I noticed in the first link I provided the phrase "This builds both LLVM and Clang for debug mode."...
So, anyone knows if my problem is due to the fact that I am compiling a "debug mode" version? if so, how could I compile the default version? and is there a way to compile ONLY clang without LLVM?
Yes, debug mode binaries are typically much larger than release mode binaries.
Cmake normally uses CMAKE_BUILD_TYPE to determine he build type. It can be set from the command line with -DCMAKE_BUILD_TYPE="Release" o -DCMAKE_BUILD_TYPE="Debug" (sometimes there are other build types as well).

"undefined reference to `__stat_time64'" when cross-compiling rust project on musl 1.2.0

I'm trying to cross-compile a rust project for arm-linux-musleabihf and am hitting a linker error when using musl-cross-make. The rust project has a dependency on libgit2 and this is the dependency that seems to be causing the problem.
Using:
the latest rust (1.43.1 via rustup)
the arm-unknown-linux-musleabihf target
the latest musl-cross-make with TARGET=arm-linux-musleabihf
pointing TARGET_CC_linux_arm-unknown-linux-musleabihf and CARGO_TARGET_ARM_UNKNOWN_LINUX_MUSLEABIHF_LINKER at /opt/musl-cross-make/output/bin/arm-linux-musleabihf-gcc
I get an error when building:
error: linking with `/opt/musl-cross-make/output/bin/arm-linux-musleabihf-gcc` failed: exit code: 1
...
= note: /opt/musl-cross-make/output/bin/../lib/gcc/arm-linux-musleabihf/9.2.0/../../../../arm-linux-musleabihf/bin/ld: /tmp/rustcvSvGAJ/liblibgit2_sys-e56c2f9bd024a0a9.rlib(odb.o): in function `git_odb__add_default_backends':
odb.c:(.text.git_odb__add_default_backends+0x24): undefined reference to `__stat_time64'
/opt/musl-cross-make/output/bin/../lib/gcc/arm-linux-musleabihf/9.2.0/../../../../arm-linux-musleabihf/bin/ld: /tmp/rustcvSvGAJ/liblibgit2_sys-e56c2f9bd024a0a9.rlib(config.o): in function `git_config_add_file_ondisk':
config.c:(.text.git_config_add_file_ondisk+0x34): undefined reference to `__stat_time64'
/opt/musl-cross-make/output/bin/../lib/gcc/arm-linux-musleabihf/9.2.0/../../../../arm-linux-musleabihf/bin/ld: /tmp/rustcvSvGAJ/liblibgit2_sys-e56c2f9bd024a0a9.rlib(config_file.o): in function `config_file_read':
config_file.c:(.text.config_file_read+0x48): undefined reference to `__stat_time64'
...etc...
It looks like the linker is having difficulty resolving the musl-specific time64 symbols, and it's not clear why.
This works fine if:
I use the x86_64-linux-musl target on both rust and musl-cross-make
I build musl-cross-make with MUSL_VER=1.1.24
I also wrote a little C program that uses both time and stat, and this builds on musl 1.2.0 on the cross compiler without any issue.
What's going on here? What's special about libgit2 which means that it can't find the right __time64 symbols?
The problem is that the MUSL libc that ships with Rust versions up to and including 1.44 is MUSL libc 1.1.X based, not 1.2.0.
When Rust builds libgit2 is also needs to build libgit2-sys, which is C code. When building libgit2-sys it uses the MUSL libc version that you've built and installed yourself with musl-cross-make. This is 1.2.0 by default, which has reworked time_t 32/64 bit support, having a dependency on __stat_time64 and various other similarly named methods (such as __time64).
However, when Rust is linking your final application it is using the version of MUSL libc shipped with Rust for the x86_64-linux-musl target, which doesn't include that new time_t support, and doesn't have __stat_time64, __time64, etc. So the link fails.
Right now you have 2 options:
Use musl-cross-make to build 1.1.24 of MUSL lib. I'm not 100% what version is included with Rust 1.44. It may be 1.1.22, although from my own testing I found 1.1.24 works just fine (as have you).
Build your own version of Rust and/or the target liblibc.rlib with your own version of MUSL libc. I've never managed to successfully achieve this myself, although this might be a good place to start if you want to try this.
The general issue of using libc shipped with Rust, instead of a locally provided version, is being worked on, e.g. here.
You could try the instructions listed in https://github.com/richfelker/libcompat_time32:
Add -Wl,--whole-archive -lcompat_time32 -Wl,--no-whole-archive to the link command line. Special hacks (like prepending -Wl, to -lcompat_time32) may be needed if libtool is intercepting and mangling the command line.
I would recommend trying out https://github.com/rust-embedded/cross : it sets up the environment for cross-compilation in docker and seamlessly works, even for the case highlighted here.
AFAICT, they recompile musl with the correct version.

Rust cross-compile -lpcap from macos to linux

I am trying to cross-compile my Rust project on Mac OS to Linux using cargo build --target=x86_64-unknown-linux-musl.
I installed the binary for Linux + musl cross-compilation on mac using brew install FiloSottile/musl-cross/musl-cross as I would ideally want a standalone binary.
I also installed the target using rustup target add x86_64-unknown-linux-gnu
And I have the following in my .cargo/config:
[target.x86_64-unknown-linux-musl]
linker = "x86_64-linux-musl-gcc"
However, I ran into issues with 2 libraries - sqlite3 and pcap:
= note: /usr/local/Cellar/musl-cross/0.9.8/libexec/bin/../lib/gcc/x86_64-linux-musl/6.4.0/../../../../x86_64-linux-musl/bin/ld: cannot find -lsqlite3
/usr/local/Cellar/musl-cross/0.9.8/libexec/bin/../lib/gcc/x86_64-linux-musl/6.4.0/../../../../x86_64-linux-musl/bin/ld: cannot find -lpcap
collect2: error: ld returned 1 exit status
I was able to solve the sqlite3 linker issue by adding features = ["bundled"] to my Cargo.toml file (similar to what is described here - https://users.rust-lang.org/t/linker-cannot-find-lsqlite3/23230/18) as that likely built it from source (which was great) but when I tried doing the same with pcap, it gave the following error:
the package `myProject` depends on `pcap`, with features: `bundled` but `pcap` does not have these features.
After reading somewhere I also tried (with low hopes) of providing the path to the installed libpcap on mac using RUSTPATH='-L/...' cargo build ... but that resulted, of course in undefined symbol errors.
Any ideas how can I get past this issue and cross compile my Rust project into a statically linked binary on macos to run on linux?
Cross compilation does not magically take care of libraries. You cannot just say "I want musl" and have something take care of all your dependencies.
The error message you are seeing is telling you exactly this: it cannot find libsqlite3 and libpcap.
The reason the error for sqlite disappears is because your sqlite library has a bundled feature, which replaces the linking with a built-in sqlite client. This, however, also requests the pcap bundled feature, which does not exist.
You have two options:
If you do not mind the performance loss in the bundled sqlite client, change your feature definition to target the feature of the dependency requiring sqlite
If you want the raw library itself, you will have to compile it for musl
No matter what happens, you will need to cross-compile libpcap for musl with the default sysroot provided by your musl compiler. As this varies per library, you will need to consult the libpcap documentation. once you have done so, you should be able to use the -lpcap flag, and the error will resolve itself.

LLVM won't build libLLVM-3.4.so

I'm trying to build llvm 3.4.2 on CentOS 7 with GCC 4.8.5. I can successfully build all of the libs, except libLLVM-3.4.so doesn't want to build - everything else gets created except that one. What's worse is I've managed it previously in the past, but can't do it again now.
I've tried both with CMake and autotools, with the same result. Is there an option I'm missing? Or some error in configuration possibly?
Found it - it was the --enable-shared flag to configure which causes the main shared library to be built. Confusingly this does something completely different from the CMake BUILD_SHARED_LIBS variable, which causes each of the individual libraries to be built as a shared library instead of static, but doesn't build the main shared library.
You can use
LLVM_BUILD_LLVM_DYLIB
when building from source.
The official docs say
BUILD_SHARED_LIBS is only recommended for use by LLVM developers. If you want to build LLVM as a shared library, you should use the LLVM_BUILD_LLVM_DYLIB option.
source: https://llvm.org/docs/CMake.html

crosscompile glibc for arm

Good day
Currently, I'm working on an embedded device based on arm-linux. I want to build GCC for my target architecture with Glibc. GCC builds successful, but I have trouble with Glibc build.
I use the latest version of Glibc (ftp.gnu.org/gnu/glibc/glibc-2.12.1.tar.gz) and port for them (ftp.gnu.org/gnu/glibc/glibc-ports-2.12.1.tar.gz)
my configuration line:
../../glibc-2.12.1/configure --host=arm-none-linux-gnueabi --prefix=/home/anatoly/Desktop/ARM/build/glibc-build --enable-add-ons --with-binutils=/home/anatoly/Desctop/ARM/toolchain/arm/bin/
configuration script work fine, but i get some compile error:
...
/home/anatoly/Desktop/ARM/src/glibc-2.12.1/malloc/libmemusage_pic.a(memusage.os): In function me':
/home/anatoly/Desktop/ARM/src/glibc-2.12.1/malloc/lmemusage.c:253: undefined reference to__eabi+read_tp'
...
I also tried using the old version (2.11, 2.10) but have the same error.
Does anybody know the solution for this problem?
Use a precompiled toolchain, like those provided by code sourcery.
If you want to make your own, optimised (premature optimization is the root of all evil), use crosstool-NG, which is a tool dedicated to cross-compilation toolchain building.
If you are not convinced, and want to do everything with your own hands, ask your question on the crosstool-NG mailing list.
Try substituting arm-linux-gnueabi for arm-none-linux-gnueabi. Check that a compiler, loader etc. with the prefix you used for "host" exist on your path.

Resources