【问题标题】:CMake project using external SDK toolchain file cross-compile errorCMake项目使用外部SDK工具链文件交叉编译错误
【发布时间】:2020-06-05 17:54:30
【问题描述】:

我的目标是使用在 Linux 机器上构建的外部 SDK 工具链交叉编译存在于 Windows 上的应用程序,以便为我的 ARM 平台提供可执行代码

我在 Windows 机器上使用 VisualStudio CMake 项目

我正在使用一个外部 SDK为 Linux arm 架构交叉编译我的 C++ 程序

我在我的 Linux 机器 上使用 Yocto 项目 构建了这个 SDK不是 ARM 平台!

我的 Linux 机器上的 CMake 工具链文件路径是:

/opt/poky-atmel/2.5.3/sysroots/x86_64-pokysdk-linux/usr/share/cmake/OEToolchainConfig.cmake

我可以看到我的SDK在这个路径下可以使用多个交叉编译器:

/opt/poky-atmel/2.5.3/sysroots/x86_64-pokysdk-linux/usr/bin/arm-poky-linux-gnueabi

我可以提及 arm-poky-linux-gnueabi-gcc 编译器,我想用它来交叉编译我的应用程序并在我的 ARM 平台上执行它。

在将此交叉编译器的路径包含到我的 VisualStudio CMakeSettings 文件之前,我曾尝试在我的 Linux 机器(托管我的 SDK)上使用它来编译一个简单的代码并执行它在ARM平台上。我已经成功做到了!

请注意我必须获取和设置环境,以便导出 SDK 工具链的重要路径和变量,以便编译我的代码

现在,在我确定我的 SDK 交叉编译器的出色工作后,我必须在我的 Windows 机器上的 VisualStudio 中使用它,这也是出于同样的目的(交叉编译我的代码以便在我的 ARM 上使用它架构)。

VisualStudio 上打开 CMake 项目连接到我的 Linux 系统后,请按照以下步骤操作:

Remote Connection

为了实现我的目标,我已经修改了所有需要的设置。

您可以在此处查看我的 c++ .cpp 文件代码,该代码正在使用 Boost 库:

#include "CMakeProject4.h"
#include <boost/lambda/lambda.hpp>
#include <iostream>
#include <iterator>
#include <algorithm>

using namespace std;

int main()
{
    typedef std::istream_iterator<int> in;

    std::cout << "Type in any number: ";

    std::for_each(
        in(std::cin), in(), std::cout
        << (boost::lambda::_1 * 10)
        << "\nType in another number: ");
}

这是我的 CMakeList.txt

set(CMAKE_SYSTEM_NAME Linux)
set(CMAKE_SYSTEM_PROCESSOR arm)

set(Boost_USE_STATIC_LIBS ON) 
set(Boost_USE_MULTITHREADED OFF)  
set(Boost_USE_STATIC_RUNTIME OFF)

list(APPEND CMAKE_PREFIX_PATH /opt/poky-atmel/2.5.3/sysroots/cortexa5hf-neon-poky-linux-gnueabi/usr/include)
set(Boost_NO_BOOST_CMAKE ON)

message(STATUS "CMAKE_TOOLCHAIN_FILE='${CMAKE_TOOLCHAIN_FILE}'")
set(CROSS_COMPILER_DIR /opt/poky-atmel/2.5.3/sysroots/x86_64-pokysdk-linux/usr)
set(CMAKE_C_COMPILER ${CROSS_COMPILER_DIR}/bin/arm-poky-linux-gnueabi/arm-poky-linux-gnueabi-gcc)
set(CMAKE_CXX_COMPILER ${CROSS_COMPILER_DIR}/bin/arm-poky-linux-gnueabi/arm-poky-linux-gnueabi-gcc)


message(STATUS "CMAKE_C_COMPILER='${CMAKE_C_COMPILER}'")
message(STATUS "CMAKE_CXX_COMPILER='${CMAKE_CXX_COMPILER}'")

find_package(Boost 1.66.0) 

if(Boost_FOUND)

    message (STATUS "success!")
    add_executable (CMakeProject4 "CMakeProject4.cpp" "CMakeProject4.h") 
    include_directories(${Boost_INCLUDE_DIRS})  
    target_link_libraries(CMakeProject4 ${Boost_LIBRARIES})

endif()

这是我的 CMakeSettings.json 文件:

{
  "configurations": [
    {
      "addressSanitizerRuntimeFlags": "detect_leaks=0",
      "buildCommandArgs": "",
      "cmakeCommandArgs": "cmake -DBoost_DEBUG=ON -DCMAKE_CXX_COMPILER=/opt/poky-atmel/2.5.3/sysroots/x86_64-pokysdk-linux/usr/bin/arm-poky-linux-gnueabi/arm-poky-linux-gnueabi-gcc",
      "cmakeExecutable": "/home/ubuntu/CMake/Executable",
      "cmakeToolchain": "/opt/poky-atmel/2.5.3/sysroots/x86_64-pokysdk-linux/usr/share/cmake/OEToolchainConfig.cmake",
      "configurationType": "RelWithDebInfo",
      "ctestCommandArgs": "",
      "generator": "Unix Makefiles",
      "inheritEnvironments": [ "linux_arm" ],
      "name": "Linux-Release",
      "remoteBuildRoot": "/home/ubuntu/CMake/RemoteBR",
      "remoteCMakeListsRoot": "/home/ubuntu/CMake/RemoteCML",
      "remoteCopyBuildOutput": false,
      "remoteCopySources": true,
      "remoteCopySourcesExclusionList": [ ".vs", ".git", "out" ],
      "remoteCopySourcesMethod": "rsync",
      "remoteInstallRoot": "/home/ubuntu/CMake/RemoteIL",
      "remoteMachineName": "867574967;192.168.1.12 (username=ubuntu, port=22, authentication=PrivateKey)",
      "rsyncCommandArgs": "-t --delete --delete-excluded",
      "variables": [
        {
          "name": "Boost_INCLUDE_DIRS",
          "value": "/opt/poky-atmel/2.5.3/sysroots/cortexa5hf-neon-poky-linux-gnueabi/usr/include",
          "type": "PATH"
        },
        {
          "name": "Boost_LIBRARIES",
          "value": "/opt/poky-atmel/2.5.3/sysroots/cortexa5hf-neon-poky-linux-gnueabi/usr/lib",
          "type": "PATH"
        },
        {
          "name": "Boost_INCLUDE_DIR",
          "value": "/opt/poky-atmel/2.5.3/sysroots/cortexa5hf-neon-poky-linux-gnueabi/usr/include",
          "type": "PATH"
        }

      ]
    }
  ]
}

如您所见,我将我的 SDK 编译器 bin 路径设置为 CMAKE_CXX_COMPILER 变量。

这也是我在我的 Linux 机器上找到的 OEToolchainConfig.cmake 文件:

set( CMAKE_SYSTEM_NAME Linux )
set( CMAKE_C_FLAGS $ENV{CFLAGS} CACHE STRING "" FORCE )
set( CMAKE_CXX_FLAGS $ENV{CXXFLAGS}  CACHE STRING "" FORCE )
set( CMAKE_ASM_FLAGS ${CMAKE_C_FLAGS} CACHE STRING "" FORCE )
set( CMAKE_LDFLAGS_FLAGS ${CMAKE_CXX_FLAGS} CACHE STRING "" FORCE )

set( CMAKE_FIND_ROOT_PATH $ENV{OECORE_TARGET_SYSROOT} $ENV{OECORE_NATIVE_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 )
set( CMAKE_FIND_ROOT_PATH_MODE_PACKAGE ONLY )

# Set CMAKE_SYSTEM_PROCESSOR from the sysroot name (assuming processor-distro-os).
if ($ENV{SDKTARGETSYSROOT} MATCHES "/sysroots/([a-zA-Z0-9_-]+)-.+-.+")
  set(CMAKE_SYSTEM_PROCESSOR ${CMAKE_MATCH_1})
endif()

# Include the toolchain configuration subscripts
file( GLOB toolchain_config_files "${CMAKE_TOOLCHAIN_FILE}.d/*.cmake" )
foreach(config ${toolchain_config_files})
    include(${config})
endforeach()

我已经在我的 Linux 机器上获取了环境,然后我尝试编译。

这是我用来编译代码的命令

cmake -DBoost_DEBUG=ON -DCMAKE_CXX_COMPILER=/opt/poky-atmel/2.5.3/sysroots/x86_64-pokysdk-linux/usr/bin/arm-poky-linux-gnueabi/arm-poky-linux-gnueabi-gcc

但是,这条消息来自 CMake,说编译器已损坏以及 CMake 无法找到的其他一些东西:

CMake message

这是我的 CMakeCache 文件,您可以在其中查看我的项目使用的变量(编译器和其他东西..):

CMakeCache

我猜的第一件事是,环境设置不正确,或者 VisualStudio 从我的 Linux 机器获取环境后没有看到环境变量。这只是一个意见。 我真的不知道这里有什么问题以及为什么我无法编译我的代码。

感谢您的帮助!

谢谢!

编辑

我添加了日志文件:

这里是 CMakeError.log 文件:

CMakeError.log

这里是 CMakeOutput.log 文件:

CMakeOutput.log

【问题讨论】:

  • The answer 对您之前的问题说,当您设置工具链文件时,您不应该手动设置编译器。为什么你坚持你的编译器设置?如果编译器不是由工具链设置的,那么是工具链中的问题 或环境设置中的问题。您显示使用的文件OEToolchainConfig.cmake 包含一些信息:它include()-s 其他文件 似乎执行详细设置,但我们不知道这些文件的内容。
  • @Tsyvarev 当我做出上一个答案中描述的内容时,CMake 项目根本无法识别编译器,并且 CMAKE_CXX_COMPILER 使用的是默认的 VS 编译器:CMAKE_CXX_COMPILER=/usr/bin/c++ 这就是我不接受的原因回答。我认为问题出在环境设置中,但我无法理解 OEToolchainConfig.cmake 中写的内容,这就是为什么我不知道该做什么以及该修改什么

标签: visual-studio cmake sdk cross-compiling yocto


【解决方案1】:

我的猜测是 OEToolchainConfig.cmake 文件使用环境变量来查找例如目标 sysroot,$ENV{OECORE_TARGET_SYSROOT} 部分,这就是它不起作用的原因。

您写道,您已经在 linux 机器上获取了 environment-setup 脚本,但是当您尝试从 Windows 构建 VS 时,这不会对环境产生任何影响。

要么看看是否有一种方法可以通过 VS 使用环境脚本进行构建,要么只是在获取安装脚本后查看 OEToolchainConfig.cmake 中使用的环境变量在 linux 机器上具有什么值,然后替换 $ OEToolchainConfig.cmake 的 ENV{} 部分使用实际值代替。

【讨论】:

  • 我想我从你的回答中了解到,我必须首先找出这些值在我的 Linux 机器上存在的位置 CMAKE_C_FLAGS CMAKE_CXX_FLAGS OECORE_TARGET_SYSROOT OECORE_NATIVE_SYSROOT SDKTARGETSYSROOT ,然后我获取脚本,然后在我的 CMake 项目中输入它们的值.这是重点吗?
  • 在您的 linux 机器上,获取环境脚本,然后执行 echo $CFLAGS 并记下该值。然后将 OEToolchainCONfig.cmake 中的 $ENV{CFLAGS} 替换为您从 echo 获得的值。重复 CXXFLAGS、OECORE_TARGET_SYSROOT、OECORE_NATIVE_SYSROOT、SDKTARGETSYSROOT。
  • 您是否提到过,您可以在此处查看我如何在此链接中修改 OEToolchainConfig.cmake 文件:(pastebin.com/FFcXzdL4),您可以在此处查看我从 Visual Studio 收到的新消息: (pastebin.com/UJiunc8E)。我猜他现在在抱怨他的默认 C 编译器
  • 您可能需要将 echo 的输出包装在 "" 中。
【解决方案2】:

我和你有同样的问题,这篇文章帮助找到了解决方案。 错误消息如下:

ld: 找不到 crt1.o: 没有这样的文件或目录

链接器错误可能是由于没有在您的构建命令中指定sysroot

在 VS 2022 中,我已经能够交叉编译一个简单的 hello world 程序。

这里是我CMakePresets.json的相关部分:

{
    "name": "linux-debug",
    "displayName": "Linux Debug",
    "generator": "Unix Makefiles",
    "toolchainFile": "/opt/fslc-framebuffer/2.4.1/sysroots/x86_64-fslcsdk-linux/usr/share/cmake/OEToolchainConfig.cmake",
    "environment": {
      "CXX": "/opt/fslc-framebuffer/2.4.1/sysroots/x86_64-fslcsdk-linux/usr/bin/arm-fslc-linux-gnueabi/arm-fslc-linux-gnueabi-g++ -march=armv7-a -mthumb -mfpu=neon -mfloat-abi=hard --sysroot=/opt/fslc-framebuffer/2.4.1/sysroots/armv7at2hf-neon-fslc-linux-gnueabi",
      "CFLAGS": "-O2 -pipe -g -feliminate-unused-debug-types",
      "CXXFLAGS": "-O2 -pipe -g -feliminate-unused-debug-types",
      "OECORE_TARGET_SYSROOT": "/opt/fslc-framebuffer/2.4.1/sysroots/armv7at2hf-neon-fslc-linux-gnueabi",
      "OECORE_NATIVE_SYSROOT": "/opt/fslc-framebuffer/2.4.1/sysroots/x86_64-fslcsdk-linux",
      "SDKTARGETSYSROOT": "/opt/fslc-framebuffer/2.4.1/sysroots/armv7at2hf-neon-fslc-linux-gnueabi"
    },
    "binaryDir": "${sourceDir}/out/build/${presetName}",
    "installDir": "${sourceDir}/out/install/${presetName}",
    "cacheVariables": {
      "CMAKE_BUILD_TYPE": "Debug"
    },
    "condition": {
      "type": "equals",
      "lhs": "${hostSystemName}",
      "rhs": "Linux"
    },
    "vendor": {
      "microsoft.com/VisualStudioRemoteSettings/CMake/1.0": {
        "sourceDir": "$env{HOME}/.vs/$ms{projectDirName}"
      }
    }
  }

请注意,我添加了对我的工具链文件的引用(密钥:toolchainFile)并根据需要设置了环境变量(这些将通过采购您的 SDK 来设置)。 因此,无需先获取 SDK,只需告诉 VS 在哪里可以找到 toolchainFile 并确保设置了所有相关的环境变量即可。

【讨论】:

    猜你喜欢
    • 2020-06-04
    • 1970-01-01
    • 1970-01-01
    • 2017-03-31
    • 2020-11-11
    • 2013-09-07
    • 2012-07-10
    • 2019-08-17
    相关资源
    最近更新 更多