Menu

#345 Building libmpg123 for Android emits 'warning: shared library text segment is not shareable'

1.29.x
closed-fixed
nobody
None
5
2022-11-03
2022-10-11
Maarten
No

Using the CMake toolchain, when building libmpg123 targeting Android and x86, the following link warning is shown:

/opt/android/ndk/21.4.7075529/toolchains/llvm/prebuilt/linux-x86_64/lib/gcc/i686-linux-android/4.9.x/../../../../i686-linux-android/bin/ld: warning: shared library text segment is not shareable
/opt/android/ndk/21.4.7075529/toolchains/llvm/prebuilt/linux-x86_64/lib/gcc/i686-linux-android/4.9.x/../../../../i686-linux-android/bin/ld: error: treating warnings as errors

This is the same error discussed in https://discourse.libsdl.org/t/warning-shared-library-text-segment-is-not-shareable/23517 and fixed in https://github.com/libsdl-org/SDL_mixer/commit/4e9075f83f2b721b703a9b73314f99e0b3d500e6

By forcing MACHINE in "external/mpg123/ports/cmake/src/libmpg123/CMakeLists.txt" to generic, I was able to get rid of the warning.

So there are 2 ways to fix this issue:
- fix the assembly
- add a cmake option to disable assembly usage

Discussion

1 2 > >> (Page 1 of 2)
  • Maarten

    Maarten - 2022-10-12

    I have attached the build log.

     
    • Thomas Orgis

      Thomas Orgis - 2022-10-12

      Is this only the case with the CMake build? I think Android worked before with the autoconf build.

      I fear that people see ports/cmake for more than what it is. It came to be as vehicle to generate MSVC projects automatically. Autoconf is the main build, especially for Unix/Linux systems like Android.

      So ... I am asking before diving into the linked resources: Is this a build issue or a code issue?

       

      Last edit: Thomas Orgis 2022-10-12
      • Maarten

        Maarten - 2022-10-12

        I just tried building with autotools and libmpg123.so is built without issues there.

        In SDL_mixer, we made it possible to use "vendored" libraries. With CMake, this can be easily done across platforms: no need for a shell.

         
  • Maarten

    Maarten - 2022-10-12

    In libsdl's fork of mpg123, assembly for i686-Android is disabled using the following patch:

    diff --git a/ports/cmake/src/libmpg123/CMakeLists.txt b/ports/cmake/src/libmpg123/CMakeLists.txt
    index 9305452..8c73894 100644
    --- a/ports/cmake/src/libmpg123/CMakeLists.txt
    +++ b/ports/cmake/src/libmpg123/CMakeLists.txt
    @@ -38,6 +38,10 @@ else()
         message(WARNING "Unknown processor. Using generic optimizations.")
         set(MACHINE generic)
     endif()
    +# avoid assembly when building an android x86 library: https://sourceforge.net/p/mpg123/bugs/345/
    +if(ANDROID AND MACHINE STREQUAL "x86")
    +    set(MACHINE "generic")
    +endif()
     message(STATUS "Detected machine: ${MACHINE}")
    
     configure_file("${CMAKE_CURRENT_SOURCE_DIR}/../../../../src/libmpg123/mpg123.h.in" mpg123.h)
    
     
    • Thomas Orgis

      Thomas Orgis - 2022-10-12

      I guess it's one of these paranoia flags ...

      -fdata-sections -ffunction-sections -funwind-tables -fstack-protector-strong -no-canonical-prefixes -mstackrealign -D_FORTIFY_SOURCE=2 -Wformat -Werror=format-security -O2 -DNDEBUG -fPIC -MD -MT

      I wonder if we have to switch to inline asm to support these compiler games. Is this no issue for Android on ARM? The NEON code is fine?

      (And why has libsdl a fork of libmpg123 at all? I take pains to keep API and ABI stable. Any special patches?)

      (Really, Sourceforge? When I reply by mail, you see the signature separator as headline markup?!)

       

      Last edit: Thomas Orgis 2022-10-12
      • Maarten

        Maarten - 2022-10-12

        I copied the log to a bash shell and ran the commands manually. Every assembly file causes the warning/error to be emitted.

         
        • Maarten

          Maarten - 2022-10-12

          The issue is only with x86.
          x86_64, arm 32- and arm 64-bit don't have any issue.
          I didn't need to override any default, so I guess neon works fine.

          libsdl2's fork contains our build fixes on top of your mpg123 + a Android.mk script.
          No c source has been modified.
          See https://github.com/libsdl-org/mpg123/tree/v1.29.3-SDL

           
  • Thomas Orgis

    Thomas Orgis - 2022-10-12

    Is this only about getcpuflags.S? Not the actual assembly routines that do the work?

    We had the textrel issue treated with bug 168, merged in 5 years ago. https://sourceforge.net/p/mpg123/bugs/168/

    So it may indeed be just a little nitpick with getcpuflags.S, which is a rather trivial function.

     

    Last edit: Thomas Orgis 2022-10-12
  • Thomas Orgis

    Thomas Orgis - 2022-10-12

    So … what is the actual relocation? In getcpuflags.S there is just one self-contained function. I cannot reproduce the error with a x86 build from a x86-64 Linux system with gcc 9. Is ist a quirk of the compiler/linker used in the Android NDK?

     
  • Thomas Orgis

    Thomas Orgis - 2022-10-12

    I wonder what's the source of the NDK complaint.

     $ LANG=C readelf -e src/libmpg123/.libs/getcpuflags.o 
    ELF Header:
      Magic:   7f 45 4c 46 01 01 01 00 00 00 00 00 00 00 00 00 
      Class:                             ELF32
      Data:                              2's complement, little endian
      Version:                           1 (current)
      OS/ABI:                            UNIX - System V
      ABI Version:                       0
      Type:                              REL (Relocatable file)
      Machine:                           Intel 80386
      Version:                           0x1
      Entry point address:               0x0
      Start of program headers:          0 (bytes into file)
      Start of section headers:          392 (bytes into file)
      Flags:                             0x0
      Size of this header:               52 (bytes)
      Size of program headers:           0 (bytes)
      Number of program headers:         0
      Size of section headers:           40 (bytes)
      Number of section headers:         8
      Section header string table index: 7
    
    Section Headers:
      [Nr] Name              Type            Addr     Off    Size   ES Flg Lk Inf Al
      [ 0]                   NULL            00000000 000000 000000 00      0   0  0
      [ 1] .text             PROGBITS        00000000 000034 0000a4 00  AX  0   0  4
      [ 2] .data             PROGBITS        00000000 0000d8 000000 00  WA  0   0  1
      [ 3] .bss              NOBITS          00000000 0000d8 000000 00  WA  0   0  1
      [ 4] .note.GNU-stack   PROGBITS        00000000 0000d8 000000 00      0   0  1
      [ 5] .symtab           SYMTAB          00000000 0000d8 000060 10      6   5  4
      [ 6] .strtab           STRTAB          00000000 000138 000014 00      0   0  1
      [ 7] .shstrtab         STRTAB          00000000 00014c 00003c 00      0   0  1
    Key to Flags:
      W (write), A (alloc), X (execute), M (merge), S (strings), I (info),
      L (link order), O (extra OS processing required), G (group), T (TLS),
      C (compressed), x (unknown), o (OS specific), E (exclude),
      p (processor specific)
    
    There are no program headers in this file.
    
     
  • Maarten

    Maarten - 2022-10-12

    I tried building with the latest ndk (25.1.8937393), and this one emits a nice error.
    See attachment.

     
  • Thomas Orgis

    Thomas Orgis - 2022-10-12

    Ah, that looks like the usual you-forgot-PIC-flags error. We need -DPIC for mangle.h to do global offset table stuff.

    Incidentally … there might lurk another portability issue here: Is PIC relevant for MS Windows binaries? I really don't know. Only ELF and APPLE binaries are covered.

     
  • Thomas Orgis

    Thomas Orgis - 2022-10-12

    Does -DCMAKE_POSITION_INDEPENDENT_CODE=ON help on the whole build? I guess it's already active and implying -fPIC … but we also need -DPIC to make the preprocessor magic work.

     
  • Maarten

    Maarten - 2022-10-12

    I added

    set(CMAKE_POSITION_INDEPENDENT_CODE ON)
    add_definitions(-DPIC)
    

    at the top of ports/cmake/src/libmpg123/CMakeLists.txt and this reduces the error to only:

    ld: error: relocation R_386_GOTOFF cannot be used against symbol 'INT123_costab_mmxsse'; recompile with -fPIC
    >>> defined in external/mpg123/ports/cmake/src/libmpg123/CMakeFiles/libmpg123.dir/__/__/__/__/src/libmpg123/tabinit_mmx.S.o
    >>> referenced by dct64_sse_float.S:83 (/src/external/mpg123/src/libmpg123/dct64_sse_float.S:83)
    >>>               external/mpg123/ports/cmake/src/libmpg123/CMakeFiles/libmpg123.dir/__/__/__/__/src/libmpg123/dct64_sse_float.S.o:(.text+0x7B)
    clang: error: linker command failed with exit code 1 (use -v to see invocation)
    

    dct64_sse_float.S is compiled/assembled with the following command:

    /opt/android/ndk/25.1.8937393/toolchains/llvm/prebuilt/linux-x86_64/bin/clang -target i686-none-linux-android19 --sysroot=/opt/android/ndk/25.1.8937393/toolchains/llvm/prebuilt/linux-x86_64/sysroot -DNOXFERMEM -DOPT_SSE -DPIC -DREAL_IS_FLOAT -Dlibmpg123_EXPORTS -I/src/external/mpg123/ports/cmake/src/../../../src -I/src/build-android-prefab/build_x86/shared_ON/external/mpg123/ports/cmake/src -I/src/external/mpg123/ports/cmake/src/../../../src/compat -I/src/external/mpg123/ports/cmake/src/../../../src/libmpg123 -I/src/build-android-prefab/build_x86/shared_ON/external/mpg123/ports/cmake/src/libmpg123 -I/src/external/mpg123/ports/cmake/src/libmpg123/../../../../src/libmpg123 -g -DANDROID -fdata-sections -ffunction-sections -funwind-tables -fstack-protector-strong -no-canonical-prefixes -mstackrealign -D_FORTIFY_SOURCE=2 -Wformat -Werror=format-security  -O3 -DNDEBUG  -fPIC -MD -MT external/mpg123/ports/cmake/src/libmpg123/CMakeFiles/libmpg123.dir/__/__/__/__/src/libmpg123/dct64_sse_float.S.o -MF external/mpg123/ports/cmake/src/libmpg123/CMakeFiles/libmpg123.dir/__/__/__/__/src/libmpg123/dct64_sse_float.S.o.d -o external/mpg123/ports/cmake/src/libmpg123/CMakeFiles/libmpg123.dir/__/__/__/__/src/libmpg123/dct64_sse_float.S.o -c /src/external/mpg123/src/libmpg123/dct64_sse_float.S
    
     
  • Maarten

    Maarten - 2022-10-12

    (double post)

     

    Last edit: Maarten 2022-10-12
  • Maarten

    Maarten - 2022-10-12

    Setting CMAKE_POSITION_INDEPENDENT_CODE does not matter when building a shared library. It is only important when building a static library/executable where you can choose between pic'ness. See https://cmake.org/cmake/help/latest/prop_tgt/POSITION_INDEPENDENT_CODE.html

     
  • Maarten

    Maarten - 2022-10-12

    The "CMake way" to add this define is to add the following:

    target_compile_definitions(${TARGET} PRIVATE
        $<$<BOOL:$<TARGET_PROPERTY:POSITION_INDEPENDENT_CODE>>:PIC>
    )
    
     
  • Thomas Orgis

    Thomas Orgis - 2022-10-12

    Hm, is -DPIC also present when building tabinit_mmx.o?

     
  • Maarten

    Maarten - 2022-10-12

    Yes, this is the command:

    /opt/android/ndk/25.1.8937393/toolchains/llvm/prebuilt/linux-x86_64/bin/clang -target i686-none-linux-android19 --sysroot=/opt/android/ndk/25.1.8937393/toolchains/llvm/prebuilt/linux-x86_64/sysroot -DNOXFERMEM -DOPT_SSE -DPIC -DREAL_IS_FLOAT -Dlibmpg123_EXPORTS -I/src/external/mpg123/ports/cmake/src/../../../src -I/src/build-android-prefab/build_x86/shared_ON/external/mpg123/ports/cmake/src -I/src/external/mpg123/ports/cmake/src/../../../src/compat -I/src/external/mpg123/ports/cmake/src/../../../src/libmpg123 -I/src/build-android-prefab/build_x86/shared_ON/external/mpg123/ports/cmake/src/libmpg123 -I/src/external/mpg123/ports/cmake/src/libmpg123/../../../../src/libmpg123 -g -DANDROID -fdata-sections -ffunction-sections -funwind-tables -fstack-protector-strong -no-canonical-prefixes -mstackrealign -D_FORTIFY_SOURCE=2 -Wformat -Werror=format-security  -O3 -DNDEBUG  -fPIC -MD -MT external/mpg123/ports/cmake/src/libmpg123/CMakeFiles/libmpg123.dir/__/__/__/__/src/libmpg123/tabinit_mmx.S.o -MF external/mpg123/ports/cmake/src/libmpg123/CMakeFiles/libmpg123.dir/__/__/__/__/src/libmpg123/tabinit_mmx.S.o.d -o external/mpg123/ports/cmake/src/libmpg123/CMakeFiles/libmpg123.dir/__/__/__/__/src/libmpg123/tabinit_mmx.S.o -c /src/external/mpg123/src/libmpg123/tabinit_mmx.S
    

    Just to make sure you're looking at the correct version, sdl_mixer is using mpg123 1.29.3

     
  • Maarten

    Maarten - 2022-10-12

    Never mind, I just bumped to 1.30.2 and the error is the same.

     
  • Thomas Orgis

    Thomas Orgis - 2022-10-12

    And building the same codebase using the same toolchain with the autoconf build is fine, yes? It's just the cmake build? Then the difference should be apparent from the compile logs …

     
  • Thomas Orgis

    Thomas Orgis - 2022-10-12

    As I said … we at least had the relocation stuff sorted out in 2017 for „normal“ systems (including OSX;-).

     
    • Maarten

      Maarten - 2022-10-12

      Not a solution, but changing

      #if defined(PIC) && defined(__APPLE__)
      

      to

      #if defined(PIC)
      

      makes it building for all 4 android abi's. (and fail for ordinary Linux)

       

      Last edit: Maarten 2022-10-12
      • Thomas Orgis

        Thomas Orgis - 2022-10-12

        Wait, what? So the code branch for MACH-O binaries works for Android? Why is __ELF__ not defined, I thought Android uses ELF format. Does same trick work for you when forcing the first section with

        #if defined(PIC) && defined(__ELF__)
        

        (Or just by adding -D__ELF__ to compiler flags, I guess.) ?

        Maybe we can add a || defined(__ANDROID__) to that branch and call it a day?

         

        Last edit: Thomas Orgis 2022-10-12
        • Maarten

          Maarten - 2022-10-12

          Yes, Android uses elf files. It's based on Linux after all.

          So I tried the following in dct64_sse_float.S:

          • The following works (on both android and and x86/x86_64 Linux):
          #if defined(PIC) && defined(__ELF__)
              mov         GLOBAL_VAR_PTR(costab_mmxsse), %eax
          #else
              lea         GLOBAL_VAR(costab_mmxsse), %eax
          #endif
          
          • This works too (on both android and x86/x86_64 linux):
          #if defined(PIC) && defined(__APPLE__)
              movl GLOBAL_VAR_PTR(costab_mmxsse),%ebx
          #else
              leal GLOBAL_VAR(costab_mmxsse),%ebx
          #endif
          
           
1 2 > >> (Page 1 of 2)

Log in to post a comment.