feat(CI): Windows MSVC and GCC build (#6015)

This commit is contained in:
Liam 2024-04-18 09:12:50 -04:00 committed by GitHub
parent d0436fbb59
commit e72f52d0bd
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
20 changed files with 269 additions and 92 deletions

View File

@ -27,6 +27,37 @@ jobs:
- name: Building ${{ matrix.build_option }}
run: python tests/main.py --build-option=${{ matrix.build_option }} build
build-windows-GCC:
runs-on: windows-2022
name: Build Windows GCC
steps:
- uses: actions/checkout@v4
- uses: ammaraskar/gcc-problem-matcher@master
- name: Install prerequisites
run: scripts\install-prerequisites.bat
- name: Build
run: python tests/main.py build
env:
CC: gcc
build-windows-MSVC:
runs-on: windows-2022
name: Build Windows MSVC
steps:
- uses: actions/checkout@v4
- name: Install prerequisites
run: scripts\install-prerequisites.bat
- uses: ilammy/msvc-dev-cmd@v1
with:
arch: x64
- uses: ruby/setup-ruby@v1
with:
ruby-version: 'mswin'
- name: Build
run: python tests/main.py build
env:
CC: cl
test-native:
runs-on: ubuntu-latest
name: amd64 Executable Tests

View File

@ -3,7 +3,11 @@ cmake_minimum_required(VERSION 3.12.4)
set(CMAKE_WINDOWS_EXPORT_ALL_SYMBOLS ON)
if(NOT ESP_PLATFORM)
if(NOT (CMAKE_C_COMPILER_ID STREQUAL "MSVC"))
project(lvgl LANGUAGES C CXX ASM HOMEPAGE_URL https://github.com/lvgl/lvgl)
else()
project(lvgl LANGUAGES C CXX HOMEPAGE_URL https://github.com/lvgl/lvgl)
endif()
endif()
set(LVGL_ROOT_DIR ${CMAKE_CURRENT_LIST_DIR})

View File

@ -25,10 +25,16 @@ file(GLOB_RECURSE THORVG_SOURCES ${LVGL_ROOT_DIR}/src/libs/thorvg/*.cpp ${LVGL_R
add_library(lvgl ${SOURCES})
add_library(lvgl::lvgl ALIAS lvgl)
if(NOT (CMAKE_C_COMPILER_ID STREQUAL "MSVC"))
target_compile_definitions(
lvgl PUBLIC $<$<BOOL:${LV_LVGL_H_INCLUDE_SIMPLE}>:LV_LVGL_H_INCLUDE_SIMPLE>
$<$<BOOL:${LV_CONF_INCLUDE_SIMPLE}>:LV_CONF_INCLUDE_SIMPLE>
$<$<COMPILE_LANGUAGE:ASM>:__ASSEMBLY__>)
else()
target_compile_definitions(
lvgl PUBLIC $<$<BOOL:${LV_LVGL_H_INCLUDE_SIMPLE}>:LV_LVGL_H_INCLUDE_SIMPLE>
$<$<BOOL:${LV_CONF_INCLUDE_SIMPLE}>:LV_CONF_INCLUDE_SIMPLE>)
endif()
# Add definition of LV_CONF_PATH only if needed
if(LV_CONF_PATH)
@ -51,7 +57,9 @@ if(NOT LV_CONF_BUILD_DISABLE_THORVG_INTERNAL)
target_link_libraries(lvgl_thorvg PUBLIC lvgl)
endif()
if(NOT (CMAKE_C_COMPILER_ID STREQUAL "MSVC"))
set_source_files_properties(${LVGL_ROOT_DIR}/src/others/vg_lite_tvg/vg_lite_tvg.cpp PROPERTIES COMPILE_FLAGS -Wunused-parameter)
endif()
# Build LVGL example library
if(NOT LV_CONF_BUILD_DISABLE_EXAMPLES)

View File

@ -0,0 +1,4 @@
vcpkg install vcpkg-tool-ninja libpng freetype
if %errorlevel% neq 0 exit /b %errorlevel%
pip install pypng lz4
if %errorlevel% neq 0 exit /b %errorlevel%

View File

@ -16,6 +16,7 @@
#include "lv_vg_lite_pending.h"
#include "lv_vg_lite_utils.h"
#include "lv_vg_lite_grad.h"
#include <float.h>
/*********************
* DEFINES
@ -290,10 +291,10 @@ static void lv_path_to_vg(lv_vg_lite_path_t * dest, const lv_vector_path_t * src
lv_vg_lite_path_set_quality(dest, lv_quality_to_vg(src->quality));
/* init bounds */
float min_x = __FLT_MAX__;
float min_y = __FLT_MAX__;
float max_x = __FLT_MIN__;
float max_y = __FLT_MIN__;
float min_x = FLT_MAX;
float min_y = FLT_MAX;
float max_x = FLT_MIN;
float max_y = FLT_MIN;
#define CMP_BOUNDS(point) \
do { \

View File

@ -218,10 +218,10 @@ bool lv_vg_lite_path_update_bonding_box(lv_vg_lite_path_t * path)
lv_vg_lite_path_bounds_t bounds;
/* init bounds */
bounds.min_x = __FLT_MAX__;
bounds.min_y = __FLT_MAX__;
bounds.max_x = __FLT_MIN__;
bounds.max_y = __FLT_MIN__;
bounds.min_x = FLT_MAX;
bounds.min_y = FLT_MAX;
bounds.max_x = FLT_MIN;
bounds.max_y = FLT_MIN;
/* calc bounds */
lv_vg_lite_path_for_each_data(lv_vg_lite_path_get_path(path), path_bounds_iter_cb, &bounds);

View File

@ -10,7 +10,12 @@
#include "lv_windows_context.h"
#if LV_USE_WINDOWS
#ifdef __GNUC__
#pragma GCC diagnostic ignored "-Wcast-function-type"
#endif
#include "lv_windows_display.h"
#include "lv_windows_input_private.h"
/*********************
* DEFINES
@ -37,27 +42,6 @@ static LRESULT CALLBACK lv_windows_window_message_callback(
WPARAM wParam,
LPARAM lParam);
bool lv_windows_pointer_device_window_message_handler(
HWND hWnd,
UINT uMsg,
WPARAM wParam,
LPARAM lParam,
LRESULT * plResult);
bool lv_windows_keypad_device_window_message_handler(
HWND hWnd,
UINT uMsg,
WPARAM wParam,
LPARAM lParam,
LRESULT * plResult);
bool lv_windows_encoder_device_window_message_handler(
HWND hWnd,
UINT uMsg,
WPARAM wParam,
LPARAM lParam,
LRESULT * plResult);
/**********************
* STATIC VARIABLES
**********************/
@ -154,6 +138,7 @@ static void lv_windows_delay_callback(uint32_t ms)
static void lv_windows_check_display_existence_timer_callback(
lv_timer_t * timer)
{
LV_UNUSED(timer);
if(!lv_display_get_next(NULL)) {
// Don't use lv_deinit() due to it will cause exception when parallel
// rendering is enabled.
@ -186,7 +171,7 @@ static HDC lv_windows_create_frame_buffer(
typedef struct _BITMAPINFO_16BPP {
BITMAPINFOHEADER bmiHeader;
DWORD bmiColorMask[3];
} BITMAPINFO_16BPP, * PBITMAPINFO_16BPP;
} BITMAPINFO_16BPP;
BITMAPINFO_16BPP bitmap_info = { 0 };
#else
@ -275,7 +260,7 @@ static void lv_windows_display_timer_callback(lv_timer_t * timer)
context->display_device_object,
context->display_framebuffer_base,
NULL,
context->display_framebuffer_size,
(uint32_t)context->display_framebuffer_size,
LV_DISPLAY_RENDER_MODE_DIRECT);
}
}
@ -290,6 +275,8 @@ static void lv_windows_display_driver_flush_callback(
const lv_area_t * area,
uint8_t * px_map)
{
LV_UNUSED(area);
HWND window_handle = lv_windows_get_display_window_handle(display);
if(!window_handle) {
lv_display_flush_ready(display);

View File

@ -10,8 +10,14 @@
#include "lv_windows_input.h"
#if LV_USE_WINDOWS
#ifdef __GNUC__
#pragma GCC diagnostic ignored "-Wcast-function-type"
#endif
#include "lv_windows_context.h"
#include "lv_windows_display.h"
#include "lv_windows_input_private.h"
#include "../../misc/lv_text_private.h"
#include <windowsx.h>
@ -557,6 +563,8 @@ bool lv_windows_keypad_device_window_message_handler(
LPARAM lParam,
LRESULT * plResult)
{
LV_UNUSED(lParam);
switch(uMsg) {
case WM_KEYDOWN:
case WM_KEYUP: {
@ -791,6 +799,8 @@ bool lv_windows_encoder_device_window_message_handler(
LPARAM lParam,
LRESULT * plResult)
{
LV_UNUSED(lParam);
switch(uMsg) {
case WM_MBUTTONDOWN:
case WM_MBUTTONUP: {

View File

@ -0,0 +1,65 @@
/**
* @file lv_windows_input_private.h
*
*/
#ifndef LV_WINDOWS_INPUT_PRIVATE_H
#define LV_WINDOWS_INPUT_PRIVATE_H
#ifdef __cplusplus
extern "C" {
#endif
/*********************
* INCLUDES
*********************/
#if LV_USE_WINDOWS
#include <stdbool.h>
#include <windows.h>
/*********************
* DEFINES
*********************/
/**********************
* TYPEDEFS
**********************/
/**********************
* GLOBAL PROTOTYPES
**********************/
bool lv_windows_pointer_device_window_message_handler(
HWND hWnd,
UINT uMsg,
WPARAM wParam,
LPARAM lParam,
LRESULT * plResult);
bool lv_windows_keypad_device_window_message_handler(
HWND hWnd,
UINT uMsg,
WPARAM wParam,
LPARAM lParam,
LRESULT * plResult);
bool lv_windows_encoder_device_window_message_handler(
HWND hWnd,
UINT uMsg,
WPARAM wParam,
LPARAM lParam,
LRESULT * plResult);
/**********************
* MACROS
**********************/
#endif // LV_USE_WINDOWS
#ifdef __cplusplus
} /*extern "C"*/
#endif
#endif /*LV_WINDOWS_INPUT_PRIVATE_H*/

View File

@ -27,7 +27,7 @@
* TYPEDEFS
**********************/
typedef struct {
#ifdef WIN32
#ifdef _WIN32
HANDLE dir_p;
char next_fn[MAX_PATH_LEN];
#else

View File

@ -413,6 +413,7 @@ static void * fs_dir_open(lv_fs_drv_t * drv, const char * path)
static lv_fs_res_t fs_dir_read(lv_fs_drv_t * drv, void * dir_p, char * fn, uint32_t fn_len)
{
LV_UNUSED(drv);
LV_UNUSED(fn_len);
dir_handle_t * handle = (dir_handle_t *)dir_p;
lv_strcpy(fn, handle->next_fn);
lv_fs_res_t current_error = handle->next_error;

View File

@ -223,7 +223,7 @@ static lv_result_t decoder_get_area(lv_image_decoder_t * decoder, lv_image_decod
if(decoded_area->y1 == LV_COORD_MIN) {
decoded_area->y1 = 0;
decoded_area->y2 = my - 1;
decoded_area->x1 = -mx;
decoded_area->x1 = -((int32_t)mx);
decoded_area->x2 = -1;
jd->scale = 0;
jd->dcv[2] = jd->dcv[1] = jd->dcv[0] = 0; /* Initialize DC values */

View File

@ -19,6 +19,7 @@ extern "C" {
#include "libs/freetype/lv_freetype_private.h"
#include "misc/cache/lv_cache_entry_private.h"
#include "misc/cache/lv_cache_private.h"
#include "drivers/windows/lv_windows_input_private.h"
/*********************
* DEFINES

View File

@ -32,9 +32,16 @@
extern "C" {
#endif
/**
* causes MSVC error C1189.
* Not needed because "The __inline keyword is equivalent to inline."
* See: https://learn.microsoft.com/en-us/cpp/cpp/inline-functions-cpp?view=msvc-170
*/
/*
#if defined(_MSC_VER)
#define inline __inline
#endif
*/
#include <stddef.h>
#include <stdint.h>

View File

@ -463,7 +463,11 @@ extern "C" {
vg_lite_uint32_t stride = VG_LITE_ALIGN((buffer->width * mul / div), align);
buffer->stride = stride;
#ifndef _WIN32
buffer->memory = aligned_alloc(LV_VG_LITE_THORVG_BUF_ADDR_ALIGN, stride * buffer->height);
#else
buffer->memory = _aligned_malloc(stride * buffer->height, LV_VG_LITE_THORVG_BUF_ADDR_ALIGN);
#endif
LV_ASSERT(buffer->memory);
buffer->address = (vg_lite_uint32_t)(uintptr_t)buffer->memory;
buffer->handle = buffer->memory;
@ -473,7 +477,11 @@ extern "C" {
vg_lite_error_t vg_lite_free(vg_lite_buffer_t * buffer)
{
LV_ASSERT(buffer->memory);
#ifndef _WIN32
free(buffer->memory);
#else
_aligned_free(buffer->memory);
#endif
memset(buffer, 0, sizeof(vg_lite_buffer_t));
return VG_LITE_SUCCESS;
}
@ -2190,8 +2198,8 @@ static Result shape_append_path(std::unique_ptr<Shape> & shape, vg_lite_path_t *
float x_max = path->bounding_box[2];
float y_max = path->bounding_box[3];
if(math_equal(x_min, __FLT_MIN__) && math_equal(y_min, __FLT_MIN__)
&& math_equal(x_max, __FLT_MAX__) && math_equal(y_max, __FLT_MAX__)) {
if(math_equal(x_min, FLT_MIN) && math_equal(y_min, FLT_MIN)
&& math_equal(x_max, FLT_MAX) && math_equal(y_max, FLT_MAX)) {
return Result::Success;
}

View File

@ -7,6 +7,12 @@ if(ESP_PLATFORM)
else()
cmake_minimum_required(VERSION 3.16)
if(WIN32)
set(VCPKG_TARGET_TRIPLET "x64-windows")
include($ENV{VCPKG_INSTALLATION_ROOT}/scripts/buildsystems/vcpkg.cmake)
endif()
project(lvgl_tests LANGUAGES C CXX)
set(CMAKE_CXX_STANDARD 14)
set(CMAKE_C_STANDARD 99)
@ -130,6 +136,12 @@ endif()
set(COMPILE_OPTIONS
-DLV_CONF_PATH=${LVGL_TEST_DIR}/src/lv_test_conf.h
-DLV_BUILD_TEST
${BUILD_OPTIONS}
${BUILD_TARGET_DEF}
)
if(NOT (CMAKE_C_COMPILER_ID STREQUAL "MSVC"))
list(APPEND COMPILE_OPTIONS
-pedantic-errors
-Wall
-Wclobbered
@ -158,12 +170,22 @@ set(COMPILE_OPTIONS
-Wno-double-promotion
-Wno-unused-but-set-parameter
-Wno-unreachable-code
)
else()
list(APPEND COMPILE_OPTIONS
/W3 # enable all "production quality" warnings
/we4013 # treat function undefined as error
)
endif()
list(APPEND COMPILE_OPTIONS
${BUILD_OPTIONS}
${BUILD_TARGET_DEF}
)
filter_compiler_options(C LVGL_C_COMPILE_OPTIONS ${COMPILE_OPTIONS})
if(NOT (CMAKE_C_COMPILER_ID STREQUAL "MSVC"))
# Options test cases are compiled with.
filter_compiler_options(C LVGL_TESTFILE_COMPILE_OPTIONS ${LVGL_C_COMPILE_OPTIONS} -Wno-missing-prototypes)
@ -177,13 +199,23 @@ filter_compiler_options(CXX LVGL_CXX_COMPILE_OPTIONS
-Wno-float-conversion
-Wno-pedantic
)
else()
# Options test cases are compiled with.
filter_compiler_options(C LVGL_TESTFILE_COMPILE_OPTIONS ${LVGL_C_COMPILE_OPTIONS})
filter_compiler_options(CXX LVGL_CXX_COMPILE_OPTIONS
${COMPILE_OPTIONS}
)
endif()
get_filename_component(LVGL_DIR ${LVGL_TEST_DIR} DIRECTORY)
# Include lvgl project file.
include(${LVGL_DIR}/CMakeLists.txt)
target_compile_options(lvgl PUBLIC $<$<COMPILE_LANGUAGE:C>: ${LVGL_C_COMPILE_OPTIONS}>)
if(NOT (CMAKE_C_COMPILER_ID STREQUAL "MSVC"))
target_compile_options(lvgl PUBLIC $<$<COMPILE_LANGUAGE:ASM>: ${LVGL_C_COMPILE_OPTIONS}>)
endif()
target_compile_options(lvgl PUBLIC $<$<COMPILE_LANGUAGE:CXX>: ${LVGL_CXX_COMPILE_OPTIONS}>)
if (TARGET lvgl_examples)
target_compile_options(lvgl_examples PUBLIC ${LVGL_C_COMPILE_OPTIONS})
@ -244,9 +276,11 @@ set(generate_test_runner_rb
${CMAKE_CURRENT_SOURCE_DIR}/unity/generate_test_runner.rb)
set(generate_test_runner_config ${CMAKE_CURRENT_SOURCE_DIR}/config.yml)
if(NOT WIN32)
# libjpeg is required for the jpeg test case
find_package(JPEG REQUIRED)
include_directories(${JPEG_INCLUDE_DIR})
endif()
# libpng is required for the png test case
find_package(PNG REQUIRED)
@ -287,6 +321,11 @@ if(APPLE)
add_definitions(-DLV_USE_LINUX_FBDEV=0)
endif()
if(WIN32)
add_definitions(-DLV_USE_LINUX_FBDEV=0)
add_definitions(-DLV_USE_WINDOWS=1)
endif()
# disable test targets for build only tests
if (ENABLE_TESTS)
file(GLOB_RECURSE TEST_CASE_FILES src/test_cases/*.c)

View File

@ -55,8 +55,13 @@
#define LV_USE_FS_STDIO 1
#define LV_FS_STDIO_LETTER 'A'
#define LV_FS_STDIO_CACHE_SIZE 512
#ifndef _WIN32
#define LV_USE_FS_POSIX 1
#define LV_FS_POSIX_LETTER 'B'
#else
#define LV_USE_FS_WIN32 1
#define LV_FS_WIN32_LETTER 'C'
#endif
#define LV_USE_FS_MEMFS 1
#define LV_FS_MEMFS_LETTER 'M'
@ -66,7 +71,9 @@
#define LV_USE_LIBPNG 1
#define LV_USE_BMP 1
#define LV_USE_TJPGD 1
#ifndef _WIN32
#define LV_USE_LIBJPEG_TURBO 1
#endif
#define LV_USE_GIF 1
#define LV_USE_QRCODE 1
#define LV_USE_BARCODE 1

View File

@ -3,7 +3,6 @@
#include <stdio.h>
#include <stdlib.h>
#include <sys/time.h>
#include "lv_test_indev.h"
#include "lv_test_init.h"

View File

@ -1,7 +1,6 @@
#if LV_BUILD_TEST
#include "lv_test_init.h"
#include "lv_test_indev.h"
#include <sys/time.h>
#include <stdio.h>
#include <stdlib.h>
#include "../unity/unity.h"

View File

@ -13,16 +13,23 @@
*********************/
#if LV_BUILD_TEST
#include "../lvgl.h"
#include <unistd.h>
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include <stdarg.h>
#include <sys/stat.h>
#include <errno.h>
#include "unity.h"
#define PNG_DEBUG 3
#include <png.h>
#ifdef _WIN32
#include <direct.h>
#define mkdir(pathname, mode) _mkdir(pathname)
#define strtok_r strtok_s
#else
#include <sys/stat.h>
#endif
/*********************
* DEFINES
*********************/
@ -429,21 +436,20 @@ static void create_folders_if_needed(const char * path)
char * token = strtok_r(pathCopy, "/", &ptr);
char current_path[1024] = {'\0'}; // Adjust the size as needed
struct stat st;
while(token && ptr && *ptr != '\0') {
strcat(current_path, token);
strcat(current_path, "/");
if(stat(current_path, &st) != 0) {
// Folder doesn't exist, create it
if(mkdir(current_path, 0777) != 0) {
int mkdir_retval = mkdir(current_path, 0777);
if (mkdir_retval == 0) {
printf("Created folder: %s\n", current_path);
}
else if (errno != EEXIST) {
perror("Error creating folder");
free(pathCopy);
exit(EXIT_FAILURE);
}
printf("Created folder: %s\n", current_path);
}
token = strtok_r(NULL, "/", &ptr);
}