环境配置
操作系统:ubantu16.04
Cmake编译器:3.10.2
Cmake地址:/usr/bin 【直接apt-get安装的】
出现的问题以及解决办法
问题一
ztn@ubuntu:~/QT/mqtt_prj/build$ cmake -DCMAKE_TOOLCHAIN_FILE=../cmake/arm-linux-setup.cmake -DCMAKE_BUILD_TYPE=Release ..
Change Dir: /home/ztn/QT/mqtt_prj/build/CMakeFiles/CMakeTmp
Run Build Command:"/usr/bin/make" "cmTC_30da4/fast"
/usr/bin/make -f CMakeFiles/cmTC_30da4.dir/build.make CMakeFiles/cmTC_30da4.dir/build
make[1]: 进入目录“/home/ztn/QT/mqtt_prj/build/CMakeFiles/CMakeTmp”
Building C object CMakeFiles/cmTC_30da4.dir/testCCompiler.c.o
/opt/fsl-imx-x11/4.1.15-2.1.0/sysroots/x86_64-pokysdk-linux/usr/bin/arm-poky-linux-gnueabi/arm-poky-linux-gnueabi-gcc --sysroot=/opt/fsl-imx-x11/4.1.15-2.1.0/sysroots/cortexa7hf-neon-poky-linux-gnueabi -o CMakeFiles/cmTC_30da4.dir/testCCompiler.c.o -c /home/ztn/QT/mqtt_prj/build/CMakeFiles/CMakeTmp/testCCompiler.c
Linking C executable cmTC_30da4
/usr/bin/cmake -E cmake_link_script CMakeFiles/cmTC_30da4.dir/link.txt --verbose=1
/opt/fsl-imx-x11/4.1.15-2.1.0/sysroots/x86_64-pokysdk-linux/usr/bin/arm-poky-linux-gnueabi/arm-poky-linux-gnueabi-gcc --sysroot=/opt/fsl-imx-x11/4.1.15-2.1.0/sysroots/cortexa7hf-neon-poky-linux-gnueabi -rdynamic CMakeFiles/cmTC_30da4.dir/testCCompiler.c.o -o cmTC_30da4
/opt/fsl-imx-x11/4.1.15-2.1.0/sysroots/x86_64-pokysdk-linux/usr/libexec/arm-poky-linux-gnueabi/gcc/arm-poky-linux-gnueabi/5.3.0/real-ld: error: cmTC_30da4 uses VFP register arguments, CMakeFiles/cmTC_30da4.dir/testCCompiler.c.o does not
/opt/fsl-imx-x11/4.1.15-2.1.0/sysroots/x86_64-pokysdk-linux/usr/libexec/arm-poky-linux-gnueabi/gcc/arm-poky-linux-gnueabi/5.3.0/real-ld: failed to merge target specific data of file CMakeFiles/cmTC_30da4.dir/testCCompiler.c.o
collect2: error: ld returned 1 exit status
CMakeFiles/cmTC_30da4.dir/build.make:97: recipe for target 'cmTC_30da4' failed
make[1]: *** [cmTC_30da4] Error 1
make[1]: 离开目录“/home/ztn/QT/mqtt_prj/build/CMakeFiles/CMakeTmp”
Makefile:126: recipe for target 'cmTC_30da4/fast' failed
make: *** [cmTC_30da4/fast] Error 2
解决办法
在您的arm-linux-setup.cmake工具链文件中,明确指定浮点编译选项:
set(CMAKE_C_FLAGS "--sysroot=${SYSROOT} -march=armv7-a -mfpu=neon -mfloat-abi=hard" CACHE STRING "C Flags")
set(CMAKE_CXX_FLAGS "--sysroot=${SYSROOT} -march=armv7-a -mfpu=neon -mfloat-abi=hard" CACHE STRING "C++ Flags")
问题二
ztn@ubuntu:~/QT/mqtt_prj/build$ cmake -DCMAKE_TOOLCHAIN_FILE=../cmake/arm-linux-setup.cmake -DCMAKE_BUILD_TYPE=Release ..
-- The C compiler identification is GNU 5.3.0
-- Check for working C compiler: /opt/fsl-imx-x11/4.1.15-2.1.0/sysroots/x86_64-pokysdk-linux/usr/bin/arm-poky-linux-gnueabi/arm-poky-linux-gnueabi-gcc
-- Check for working C compiler: /opt/fsl-imx-x11/4.1.15-2.1.0/sysroots/x86_64-pokysdk-linux/usr/bin/arm-poky-linux-gnueabi/arm-poky-linux-gnueabi-gcc -- works
-- Detecting C compiler ABI info
-- Detecting C compiler ABI info - done
-- Detecting C compile features
-- Detecting C compile features - done
-- CMake version: 3.10.2
-- CMake system name: Linux
-- CMake system processor: arm
CMake Error at CMakeLists.txt:31 (target_link_options):
Unknown CMake command "target_link_options".
解决办法
修改 CMakeLists.txt
# 删除或注释以下行:
# target_link_options(mqttClient PRIVATE "--sysroot=${CMAKE_SYSROOT}")
# 改为通过全局链接器标志传递 sysroot(适用于交叉编译)
set(CMAKE_EXE_LINKER_FLAGS "--sysroot=${CMAKE_SYSROOT} ${CMAKE_EXE_LINKER_FLAGS}")
问题三
ztn@ubuntu:~/QT/mqtt_prj/build$ make
Scanning dependencies of target mqttClient
[ 50%] Building C object CMakeFiles/mqttClient.dir/mqttClient.c.o
[100%] Linking C executable bin/mqttClient
/opt/fsl-imx-x11/4.1.15-2.1.0/sysroots/x86_64-pokysdk-linux/usr/libexec/arm-poky-linux-gnueabi/gcc/arm-poky-linux-gnueabi/5.3.0/real-ld: cannot find -lpaho-mqtt3c
collect2: error: ld returned 1 exit status
CMakeFiles/mqttClient.dir/build.make:94: recipe for target 'bin/mqttClient' failed
make[2]: *** [bin/mqttClient] Error 1
CMakeFiles/Makefile2:67: recipe for target 'CMakeFiles/mqttClient.dir/all' failed
make[1]: *** [CMakeFiles/mqttClient.dir/all] Error 2
Makefile:83: recipe for target 'all' failed
make: *** [all] Error 2
解决办法
在 CMakeLists.txt 中直接使用绝对路径链接库:
target_link_libraries(mqttClient PRIVATE
/home/ztn/tools/paho.mqtt.c-1.3.8/install/lib/libpaho-mqtt3c.so
)
完整的文件如下
CMakeLists.txt
cmake_minimum_required(VERSION 2.8.12)
project(MQTTClient C)
message(STATUS "CMake version: " ${CMAKE_VERSION})
message(STATUS "CMake system name: " ${CMAKE_SYSTEM_NAME})
message(STATUS "CMake system processor: " ${CMAKE_SYSTEM_PROCESSOR})
# 设置可执行文件输出路径
set(EXECUTABLE_OUTPUT_PATH ${PROJECT_BINARY_DIR}/bin)
# 定义可执行文件目标
add_executable(mqttClient mqttClient.c)
# 指定头文件路径
target_include_directories(mqttClient PRIVATE
/home/ztn/tools/paho.mqtt.c-1.3.8/install/include
)
# 指定库路径
link_directories(/home/ztn/tools/paho.mqtt.c-1.3.8/install/lib)
# 链接库
target_link_libraries(mqttClient PRIVATE
paho-mqtt3c
)
# 添加链接器选项(兼容旧版 CMake)
set(CMAKE_EXE_LINKER_FLAGS
"${CMAKE_EXE_LINKER_FLAGS} -L/home/ztn/tools/paho.mqtt.c-1.3.8/install/lib -Wl,-rpath-link,/home/ztn/tools/paho.mqtt.c-1.3.8/install/lib"
)
# 交叉编译兼容性:通过全局标志传递 sysroot
if(CMAKE_CROSSCOMPILING)
set(CMAKE_EXE_LINKER_FLAGS "--sysroot=${CMAKE_SYSROOT} ${CMAKE_EXE_LINKER_FLAGS}")
endif()
arm-linux-setup.cmake
# arm-linux-setup.cmake
set(CMAKE_CROSSCOMPILING TRUE)
set(CMAKE_SYSTEM_NAME Linux)
set(CMAKE_SYSTEM_PROCESSOR arm)
# 指定编译器的sysroot路径
set(TOOLCHAIN_DIR /opt/fsl-imx-x11/4.1.15-2.1.0/sysroots)
set(CMAKE_SYSROOT ${TOOLCHAIN_DIR}/cortexa7hf-neon-poky-linux-gnueabi)
# 指定交叉编译器arm-linux-gcc
set(CMAKE_C_COMPILER ${TOOLCHAIN_DIR}/x86_64-pokysdk-linux/usr/bin/arm-poky-linux-gnueabi/arm-poky-linux-gnueabi-gcc)
# 添加编译和链接参数
set(CMAKE_C_FLAGS "-march=armv7ve -mfpu=neon -mfloat-abi=hard -mcpu=cortex-a7")
set(CMAKE_CXX_FLAGS "${CMAKE_C_FLAGS}")
set(CMAKE_EXE_LINKER_FLAGS "-march=armv7ve -mfpu=neon -mfloat-abi=hard")
# 设置编译器标志
set(CMAKE_C_FLAGS "--sysroot=${SYSROOT} -march=armv7-a -mfpu=neon -mfloat-abi=hard" CACHE STRING "C Flags")
set(CMAKE_CXX_FLAGS "--sysroot=${SYSROOT} -march=armv7-a -mfpu=neon -mfloat-abi=hard" CACHE STRING "C++ Flags")
# 强制隔离交叉编译环境
set(CMAKE_FIND_ROOT_PATH ${CMAKE_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)