Skip to content
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

cross-compiling on Linux to macOS target #272

Open
efa opened this issue Nov 8, 2022 · 21 comments
Open

cross-compiling on Linux to macOS target #272

efa opened this issue Nov 8, 2022 · 21 comments

Comments

@efa
Copy link

efa commented Nov 8, 2022

hi,
I want try to cross-build from Linux to macOS.
This is something I regularly do for c files, so if hbmk2 can leave the .c file in tmp, I can manually cross-compile to both x64 and arm64
Please add an option to not delete temporary .c files

@alcz
Copy link
Contributor

alcz commented Nov 8, 2022

There is incremental build mode which leaves those files.
Use hbmk2 -inc option or the same option in .hbp file, it will then put your .c files in .hbmk/ subdir.
You can also setup cross compiling Harbour environment so that hbmk2 executes your .c cross compiler. Even if you prefer manually executing that, you will later need cross compiled Harbour libs anyway.

For cross compiling you need to setup few environment variables before
https://groups.google.com/g/harbour-devel/c/-MKTZ8eHBxU/m/Seez9Iw14V4J
https://groups.google.com/g/harbour-devel/c/gt4OPyThLhA/m/aleR6vFXAiUJ

Please search or ask harbour-devel, harbour-users mailing lists for some examples.

@lailton
Copy link
Contributor

lailton commented Nov 9, 2022

You can combine too with -workdir=output_folder
examples:
https://github.com/harbour/core/search?q=workdir&type=code

@efa
Copy link
Author

efa commented Nov 13, 2022

Following your hints, I made some basic tests.
I set the env vars as so:

 export OSXROOT=/opt/osxcross
 export OSX=$OSXROOT/target/bin
 export OHOST=x86_64-apple-darwin18
 export OCROSS=$OHOST-

 export HB_BUILD_3RDEXT=no
 export HB_BUILD_CONTRIBS=no
 export HB_BUILD_DYN=no
 export HB_BUILD_NAME=$OHOST
 export HB_CCPATH=$OSX
 export HB_CCPREFIX=$OCROSS
 export HB_COMPILER=clang
 export HB_CPU=x86-64
 export HB_HOST_BIN=~/c/harbour-core/bin/linux/gcc
 export HB_PLATFORM=darwin
 export HB_WITH_CURSES=no
 export HB_USER_LDFLAGS="-L$OSXROOT/target/lib/"

I can compile the .c sources to .o and I can confirm are darwin obj:

$ file hello.o _hbmkaut_hello.o
hello.o:          Mach-O 64-bit x86_64 object, flags:<|SUBSECTIONS_VIA_SYMBOLS>
_hbmkaut_hello.o: Mach-O 64-bit x86_64 object, flags:<|SUBSECTIONS_VIA_SYMBOLS>

but the link stage stop.
The first thing that is missing is the lib 'hbextern' (and maybe the other follow) built for macOS/darwin:

$ ~/c/harbour-core/bin/linux/gcc/hbmk2 -workdir=. -inc hello.prg
hbmk2: Processing environment options: -plat=darwin -comp=clang -cpu=x86-64
       -build=x86_64-apple-darwin18
hbmk2: Compiling Harbour sources...
Harbour 3.2.0dev (r-2084736466)
Copyright (c) 1999-2021, https://harbour.github.io/
Compiling 'hello.prg'...
Lines 7, Functions/Procedures 1
Generating C source output to './hello.c'... Done.
hbmk2: Compiling...
hbmk2: Linking... hello
ld: library not found for -lhbextern
clang: error: linker command failed with exit code 1 (use -v to see invocation)
hbmk2: Error: Running linker. 1
x86_64-apple-darwin18-clang ./hello.o './_hbmkaut_hello.o'  -L/opt/osxcross/target/lib/ -lhbextern -lhbdebug -lhbvm -lhbrtl -lhblang -lhbcpage -lgtcgi -lgtpca -lgtstd -lgttrm -lhbrdd -lhbuddall -lhbusrrdd -lrddntx -lrddcdx -lrddnsx -lrddfpt -lhbrdd -lhbhsx -lhbsix -lhbrtl -lhbvm -lhbmacro -lhbcplr -lhbpp -lhbcommon -lm -lpcre -lz   -Wl,-headerpad,400 -o hello -L'/home/efa/c/harbour-core/lib'

I see there are no release/tag on github, are there some (recent) pre-built library mach/x86-64 (and maybe arm64) .a/.dylib, so I can avoid to cross-build all the harbour env, maybe I unable to do?
THANKS

@efa
Copy link
Author

efa commented Nov 13, 2022

I saw the file harbour-1.0.1-darwin_9.5.0.bin.tar.gz at:
https://sourceforge.net/projects/harbour-project/files/binaries-osx/1.0.1/
is dated 2008, and I checked the .a lib inside ./usr/local/lib/harbour/, it miss:
hbuddall
rddnsx

@alcz
Copy link
Contributor

alcz commented Nov 13, 2022

Don't use those old libraries.
Depending on how complete your toolchain is (macOS system libs, headers), you should be able to build cross-compiled libraries with those settings just by issuing make.
Lately nobody contributed automatic build configurations, i think macOS binaries could be even built by Github Actions. I can make a one time build on a random x64 mac here, i'll share a link when it's done.

@alcz
Copy link
Contributor

alcz commented Nov 13, 2022

Not warranties whatsoever, but here they are.
https://os.allcom.pl/hb/bin/harbour-3.2.0dev-r2211112015-darwin.bin.tar.gz
https://os.allcom.pl/hb/bin/harbour-3.2.0dev-r2211112015-darwin.binsrc.tar.gz

Harbour Build Info
---------------------------
Version: Harbour 3.2.0dev (r2211112015)
Compiler: LLVM/Clang C 12.0 (clang-1200.0.32.29) (64-bit)
Platform: Darwin 19.6.0 x86_64
PCode version: 0.3
ChangeLog last entry: 2022-11-11 21:15 UTC+0100 Przemyslaw Czerpak (druzus/at/poczta.onet.pl)
ChangeLog ID: 9d578a24e6d5a2c3d20b68026b49147b4ccbb9cb
Built on: Nov 13 2022 19:37:05
Build options: (Clipper 5.3b) (Clipper 5.x undoc) 

@alcz alcz changed the title option to not delete /tmp/hbmk_hash.dir/name.c file cross-compiling on Linux to macOS target Nov 13, 2022
@efa
Copy link
Author

efa commented Nov 17, 2022

I got another link error:

$ ~/c/harbour-core/bin/linux/gcc/hbmk2 -workdir=. -inc hello 
hbmk2: Processing environment options: -plat=darwin -comp=clang -cpu=x86-64
       -build=x86_64-apple-darwin18
hbmk2: Processing local make script: hbmk.hbm
hbmk2: Compiling Harbour sources...
Harbour 3.2.0dev (r-2084736466)
Copyright (c) 1999-2021, https://harbour.github.io/
Compiling 'hello.prg'...
Lines 7, Functions/Procedures 1
Generating C source output to './hello.c'... Done.
hbmk2: Compiling...
hbmk2: Linking... hello
Undefined symbols for architecture x86_64:
  "___darwin_check_fd_set_overflow", referenced from:
      _hb_fsCanAccess in libhbrtl.a(filesys.o)
      _hb_fsPoll in libhbrtl.a(filesys.o)
ld: symbol(s) not found for architecture x86_64
clang: error: linker command failed with exit code 1 (use -v to see invocation)
hbmk2: Error: Running linker. 1
x86_64-apple-darwin18-clang ./hello.o './_hbmkaut_hello.o'  -L/home/efa/c/harbour.src/lib/darwin/clang -L/opt/osxcross/target/lib/ -lhbextern -lhbdebug -lhbvm -lhbrtl -lhblang -lhbcpage -lgtcgi -lgtpca -lgtstd -lgttrm -lhbrdd -lhbuddall -lhbusrrdd -lrddntx -lrddcdx -lrddnsx -lrddfpt -lhbrdd -lhbhsx -lhbsix -lhbrtl -lhbvm -lhbmacro -lhbcplr -lhbpp -lhbcommon -lm -lpcre -lz   -Wl,-headerpad,400 -o hello -L'/home/efa/c/harbour-core/lib'

Now I'm generating the Darwin19 osxcross compiler tools to see if make difference, as my toolchain target 18 while I saw you used 19

@efa
Copy link
Author

efa commented Nov 17, 2022

OK, now work:

$ ~/c/harbour-core/bin/linux/gcc/hbmk2 -workdir=. -inc hello 
hbmk2: Processing environment options: -plat=darwin -comp=clang -cpu=x86-64
       -build=x86_64-apple-darwin19
hbmk2: Processing local make script: hbmk.hbm
hbmk2: Compiling Harbour sources...
Harbour 3.2.0dev (r-2084736466)
Copyright (c) 1999-2021, https://harbour.github.io/
Compiling 'hello.prg'...
Lines 7, Functions/Procedures 1
Generating C source output to './hello.c'... Done.
hbmk2: Compiling...
hbmk2: Linking... hello

$ file hello
hello: Mach-O 64-bit x86_64 executable, flags:<NOUNDEFS|DYLDLINK|TWOLEVEL|PIE>

$ ls -l hello
-rwxr-xr-x 1 efa efa 1191000 Nov 17 22:55 hello

Will try to build something more complex now, with other deps.

Did you have an arm64 build too?

@efa
Copy link
Author

efa commented Nov 23, 2022

I can say the cross-build from harbour source to macOS/x86_64 work well using CLANG and OSXCROSS: https://github.com/tpoechtrager/osxcross
Maybe you can flag Linux to macOS as supported in the platform matrix: https://github.com/harbour/core#platform-matrix

Now I want try build a binary for Apple Silicon.
Did you have the harbour lib built for ARM64 ?

thank you in advance

@lailton
Copy link
Contributor

lailton commented Nov 23, 2022

@alcz
Copy link
Contributor

alcz commented Nov 23, 2022

Thanks for reporting! Good to know that it's possible to make such cross-build. Seems more practical for automated builds than personal usage.

@efa
Copy link
Author

efa commented Nov 23, 2022

@efa, Here you have harbour for mac arm64: https://drive.google.com/file/d/1k_F5ZznwxBayYGI7_AQl1tWqk6WcUOYj/view?usp=share_link

what Darwin version do you use? 20, 21 or 22?
I'm trying with: macOS/SDK 11.1, Xcode 12.3 , darwin 20.2

@efa
Copy link
Author

efa commented Nov 23, 2022

found, confirm do you used macOS 13.0 ?

@efa
Copy link
Author

efa commented Nov 24, 2022

I got lot of warnings in the link phase:
ld: warning: object file (/home/efa/c/harbour_macOS.arm64/harbour_arm64/lib/darwin/clang/libhbrtl.a(arc4.o)) was built for newer macOS version (13.0) than being linked (11.1)
but the binary is generated and is a macOS/arm64:

$ file hello
hello: Mach-O 64-bit arm64 executable, flags:<NOUNDEFS|DYLDLINK|TWOLEVEL|PIE>

@lailton
Copy link
Contributor

lailton commented Nov 24, 2022

Yep, 13.0.1 (22A400) MacOS Ventura

@efa
Copy link
Author

efa commented Nov 24, 2022

Seems more practical for automated builds than personal usage

I use a simple bash script that set all the env vars, than run hbmk2

@lailton
Copy link
Contributor

lailton commented Nov 24, 2022

Looks interesting, I remember few years ago I did the same thing but for mingw to compile on MACOS exes for windows.

Harbour is really fantastic :)

@efa
Copy link
Author

efa commented Nov 24, 2022

#!/bin/sh
# Copyright 2022 Valerio Messina, harbour 1.0.0 2022/11/23
#   harbour is free software: you can redistribute it and/or modify
#   it under the terms of the GNU General Public License ver 3
# this script (cross)compile a PRG file with harbour
# Syntax: $ harbour <source.prg> [mac [arm]]

if (test "" = "$1") then
   echo ERROR: harbour need a PRG file name
   echo "Syntax: $ harbour <source.prg> [mac [arm]]"
   exit
fi
rm *.o *.c 2> /dev/null
deps="hbct.hbc xhb.hbc"
#deps=""

if (test "$2" = "mac") then
   echo "Cross-building for macOS64 ..."
   # set env vars for osxcross ...
   export SDK_VERSION=11.1   # set built tools generation
   export ODVER=20.2
   export OHOST=i386-apple-darwin$ODVER   # only till darwin17
   export OHOST=x86_64-apple-darwin$ODVER
   if (test "$3" = "arm") then
      echo "arm64 Apple Silicon"
      export OHOST=arm64-apple-darwin$ODVER
   fi
   export OCROSS=$OHOST-
   export OSXROOT=/opt/osxcross
   export OSX=$OSXROOT/target/bin
   export OSXDEPS=$OSXROOT/target/macports
   export OSXQUARTZ=$OSXROOT/target/quartz
   export OSXCROSS_TARGET=darwin$ODVER
   export MACOSX_DEPLOYMENT_TARGET=$SDK_VERSION   # used for macports
   export OSXCROSS_PKG_CONFIG_USE_NATIVE_VARIABLES=1
   export PKG_CONFIG_LIBDIR=$OSXDEPS/pkgs/opt/local/lib/pkgconfig:$OSXDEPS/pkgs/opt/local/share/pkgconfig
   export PKG_CONFIG_PATH=$PKG_CONFIG_LIBDIR
   export PATH=$OSX:$PATH

   # set env vars for harbour ...
   export TOOLCHAINDIR=$OSXROOT
   export TOOLCHAIN_DIR=$OSXROOT
   export HB_BUILD_3RDEXT=no
   export HB_BUILD_CONTRIBS=no
   export HB_BUILD_DYN=no
   export HB_BUILD_NAME=$OHOST
   export HB_CCPATH=$OSX
   export HB_CCPREFIX=$OCROSS
   export HB_COMPILER=clang
   export HB_CPU=x86-64
   if (test "$3" = "arm") then
      export HB_CPU=arm
   fi
   export HB_HOST_BIN=$HOME/c/harbour-core/bin/linux/gcc
   export HB_PLATFORM=darwin
   export HB_WITH_CURSES=no
   export HB_USER_LDFLAGS="-L$HOME/c/harbour_macOS.amd64/lib/darwin/clang -L$OSXROOT/target/lib/"
   if (test "$3" = "arm") then
      export HB_USER_LDFLAGS="-L$HOME/c/harbour_macOS.arm64/lib/darwin/clang -L$OSXROOT/target/lib/"
   fi
else   # native compile
   echo "Native building for Linux64 ..."
fi

echo "Running: $HOME/c/harbour-core/bin/linux/gcc/hbmk2 -workdir=. -inc $1 $deps"
$HOME/c/harbour-core/bin/linux/gcc/hbmk2 -workdir=. -inc $1 $deps
#rm *.o *.c 2> /dev/null
echo ""

@efa
Copy link
Author

efa commented Nov 24, 2022

do something similar targeting windows

@JoseQuintas
Copy link

JoseQuintas commented Nov 24, 2022 via email

@efa
Copy link
Author

efa commented Nov 25, 2022

A build for another SO is an automated build

sorry, I can't understand what you mean.
Locally I can do a manual or automatic build for my OS, but also a manual or automatic cross-build for another OS

With manual build I mean invoking gcc or clang from the command prompt.
While automatic build I mean invoking gcc or clang from Makefile or complex script
In both case the target can be local host OS, or a different one in case of cross-build

Remotely, like with github machines, I suppose are the same all 4 combinations.
Is this right?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

4 participants