Windows-on-ARM-Experiments / mingw-woarm64-build

Build script for Windows on Arm64 GNU cross compiler aarch64-w64-mingw32.
GNU General Public License v2.0
27 stars 3 forks source link

Linking to libbfd in C++ example. #134

Closed blapie closed 3 months ago

blapie commented 3 months ago

Hi! I’m currently working on porting a piece of C/C++ software to WoA, that relies heavily on libbfd. I believe there is no framework available to compile it and link directly on WoA, therefore I have been trying your experimental toolchain.

I managed to build the cross-compiler successfully, then build the examples on Linux and run them on a WoA instance.

Compiling my project was fairly seamless, however I have an issue at link time, that I was able to reproduce with the following example code.

// test.cpp
#define PACKAGE
#define PACKAGE_VERSION
#include <bfd.h>

int main() {
   auto ptr = bfd_openr(nullptr, nullptr);
   return 0;
}

Linking fails with undefined symbols although nm seems to indicate that symbols are in the library libbfd.a.

$ ~/cross/bin/aarch64-w64-mingw32-g++ test.cpp -o test \
      -I~/woa-exp/mingw-woarm64-build/build-aarch64-w64-mingw32/binutils/bfd \
      ~/woa-exp/mingw-woarm64-build/build-aarch64-w64-mingw32/binutils/bfd/.libs/libbfd.a

~/cross/lib/gcc/aarch64-w64-mingw32/15.0.0/../../../../aarch64-w64-mingw32/bin/ld: /tmp/ccV95jeV.o:(.rdata$.refptr.bfd_openr[.refptr.bfd_openr]+0x0): undefined reference to `bfd_openr'
collect2: error: ld returned 1 exit status

Please let me know if there is anything fundamental that I don’t understand about how to use the toolchain, or if maybe that’s a new/known issue?

eukarpov commented 3 months ago

Hi Pierre, Thank you for using the toolchain and letting us know about the issue you are facing.

It looks like during the linking, libbfd.a is used which was compiled for x86_64-pc-linux-gnu target. The aarch64-w64-mingw32 toolchain should be used to compile libbfd.a.

Here are steps which might help to resolve the issue.

  1. Build the aarch64-w64-mingw32 toolchain and add the toolchain to the path PATH=$PATH:~/cross-aarch64-w64-mingw32-msvcrt/bin

  2. Build zlib with the toolchain. .github/scripts/zlib/build.sh

  3. Patch binutils. That should be done after the toolchain is built. It looks like it is known issue and the patch for upstreaming will be prepared soon if it has not been fixed yet.

diff --git a/gnulib/import/setenv.c b/gnulib/import/setenv.c
index ebfd4e550e8..18d42d1d3ac 100644
--- a/gnulib/import/setenv.c
+++ b/gnulib/import/setenv.c
@@ -219,7 +219,7 @@ __add_to_environ (const char *name, const char *value, const char *combined,

       new_environ[size + 1] = NULL;

-      last_environ = __environ = new_environ;
+      last_environ = new_environ;
     }
   else if (replace)
     {
@@ -315,7 +315,6 @@ clearenv (void)
     }

   /* Clear the environment pointer removes the whole environment.  */
-  __environ = NULL;

   UNLOCK;

diff --git a/libiberty/setenv.c b/libiberty/setenv.c
index 232b2d6a15c..3645b668952 100644
--- a/libiberty/setenv.c
+++ b/libiberty/setenv.c
@@ -133,7 +133,7 @@ setenv (const char *name, const char *value, int replace)

       new_environ[size + 1] = NULL;

-      last_environ = __environ = new_environ;
+      last_environ = new_environ;
     }
   else if (replace)
     {
  1. Finally, build binutils with the toolchain.
mkdir build-aarch64-w64-mingw32-msvcrt/binutils-mingw
cd build-aarch64-w64-mingw32-msvcrt/binutils-mingw
../../code/binutils-master/configure --host=aarch64-w64-mingw32 --build=x86_64-pc-linux-gnu --disable-werror --disable-gdb
make -j$(nproc)

Now, test.cpp with bfd dependency should compile.

~/cross-aarch64-w64-mingw32-msvcrt/bin/aarch64-w64-mingw32-g++ test.cpp -o test -Icode/binutils-master/include -Ibuild-aarch64-w64-mingw32-msvcrt/binutils/bfd build-aarch64-w64-mingw32-msvcrt/binutils-mingw/bfd/.libs/libbfd.a ~/zlib/lib/libz-static.a build-aarch64-w64-mingw32-msvcrt/binutils-mingw/libiberty/libiberty.a build-aarch64-w64-mingw32-msvcrt/binutils-mingw/libsframe/.libs/libsframe.a

I hope it will help.

blapie commented 3 months ago

Sorry for the late reply. I tried the steps above and it fixed the reproducer, thank you very much. My application compiled successfully too but then I get a segmentation fault that I'm still trying to isolate and reproduce. Might need to re-open this issue when I get to that point. Cheers