4

(最新の) タグ v3.2.1 を確認した後:

% sh autogen.sh
% ./configure CC=i686-pc-mingw32-gcc
% make check

すべてのテストが失敗したように見えます。

CC=gcc を使用すると、テストは正常に動作するようです。残念ながら、私は JNI DLL を構築しているので、結果のビルドには cygwin の依存関係がないようにする必要があります。

4

1 に答える 1

1

libffiMSYS2 環境を使用してビルドしようとしましmingw-w64たが、同じ壁にぶつかりました。

a)実行するとすべてのテストが失敗するようですmake check

b) libffi Hello Worldの例をでコンパイルしようとすると-lffi、リンカはすべての ffi 関連シンボルへの未解決の参照について不平を言います (シンボルは確かに に含まれていますがlibffi.a、おそらく循環依存関係とオブジェクト ファイルの順序が原因で、リンカは失敗します。すべてのシンボルを集める)

幸いなことに、 libffi 操作によって作成された-lffiすべてのオブジェクト ファイル ( )を削除して含めると、作成された実行可能ファイルは正常に実行されます。*.omake

私が使用した libffi Hello Worldの例 へのリンクは次のとおりです

[編集]

いくつかの追加の実験の後、 に置き換えること-lffiでプログラムをコンパイルすることができました-Wl,--whole-archive,-lffi,--no-whole-archive。このようにして、リンカーはすべてのオブジェクト ファイルをインクルードしlibffi.a、すべてが正常に機能します。

誰かがこの情報が役に立つと思った場合に備えて、使用した詳細な手順を含むHello Worldの例 ( ) を次に示します。hello.c

/*
 * Steps for building libffi on Windows and running this Hello World example:
 *
 * 1. Download and install the latest version of MSYS2
 *    a) download the latest (64-bit or 32-bit) installer from http://msys2.github.io
 *    b) run the installer accepting default settings
 *    c) execute the following commands to update the system core
 *        pacman -Sy pacman
 *        pacman -Syu
 *        pacman -Su
 *    d) restart MSYS2, if requested to do so
 *    e) execute the following command to install development tools
 *       for 64-bit gcc:
 *        pacman --needed -S base-devel dejagnu mingw-w64-x86_64-gcc
 *       for 32-bit gcc:
 *        pacman --needed -S base-devel dejagnu mingw-w64-i686-gcc
 *    f) restart MSYS2
 * 2. Download and compile the latest version of libffi
 *    a) download the latest source code bundle from https://github.com/libffi/libffi/releases
 *    b) unpack the source code bundle in MSYS2 tmp directory (e.g. C:\msys64\tmp)
 *    c) execute the following MSYS2 commands to compile libffi (adapt the version number):
 *        cd /tmp/libffi-3.2.1
 *        ./autogen.sh
 *        ./configure --prefix=/tmp/out --enable-static --disable-shared
 *        make
 *    d) optionally, execute the following command to run the tests:
 *        make check
 *    e) copy the distributable files to the configured /tmp/out directory
 *        make install
 *       the following files are needed for the next step:
 *        /tmp/out/lib/libffi.a
 *        /tmp/out/lib/libffi-3.2.1/include/ffi.h
 *        /tmp/out/lib/libffi-3.2.1/include/ffitarget.h
 * 3. Compile this example
 *    a) copy this file to MSYS2 tmp directory (e.g. C:\msys64\tmp\hello.c)
 *    b) execute the following MSYS2 command to compile the example:
 *        gcc -I /tmp/out/lib/libffi-3.2.1/include -L /tmp/out/lib -lffi -o /tmp/hello /tmp/hello.c
 *    c) run the example (/tmp/hello.exe), the output should be:
 *        Hello World!
 *
 * Troubleshooting
 *
 * If the tests seem to fail and the compilation in step 3b) above reports undefined references to 'ffi_*' symbols,
 * try compiling using the following command instead:
 *        gcc -I /tmp/out/lib/libffi-3.2.1/include -L /tmp/out/lib -Wl,--whole-archive,-lffi,--no-whole-archive -o /tmp/hello /tmp/hello.c
 * Another alternative is to try linking the original libffi object files (*.o) and drop -lffi as follows:
 * For 64-bit version:
 *        export SRC=/tmp/libffi-3.2.1/x86_64-w64-mingw32/src
 *        gcc -I /tmp/out/lib/libffi-3.2.1/include -o /tmp/hello /tmp/hello.c $SRC/prep_cif.o $SRC/types.o $SRC/raw_api.o $SRC/java_raw_api.o $SRC/closures.o $SRC/x86/ffi.o $SRC/x86/win64.o
 * For 32-bit version:
 *        export SRC=/tmp/libffi-3.2.1/i686-w64-mingw32/src
 *        gcc -I /tmp/out/lib/libffi-3.2.1/include -o /tmp/hello /tmp/hello.c $SRC/prep_cif.o $SRC/types.o $SRC/raw_api.o $SRC/java_raw_api.o $SRC/closures.o $SRC/x86/ffi.o $SRC/x86/win32.o
 */

#include <stdio.h>
#include <ffi.h>

/* Acts like puts with the file given at time of enclosure */
void puts_binding(ffi_cif* cif, void* ret, void* args[], void* stream) {
  *(ffi_arg*) ret = fputs(*(char**) args[0], (FILE*) stream);
}

typedef int (*puts_t)(char*);

int main() {
  ffi_cif cif; /* The call interface */
  ffi_type* args[1]; /* The array of pointers to function argument types */
  ffi_closure* closure; /* The allocated closure writable address */
  void* bound_puts; /* The allocated closure executable address */
  int rc; /* The function invocation return code */

  /* Allocate closure (writable address) and bound_puts (executable address) */
  closure = ffi_closure_alloc(sizeof(ffi_closure), &bound_puts);

  if (closure) {
    /* Initialize the array of pointers to function argument types */
    args[0] = &ffi_type_pointer;

    /* Initialize the call interface describing the function prototype */
    if (ffi_prep_cif(&cif, FFI_DEFAULT_ABI, 1, &ffi_type_sint, args) == FFI_OK) {
      /* Initialize the closure, setting stream to stdout */
      if (ffi_prep_closure_loc(closure, &cif, puts_binding, stdout, bound_puts) == FFI_OK) {
        rc = ((puts_t) bound_puts)("Hello World!");
        /* rc now holds the result of the call to fputs */
      }
    }
  }

  /* Deallocate both closure, and bound_puts */
  ffi_closure_free(closure);

  return 0;
}
于 2016-11-16T21:12:01.947 に答える