Проблема кросс-платформенных библиотек Poco - PullRequest
2 голосов
/ 06 мая 2019

Я скомпилировал Poco на платформе Ubuntu amd с помощью cmake, используя специальный файл набора инструментов arm и скрипт сборки:

#!/bin/sh

cd cmake_build
cmake \
    -G "Unix Makefiles" \
    -DCMAKE_BUILD_TYPE=Debug \
    -DCMAKE_TOOLCHAIN_FILE=~/RPi/Toolchain-RaspberryPi.cmake \
    -DCMAKE_INSTALL_PREFIX=~/RPi/rootfs/usr/local \
    ..

make -j4

Файл набора инструментов:

SET(CMAKE_SYSTEM_NAME Linux)
SET(CMAKE_SYSTEM_VERSION 1)

# Specify the cross compiler
SET(CMAKE_C_COMPILER $ENV{HOME}/RPi/tools/arm-bcm2708/gcc-linaro-arm-linux-gnueabihf-raspbian-x64/bin/arm-linux-gnueabihf-gcc)
SET(CMAKE_CXX_COMPILER $ENV{HOME}/RPi/tools/arm-bcm2708/gcc-linaro-arm-linux-gnueabihf-raspbian-x64/bin/arm-linux-gnueabihf-g++)

# Where is the target environment
SET(CMAKE_FIND_ROOT_PATH $ENV{HOME}/RPi/rootfs)
SET(CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} --sysroot=${CMAKE_FIND_ROOT_PATH}")
SET(CMAKE_SHARED_LINKER_FLAGS "${CMAKE_SHARED_LINKER_FLAGS} --sysroot=${CMAKE_FIND_ROOT_PATH}")
SET(CMAKE_MODULE_LINKER_FLAGS "${CMAKE_MODULE_LINKER_FLAGS} --sysroot=${CMAKE_FIND_ROOT_PATH}")

# Search for programs only in the build host directories
SET(CMAKE_FIND_ROOT_PATH_MODE_PROGRAM NEVER)

# Search for libraries and headers only in the target directories
SET(CMAKE_FIND_ROOT_PATH_MODE_LIBRARY ONLY)
SET(CMAKE_FIND_ROOT_PATH_MODE_INCLUDE ONLY)

Я установил poco с make install дляпредварительно настроенная папка: ~/RPi/rootfs/usr/local/.

Я скопировал все файлы Poco в файловую систему Raspberry - lib, lib/cmake, include.

У меня есть небольшой тестовый проект с follow cmake:

cmake_minimum_required (VERSION 3.7)

# Name of the project
project(raspi_ld_test)
message("BUILD ENVIRONMENT SET TO -${BUILD_ENV}-")

if (${BUILD_ENV} STREQUAL "UBUNTU")
  set(POCO_PATH "~/RPi/rootfs/usr/local")
elseif(${BUILD_ENV} STREQUAL "RASPI")
  set(POCO_PATH "/usr/local")
else()
  message(FATAL_ERROR "Undefined environment")
endif()

find_package(Poco REQUIRED Foundation Util HINTS ${POCO_PATH} NO_CMAKE_FIND_ROOT_PATH)
find_package(Threads REQUIRED)

# Alert the user if we do not find it
if(NOT WPI_LIB)
    message(FATAL_ERROR "wiringPi library not found")
endif()

# Add the local ‘include’ directory and the wiringPi directory to grab headers
include_directories("${POCO_PATH}/include")

set(CMAKE_CXX_STANDARD 14)
set(CMAKE_CXX_STANDARD_REQUIRED on)

# Add all the *.cpp files in our source directory to our executable output
file(
  GLOB_RECURSE 
  SOURCES 
  "src/*.cpp"
)

add_executable(raspi_ld_test ${SOURCES})

link_directories(${POCO_PATH}/lib)

# Link the pre-compiled wiringPi library to the executable we just declared 
target_link_libraries(
  raspi_ld_test
  ${CMAKE_THREAD_LIBS_INIT}
  Poco::Foundation
)

И у меня ПРОСТО один src / main.cpp:

#include "Poco/BasicEvent.h"
#include "Poco/Delegate.h"
#include <iostream>

using Poco::BasicEvent;
using Poco::Delegate;

class Source
{
public:
    BasicEvent<int> theEvent;

    void fireEvent(int n)
    {
        theEvent(this, n);
    }
};

class Target
{
public:
    void onEvent(const void* pSender, int& arg)
    {
        std::cout << "onEvent: " << arg << std::endl;
    }
};

int main(int argc, char** argv)
{
    Source source;
    Target target;

    source.theEvent += Delegate<Target, int>(
        &target, &Target::onEvent);

    source.fireEvent(42);

    source.theEvent -= Delegate<Target, int>(
        &target, &Target::onEvent);

    return 0;
}

Теперь я могу успешно скомпилировать проект в Ubuntu.Если я скопирую raspi_ld_test в Raspberry, я могу успешно запустить его.НО!Я не могу построить проект на Raspberry, я получаю следующее сообщение об ошибке:

CMakeFiles / raspi_ld_test.dir / src / main.cpp.o: в функции Poco::MutexImpl::lockImpl()': /usr/local/include/Poco/Mutex_POSIX.h:60: undefined reference to Poco :: SystemException :: SystemException (std :: __cxx11 :: basic_string, std :: allocator> const &, int) 'CMakeFiles / raspi_ld_test.dir / src / main.cpp.o: в функции Poco::MutexImpl::unlockImpl()': /usr/local/include/Poco/Mutex_POSIX.h:79: undefined reference to Poco :: SystemException :: SystemException (std :: __ cxx11:: basic_string, std :: allocator> const &, int) 'collect2: error: ld вернул 1 состояние выхода CMakeFiles / raspi_ld_test.dir / build.make: 99: рецепт для цели' raspi_ld_test 'не выполнен make [2]: *[raspi_ld_test] Ошибка 1 CMakeFiles / Makefile2: 67: не удалось создать рецепт для цели «CMakeFiles / raspi_ld_test.dir / all» [1]: * [CMakeFiles / raspi_ld_test.dir / all] Ошибка 2 Makefile: 83: рецепт дляцель 'all' не выполнена make: *** [all] Ошибка 2

Я вижу, что библиотеки успешно связаны:

pi@raspberrypi:/usr/local/lib $ ldd libPocoFoundationd.so
    linux-vdso.so.1 (0x7ef90000)
    /usr/lib/arm-linux-gnueabihf/libarmmem.so (0x76bfe000)
    libpthread.so.0 => /lib/arm-linux-gnueabihf/libpthread.so.0 (0x76bd5000)
    libdl.so.2 => /lib/arm-linux-gnueabihf/libdl.so.2 (0x76bc2000)
    librt.so.1 => /lib/arm-linux-gnueabihf/librt.so.1 (0x76bab000)
    libstdc++.so.6 => /usr/lib/arm-linux-gnueabihf/libstdc++.so.6 (0x76a63000)
    libm.so.6 => /lib/arm-linux-gnueabihf/libm.so.6 (0x769e4000)
    libgcc_s.so.1 => /lib/arm-linux-gnueabihf/libgcc_s.so.1 (0x769b7000)
    libc.so.6 => /lib/arm-linux-gnueabihf/libc.so.6 (0x76878000)
    /lib/ld-linux-armhf.so.3 (0x76f03000)

UPDATE

Это вывод ldd, скомпилированный в amd и скопированный в исполняемый файл arm:

pi@raspberrypi:~/raspi_ld_test/build $ ldd raspi_ld_test 
    linux-vdso.so.1 (0x7efd0000)
    /usr/lib/arm-linux-gnueabihf/libarmmem.so (0x76f0f000)
    libwiringPi.so => /usr/lib/libwiringPi.so (0x76ef1000)
    libPocoUtild.so.60 => /usr/local/lib/libPocoUtild.so.60 (0x76e35000)
    libpthread.so.0 => /lib/arm-linux-gnueabihf/libpthread.so.0 (0x76e0c000)
    libPocoXMLd.so.60 => /usr/local/lib/libPocoXMLd.so.60 (0x76d1f000)
    libPocoJSONd.so.60 => /usr/local/lib/libPocoJSONd.so.60 (0x76c8b000)
    libPocoFoundationd.so.60 => /usr/local/lib/libPocoFoundationd.so.60 (0x7699c000)
    libdl.so.2 => /lib/arm-linux-gnueabihf/libdl.so.2 (0x76989000)
    librt.so.1 => /lib/arm-linux-gnueabihf/librt.so.1 (0x76972000)
    libstdc++.so.6 => /usr/lib/arm-linux-gnueabihf/libstdc++.so.6 (0x7682a000)
    libm.so.6 => /lib/arm-linux-gnueabihf/libm.so.6 (0x767ab000)
    libgcc_s.so.1 => /lib/arm-linux-gnueabihf/libgcc_s.so.1 (0x7677e000)
    libc.so.6 => /lib/arm-linux-gnueabihf/libc.so.6 (0x7663f000)
    libcrypt.so.1 => /lib/arm-linux-gnueabihf/libcrypt.so.1 (0x76600000)
    /lib/ld-linux-armhf.so.3 (0x76f25000)

Это выводrunning:

pi@raspberrypi:~/raspi_ld_test/build $ ./raspi_ld_test 
onEvent: 42

Вопрос: как это возможно, что библиотеки Poco, скомпилированные на amd для руки, хороши для соединения во время выполнения на руке, но не хороши для соединения во время сборки на руке, и чтоМне нужно сделать для сборки проекта на руку?

ОБНОВЛЕНИЕ

Так что, как я вижу из комментариев, невозможно скомпилировать проект на руку с библиотеками, скомпилированными на AMDс набором инструментов arm с использованием различных версий g ++ ...
У меня есть следующие версии:

Набор инструментов ARM в Ubuntu:

olga@olga-MS-7758:~/raspi_ld_test$ ~/RPi/tools/arm-bcm2708/arm-linux-gnueabihf/bin/arm-linux-gnueabihf-g++ --version
arm-linux-gnueabihf-g++ (crosstool-NG crosstool-ng-1.22.0-88-g8460611) 4.9.3
Copyright (C) 2015 Free Software Foundation, Inc.
This is free software; see the source for copying conditions.  There is NO
warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.

Набор инструментов ARM в Raspbian:

pi@raspberrypi:~/Poco/cmake $ g++ --version
g++ (Raspbian 6.3.0-18+rpi1+deb9u1) 6.3.0 20170516
Copyright (C) 2016 Free Software Foundation, Inc.
This is free software; see the source for copying conditions.  There is NO
warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.

Так что мне нужно искать BCM (малиновый) 6.3 g ++, скомпилированный для Ubuntu?

...