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

Added minor fixes to build without errors with gcc 4.9.2 #4417

Merged
merged 1 commit into from Sep 23, 2023
Merged

Added minor fixes to build without errors with gcc 4.9.2 #4417

merged 1 commit into from Sep 23, 2023

Conversation

inobelar
Copy link
Contributor

@inobelar inobelar commented Sep 23, 2023

First of all, I want to thank you for your work on compatibility with quite old compilers!

At work, I happen to use a rather ancient environment & compiler:

  • gcc --version: gcc (Debian 4.9.2-10) 4.9.2
  • gcc -dumpmachine: arm-linux-gnueabihf
  • uname -srmio: Linux 4.1.15-g14db131-dirty armv7l unknown GNU/Linux.

When trying to compile the latest sources (current latest commit: b8121cc) I encountered several compilation errors, which I tried to solve in this pull request. Next, I describe the errors that occurred (in the order they occurred) and the way to solve them.

I build harfbuzz with pre-build freetype and icu with (deprecated) CMake in the next way:

$ cmake ../harfbuzz \
     -G "Unix Makefiles" \
     -D CMAKE_BUILD_TYPE:STRING=Release \
     -D CMAKE_INSTALL_PREFIX:PATH=`pwd`/../installed/harfbuzz/ \
     \
     -D BUILD_SHARED_LIBS=OFF \
     \
     -D HB_HAVE_FREETYPE=ON \
     -D HB_HAVE_GRAPHITE2=OFF \
     -D HB_HAVE_GLIB=OFF \
     -D HB_HAVE_ICU=ON \
     \
     -D CMAKE_PREFIX_PATH="`realpath ../installed/freetype/`;`realpath ../installed/icu/`" \
     -D CMAKE_CXX_FLAGS="${CMAKE_CXX_FLAGS} -DHB_NO_UCD -DHAVE_ICU_BUILTIN"
Output
-- The C compiler identification is GNU 4.9.2
-- The CXX compiler identification is GNU 4.9.2
-- Detecting C compiler ABI info
-- Detecting C compiler ABI info - done
-- Check for working C compiler: /usr/bin/cc - skipped
-- Detecting C compile features
-- Detecting C compile features - done
-- Detecting CXX compiler ABI info
-- Detecting CXX compiler ABI info - done
-- Check for working CXX compiler: /usr/bin/c++ - skipped
-- Detecting CXX compile features
-- Detecting CXX compile features - done
WARNHarfBuzz has a Meson port and tries to migrate all the other build systems to it, please consider using it as we might remove our cmake port soon.
CMake Warning (dev) at CMakeLists.txt:78 (include):
  Policy CMP0148 is not set: The FindPythonInterp and FindPythonLibs modules
  are removed.  Run "cmake --help-policy CMP0148" for policy details.  Use
  the cmake_policy command to set the policy and suppress this warning.

This warning is for project developers.  Use -Wno-dev to suppress it.

-- Found PythonInterp: /usr/bin/python (found version "2.7.9") 
-- Looking for atexit
-- Looking for atexit - found
-- Looking for mprotect
-- Looking for mprotect - found
-- Looking for sysconf
-- Looking for sysconf - found
-- Looking for getpagesize
-- Looking for getpagesize - found
-- Looking for mmap
-- Looking for mmap - found
-- Looking for isatty
-- Looking for isatty - found
-- Looking for unistd.h
-- Looking for unistd.h - found
-- Looking for sys/mman.h
-- Looking for sys/mman.h - found
-- Looking for stdbool.h
-- Looking for stdbool.h - found
-- Performing Test CMAKE_HAVE_LIBC_PTHREAD
-- Performing Test CMAKE_HAVE_LIBC_PTHREAD - Failed
-- Check if compiler accepts -pthread
-- Check if compiler accepts -pthread - yes
-- Found Threads: TRUE  
-- Found Freetype: ../installed/freetype/lib/libfreetype.a (found version "2.13.2") 
-- Looking for FT_Get_Var_Blend_Coordinates
-- Looking for FT_Get_Var_Blend_Coordinates - found
-- Looking for FT_Set_Var_Blend_Coordinates
-- Looking for FT_Set_Var_Blend_Coordinates - found
-- Looking for FT_Done_MM_Var
-- Looking for FT_Done_MM_Var - found
-- Found PkgConfig: /usr/bin/pkg-config (found version "0.28") 
-- Performing Test CXX_SUPPORTS_FLAG_BSYMB_FUNCS
-- Performing Test CXX_SUPPORTS_FLAG_BSYMB_FUNCS - Success
-- Performing Test COMPILER_SUPPORTS_CXX11
-- Performing Test COMPILER_SUPPORTS_CXX11 - Success
-- Configuring done (30.4s)
-- Generating done (0.1s)
-- Build files have been written to: ./__harfbuzz_build

Error 1

In file included from ./harfbuzz/src/hb-serialize.hh:36:0,
                 from ./harfbuzz/src/hb-subset.hh:36,
                 from ./harfbuzz/src/hb-open-type.hh:37,
                 from ./harfbuzz/src/hb-aat-ltag-table.hh:28,
                 from ./harfbuzz/src/hb-aat-layout.hh:33,
                 from ./harfbuzz/src/hb-aat-layout.cc:30,
                 from ./harfbuzz/src/harfbuzz.cc:1:
./harfbuzz/src/hb-map.hh:109:40: error: ‘is_trivially_constructible’ is not a member of ‘std’
     static constexpr bool is_trivial = std::is_trivially_constructible<K>::value &&
                                        ^
./harfbuzz/src/hb-map.hh:109:73: error: expected primary-expression before ‘>’ token
     static constexpr bool is_trivial = std::is_trivially_constructible<K>::value &&
                                                                         ^
./harfbuzz/src/hb-map.hh:109:74: error: ‘::value’ has not been declared
     static constexpr bool is_trivial = std::is_trivially_constructible<K>::value &&
                                                                          ^
./harfbuzz/src/hb-map.hh:111:12: error: ‘is_trivially_constructible’ is not a member of ‘std’
            std::is_trivially_constructible<V>::value &&
            ^
./harfbuzz/src/hb-map.hh:111:45: error: expected primary-expression before ‘>’ token
            std::is_trivially_constructible<V>::value &&
                                             ^
./harfbuzz/src/hb-map.hh:111:46: error: ‘::value’ has not been declared
            std::is_trivially_constructible<V>::value &&
                                              ^

This error is easier to solve - due to known compiler bugs ('gcc < 5' - missing type traits implementation, we need to use build-in functions instead) - we just need to use already used defines from here:

harfbuzz/src/hb-meta.hh

Lines 202 to 214 in b8121cc

#if defined(__GNUC__) && __GNUC__ < 5 && !defined(__clang__)
#define hb_is_trivially_copyable(T) __has_trivial_copy(T)
#define hb_is_trivially_copy_assignable(T) __has_trivial_assign(T)
#define hb_is_trivially_constructible(T) __has_trivial_constructor(T)
#define hb_is_trivially_copy_constructible(T) __has_trivial_copy_constructor(T)
#define hb_is_trivially_destructible(T) __has_trivial_destructor(T)
#else
#define hb_is_trivially_copyable(T) std::is_trivially_copyable<T>::value
#define hb_is_trivially_copy_assignable(T) std::is_trivially_copy_assignable<T>::value
#define hb_is_trivially_constructible(T) std::is_trivially_constructible<T>::value
#define hb_is_trivially_copy_constructible(T) std::is_trivially_copy_constructible<T>::value
#define hb_is_trivially_destructible(T) std::is_trivially_destructible<T>::value
#endif

so

harfbuzz/src/hb-map.hh

Lines 109 to 112 in b8121cc

static constexpr bool is_trivial = std::is_trivially_constructible<K>::value &&
std::is_trivially_destructible<K>::value &&
std::is_trivially_constructible<V>::value &&
std::is_trivially_destructible<V>::value;

become

    static constexpr bool is_trivial = hb_is_trivially_constructible(K) &&
				       hb_is_trivially_destructible(K) &&
				       hb_is_trivially_constructible(V) &&
				       hb_is_trivially_destructible(V);

Error 2

In file included from ./harfbuzz/src/hb.hh:531:0,
                 from ./harfbuzz/src/hb-aat-layout.cc:28,
                 from ./harfbuzz/src/harfbuzz.cc:1:
./harfbuzz/src/hb-map.hh: In instantiation of ‘struct hb_hashmap_t<unsigned int, unsigned int, true>’:
./harfbuzz/src/hb-map.hh:525:19:   required from here
./harfbuzz/src/hb-map.hh:401:29: error: cannot call member function ‘unsigned int hb_hashmap_t<K, V, minus_one>::size() const [with K = unsigned int; V = unsigned int; bool minus_one = true]’ without object
     + hb_iter (items, size ())
                             ^
./harfbuzz/src/hb-meta.hh:76:41: note: in definition of macro ‘HB_AUTO_RETURN’
 #define HB_AUTO_RETURN(E) -> decltype ((E)) { return (E); }
                                         ^
./harfbuzz/src/hb-map.hh:406:19: error: ‘iter_items’ was not declared in this scope
     + iter_items ()
                   ^
./harfbuzz/src/hb-meta.hh:76:41: note: in definition of macro ‘HB_AUTO_RETURN’
 #define HB_AUTO_RETURN(E) -> decltype ((E)) { return (E); }
                                         ^
./harfbuzz/src/hb-map.hh:411:19: error: ‘iter_items’ was not declared in this scope
     + iter_items ()
                   ^
./harfbuzz/src/hb-meta.hh:76:41: note: in definition of macro ‘HB_AUTO_RETURN’
 #define HB_AUTO_RETURN(E) -> decltype ((E)) { return (E); }
                                         ^
./harfbuzz/src/hb-map.hh:416:19: error: ‘iter_items’ was not declared in this scope
     + iter_items ()
                   ^
./harfbuzz/src/hb-meta.hh:76:41: note: in definition of macro ‘HB_AUTO_RETURN’
 #define HB_AUTO_RETURN(E) -> decltype ((E)) { return (E); }
                                         ^
./harfbuzz/src/hb-map.hh:421:17: error: ‘keys_ref’ was not declared in this scope
     + keys_ref ()
                 ^
./harfbuzz/src/hb-meta.hh:76:41: note: in definition of macro ‘HB_AUTO_RETURN’
 #define HB_AUTO_RETURN(E) -> decltype ((E)) { return (E); }
                                         ^
./harfbuzz/src/hb-map.hh:426:19: error: ‘iter_items’ was not declared in this scope
     + iter_items ()
                   ^
./harfbuzz/src/hb-meta.hh:76:41: note: in definition of macro ‘HB_AUTO_RETURN’
 #define HB_AUTO_RETURN(E) -> decltype ((E)) { return (E); }
                                         ^
./harfbuzz/src/hb-map.hh:431:19: error: ‘values_ref’ was not declared in this scope
     + values_ref ()
                   ^
./harfbuzz/src/hb-meta.hh:76:41: note: in definition of macro ‘HB_AUTO_RETURN’
 #define HB_AUTO_RETURN(E) -> decltype ((E)) { return (E); }
                                         ^

This is the first time I have encountered errors of this kind, but a quick search suggested that here we need to add an explicit
this-> in related places:

So the next code:

harfbuzz/src/hb-map.hh

Lines 399 to 433 in b8121cc

auto iter_items () const HB_AUTO_RETURN
(
+ hb_iter (items, size ())
| hb_filter (&item_t::is_real)
)
auto iter_ref () const HB_AUTO_RETURN
(
+ iter_items ()
| hb_map (&item_t::get_pair_ref)
)
auto iter () const HB_AUTO_RETURN
(
+ iter_items ()
| hb_map (&item_t::get_pair)
)
auto keys_ref () const HB_AUTO_RETURN
(
+ iter_items ()
| hb_map (&item_t::get_key)
)
auto keys () const HB_AUTO_RETURN
(
+ keys_ref ()
| hb_map (hb_ridentity)
)
auto values_ref () const HB_AUTO_RETURN
(
+ iter_items ()
| hb_map (&item_t::get_value)
)
auto values () const HB_AUTO_RETURN
(
+ values_ref ()
| hb_map (hb_ridentity)
)

become a little bit explicit:

  auto iter_items () const HB_AUTO_RETURN
  (
    + hb_iter (items, this->size ())
    | hb_filter (&item_t::is_real)
  )
  auto iter_ref () const HB_AUTO_RETURN
  (
    + this->iter_items ()
    | hb_map (&item_t::get_pair_ref)
  )
  auto iter () const HB_AUTO_RETURN
  (
    + this->iter_items ()
    | hb_map (&item_t::get_pair)
  )
  auto keys_ref () const HB_AUTO_RETURN
  (
    + this->iter_items ()
    | hb_map (&item_t::get_key)
  )
  auto keys () const HB_AUTO_RETURN
  (
    + this->keys_ref ()
    | hb_map (hb_ridentity)
  )
  auto values_ref () const HB_AUTO_RETURN
  (
    + this->iter_items ()
    | hb_map (&item_t::get_value)
  )
  auto values () const HB_AUTO_RETURN
  (
    + this->values_ref ()
    | hb_map (hb_ridentity)
  )

Error 3

In file included from ./harfbuzz/src/hb.hh:540:0,
                 from ./harfbuzz/src/hb-aat-layout.cc:28,
                 from ./harfbuzz/src/harfbuzz.cc:1:
./harfbuzz/src/hb-vector.hh: In instantiation of ‘Type hb_vector_t<Type, sorted>::pop() [with Type = hb_user_data_array_t::hb_user_data_item_t; bool sorted = false]’:
./harfbuzz/src/hb-object.hh:127:7:   required from ‘void hb_lockable_set_t<item_t, lock_t>::fini(lock_t&) [with item_t = hb_user_data_array_t::hb_user_data_item_t; lock_t = hb_mutex_t]’
./harfbuzz/src/hb-object.hh:178:34:   required from here
./harfbuzz/src/hb-vector.hh:463:43: error: cannot convert ‘std::remove_reference<hb_user_data_array_t::hb_user_data_item_t&>::type {aka hb_user_data_array_t::hb_user_data_item_t}’ to ‘hb_user_data_key_t*in initialization
     Type v {std::move (arrayZ[length - 1])};
                                           ^

The strangest mistake that took a lot of time. As can be seen from the strange error message, the compiler does not understand what we want at all. Let's look at the relevant code blocks:

harfbuzz/src/hb-object.hh

Lines 160 to 174 in b8121cc

struct hb_user_data_array_t
{
struct hb_user_data_item_t {
hb_user_data_key_t *key;
void *data;
hb_destroy_func_t destroy;
bool operator == (const hb_user_data_key_t *other_key) const { return key == other_key; }
bool operator == (const hb_user_data_item_t &other) const { return key == other.key; }
void fini () { if (destroy) destroy (data); }
};
hb_mutex_t lock;
hb_lockable_set_t<hb_user_data_item_t, hb_mutex_t> items;

harfbuzz/src/hb-vector.hh

Lines 460 to 467 in b8121cc

Type pop ()
{
if (!length) return Null (Type);
Type v {std::move (arrayZ[length - 1])};
arrayZ[length - 1].~Type ();
length--;
return v;
}

The simplest explanation I came up with for this error is: weak support of 'list initialization' (using curly braces) in old compiler. So to solve it I simply replaced 'curly braces' with 'parentheses':

Type v {std::move (arrayZ[length - 1])};
//     ^                              ^

become

Type v (std::move (arrayZ[length - 1]));
//     ^                              ^

and it fixes it! :D


The subsequent build was successful - without errors, although with a few warnings, in the style:

./harfbuzz/src/hb-ot-map.cc:90:44: warning: cannot optimize loop, the loop counter may overflow [-Wunsafe-loop-optimizations]
 hb_ot_map_builder_t::~hb_ot_map_builder_t ()
                                            ^
./harfbuzz/src/hb-serialize.hh:193:5: warning: cannot optimize loop, the loop counter may overflow [-Wunsafe-loop-optimizations]
     for (object_t *_ : ++hb_iter (packed)) _->fini ();
     ^
./harfbuzz/src/hb-ot-layout.cc: In function ‘hb_bool_t hb_ot_layout_get_font_extents(hb_font_t*, hb_direction_t, hb_tag_t, hb_tag_t, hb_font_extents_t*)’:
./harfbuzz/src/hb-ot-layout.cc:2131:31: warning: ‘max’ may be used uninitialized in this function [-Wmaybe-uninitialized]
       extents->ascender  = max;
                               ^
./harfbuzz/src/hb-ot-layout.cc:2132:31: warning: ‘min’ may be used uninitialized in this function [-Wmaybe-uninitialized]
       extents->descender = min;
                               ^

Unfortunately, github does not allow to paste the entire build log here. For those interested, you can watch it here.

I really appreciate the support of legacy systems in our imprefect world. I hope this pull request will be considered with understanding. Thanks for your time!

@behdad
Copy link
Member

behdad commented Sep 23, 2023

Thank you for debugging this and submitting fixes. Typically people just throw the errors in an issue and then I have to scratch my head about how to fix. :)

@behdad behdad merged commit 69da5aa into harfbuzz:main Sep 23, 2023
22 checks passed
@inobelar inobelar deleted the fixes_for_gcc_4_9_2 branch September 23, 2023 19:23
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

Successfully merging this pull request may close these issues.

None yet

2 participants