我的目标是使用在 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 系统后,请按照以下步骤操作:
我已经修改了实现目标所需的所有设置。
您可以在这里看到我使用 Boost 库的 c++ .cpp 文件代码:
#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 无法找到的其他一些内容:
这是我的CMakeCache 文件,您可以在其中查看我的项目使用了哪些变量(编译器和其他东西..):
我猜想的第一件事是,环境设置不正确,或者从我的 Linux 计算机获取环境后,VisualStudio 没有看到环境变量。这只是一个意见。 我真的不知道这里有什么问题以及为什么我无法编译我的代码。
我将感谢您的帮助!
谢谢!
编辑
我添加日志文件:
这是 CMakeError.log 文件:
这是 CMakeOutput.log 文件:
最佳答案
我的猜测是 OEToolchainConfig.cmake 文件使用环境变量来查找例如目标 sysroot,$ENV{OECORE_TARGET_SYSROOT}
部分,这就是它不起作用的原因。
您写道,您已经在 Linux 计算机上获取了环境设置脚本,但是当您尝试从 Windows 中的 VS 进行构建时,这不会对环境产生任何影响。
看看是否有一种方法可以通过 VS 使用环境脚本进行构建,或者在获取安装脚本后简单地查看 OEToolchainConfig.cmake 中使用的环境变量在 Linux 计算机上的值,然后替换 $ OEToolchainConfig.cmake 的 ENV{} 部分改为实际值。
关于visual-studio - 使用外部SDK工具链文件的CMake项目交叉编译错误,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/60336326/