简体   繁体   English

CMake与Poky交叉编译

[英]CMake cross compilation with Poky

I try to set up my cross-platform development environment with CMake. 我尝试使用CMake设置跨平台开发环境。

I encounter the following error only when I try to compile with poky toolchain: 我只有在尝试使用poky工具链进行编译时才会遇到以下错误:

make[2]: * No rule to make '/opt/poky/1.3/sysroots/armv5te-poky-linux-gnueabi/usr/lib/libboost_thread.so', needed by 'test'. make [2]: *没有规则来生成'test'所需的'/opt/poky/1.3/sysroots/armv5te-poky-linux-gnueabi/usr/lib/libboost_thread.so'。 Stop 停止

I tried to set up the CMake toolchain in two different methods and the result is the same. 我尝试用两种不同的方法设置CMake工具链,结果是相同的。

Method1 (simple): 方法1(简单):

###################################################################################
# Cross compile using Poky prebuilt toolchains, you need to source the
# environment first:
#
# $ rm -fr build; mkdir build; cd build
# $ source /opt/poky/1.3/environment-setup-armv5te-poky-linux-gnueabi
# $ cmake -DCMAKE_TOOLCHAIN_FILE=Toolchains/arm-poky-linux-gnueabi-simple.cmake
# $ make
###################################################################################

SET(CMAKE_SYSTEM_NAME Linux)
SET(CMAKE_SYSTEM_VERSION 1)

SET(CMAKE_FIND_ROOT_PATH $ENV{OECORE_TARGET_SYSROOT})
SET(CMAKE_FIND_ROOT_PATH_MODE_PROGRAM NEVER)
SET(CMAKE_FIND_ROOT_PATH_MODE_LIBRARY ONLY)
SET(CMAKE_FIND_ROOT_PATH_MODE_INCLUDE ONLY)

Method2: 方法2:

# this one is important
SET( CMAKE_SYSTEM_NAME Linux )

# this one not so much
SET( CMAKE_SYSTEM_VERSION 1 )

# specify the cross compiler
SET( CROSS_COMPILER_PATH /opt/poky/1.3/sysroots/x86_64-pokysdk-linux/usr/bin/armv5te-poky-linux-gnueabi )
SET( C_CROSS_COMPILER arm-poky-linux-gnueabi- )

FIND_PROGRAM( CCACHE ccache )
IF( CCACHE )
    SET( CMAKE_C_COMPILER "${CCACHE}" "${CROSS_COMPILER_PATH}/${C_CROSS_COMPILER}gcc" )
    SET( CMAKE_CXX_COMPILER "${CCACHE}" "${CROSS_COMPILER_PATH}/${C_CROSS_COMPILER}g++" )
ELSE( CCACHE )
    SET( CMAKE_C_COMPILER "${CROSS_COMPILER_PATH}/${C_CROSS_COMPILER}gcc" "" )
    SET( CMAKE_CXX_COMPILER "${CROSS_COMPILER_PATH}/${C_CROSS_COMPILER}g++" "" )
ENDIF(CCACHE)

SET( CMAKE_RANLIB "${CROSS_COMPILER_PATH}/${C_CROSS_COMPILER}ranlib" )
SET( CMAKE_AR "${CROSS_COMPILER_PATH}/${C_CROSS_COMPILER}ar" )

SET( CMAKE_COMPILER_IS_GNUCC 1 )
SET( CMAKE_COMPILER_IS_GNUCXX 1 )

INCLUDE_DIRECTORIES( BEFORE SYSTEM /opt/poky/1.3/sysroots/armv5te-poky-linux-gnueabi/usr/include )
LINK_DIRECTORIES( /opt/poky/1.3/sysroots/armv5te-poky-linux-gnueabi/usr/lib )

# where is the target environment 
SET( CMAKE_FIND_ROOT_PATH /opt/poky/1.3/sysroots/armv5te-poky-linux-gnueabi/ )

#search for libraries and header files only in the target environment
SET( CMAKE_FIND_ROOT_PATH_MODE_LIBRARY ONLY )
SET( CMAKE_FIND_ROOT_PATH_MODE_INCLUDE ONLY )

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

My CMake project is: 我的CMake项目是:

cmake_minimum_required( VERSION 2.8.9 )

project ( TEST ) 

set( BOOST_COMPONENTS thread )

find_package( Boost COMPONENTS ${BOOST_COMPONENTS} )

add_executable( test test.cpp ) 
target_link_libraries( test ${Boost_THREAD_LIBRARY} )

My cpp code used for tests: 我的cpp代码用于测试:

#include <boost/thread/thread.hpp>
#include <iostream>

void hello()
{
    std::cout << "Hello!" << std::endl;
}

int main()
{
    boost::thread thrd( &hello );
    thrd.join();
    return 0;
}

Thank you by advance for your help 预先感谢您的帮助

The solution to my problem: 我的问题的解决方案:

Solution1: 解决方法1:

###################################################################################
#
# Cross compile using Poky prebuilt toolchains, you need to source the
# environment first:
#
# $ rm -fr build; mkdir build; cd build
# $ source /opt/poky/1.3/environment-setup-armv5te-poky-linux-gnueabi
# $ cmake -DCMAKE_TOOLCHAIN_FILE=Toolchains/arm-poky-linux-gnueabi-simple.cmake
# $ make
#
###################################################################################

SET(CMAKE_SYSTEM_NAME Linux)
SET(CMAKE_SYSTEM_VERSION 1)

SET(CMAKE_FIND_ROOT_PATH /home/sylvain/Share/dev/Dev2M_CMakeCrossCompile/temp/boost $ENV{OECORE_TARGET_SYSROOT})
SET(CMAKE_FIND_ROOT_PATH_MODE_PROGRAM NEVER)
SET(CMAKE_FIND_ROOT_PATH_MODE_LIBRARY ONLY)
SET(CMAKE_FIND_ROOT_PATH_MODE_INCLUDE ONLY)

My CMake project: 我的CMake项目:

cmake_minimum_required( VERSION 2.8.9 )

project ( TEST ) 

set( BOOST_COMPONENTS atomic system thread )

#Very useful to find the source of the problem
#set( Boost_DEBUG on )

#Set the version of gcc in my case that is the source of my problems otherwise the module defines the gcc version of my ubuntu PC
set( Boost_COMPILER "-gcc" )

set( BOOST_ROOT /home/sylvain/Share/dev/Dev2M_CMakeCrossCompile/temp/boost )

find_package( Boost COMPONENTS ${BOOST_COMPONENTS} true )

set( MY_BOOST_LIBRARIES
    ${Boost_ATOMIC_LIBRARY}
    ${Boost_SYSTEM_LIBRARY}
    ${Boost_THREAD_LIBRARY}
)

add_executable( test test.cpp ) 
target_link_libraries( test ${MY_BOOST_LIBRARIES} )

Boost is usually linked as follows: Boost通常链接如下:

FIND_PACKAGE( Boost COMPONENTS ${TheLibs} REQUIRED )    
include_directories(${Boost_INCLUDE_DIR})
link_directories(${Boost_LIBRARY_DIR})

add_executable(test test.cpp)
target_link_libraries( test ${Boost_LIBRARIES} )

For clarification: The message "no rule to make" often means that the target file doesn't exist. 为了澄清:消息“无规则可做”通常表示目标文件不存在。 Most of the times i check the file manually. 大多数时候,我会手动检查文件。 If the file exists and you still get errors you can try to link manually by setting linker flags eg: 如果文件存在并且仍然出现错误,则可以尝试通过设置链接器标志来手动链接,例如:

SET(CMAKE_CXX_FLAGS  "${CMAKE_CXX_FLAGS} -l${PATH_TO_LIBRARY}")

If it still doesn't work, then call make with the Verbose flag (usually VERBOSE=1) and look if the link step is executed correctly. 如果仍然不起作用,请使用Verbose标志(通常为VERBOSE = 1)调用make并查看链接步骤是否正确执行。


A general approach to link a external library is to add it as an own target. 链接外部库的一般方法是将其添加为自己的目标。 The advantage is that you can reuse it for multiple executables or libraries in the same Project. 优点是您可以将其重用于同一项目中的多个可执行文件或库。 You wouldn't use that for boost, because they usually handle that for you. 您不会将其用于提升,因为它们通常会为您处理。

add_library( libABCDEFG SHARED/STATIC IMPORTED )
set_target_properties( mylib PROPERTIES IMPORTED_LOCATION ${PathToLibrary} )
TARGET_LINK_LIBRARIES(test libABCDEFG)

Another hint to CMake usage with Toolchains: 使用工具链使用CMake的另一个提示:

A Toolchain is only included on the first creation of the project (except you include it otherwise). 工具链仅包含在项目的首次创建中(除非另外包含)。 If you change any settings inside of the toolchain you have to delete the CMake Cache and re-execute the first CMake call. 如果更改工具链内的任何设置,则必须删除CMake缓存并重新执行第一个CMake调用。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM