Кросс-компиляция enet из Linux в Windows, связывание ошибок - PullRequest
0 голосов
/ 21 февраля 2019

Введение

  • Я пытаюсь выполнить кросс-компиляцию для Windows из Linux, используя MinGW-W64.
  • Я работал до того, как добавил enet в свой проект, однако я 'm теперь получает проблемы со связью с 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 для генерации make-файлов и набор инструментов для перекрестной компиляции.сборник.Программа компилируется с 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

...