一、安装需要用到的依赖
安装gcc用来编译程序,cmake用来完成构建,ccache用来加速编译,ninja用来加速构建过程。
apt install gcc cmake ccache ninja-build
CMake是一个开源的跨平台构建系统,它使用一个简单的语言来描述项目的构建过程。这个语言可以用来描述项目的源文件、库依赖、构建选项等。CMake可以生成用于构建、测试和打包项目的Makefile、Visual Studio项目文件或者Xcode项目文件。
CMake的主要特点包括:
- 跨平台支持:CMake可以在多个平台上构建项目,包括Windows、Linux和macOS。
- 简单的语法:CMake使用一个简单的语法来描述项目的构建过程,使得它易于使用和学习。
CMake和Ninja一起使用可以提供以下优势:
- 构建效率:Ninja是一个快速的构建系统,它可以充分利用多核处理器的并行构建能力。而CMake使用一个简单的语法来描述构建过程,使得它易于使用和学习。当与Ninja一起使用时,CMake可以生成Ninja构建文件,从而充分利用Ninja的构建效率。
- 跨平台支持:CMake是一个开源的跨平台构建系统,它可以在多个平台上构建项目,包括Windows、Linux和macOS。而Ninja是一个跨平台的构建系统,它可以在多个操作系统上构建项目,包括Windows、Linux和macOS。当与CMake一起使用时,可以在不同的平台上构建项目,并且保持一致的构建过程。
- 构建规则灵活性:CMake提供了丰富的构建规则,可以满足各种项目的需求。而Ninja则提供了简单的构建规则,使得构建过程简单和快速。当与CMake一起使用时,可以使用CMake的丰富构建规则,同时又具备Ninja的快速构建速度。
而ccache是一个用于减少编译时间的工具,它可以缓存编译器的输出,以便在多次构建相同的代码时重复利用。简单来说,就是用空间换时间。
二、创建LVGL的CMake工程
下载lvgl源码,不想把lvgl源码当做git工程的一部分提交,所以使用子仓模式添加lvgl源码
mkdir lvgl_cmake
cd lvgl_cmake/
git submodule add -b release/v8.3 git@gitee.com:my_lvgl/lvgl.git lvgl
源码拉取完毕之后,创建cmake工程配置文件。
vi CMakeList.txt
将以下内容输入该文件
cmake_minimum_required(VERSION 3.12)
project(lvgl VERSION 1.0)
add_compile_options(-std=c99)
find_program(CCACHE_FOUND ccache)
if(CCACHE_FOUND)
set_property(GLOBAL PROPERTY RULE_LAUNCH_COMPILE ccache)
set_property(GLOBAL PROPERTY RULE_LAUNCH_LINK ccache)
endif(CCACHE_FOUND)
set(LVGL_SDK_PATH ${PROJECT_SOURCE_DIR}/lvgl)
set(LVGL_MAIN_SOURCE ${PROJECT_SOURCE_DIR}/main/src)
include_directories(include ${PROJECT_SOURCE_DIR} ${LVGL_SDK_PATH})
file(GLOB_RECURSE INCLUDES "lvgl/src/*.h" "./*.h" "drivers/*.h" "display/*.h")
file(GLOB_RECURSE SOURCES "lvgl/src/*.c" "display/*.c" "drivers/*.c")
set(EXECUTABLE_OUTPUT_PATH ${PROJECT_SOURCE_DIR}/bin)
set(CMAKE_CXX_FLAGS "-03")
aux_source_directory(${LVGL_SDK_PATH}/../main/src src)
add_executable(main ${src} ${SOURCES} ${INCLUDES})
target_link_libraries(main PRIVATE ${LIB_LIST})
add_custom_target(run COMMAND ${EXECUTABLE_OUTPUT_PATH}/main)
复制lv_port_linux_frame_buffer里的lv_drv_conf.h和lv_conf.h到根目录。将lv_drivers仓的display目录里的fbdev.c和fbdev.h复制到display目录里。
仓库地址https://github.com/lvgl/lv_port_linux_frame_buffer
然后将main/src/main.c的内容修改成以下内容。
#include "src/widgets/lv_label.h"
#include "../../lvgl/lvgl.h"
#define LV_ATTRIBUTE_TICK_INC
#include "ini.h"
#include <stdlib.h>
#include <string.h>
#include <time.h>
#include <sys/time.h>
void fbdev_flush(lv_disp_drv_t * drv, const lv_area_t * area, lv_color_t * color_p);
static lv_obj_t *meter;
static void set_value(void *indic, int32_t v) {
lv_meter_set_indicator_end_value(meter, indic, v);
}
void lv_example_meter_xxxx(void) {
meter = lv_meter_create(lv_scr_act());
lv_obj_center(meter);
lv_obj_set_size(meter, 200, 200);
lv_obj_remove_style(meter, NULL, LV_PART_INDICATOR);
lv_meter_scale_t *scale = lv_meter_add_scale(meter);
lv_meter_set_scale_ticks(meter, scale, 11, 2, 10,
lv_palette_main(LV_PALETTE_GREY));
lv_meter_set_scale_major_ticks(meter, scale, 1, 2, 30, lv_color_hex3(0xeee),
10);
lv_meter_set_scale_range(meter, scale, 0, 100, 270, 90);
lv_meter_indicator_t *indic1 =
lv_meter_add_arc(meter, scale, 10, lv_palette_main(LV_PALETTE_RED), 0);
lv_meter_indicator_t *indic2 = lv_meter_add_arc(
meter, scale, 10, lv_palette_main(LV_PALETTE_GREEN), -10);
lv_meter_indicator_t *indic3 = lv_meter_add_arc(
meter, scale, 10, lv_palette_main(LV_PALETTE_BLUE), -20);
lv_anim_t a;
lv_anim_init(&a);
lv_anim_set_exec_cb(&a, set_value);
lv_anim_set_values(&a, 0, 100);
lv_anim_set_repeat_delay(&a, 100);
lv_anim_set_playback_delay(&a, 100);
lv_anim_set_repeat_count(&a, LV_ANIM_REPEAT_INFINITE);
lv_anim_set_time(&a, 500);
lv_anim_set_playback_time(&a, 200);
lv_anim_set_var(&a, indic1);
lv_anim_start(&a);
lv_anim_set_time(&a, 300);
lv_anim_set_playback_time(&a, 500);
lv_anim_set_var(&a, indic2);
lv_anim_start(&a);
lv_anim_set_time(&a, 100);
lv_anim_set_playback_time(&a, 1000);
lv_anim_set_var(&a, indic3);
lv_anim_start(&a);
}
#define DISP_BUF_SIZE (128 * 1024)
int main(void) {
lv_init();
fbdev_init();
static lv_color_t buf[DISP_BUF_SIZE];
static lv_disp_draw_buf_t disp_buf;
lv_disp_draw_buf_init(&disp_buf, buf, NULL, DISP_BUF_SIZE);
static lv_disp_drv_t disp_drv;
lv_disp_drv_init(&disp_drv);
disp_drv.draw_buf = &disp_buf;
disp_drv.flush_cb = fbdev_flush;
disp_drv.hor_res = 800;
disp_drv.ver_res = 480;
lv_disp_drv_register(&disp_drv);
lv_example_meter_xxxx();
printf("lvgl_example\n");
while (1) {
lv_task_handler();
usleep(30 * 1000);
}
return 0;
}
uint32_t custom_tick_get(void)
{
static uint64_t start_ms = 0;
if(start_ms == 0) {
struct timeval tv_start;
gettimeofday(&tv_start, NULL);
start_ms = (tv_start.tv_sec * 1000000 + tv_start.tv_usec) / 1000;
}
struct timeval tv_now;
gettimeofday(&tv_now, NULL);
uint64_t now_ms;
now_ms = (tv_now.tv_sec * 1000000 + tv_now.tv_usec) / 1000;
uint32_t time_ms = now_ms - start_ms;
return time_ms;
}
添加完其他必须的源文件后,就可以开始构建和编译了。
三、编译和测试
使用以下命令生成构建文件目录build
cmake -B bulid -G Ninja
效果如下图
成功生成构建目录后,需要使用ninja开始编译。一旦添加了新的源码文件,或者修改了CMake编译配置,需要删除build目录重新生成构建目录。
ninja -C bulid/
很快就编译好了,基本上不需要耗费多少时间。由于有ccache的编译缓存,以后编译的速度都会非常快。
由于这个板子的Ubuntu系统默认开启了Xorg,我暂时也没找到关闭Xorg的方法。pkill Xorg无效。在别的开发板上运行这个编译出来的main程序,是可以正常显示的。
若需要删除build构建目录,使用以下命令。
rm -rf bulid/