第一步:编译 libuv 库
windows 平台
方法一
- 安装 VS22019 或 MinGW;
-
解压后添加 cmake 工具目录到系统环境变量 PATH;
-
下载 libuv 源码;
-
powershell 下查看 cmake 的生成器:
1
cmake.exe --help
可以看到默认是 VS16 工程方式,VS16 已安装才能成功解析 CMakeLists.txt;如果没有安装 VS16,在调用 cmake.exe 时可以指定其他的工程或生成方式;
-
在 libuv 源码目录下新建 build 目录,在 build 目录中打开 powershell 并执行 cmake
如果选择 MinGW,调用 cmake 的命令是:
cmake.exe -G "MinGW Makefiles" ..
1 2 3 4
# 按照默认生成器 cmake.exe .. # 选择 VS16 生成 cmake.exe -G "Visual Studio 16 2019" ..
-
在当前 build 目录中进行生成
MinGW 使用
mingw32-make.exe
生成,使用方法和 Linux 平台 make 类似;1 2 3 4
# 生成 Debug 版本 cmake.exe --build . # 生成 Release 版本 cmake.exe --build . --config Release
在 build/Debug 或 build/Release 目录下会生成我们的编译目标:
方法二
-
安装 VS2019;
-
下载 libuv 源码;
-
使用 VS2019 打开 libuv 目录下的 CMakeLists.txt;
会在工程目录下多出 .vs 和 out 目录;
打开工程后,会自动按 x64-Debug 默认配置生成 cmake 缓存,默认路径在
out\build\${cfg_name}
目录,然后 C++ IntelliSense 也会按照 cmake 缓存进行构建; -
在解决方案资源管理器的 CMakeLists.txt 上右键 “CMake 设置”,新增一个 x64-Release 配置并保存;
会在工程目录下多出 CMakeSettings.json 文件;
-
选择 x64-Reelease 配置;
-
接着在解决方案资源管理器的 CMakeLists.txt 上右键 “生成”
最终在 out\build\x64-Release 目录下会生成我们的编译目标:
linux 平台
1
2
3
4
mkdir build
cd build
cmake ..
make
最终会生成 libuv.so、libuv_a.a 等文件;
arm 平台
1
2
3
4
mkdir build
cd build
cmake .. -DCMAKE_SYSTEM_NAME=Linux -DCMAKE_SYSTEM_PROCESSOR=arm -DCMAKE_C_COMPILER=arm-linux-gnueabihf-gcc
make
最终会生成 libuv.so、libuv_a.a 等文件;
第二步:分平台使用 libuv 库
windows 平台
测试工程文件结构如下:
main.c
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
#include <stdio.h>
#include <stdlib.h>
#include "uv.h"
int main() {
uv_loop_t* loop = malloc(sizeof(uv_loop_t));
uv_loop_init(loop);
printf("Now quitting.\n");
uv_run(loop, UV_RUN_DEFAULT);
uv_loop_close(loop);
free(loop);
return 0;
}
CMakeLists.txt
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
# 设置 CMake 最低可用版本
cmake_minimum_required(VERSION 3.10)
# 设置工程名称和其他属性
project(vs_demo DESCRIPTION "vs cmake demo 工程")
# 头文件路径
message("include dir: " ${PROJECT_SOURCE_DIR})
include_directories(${PROJECT_SOURCE_DIR})
message("include dir: " ${PROJECT_SOURCE_DIR}/include)
include_directories(${PROJECT_SOURCE_DIR}/include)
# 生成可执行文件
add_executable(main main.c)
# 添加库,可直接添加库的完整路径
target_link_libraries(main ${PROJECT_SOURCE_DIR}/lib/uv.lib)
# 构建成功后复制依赖的 dll
add_custom_command(TARGET main POST_BUILD
COMMAND ${CMAKE_COMMAND} -E copy ${PROJECT_SOURCE_DIR}/lib/uv.dll ${CMAKE_BINARY_DIR}
)
VS2019 打开 cmake 工程,成功生成后即可断点调试:
linux 平台
测试工程文件结构如下:
main.c
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
#include <stdio.h>
#include <stdlib.h>
#include "uv.h"
int main() {
uv_loop_t* loop = malloc(sizeof(uv_loop_t));
uv_loop_init(loop);
printf("Now quitting.\n");
uv_run(loop, UV_RUN_DEFAULT);
uv_loop_close(loop);
free(loop);
return 0;
}
CMakeLists.txt
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
# 设置 CMake 最低可用版本
cmake_minimum_required(VERSION 3.10)
# 设置工程名称和其他属性
project(demo DESCRIPTION "demo 工程")
# 头文件路径
message("include dir: " ${PROJECT_SOURCE_DIR})
include_directories(${PROJECT_SOURCE_DIR})
message("include dir: " ${PROJECT_SOURCE_DIR}/include)
include_directories(${PROJECT_SOURCE_DIR}/include)
# 生成可执行文件
add_executable(main main.c)
# 添加库,可直接添加库的完整路径
target_link_libraries(main ${PROJECT_SOURCE_DIR}/lib/libuv.so.1.0.0)
# 构建成功后复制依赖的 dll
add_custom_command(TARGET main POST_BUILD
COMMAND cp ${PROJECT_SOURCE_DIR}/lib/libuv.so.1.0.0 ${CMAKE_BINARY_DIR}
)
运行测试程序的结果:
arm 平台
除了需要指定交叉编译器,其他和 linux 平台使用方法相同;
1
2
SET(CMAKE_C_COMPILER arm-linux-gnueabihf-gcc)
SET(CMAKE_CXX_COMPILER arm-linux-gnueabihf-g++)
第三步:跨平台使用 libuv+lvgl
工程文件
工程文件结构如下:
SDL2/lib 目录下有 SDL2.lib SDL2main.lib SDL2.dll libSDL2.so 等文件;
uv/lib 目录下有 uv.lib uv.dll libuv.so 等文件;
-
main.c
lv_conf.h
lv_ex_conf.h
lv_drv_conf.h
来自:开源库 lv_sim_vs_sdl -
lvgl
文件夹来自:开源库 lvgl -
lv_drivers
文件夹来自:开源库 lv_drivers -
lv_examples
文件夹来自:开源库 lv_examples
CMakeLists.txt 如下:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
# 设置 CMake 最低可用版本
cmake_minimum_required(VERSION 3.10)
# 设置工程名称和其他属性
project(lvgl_test DESCRIPTION "lvgl test 工程")
# 函数:递归添加子目录到全局头文件,root_dir 需要是完整路径
function(include_sub_directories_recursively root_dir)
# 当前路径是一个目录吗,是的话就加入到包含目录
if (IS_DIRECTORY ${root_dir})
message("include dir: " ${root_dir})
include_directories(${root_dir})
endif()
# 获得当前目录下的所有文件,让如ALL_SUB列表中
file(GLOB ALL_SUB RELATIVE ${root_dir} ${root_dir}/*)
foreach(sub ${ALL_SUB})
if (IS_DIRECTORY ${root_dir}/${sub})
# 对子目录递归调用,包含
include_sub_directories_recursively(${root_dir}/${sub})
endif()
endforeach()
endfunction()
# 设置变量 C 标准为 99
set(CMAKE_C_STANDARD 99)
# 设置变量 C++ 标准为 11
set(CMAKE_CXX_STANDARD 11)
# 全局包含目录,这里包含程序目录
message("include dir: " ${PROJECT_SOURCE_DIR})
include_directories(${PROJECT_SOURCE_DIR})
message("include dir: " ${PROJECT_SOURCE_DIR}/SDL2/include)
include_directories(${PROJECT_SOURCE_DIR}/SDL2/include)
message("include dir: " ${PROJECT_SOURCE_DIR}/uv/include)
include_directories(${PROJECT_SOURCE_DIR}/uv/include)
include_sub_directories_recursively(${PROJECT_SOURCE_DIR}/lvgl)
include_sub_directories_recursively(${PROJECT_SOURCE_DIR}/lv_drivers)
include_sub_directories_recursively(${PROJECT_SOURCE_DIR}/lv_examples)
# 查找满足规则的文件名放到 SOURCES 变量
file(GLOB_RECURSE LVGL_SOURCES lvgl/src/*.c)
file(GLOB LV_DRV_SOURCES
lv_drivers/*.c
lv_drivers/indev/*.c
lv_drivers/gtkdrv/*.c
lv_drivers/display/*.c
)
file(GLOB_RECURSE LV_EXP_SOURCES lv_examples/src/*.c)
# 生成可执行文件
add_executable(main main.c ${LVGL_SOURCES} ${LV_DRV_SOURCES} ${LV_EXP_SOURCES})
if (WIN32)
# 添加库,可直接添加库的完整路径
target_link_libraries(main
${PROJECT_SOURCE_DIR}/SDL2/lib/win/x64/SDL2.lib
${PROJECT_SOURCE_DIR}/SDL2/lib/win/x64/SDL2main.lib
${PROJECT_SOURCE_DIR}/uv/lib/win/x64/uv.lib
)
#构建成功后复制依赖的 dll
add_custom_command(TARGET main POST_BUILD
COMMAND ${CMAKE_COMMAND} -E copy ${PROJECT_SOURCE_DIR}/SDL2/lib/win/x64/SDL2.dll ${CMAKE_BINARY_DIR}
COMMAND ${CMAKE_COMMAND} -E copy ${PROJECT_SOURCE_DIR}/uv/lib/win/x64/uv.dll ${CMAKE_BINARY_DIR}
)
else ()
# 添加库,可直接添加库的完整路径
target_link_libraries(main
${PROJECT_SOURCE_DIR}/SDL2/lib/linux/x64/libSDL2.so
${PROJECT_SOURCE_DIR}/uv/lib/linux/x64/libuv.so
)
#构建成功后复制依赖的 so
add_custom_command(TARGET main POST_BUILD
COMMAND cp ${PROJECT_SOURCE_DIR}/SDL2/lib/linux/x64/libSDL2.so ${CMAKE_BINARY_DIR}
COMMAND cp ${PROJECT_SOURCE_DIR}/uv/lib/linux/x64/libuv.so ${CMAKE_BINARY_DIR}/libuv.so.1
)
endif ()
main.c 有一点小修改,使用 libuv 替代 Windows API:
1
2
3
4
- #define <Windows.h>
+ #define "uv.h"
- Sleep(10); /*Just to let the system breathe */
+ uv_sleep(10); /*Just to let the system breathe */
编译运行结果
Windows 平台编译后运行结果:
Linux 平台编译后运行结果:
系统中有 cmake、make、gcc、g++ 才能编译成功;
依赖 SDL2 才能运行成功:
sudo apt-get install libsdl2-2.0-0