[x86_64] Cross-compiling on Linux

Forum for developers, compiling on Threos, etc.
Post Reply
aron
Posts: 26
Joined: Tue Dec 05, 2017 11:06 am

[x86_64] Cross-compiling on Linux

Post by aron » Mon Apr 16, 2018 9:36 am

You need the following tools to be install before proceed:
  • cat
  • rm
  • wget
  • xz
  • cpio
  • bash
  • awk
To download/extract the necessary packages follow these steps:
NOTE: Always double-check every single command, do not copy-paste them. However, the listed commands below might work perfectly on you system (which was the intention), but we cannot guarantee all commands match with your system.
  1. Create an empty folder, and cd into it

    Code: Select all

    $ mkdir threos
    $ cd threos
    
  2. Download the script from http://threos.io/files/sdk_dl.sh
    (note: we added the -O sdk_dl.sh to the wget, this is done to overwrite the previous script instead of making new files every time)

    Code: Select all

    $ wget http://threos.io/files/sdk_dl.sh -O sdk_dl.sh
    
  3. If you want, you can adjust the variables at the beginning of the shell script. In case you do not modify anything, the script will make a new directory named prefix, and downloads/extracts data into it.
    The default script will download packages belong to the x86_64 architecture.
    WARNING! The script will remove that directory.
  4. After check the content of the downloaded script, add executable right:

    Code: Select all

    $ chmod +x sdk_dl.sh
    
  5. Execute the script (this will take a while):

    Code: Select all

    $ ./sdk_dl.sh
    
  6. Missing packages will be printed to the standard output, and the script exits with non-zero exit code.
To compile the hello world example:
  1. cd prefix
  2. export MYROOT=$PWD
  3. cd usr/src/examples
  4. compile with your native gcc

    Code: Select all

    $ gcc -ffreestanding -nostdlib --no-builtin -m64 -mcmodel=large -fno-stack-protector -static-libgcc -Wl,-q,-x -I$MYROOT/usr/include -L$MYROOT/usr/lib -L$MYROOT/lib -fPIE $MYROOT/usr/lib/Scrt1.o hello1.c -lc -ldevlib -lkrnlext
    
    Command line to build a statically linked version:

    Code: Select all

    $ gcc -ffreestanding -nostdlib --no-builtin -m64 -mcmodel=large -fno-stack-protector -static-libgcc -Wl,-q,-x -I$MYROOT/usr/include -L$MYROOT/usr/lib -L$MYROOT/lib -static $MYROOT/usr/lib/crt0.o hello1.c -lc -ldevlib -lkrnlext
    
    Explanation:
    • Compile to bare machine: -ffreestanding -nostdlib --no-builtin
    • Use the large memory model (selecting the proper memory model really matters in statically linked programs, PIEs are good as are): -m64 -mcmodel=large
    • Disable the stack protector, it links against symbols in the glibc: -fno-stack-protector
    • Link libgcc statically (this is mandatory even for PIEs), otherwise the program will be linked to the libraries installed with your gcc (which ABI does not match): -static-libgcc
    • Ask the linker to keep some info for us (really matters for statically linked programs): -Wl,-q,-x
    • Statically programs that will be loaded with devman shall include -Wl,-N
    • Build the target environment (include and library search directories): -I$MYROOT/usr/include -L$MYROOT/usr/lib -L$MYROOT/lib
    • Specify output executable mode: -fPIE (NOTE: statically linked programs shall use -static)
    • Select the CRT to use: $MYROOT/usr/lib/Scrt1.o (NOTE: statically linked programs shall use $MYROOT/usr/lib/crt0.o)
    • Specify sources/objects: hello1.c (in our case)
    • Specify libraries to link with: -lc -ldevlib -lkrnlext (there are probably always mandatory, additional libraries may be required)
Separate variables for makefiles:

Code: Select all

LIBS = -lc -ldevlib -lkrnlext
CFLAGS_DYNAMIC  = -ffreestanding -nostdlib --no-builtin -m64 -mcmodel=large -fno-stack-protector -I$MYROOT/usr/include -fPIC
LDFLAGS_DYNAMIC = -ffreestanding -nostdlib --no-builtin -m64 -static-libgcc -fPIE $MYROOT/usr/lib/Scrt1.o -L$MYROOT/usr/lib -L$MYROOT/lib -Wl,-q,-x
CFLAGS_STATIC   = -ffreestanding -nostdlib --no-builtin -m64 -mcmodel=large -fno-stack-protector -I$MYROOT/usr/include -static
LDFLAGS_STATIC  = -ffreestanding -nostdlib --no-builtin -m64 -static-libgcc -static $MYROOT/usr/lib/crt0.o -L$MYROOT/usr/lib -L$MYROOT/lib -Wl,-q,-x,-N

Post Reply