iMX6ULL QT environment configuration | CMake cross-compilation environment construction and use under Linux

I am used to using cmake, and I never want to go back to the era of handwritten makefiles. Compared with hand-written makefiles, using cmake seems to realize motorization, and it becomes very simple to manage the compilation of project projects. Besides, cmake is very popular. Many software source code packages under linux are compiled using cmake. So here is a summary of how to use cmake in the embedded linux environment, and the cmake configuration of embedded qt.

Introduction to CMake

What is CMake
You may have heard of several Make tools, such as GNU Make, QT's qmake, Microsoft's MS nmake, BSD Make (pmake), Makepp, and so on. These Make tools follow different norms and standards, and the format of the Makefile they execute varies widely. This brings up a serious problem: if the software wants to be cross-platform, it must be guaranteed to be able to compile on different platforms. And if you use the above Make tool, you have to write a Makefile for each standard, which will be a crazy job, and it is not easy to write a makefile by hand.

CMake is a tool designed to address the above problems: it first allows developers to write a platform-independent CMakeList.txt file to customize the entire compilation process, and then further generates the required localized Makefile and project files according to the target user's platform. Such as a Makefile for Unix or a Visual Studio project for Windows. So as to achieve "Write once, run everywhere". Obviously, CMake is a more advanced compilation and configuration tool than the above-mentioned make. Some well-known open source projects that use CMake as a project architecture system include VTK, ITK, KDE, OpenCV, OSG, etc.

The process of using CMake to generate Makefile and compile it under the linux platform is as follows:
1. Write the CMake configuration file CMakeLists.txt.
2. Execute the command cmake PATH or ccmake PATH to generate Makefile ( the difference between ccmake and  cmake is that the former provides an interactive interface), which  PATH is the directory where CMakeLists.txt is located.
3. Use the make command to compile.

cmake install

Download | CMake

The cmake installation under linux is very simple. Take ubuntu as an example, you can directly sudo apt-get install cmake. Of course, you can also manually download the latest source package to install. The simplest way is chosen here.

sudo apt-get install cmake

Configuration in cmake cross-compilation environment

Specify the cross-compilation toolchain used by cmake (option: DCMAKE_TOOLCHAIN_FILE).

Create a new toolchains directory under the project root directory. In this directory, refer to the configuration files of other development boards and add a configuration file arm-poky-linux-gnueabi.cmake for this development board.

set(CMAKE_SYSTEM_NAME Linux)
set(CMAKE_SYSTEM_PROCESSOR arm)
set(CMAKE_C_COMPILER "arm-poky-linux-gnueabi-gcc")
set(CMAKE_CXX_COMPILER "arm-poky-linux-gnueabi-g++")
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_C_FLAGS "-march=armv7-a -mfloat-abi=hard -mfpu=neon --sysroot=/opt/fsl-imx-x11/4.1.15-2.1.0/sysroots/cortexa7hf-neon-poky-linux-gnueabi")
set(CMAKE_CXX_FLAGS "-march=armv7-a -mfloat-abi=hard -mfpu=neon --sysroot=/opt/fsl-imx-x11/4.1.15-2.1.0/sysroots/cortexa7hf-neon-poky-linux-gnueabi")

# cache flags
set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS}" CACHE STRING "c flags")
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS}" CACHE STRING "c++ flags")

cmake uses

Create a new cmake_test project folder, and create a new hello.c file source code inside.

#include <stdio.h>

int main(){
    printf("hello world\n");
    return 0;
}

Write the CMakeLists.txt file, the commented out content can be ignored, in fact, there is very little content.

cmake_minimum_required(VERSION 3.12)

project(HELLO)

#add_definitions(
 #   -D_ENABLE_LOGGING
#)

set(SRC_LIST hello.c)

#add library(libhello SHARED hello.c)
#set_target_properties(libhello PROPERTIES OUTPUT NAME "hello")
add_executable(hello ${SRC_LIST})
#target_link_libraries(hello libhello)

start compiling 

Create a build directory under the project root directory, then cd build, first enter the build directory. Note that -DCMAKE_TOOLCHAIN_FILE needs to be specified.

#先加载环境变量
source /opt/fsl-imx-x11/4.1.15-2.1.0/environment-setup-cortexa7hf-neon-poky-linux-gnueabi 

#在项目根目录,cd build,先进入build目录
cmake -DCMAKE_BUILD_TYPE=Release -DCMAKE_TOOLCHAIN_FILE=../toolchains/arm-poky-linux-gnueabi.cmake ../

Finally, an executable file is generated that can be executed on the board.

cmake script in QT cross-compilation environment

Sample demo, main.cpp:

#include <QCoreApplication>
#include<QDebug>
#include <QDir>

int main(int argc, char *argv[])
{
    QCoreApplication a(argc, argv);
    qDebug() << "hello QT test";
    return a.exec();
}

The cmake script in the cross-compilation environment of the QT project:

cmake_minimum_required(VERSION 3.12)

project(helloqt)

add_definitions(
    -D_ENABLE_LOGGING
)

#set(CMAKE_PREFIX_PATH "/opt/fsl-imx-x11/4.1.15-2.1.0/sysroots/cortexa7hf-neon-poky-linux-gnueabi/usr/lib/cmake")

set(BUILD_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR}/../build_out)
get_filename_component(ABSOLUTE_PATH ${BUILD_DIRECTORY} ABSOLUTE)
set(BUILD_DIRECTORY ${ABSOLUTE_PATH})


####################  QT dependencies ####################
set(CMAKE_CXX_STANDARD 11)
set(CMAKE_AUTOMOC ON)
set(CMAKE_AUTORCC ON)
set(CMAKE_AUTOUIC ON)

set(QT_VERSION 5)
set(CMAKE_CROSSCOMPILING TRUE)
set(OE_QMAKE_PATH_EXTERNAL_HOST_BINS /opt/fsl-imx-x11/4.1.15-2.1.0/sysroots/x86_64-pokysdk-linux/usr/bin)

set(REQUIRED_LIBS Core Quick Widgets)
set(REQUIRED_LIBS_QUALIFIED Qt5::Core Qt5::Quick Qt5::Widgets)

####################  set output directory ####################
set(BUILD_DIR ${BUILD_DIRECTORY})
set(LIB_DIR ${BUILD_DIR}/lib/Release)
#set(LIB_FIX)
#if (CMAKE_BUILD_TYPE MATCHES "Debug")
#    set(LIB_DIR ${BUILD_DIR}/lib/Debug)
#    set(LIB_FIX _d)
#endif ()

#get_filename_component(ABSOLUTE_PATH ${LIB_DIR} ABSOLUTE)
#set(LIB_DIR ${ABSOLUTE_PATH})

set(CMAKE_ARCHIVE_OUTPUT_DIRECTORY ${LIB_DIR})
set(CMAKE_LIBRARY_OUTPUT_DIRECTORY ${LIB_DIR})
set(CMAKE_PDB_OUTPUT_DIRECTORY ${LIB_DIR})
set(CMAKE_RUNTIME_OUTPUT_DIRECTORY ${LIB_DIR})

#set(LIB_DIR_FIX ${LIB_DIR})
#option(USE_VS_BUILD "use visual studio build." OFF)
#if (USE_VS_BUILD)
#    set(LIB_DIR_FIX ${LIB_DIR}/bin/Debug)
#endif ()
###########set include path ####################
include_directories(
        ${CMAKE_CURRENT_SOURCE_DIR}/
        ${BUILD_DIR}/include
)

####################  scan source files ####################
aux_source_directory(${CMAKE_CURRENT_SOURCE_DIR}/ SRC_FILES)
#aux_source_directory(${CMAKE_CURRENT_SOURCE_DIR}/source/cpp/test2 SRC_FILES)

#set(SRC_LIST hello.c)

#add library(libhello SHARED hello.c)
#set_target_properties(libhello PROPERTIES OUTPUT NAME "hello")
find_package(Qt${QT_VERSION} COMPONENTS ${REQUIRED_LIBS} REQUIRED)
#find_package(Qt5 COMPONENTS Widgets)

add_executable(${PROJECT_NAME}  ${SRC_FILES})
#target_link_libraries(hello libhello)


####################  set target dependencies ####################

set(THIRD_LIBS "")

target_link_libraries(${PROJECT_NAME} PRIVATE ${REQUIRED_LIBS_QUALIFIED} ${THIRD_LIBS})

error message

Error solution

According to the error prompt, the prompt indicates that the OE_QMAKE_PATH_EXTERNAL_HOST_BINS variable cannot be found in CMake. This is because the correct OpenEmbedded (OE) environment variables are not set in your cross-compilation environment.

The following line can be added to the CMakeLists.txt file to set the OE_QMAKE_PATH_EXTERNAL_HOST_BINS variable. Its purpose is to find the location of qmake. So it can be set as follows:

set(QT_VERSION 5)
set(CMAKE_CROSSCOMPILING TRUE)
set(OE_QMAKE_PATH_EXTERNAL_HOST_BINS /opt/fsl-imx-x11/4.1.15-2.1.0/sysroots/x86_64-pokysdk-linux/usr/bin)

start compiling 

cmake -DCMAKE_BUILD_TYPE=Release -DCMAKE_TOOLCHAIN_FILE=../toolchains/arm-poky-linux-gnueabi.cmake -DCMAKE_PREFIX_PATH=/opt/fsl-imx-x11/4.1.15-2.1.0/sysroots/cortexa7hf-neon-poky-linux-gnueabi/usr/lib/cmake ../

If you think the above command is a bit long, you can write -DCMAKE_PREFIX_PATH to the CMakeLists.txt file. As follows (with or without ""):

set(CMAKE_PREFIX_PATH "/opt/fsl-imx-x11/4.1.15-2.1.0/sysroots/cortexa7hf-neon-poky-linux-gnueabi/usr/lib/cmake")

Finally, the compilation is successful! Finally, you can happily use cmake to compile qt projects in the embedded environment. If you don't want to install and use the huge IDE of qtcreater. Or if you want to use scripts to compile qt projects, using cmake is a good choice.

After the above operations, the helloqt executable file is successfully generated. Put this file on the development board, you can see the execution effect. The location of the generated executable file is under the build_out/lib/Release/ path.

other resources

https://m.elecfans.com/article/2012326.html

Introduction and use of CMAKE (Linux platform)_cmake linux_L888666Q's Blog-CSDN Blog

[cmake actual combat 1] Two methods of installing cmake under linux

cmake super detailed introductory tutorial_cmake compilation process_yygr's blog-CSDN blog

Using VSCode+cmake+GDB+gdbserver to debug IMX6ULL's Linux C application

Guess you like

Origin blog.csdn.net/qq8864/article/details/132424908