0

序章

  • MinGW-W64 を使用して、Linux から Windows にクロス コンパイルしようとしています。
  • プロジェクトに enet を追加する前は動作していましたが、現在、enet へのリンクに関する問題が発生しています。
  • CMake は enet を正しく検出します。ENET_LIBRARY と ENET_INCLUDE_DIR が正しい場所に設定されています。
  • を使用して検証されたように、ENet にはシンボルが含まれています。/usr/x86_64-w64-mingw32/bin/objdump /usr/local/mingw64/lib/libenet.a -t
  • 「`enet_address_set_host' への未定義の参照」でビルドが失敗する
  • Visual Studio と VCPkg を使用して、同じコード ベースをネイティブにコンパイルできます。
  • 編集: libenet.a の内容を確認すると、特に私のプログラムではなく、enet のクロスコンパイルに問題があることが確認されます

私の他の依存関係はどれも GNU autoconf を使用していないので、そこに問題があると思います。

エラー

-- The C compiler identification is GNU 8.2.0
-- The CXX compiler identification is GNU 8.2.0
-- Check for working C compiler: /usr/bin/x86_64-w64-mingw32-gcc
-- Check for working C compiler: /usr/bin/x86_64-w64-mingw32-gcc -- works
-- Detecting C compiler ABI info
-- Detecting C compiler ABI info - done
-- Detecting C compile features
-- Detecting C compile features - done
-- Check for working CXX compiler: /usr/bin/x86_64-w64-mingw32-g++
-- Check for working CXX compiler: /usr/bin/x86_64-w64-mingw32-g++ -- works
-- Detecting CXX compiler ABI info
-- Detecting CXX compiler ABI info - done
-- Detecting CXX compile features
-- Detecting CXX compile features - done
-- Found SFML 2.5 in /usr/local/mingw64/include
-- Found SFGUI in /usr/local/mingw64/include
-- Found Thor in /usr/local/mingw64/include
-- Found Lua in /usr/local/mingw64/include/lua5.1/
-- Found Lua: /usr/local/mingw64/lib/liblua5.1.a  
-- Found ENet: /usr/local/mingw64/lib/libenet.a  
-- Found ENet in /usr/local/mingw64/include
-- Looking for pthread.h
-- Looking for pthread.h - found
-- Looking for pthread_create
-- Looking for pthread_create - found
-- Found Threads: TRUE  
/usr/local/mingw64/lib/liblua5.1.a/usr/local/mingw64/lib/libenet.awsock32ws2_32winmm
-- Adding executable: client (with server)
-- Configuring done
-- Generating done
-- Build files have been written to: /home/ruben/dev/rvwp
Scanning dependencies of target rvwp
[SNIP]
[ 98%] Building CXX object CMakeFiles/rvwp.dir/source/tests/t_chunk.cpp.obj
[100%] Linking CXX executable bin/rvwp.exe
/usr/lib/gcc/x86_64-w64-mingw32/8.2.0/../../../../x86_64-w64-mingw32/bin/ld: CMakeFiles/rvwp.dir/objects.a(address.cpp.obj):address.cpp:(.text+0xc6): undefined reference to `enet_address_set_host'
/usr/lib/gcc/x86_64-w64-mingw32/8.2.0/../../../../x86_64-w64-mingw32/bin/ld: CMakeFiles/rvwp.dir/objects.a(net.cpp.obj):net.cpp:(.text+0x105): undefined reference to `enet_initialize'
/usr/lib/gcc/x86_64-w64-mingw32/8.2.0/../../../../x86_64-w64-mingw32/bin/ld: CMakeFiles/rvwp.dir/objects.a(net.cpp.obj):net.cpp:(.text+0x204): undefined reference to `enet_packet_create'
/usr/lib/gcc/x86_64-w64-mingw32/8.2.0/../../../../x86_64-w64-mingw32/bin/ld: CMakeFiles/rvwp.dir/objects.a(net.cpp.obj):net.cpp:(.text+0x217): undefined reference to `enet_peer_send'
/usr/lib/gcc/x86_64-w64-mingw32/8.2.0/../../../../x86_64-w64-mingw32/bin/ld: CMakeFiles/rvwp.dir/objects.a(net.cpp.obj):net.cpp:(.text+0x29f): undefined reference to `enet_packet_create'
/usr/lib/gcc/x86_64-w64-mingw32/8.2.0/../../../../x86_64-w64-mingw32/bin/ld: CMakeFiles/rvwp.dir/objects.a(net.cpp.obj):net.cpp:(.text+0x2b3): undefined reference to `enet_peer_send'
/usr/lib/gcc/x86_64-w64-mingw32/8.2.0/../../../../x86_64-w64-mingw32/bin/ld: CMakeFiles/rvwp.dir/objects.a(net.cpp.obj):net.cpp:(.text+0x5af): undefined reference to `enet_host_destroy'
/usr/lib/gcc/x86_64-w64-mingw32/8.2.0/../../../../x86_64-w64-mingw32/bin/ld: CMakeFiles/rvwp.dir/objects.a(net.cpp.obj):net.cpp:(.text+0x65b): undefined reference to `enet_host_create'
/usr/lib/gcc/x86_64-w64-mingw32/8.2.0/../../../../x86_64-w64-mingw32/bin/ld: CMakeFiles/rvwp.dir/objects.a(net.cpp.obj):net.cpp:(.text+0x91f): undefined reference to `enet_host_create'
/usr/lib/gcc/x86_64-w64-mingw32/8.2.0/../../../../x86_64-w64-mingw32/bin/ld: CMakeFiles/rvwp.dir/objects.a(net.cpp.obj):net.cpp:(.text+0x950): undefined reference to `enet_host_connect'
/usr/lib/gcc/x86_64-w64-mingw32/8.2.0/../../../../x86_64-w64-mingw32/bin/ld: CMakeFiles/rvwp.dir/objects.a(net.cpp.obj):net.cpp:(.text+0x96c): undefined reference to `enet_host_service'
/usr/lib/gcc/x86_64-w64-mingw32/8.2.0/../../../../x86_64-w64-mingw32/bin/ld: CMakeFiles/rvwp.dir/objects.a(net.cpp.obj):net.cpp:(.text+0x1023): undefined reference to `enet_host_service'
/usr/lib/gcc/x86_64-w64-mingw32/8.2.0/../../../../x86_64-w64-mingw32/bin/ld: CMakeFiles/rvwp.dir/objects.a(net.cpp.obj):net.cpp:(.text+0x1437): undefined reference to `enet_packet_destroy'
/usr/lib/gcc/x86_64-w64-mingw32/8.2.0/../../../../x86_64-w64-mingw32/bin/ld: CMakeFiles/rvwp.dir/objects.a(net.cpp.obj):net.cpp:(.text+0x121): undefined reference to `enet_deinitialize'
collect2: error: ld returned 1 exit status
make[2]: *** [CMakeFiles/rvwp.dir/build.make:991: bin/rvwp.exe] Error 1
make[1]: *** [CMakeFiles/Makefile2:73: CMakeFiles/rvwp.dir/all] Error 2
make: *** [Makefile:130: all] Error 2

Enet のクロスコンパイル

enet をクロス コンパイルするには、次のスクリプトを使用します。

#!/bin/bash

TOOLSET="x86_64-w64-mingw32"

wget http://enet.bespin.org/download/enet-1.3.13.tar.gz
tar -xzf enet-1.3.13.tar.gz
cd enet-1.3.13
./configure \
    --build=${TOOLSET} \
    --host=x86_64-windows \
    --target=${TOOLSET} \
    --prefix=/usr/local/mingw64 \
    --enable-shared
make -j3
sudo make install

マイプログラム

私は cmake を使用してメイクファイルを生成し、ツールチェーンを使用してクロスコンパイルを許可しています。このプログラムは、SFML、thor、std::thread、および Lua で正常にコンパイルされます。これらのライブラリはいずれも GNU autoconf を使用しません

私の CMakeLists.txt は次のようになります。

find_package(ENet REQUIRED)
include_directories(${ENET_INCLUDE_DIR})

set(BASE_LIBRARIES ${CMAKE_THREAD_LIBS_INIT} ${LUA_LIBRARY} ${CMAKE_DL_LIBS} ${ENET_LIBRARY})
set(BASE_LIBRARIES ${BASE_LIBRARIES} wsock32 ws2_32 winmm)
message(${BASE_LIBRARIES})
set(EXECUTABLE_NAME "rvwp")

add_executable(${EXECUTABLE_NAME} WIN32 ${CLIENT_SRC})
set_target_properties(${EXECUTABLE_NAME} PROPERTIES BUILD_WITH_INSTALL_RPATH true)

install(TARGETS ${EXECUTABLE_NAME} DESTINATION bin)
target_link_libraries(${EXECUTABLE_NAME} ${BASE_LIBRARIES} ${SFML_LIBRARIES} ${SFGUI_LIBRARY} ${THOR_LIBRARY})

findENet ファイルは次のようになります。

FIND_PATH(ENET_INCLUDE_DIR enet/enet.h
    PATHS
    $ENV{ENETDIR}
    /usr/local
    /usr
    PATH_SUFFIXES include)

FIND_LIBRARY(ENET_LIBRARY
    NAMES enet
    PATHS
    $ENV{ENETDIR}
    /usr/local
    /usr
    PATH_SUFFIXES lib)

INCLUDE(FindPackageHandleStandardArgs)
FIND_PACKAGE_HANDLE_STANDARD_ARGS(ENet DEFAULT_MSG ENET_LIBRARY ENET_INCLUDE_DIR)

IF (ENet_FOUND)
    MESSAGE(STATUS "Found ENet in ${ENET_INCLUDE_DIR}")
    IF(WIN32)
        SET(WINDOWS_ENET_DEPENDENCIES "ws2_32;winmm")
        SET(ENET_LIBRARIES ${ENET_LIBRARY} ${WINDOWS_ENET_DEPENDENCIES})
    ELSE(WIN32)
        SET(ENET_LIBRARIES ${ENET_LIBRARY})
    ENDIF(WIN32)
ENDIF (ENet_FOUND)

MARK_AS_ADVANCED(ENET_LIBRARY ENET_LIBRARIES ENET_INCLUDE_DIR)

ツール チェーンは次のようになります。

# Sample toolchain file for building for Windows from an Ubuntu Linux system.
#
# Typical usage:
#    *) install cross compiler: `sudo apt-get install mingw-w64 g++-mingw-w64`
#    *) cd build
#    *) cmake -DCMAKE_TOOLCHAIN_FILE=~/Toolchain-Ubuntu-mingw64.cmake ..

set(CMAKE_SYSTEM_NAME Windows)

set(TOOLCHAIN_PREFIX x86_64-w64-mingw32)

# cross compilers to use for C and C++
set(CMAKE_C_COMPILER ${TOOLCHAIN_PREFIX}-gcc)
set(CMAKE_CXX_COMPILER ${TOOLCHAIN_PREFIX}-g++)
set(CMAKE_RC_COMPILER ${TOOLCHAIN_PREFIX}-windres)

SET( CMAKE_EXE_LINKER_FLAGS  "${CMAKE_EXE_LINKER_FLAGS} -static-libgcc -static-libstdc++" )

# target environment on the build host system
#   set 1st to dir with the cross compiler's C/C++ headers/libs
set(CMAKE_FIND_ROOT_PATH /usr/${TOOLCHAIN_PREFIX} /usr/local/mingw64 ./extlibs)

set(LUA_INCLUDE_DIR /usr/local/mingw64/include/lua5.1/)
set(LUA_LIBRARY /usr/local/mingw64/lib/liblua5.1.a)
set(OPENAL_LIBRARY /usr/local/mingw64/lib/libopenal32.a)

# modify default behavior of FIND_XXX() commands to
# search for headers/libs in the target environment and
# search for programs in the build host environment
set(CMAKE_FIND_ROOT_PATH_MODE_PROGRAM NEVER)
set(CMAKE_FIND_ROOT_PATH_MODE_LIBRARY ONLY)
set(CMAKE_FIND_ROOT_PATH_MODE_INCLUDE ONLY)

linklibs.rsp ファイルは、リンク コマンドをリンカに渡すために使用されます。値は次のとおりです。

/usr/local/mingw64/lib/liblua5.1.a /usr/local/mingw64/lib/libenet.a -lwsock32 -lws2_32 -lwinmm /usr/local/mingw64/lib/libsfml-system.a /usr/local/mingw64/lib/libsfml-window.a /usr/local/mingw64/lib/libsfml-graphics.a /usr/local/mingw64/lib/libsfml-network.a /usr/local/mingw64/lib/libsfml-audio.a /usr/local/mingw64/bin/sfgui.dll /usr/local/mingw64/bin/libthor.dll -lkernel32 -luser32 -lgdi32 -lwinspool -lshell32 -lole32 -loleaut32 -luuid -lcomdlg32 -ladvapi32 

(編集) AR フォーマット

動作していない libenet.a を抽出してファイルを使用すると、次のようになります。

callbacks.o: ELF 64-bit LSB relocatable, x86-64, version 1 (SYSV), with debug_info, not stripped

作業中の libsfml-graphics.a を抽出すると、次のようになります。

d000508.o: Intel amd64 COFF object file, no line number info, not stripped, 5 sections, symbol offset=0x144, 8 symbols

したがって、問題はenetのコンパイルにあるようです

4

0 に答える 0