vitasdk / packages

52 stars 52 forks source link

Harfbuzz should add -lstdc++ dependency in .pc file #300

Closed fish47 closed 8 months ago

fish47 commented 10 months ago

Problem

/opt/vitasdk/bin/../lib/gcc/arm-vita-eabi/10.3.0/../../../../arm-vita-eabi/bin/ld: /opt/vitasdk/arm-vita-eabi/lib/libharfbuzz.a(harfbuzz.cc.obj): in function `void hb_ot_map_t::apply<GPOSProxy>(GPOSProxy const&, hb_ot_shape_plan_t const*, hb_font_t*, hb_buffer_t*) const':
(.text._ZNK11hb_ot_map_t5applyI9GPOSProxyEEvRKT_PK18hb_ot_shape_plan_tP9hb_font_tP11hb_buffer_t[_ZNK11hb_ot_map_t5applyI9GPOSProxyEEvRKT_PK18hb_ot_shape_plan_tP9hb_font_tP11hb_buffer_t]+0xba6): undefined reference to `__cxa_end_cleanup'

Sources

#include <hb.h>

int main()
{
    hb_buffer_t *buf = hb_buffer_create();
    hb_buffer_destroy(buf);
    return 0;
}
cmake_minimum_required(VERSION 3.0)

set(CMAKE_TOOLCHAIN_FILE
    "$ENV{VITASDK}/share/vita.toolchain.cmake"
    CACHE PATH "toolchain file")
include("$ENV{VITASDK}/share/vita.cmake" REQUIRED)

project(hb)
add_executable(hb main.c)

include(FindPkgConfig)
pkg_check_modules(_pkg_hb REQUIRED IMPORTED_TARGET harfbuzz)

# workaround
# set_target_properties(hb PROPERTIES LINKER_LANGUAGE CXX)

target_link_libraries(hb PkgConfig::_pkg_hb)

Cause

Harfhuzz maintains pure C-style APIs, but it uses some C++ features internally, like class and RTII.

Fix

harfbuzz.pc should be something like this

...
Name: harfbuzz
...
Libs.private: -lstdc++ -lm -pthread
behdad commented 10 months ago

RTII.

We don't use RTTI and disable it in our builds. We don't use exceptions either. We don't use libstdc++.

behdad commented 10 months ago

Try building with -fno-rtti -fno-exceptions

isage commented 10 months ago

Try building with -fno-rtti -fno-exceptions

Please elaborate on rebuilding what. Testcase or harfbuzz?

behdad commented 10 months ago

Try building with -fno-rtti -fno-exceptions

Please elaborate on rebuilding what. Testcase or harfbuzz?

HarfBuzz already builds with those. I think you are using cmake. Here's the condition we use:


  # As of CMake 3.0.0, the compiler id for Apple-provided Clang is now "AppleClang"; 
  # thus we use MATCHES instead of STREQUAL to include either regular Clang or AppleClang 
  if (CMAKE_CXX_COMPILER_ID MATCHES "Clang" OR CMAKE_CXX_COMPILER_ID STREQUAL "GNU") 
    # Make sure we don't link to libstdc++ 
    set (CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -fno-rtti -fno-exceptions") 

If you use a different compiler and it supports those options, we can adjust our (three, sigh) build systems.

fish47 commented 10 months ago
# vita cross-compiling is not 'UNIX' or 'MINGW'
if (UNIX OR MINGW)
  ...
  if (CMAKE_CXX_COMPILER_ID MATCHES "Clang" OR CMAKE_CXX_COMPILER_ID STREQUAL "GNU")
    ...
    set (CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -fno-rtti -fno-exceptions")
    ...
  endif ()
endif ()

That is why vita artifacts miss those flags while cross-compiling.

behdad commented 10 months ago

That is why vita artifacts miss those flags while cross-compiling.

Can you help us detect vita compiler correctly then?

isage commented 10 months ago
if (UNIX OR MINGW)

if (UNIX OR MINGW OR VITA)

behdad commented 10 months ago

Thanks. Can you also check that meson works already? I suppose we can leave configure.ac alone...

isage commented 10 months ago

I have no experience with meson (nor we have any packages that use it) with something like this

[constants]
arch = 'arm-vita-eabi'
toolchain = '/usr/local/vitasdk'
common_flags = ['--sysroot=' + toolchain / arch]

[paths]
prefix = toolchain / arch

[binaries]
c = arch + '-gcc'
cpp = arch + '-g++'
ar = arch + '-ar'
strip = arch + '-strip'
pkg-config = arch + '-pkg-config'

[host_machine]
system = 'vita'
cpu_family = 'arm'
cpu = 'arm'
endian = 'little'

and meson setup --cross-file vita-cross.txt -Dtests=disabled -Dutilities=disabled -Ddocs=disabled build-vita

it adds -fPIC which is wrong for vita. (and seems to be trying to build dynamic library) UPD: adding -Ddefault_library=static doesn't help with -fPIC but atleast builds static lib UPD2: adding -Db_staticpic = false helped

behdad commented 10 months ago

@khaledhosny can you help here if we need any updates on HB side?

khaledhosny commented 9 months ago

In meson we add -fno-exceptions and -fno-rtti if the compiler supports them, so it should work. For autotools we checks for $GCC, so it depends on what compilers AC_PROG_CC considers to be GCC-like. I don’t know anything about CMake to figure how its check can be improved.

fish47 commented 8 months ago

Should we fix this on downstream in VITABUILD, instead of waiting for the new release of upstream? This modification should be reverted if vita-specified changes have been merged into the upstream.

prepare() {
  cd harfbuzz-$pkgver
  patch -p1 <<EOF
diff --git a/CMakeLists.txt b/CMakeLists.txt
index e22f2cfd..474f3fea 100644
--- a/CMakeLists.txt
+++ b/CMakeLists.txt
@@ -481,7 +481,7 @@ if (HB_BUILD_SUBSET)
   endif ()
 endif ()

-if (UNIX OR MINGW)
+if (UNIX OR MINGW OR VITA)
   # Make symbols link locally
   include (CheckCXXCompilerFlag)
   CHECK_CXX_COMPILER_FLAG(-Bsymbolic-functions CXX_SUPPORTS_FLAG_BSYMB_FUNCS)
EOF
}
fish47 commented 8 months ago

This bug has been fixed on downstream, and this subtle patch could be accepted on upstream, too.

behdad commented 8 months ago

I pushed the patch upstream.