Open M1cha opened 6 years ago
@M1cha Cross compiling with CGO (which fscrypt uses) can be a bit of a pain, so here are the basic steps.
You need to get all the components to build fscrypt, but for the target architecture. This means you need:
libpam
(and its headers) for the target architecture. GOARCH
set the the target architecture.Once you have everything installed, a cross compile build can be invoked like:
GOARCH=arm CGO_ENABLED=1 CC=arm-linux-gnueabihf-gcc make
This gives you arm output files:
> file bin/fscrypt
bin/fscrypt: ELF 32-bit LSB executable, ARM, EABI5 ...
> file bin/pam_fscrypt.so
bin/pam_fscrypt.so: ELF 32-bit LSB shared object, ARM, EABI5
I changed this to a documentation issue, mainly because the full process is really hairy.
Here are the full steps to get the above commands working on my Ubuntu Bionic 18.04 system:
/etc/apt/sources.list
to properly download the correct architectures.
/etc/apt/sources.list
looks like this.sudo apt update && sudo apt upgrade
libpam0g-dev
for your target architecture:
sudo apt install libpam0g-dev:armhf
sudo apt install gcc-arm-linux-gnueabihf
GOARCH=arm
CGO_ENABLED=1
(as cross compiling disables CGO by default)CC=arm-linux-gnueabihf-gcc
make
GOARCH=arm CGO_ENABLED=1 CC=arm-linux-gnueabihf-gcc make
go
command directlyGOARCH=arm CGO_ENABLED=1 CC=arm-linux-gnueabihf-gcc go build ./cmd/fscrypt
This can also be confusing when Debian, GNU, and Go all use different names to refer to architectures. The following chart is helpful (source):
Go's GOOS |
Debian's arch |
GNU's target triple |
---|---|---|
386 |
i386 |
i686-linux-gnu |
amd64 |
amd64 |
x86_64-linux-gnu |
arm64 |
arm64 |
aarch64-linux-gnu |
arm |
armhf |
arm-linux-gnueabihf |
ppc64le |
ppc64el |
powerpc64le-linux-gnu |
s390x |
s390x |
s390x-linux-gnu |
EDIT: Of course there are other GOOS
values not listed here, but they are not supported by Ubuntu, so they are probably less relevant for cross compiling.
Any idea why this happens? Toolchain is musl-cross. Host OS is Arch Linux.
Edit: Also tried: GO_FLAGS=-buildmode=pie GOARCH=arm64 CGO_ENABLED=1 make [...]
This only happens on '-static' build. Shared does work. I think this is because libpam is compiled as 'shared' always.
$ GOARCH=arm64 CGO_ENABLED=1 make LDFLAGS="-static -ldl -laudit -lcap-ng" CFLAGS="-O2 -g0 -s -pipe -pthread -Wp,-I/home/user/android/sysroot-aarch64/usr/include -Wl,-L/home/user/android/sysroot-aarch64/usr/lib" PREFIX="/tmp/myout" CGO_CFLAGS="--sysroot /home/user/android/sysroot-aarch64" CGO_LDFLAGS="--sysroot /home/user/android/sysroot-aarch64"
go build --ldflags '-s -w -X "main.version=v0.2.7-44-g636698b" -extldflags "-static -ldl -laudit -lcap-ng"' -trimpath -o bin/fscrypt ./cmd/fscrypt
# github.com/google/fscrypt/cmd/fscrypt
/usr/lib/go/pkg/tool/linux_amd64/link: running /home/user/android/gcc-musl-aarch64/bin/aarch64-linux-musl-gcc failed: exit status 1
/media/LinuxPart2/musl-cross-make/output64/bin/../lib/gcc/aarch64-linux-musl/9.2.0/../../../../aarch64-linux-musl/bin/ld: read-only segment has dynamic relocations
collect2: error: ld returned 1 exit status
make: *** [Makefile:95: bin/fscrypt] Fehler 2
Edit: The solution is -buildmode=exe
. Not tested the binary yet but at least it does compile.
GO_FLAGS=-buildmode=exe GOARCH=arm64 CGO_ENABLED=1 make LDFLAGS="-static -ldl -laudit -lcap-ng" CFLAGS="-O2 -g0 -s -static -pipe -pthread -Wp,-I/home/user/android/sysroot-aarch64/usr/include -Wl,-L/home/user/android/sysroot-aarch64/usr/lib" PREFIX="/tmp/myout" CGO_CFLAGS="--sysroot /home/user/android/sysroot-aarch64" CGO_LDFLAGS="--sysroot /home/user/android/sysroot-aarch64"
@josephlr Could you provide more details regarding "how to cross-compile with rootfs" ? When I build with "GOARCH=arm64 CGO_ENABLED=1 CC=aarch64-linux-gnu-gcc make" then i get: /usr/lib/gcc-cross/aarch64-linux-gnu/7/../../../../aarch64-linux-gnu/bin/ld: cannot find -lpam /usr/lib/gcc-cross/aarch64-linux-gnu/7/../../../../aarch64-linux-gnu/bin/ld: cannot find -lpam
and i try to fix it with below parammeter(libpam is already installed in arm-rootfs): CGO_CFLAGS="--sysroot /home/work/arm-rootfs" -lpam is also cannot be found.
I'm looking some more into this and would like some feedback on use-cases.
It looks like both cases are 64bit arm, on these systems, would you need to use user login passwords (i.e. do you need to make sure the encryption password matches the user's login passphrase), or do you just need normal passwords?
@JasonShigit which Linux distro are you using for the host? I know @BlueMax was using Arch Linux.
If it turns out user passphrases are not needed, we can just add a flag to disable the PAM dependency at compile time. This should remove all need for cgo and libpam, which should make cross compiling much, much easier.
@JasonShigit it looks like the linker can't find libpam because the search path is incorrect. Fixing this might be distro/toolchain specific. I'm not familiar with using a rootfs for this case. Do you have more information?
I'm looking some more into this and would like some feedback on use-cases.
It looks like both cases are 64bit arm, on these systems, would you need to use user login passwords (i.e. do you need to make sure the encryption password matches the user's login passphrase), or do you just need normal passwords?
@JasonShigit which Linux distro are you using for the host? I know @BlueMax was using Arch Linux.
If it turns out user passphrases are not needed, we can just add a flag to disable the PAM dependency at compile time. This should remove all need for cgo and libpam, which should make cross compiling much, much easier.
Thanks for your reply. My host OS is ubuntu18.04, and arm target os is ubuntu18.04 too. So user passphrases is required, i think.
Issue fixed with CGO_LDFLAGS="--sysroot /home/work/arm-rootfs"
GOOS=linux GOARCH=arm64 CGO_ENABLED=1 CC=aarch64-linux-gnu-gcc CGO_LDFLAGS="--sysroot /home/work/arm-rootfs" make
In case it helps folks, I've been able to cross compile from macOS to linux, using zig. Basically following the instructions at https://dev.to/kristoff/zig-makes-go-cross-compilation-just-work-29ho (with a little adjustment to translate GOOS
and GOARCH
can some explain the below: $make mkdir -p /home/venk/mxcam/P7/mxcam74011/pkg_root/target/lib ( cd fscrypt-0.2.5 && \ PKG_CONFIG_PATH=/home/venk/mxcam/P7/mxcam74011/pkg_root/target/usr/lib/pkgconfig PKG_ROOT=/home/venk/mxcam/P7/mxcam74011/pkg_root/target \
#aarch64-linux-gnu \
#--without-selinux --without-libmount --without-blkid --enable-dependency-tracking \
CFLAGS="-mcpu=cortex-a53 -mfpu=crypto-neon-fp-armv8 -flto=16 -Wundef -DGLIBC_VERSION=022800 -DHAS_WINPACKAGE=0 -DHOST_TOOL=0 -DOPENSSL_MINIMAL=0 -DKERNEL_MODULE_SET=3 -DHAS_DEVICETREE=1 -DHAS_EMMC=1 -DMIC_BLOW_FUSE=0 -DVOIP_VERSION=3 -DWITH_H264=1 -DANDROMEDA=1 -DWITH_ALSA=0 -DWITH_ONVIF=1 -DWITH_STRATOCAST=1 -DAUDIOTEST_LEVELS=320 -DMX_PLUGINS=1 -DMX_PLUGINS_RAW_IMAGE=1 -DWITH_LXC=0 -DARCH_ARM -DBAYER_SUPPORT=0 -DP7_FRAMEHEADER=1 -DBOOST_PP_VARIADICS_MSVC=0 -D_FILE_OFFSET_BITS=64 -DAS2V1_INTEGRATED=1 -DMXACTIVITY_SENSOR_USE_DESIRED_FRAME_RATE=1 -DIMA_DENOISING=1 -DTHERMAL_EXTREMUM_POSITION=1 -DWITH_PYTHON=0 -DMX_OEM=0 -DNUMOFACTIONHANDLERS=20 -DMXANALYTICS_INTEGRATED=1 -DMXANALYTICS_PEOPLE_COUNTING=1 -DMXANALYTICS_HEAT_MAP=1 -std=gnu99 -O2 -w -Wno-undef -std=gnu11 -I/home/venk/mxcam/P7/mxcam74011/pkg_root/target/usr/include/security" \
LDFLAGS="-mcpu=cortex-a53 -mfpu=crypto-neon-fp-armv8 -flto=16 -O2 -L/home/venk/mxcam/P7/mxcam74011/pkg_root/target/usr/lib -L/home/venk/mxcam/P7/mxcam74011/pkg_root/target/lib" \
gccgoflags=" -L/home/venk/mxcam/P7/mxcam74011/pkg_root/target/usr/local/go/bin" \
#CGO_LDFLAGS=" -L/home/venk/mxcam/P7/mxcam74011/pkg_root/target/usr/arm-linux-gnueabihf/lib " \
GOARCH=arm \
CGO_ENABLED=1 \
CC=gcc-arm-linux-gnueabihf \
make \
) make[1]: Entering directory '/home/venk/mxcam/P7/mxcam74011/source-base/fscrypt/fscrypt-0.2.5' go build --ldflags '-s -w -X "main.version=MX-V5-7-0-24-39-g0160143edf" -X "main.buildTime=Mo 9. Mai 16:57:11 CEST 2022" -extldflags ""' -o bin/fscrypt ./cmd/fscrypt go build: when using gccgo toolchain, please pass linker flags using -gccgoflags, not -ldflags
x86_64-linux-gnu-gccgo-9: error: unrecognized command line option ‘-marm’; did you mean ‘-mabm’?
x86_64-linux-gnu-gccgo-9: error: unrecognized command line option ‘-marm’; did you mean ‘-mabm’?
x86_64-linux-gnu-gccgo-9: error: unrecognized command line option ‘-marm’; did you mean ‘-mabm’?
x86_64-linux-gnu-gccgo-9: error: unrecognized command line option ‘-marm’; did you mean ‘-mabm’?
x86_64-linux-gnu-gccgo-9: error: unrecognized command line option ‘-marm’; did you mean ‘-mabm’?
x86_64-linux-gnu-gccgo-9: error: unrecognized command line option ‘-marm’; did you mean ‘-mabm’? make[1]: [Makefile:89: bin/fscrypt] Error 2 make[1]: Leaving directory '/home/venk/mxcam/P7/mxcam74011/source-base/fscrypt/fscrypt-0.2.5' make: [Makefile:34: done/configure] Error 2
how to build for 32bit?
arm-v7a-linux-gnueabihf-gcc: error: unrecognized command line option '-m64'
arm-v7a-linux-gnueabihf-gcc: error: unrecognized command line option '-m64'
arm-v7a-linux-gnueabihf-gcc: error: unrecognized command line option '-m64'
arm-v7a-linux-gnueabihf-gcc: error: unrecognized command line option '-m64' make[1]: [Makefile:89: bin/fscrypt] Error 2 make[1]: Waiting for unfinished jobs.... make[1]: [Makefile:92: bin/pam_fscrypt.so] Error 2 make[1]: Leaving directory '/home/venk/mxcam/P7/mxcam74011/source-base/fscrypt/fscrypt-0.2.5' make: [Makefile:91: done/build] Error 2
Anyone who has managed to build a static build of this for arm or aarch64? Dynamically linked works fine, but static....
Apparently cross-compiling fscrypt doesn't work:
This problem looks really weird since all the symbols it's complaining about are actually there.