Compiling Harbour with -fPIC

121 views
Skip to first unread message

tomalla5120x

unread,
Jun 6, 2025, 3:14:14 PMJun 6
to Harbour Developers
Here's what I want to achieve (I'm working on Ubuntu 22):
1. Compile Harbour into *.a libraries with -fPIC flag to make the code position-independent.
2. Create a *.prg file with some code and compile it into *.so library with Harbour VM functions linked in (hbmk2 "-hbdynvm" compile flag).

The problem is with the first step - for the love of me I can't compile Harbour into PIC *.a libraries. Make builds all object files exclusively in the "no PIC" mode.

The HB_BUILD_DYN=yes env variable enables additional compilation of the libharbour.so library. And sure thing the make tool adds the gcc "-fPIC" flag to compile object files used to build the libharbour.so library, for example:

gcc  -I. -I../../../../../include -W -Wall -O3   -ohvmall_dyn.o -DHB_DYNLIB -fPIC  -c ../../../hvmall.c

... and later on:

gcc -shared -L../../../../../lib/linux/gcc -L/usr/X11R6/lib64 -L/usr/X11R6/lib -Wl,-soname,libharbour.so.3.2  -o ../../../../../lib/linux/gcc/libharbour.so.3.2.0 (...) ../../../../../src/vm/vmmt/obj/linux/gcc/hvmall_dyn.o (...)

The static libraries however remain in the "no PIC" mode and the object files get compiled without the -fPIC flag:

gcc  -I. -I../../../../../include -W -Wall -O3   -ohvmall.o  -c ../../../hvmall.c

There's also HB_BUILD_SHARED=yes/no env variable but I'm not sure what it's exactly used for. Either way it doesn't seem to be relevant in my case.

I've managed to cheese the compilation process using the HB_USER_CFLAGS="-fPIC" env variable and thus directly adding the gcc compilation flag. But it truly feels like a hack and I'm afraid it would break something in the future when I least expect it.

Why isn't there any formal way to compile Harbour into static *.a libraries in PIC mode? Is it intentional? Or perhaps I'm missing something?

Your truly,
Tom

Aleksander Czajczynski

unread,
Jun 10, 2025, 1:02:58 PMJun 10
to harbou...@googlegroups.com
tomalla5120x wrote:
Why isn't there any formal way to compile Harbour into static *.a libraries in PIC mode? Is it intentional? Or perhaps I'm missing something?D

HB_USER_CFLAGS= is not a hack itself, it is formal way to add flags in advanced setups.

no -PIC in static build is traditionally there, because of performance penalty caused by enabling it, on architectures like x86 and MIPS. This is less of an issue on x64 or today in general.

Though if you go all dynamic/shared, then -hbdynvm should do it, hbmk2 -help states:
-pic[-] create position independent object code (always enabled in -hbdyn/-hbdynvm modes)

So you shouldn't have a problem, except in a situation, where you do different incremental builds in the same working directory.
If you happen to do: hbmk2 -inc -hbdynvm then consider adding something like -workdir=picobj

Best regards, Aleksander


tomalla5120x

unread,
Jun 10, 2025, 1:43:43 PMJun 10
to Harbour Developers
"HB_USER_CFLAGS= is not a hack itself, it is formal way to add flags in advanced setups."

If I set HB_USER_CFLAGS="-fPIC" along with the HB_BUILD_DYN=yes option the gcc receives the -fPIC flag twice - once from my HB_USER_CFLAGS value and once because of the HB_BUILD_DYN option. Sure it serves its purpose but it doesn't look good.

"Though if you go all dynamic/shared, then -hbdynvm should do it, hbmk2 -help states:
-pic[-] create position independent object code (always enabled in -hbdyn/-hbdynvm modes)"

The problem is the -pic option in hbmk2 refers to the files actually compiled by hbmk2. All the option -hbdynvm does is link in additional Harbour static libraries like: -lhbextern -lhbdebug -lhbvmmt -lhbrtl and so on which already have to exist at this point. And if they're not PIC, the linking fails.

I've eventually solved the problem in a more elegant manner. I compile Harbour with the HB_BUILD_DYN=yes option so that the build process creates the dynamic library libharbour.so. Then when running hbmk2 I use two options: -lharbour and -hbdyn. This way I build my shared library with a dependency to libharbour.so. Sure, I need two shared libraries in the end but on the plus side I don't mess with the Harbour build process too much.

But this raises the question: if the -hbdynvm option builds a shared library and links in Harbour static libraries which are required to have PIC, why the Harbour build process doesn't allow it out of the box? As if the -hbdynvm option was designed with other operating systems in mind which don't use PIC like Windows. I understand why traditionally Harbour static libraries are compiled without PIC (a performance penalty) but the Makefile should at least allow for such option in my opinion.

Tom

Reply all
Reply to author
Forward
0 new messages