google/cpu_features

Can't build as static OR shared in Haiku (OS)

victroniko opened this issue ยท 8 comments

Hello, I'm trying to build the VOLK libraries on Haiku (operating system). VOLK uses cpu_features as a submodule, I want/need to do a shared build but it doesn't work.

To isolate the problem I'm trying to build cpu_features alone. It seems no matter how I force it, explicitly using -DBUILD_SHARED_LIBS=ON and -DBUILD_PIC=ON args or even directly fumbling with those in CMakeLists.txt (ugly!) result is the same:

...
ld: CMakeFiles/list_cpu_features.dir/src/utils/list_cpu_features.c.o: relocation R_X86_64_PC32 against symbol 'gBumpAllocator' can not be used when making a shared object; recompile with -fPIC
ld: final link failed: bad value
collect2: error: ld returned 1 exit status
CMakeFiles/list_cpu_features.dir/build.make:97: recipe for target 'list_cpu_features' failed

The reason to try a shared build is because the static one also doesn't build:

...
ld: CMakeFiles/list_cpu_features.dir/src/utils/list_cpu_features.c.o: in function 'CreateTree':
list_cpu_features.c:(.text+0x51d): undefined reference to 'GetX86Info'
ld: list_cpu_features.c:(.text+0x529): undefined reference to 'GetX86CacheInfo'
ld: list_cpu_features.c:(.text+0x531): undefined reference to 'FillX86BrandString'
ld: list_cpu_features.c:(.text+0x617): undefined reference to 'GetX86Microarchitecture'
ld: list_cpu_features.c:(.text+0x61e): undefined reference to 'GetX86MicroarchitectureName'
ld: list_cpu_features.c:(.text+0x668): undefined reference to 'GetX86FeaturesEnumValue'
ld: list_cpu_features.c:(.text+0x677): undefined reference to 'GetX86FeaturesEnumName'
collect2: error: ld returned 1 exit status
CMakeFiles/list_cpu_features.dir/build.make:97: recipe for target 'list_cpu_features' failed

In both cases, list_cpu_features is the culprit. I'm stuck about how to properly approach this. Do I "disable" said command as recommended here, and build shared anyway? Or is there something to possibly do in cpu_features side that'll enable a correct static build?

FYI, version of things in Haiku are as follows: cmake 3.24.2-1, gcc 11.2.0, binutils 2.31.1-2

Any help will be appreciated :)

@victroniko, actually we don't have any architecture support for Haiku OS., see https://github.com/google/cpu_features#whats-supported. Since for older processors we have to get the processor information from the OS, that's why you get errors like undefined reference to DetectFeaturesFromOs and OverrideOsPreserves...

image

I added test commit 7badfd0 and all works fine:
image

tested on Haiku x86 32 bit via VirtualBox

probably for old processors we can get info via sysinfo:
image

also, in CMakeLists CMAKE_SYSTEM_PROCESSOR MATCHES it worth to add detection "x86" case:
cpu_features_x86

cc: @gchatelet, @Mizux

Thank you for looking into this. Yes I know Haiku isn't supported... yet :)

The x86 variant is mantained mainly for binary compatibility with old BeOS 5.x, so things there are less than ideal for modern code. I was building on Haiku x86_64 (sorry I should've absolutely mentioned that!), as I believe it's the most sensible choice re: future support, codebase etc.

I tried anyway to build the test commit on x86_64, and it went further - list_cpu_features now compiles fine. But as expected, final linking fails with a bunch of x86-specific (?) undefined refs.

error1
...
cpu_features-linkfail-haiku_x64

Below is a full build log from haikuporter (Haiku's tool for building packages, similar to Gentoo portage).

cpu_features-haikux64_buildlog_static.txt

@victroniko, yes, it fails because I added test commit just to check list_cpu_features without testing.
You can run list_cpu_features with the following commands:

cmake -S. -Bcmake-build-release -DBUILD_TESTING=OFF -DCMAKE_BUILD_TYPE=Release
cmake --build cmake-build-release --config Release
./cmake-build-release/list_cpu_features

About x86, no matter what architecture x86 or x86_64 is the same code in cpu_features. I didn't use BeOS compatibility using gcc 2.95 (need to change code to support the compiler), I used the setarch x86 command which allows you to use the latest version of gcc.

I added haiku_x86 impl file to tests and disabled OS specific tests (484a951) and it works

image

I can confirm it now builds (as stand-alone) correctly on Haiku x86_64. Still requires a bit more massaging to install succesfully. This is what happens if we follow install instructions as-is:

...
Install the project...
/boot/system/bin/cmake -P cmake_install.cmake
-- Install configuration: "RelWithDebInfo"
-- Installing: /boot/system/lib/libcpu_features.a
CMake Error at cmake_install.cmake:41 (file):
file INSTALL cannot copy file
"/sources/cpu_features-484a95133ca6493d80cf76782c9d15de9e1aa0d2/build/libcpu_features.a"
to "/boot/system/lib/libcpu_features.a": Read-only file system.
Makefile:109: recipe for target 'install' failed

This doesn't work because Haiku system-dirs are read only: installed packages are mounted on boot then "overlayed" on top of FS. So at install step we have to use a path-abstraction variable along with DESTDIR=, in this way cpu_features builds to 100%. But it seems it wants to install to absolute paths on /boot - there is NO abstraction for that, only for libs bin devel docs... etc.

(edit. There is $installDestDir which seems usable, but it's description says it's for other things - I've tested it and certainly, it does not change the outcome with cmake above.)

To make a crude example, this is the resulting package built with DESTDIR=$libsDir (/boot/system/lib), and the final path where things end:

cpu_features-pkg
cpu_features-wrongpath

As can be seen everything after $libsDir is hardcoded to /boot. With DESTDIR=$binDir things end in /boot/system/bin/boot/*, and so on. Anyway it does install, and list_cpu_features can be ran by manually cd'ing to resulting path. So it seems this is the last thing before a fully working standalone build.

Here is an example for working with Haiku's path-abstractions in C/C++, hope this helps.

Now I'm off to test if it builds as submodule of VOLK...

@victroniko, according to the haiku cli documentation and os discussion, we can install them to ~/config/non-packaged/bin/ and this folder is user writable.

refs:
https://www.haiku-os.org/docs/userguide/en/applications/cli-apps.html
https://www.haiku-os.org/docs/userguide/en/filesystem-layout.html
https://discuss.haiku-os.org/t/how-do-i-make-a-libary-for-haiku-os/7075/4

Added install path c8e5e09

if(CMAKE_SYSTEM_NAME MATCHES "Haiku")
  set(CMAKE_INSTALL_LIBDIR ~/config/non-packaged/lib)
  set(CMAKE_INSTALL_BINDIR ~/config/non-packaged/bin)
  set(CMAKE_INSTALL_INCLUDEDIR ~/config/non-packaged/include)
endif()

image

cc: @Mizux

@gchatelet, what do you think, can we try to add support Haiku OS?

I was about to reply. It would be nice to support Haiku OS but only if we can have a CI machine. @Mizux ?

Mizux commented

Like for FreeBSD ci we could use a Vagrant box to perform a build:
see: https://app.vagrantup.com/haiku-os/boxes/r1beta4-x86_64
And like for FreeBSD, the CI will be fragile with the "too many request" hitting us...

note: At least we could have the Vagrant file and we could run it from time to time as best/community effort support...
ref:

@echo -e "\t${BOLD}<VM>${RESET}:"
@echo -e "\t\t${BOLD}freebsd${RESET} (FreeBSD)"

VMS = freebsd

https://github.com/google/cpu_features/blob/main/cmake/ci/vagrant/freebsd/Vagrantfile