skui學習筆記(一)

一、skui簡介

使用Skia作爲低級繪圖工具包的UI框架。它使用C ++標準庫的最新功能(當前針對C ++ 17)。目前這個倉庫處於開發階段,功能還不穩定。該倉庫的源代碼在github上(https://github.com/skui-org/skui),作者是Ruben Van Boxem,遵循MIT開源協議。

這裏不得不先介紹一下skia。Skia是一個開源2D圖形庫,它提供可在各種硬件和軟件平臺上工作的通用API。它用作Google Chrome和Chrome OS,Android,Mozilla Firefox和Firefox OS以及許多其他產品的圖形引擎。Skia由Google贊助和管理,根據BSD自由軟件許可,任何人均可使用。skia的優勢在於CPU和2D渲染。

二、編譯環境搭建

我的編譯環境:Ubuntu18.04LTS,GCC版本7.4.0
首先從github上克隆倉庫

git clone https://github.com/skui-org/skui.git

進入倉庫

cd skui

更新子模塊倉庫

git submodule update --init --recursive

有的時候會在拉取skia的時候卡住,這時候進入3rdparty目錄再次拉取

cd 3rdparty
git submodule update --init --recursive
cd ..

這樣就拉取了skui所有源碼。

然後就可以編譯

mkdir ../skui-build
cd ../skui-build
cmake ../skui -G Ninja
cmake --build .

可以運行一下例程,是個很小的彈出窗口。

./examples/widget_gallery/widget_gallery

在這裏插入圖片描述

三、cmake目錄分析

不想了解cmake編譯的這部分可以跳過。
文件樹狀圖如下:

.
├── 3rdparty
│   ├── boost
│   ├── ci
│   ├── cmake
│   ├── giflib
│   ├── libexpat
│   ├── libjpeg-turbo
│   ├── libpng
│   ├── opengl-api
│   ├── skia
│   ├── vulkan-api
│   └── zlib
├── ci
├── cmake
├── core
├── css
├── examples
│   └── widget_gallery
├── graphics
├── gui
├── opengl
├── scripts
├── system
└── tests

1、CMakeLists

源碼根目錄CMakeLists定義了工程名和編譯選項,設置了cmake模塊目錄,添加toolchain_options.cmake

cmake_minimum_required(VERSION 3.13)
project(skui)

list(APPEND CMAKE_MODULE_PATH "${CMAKE_CURRENT_LIST_DIR}/cmake")
include(toolchain_options)

set(CMAKE_CXX_STANDARD 17)
set(CMAKE_CXX_EXTENSIONS OFF)

set_property(GLOBAL PROPERTY USE_FOLDERS ON)

添加了幾個option開關,添加3rdparty_options.cmake

# 3rdparty dependencies
option(SKUI_USE_PREBUILT_3RDPARTY "Use a prebuilt 3rdparty package" OFF)
set(SKUI_PREBUILT_3RDPARTY_PATH CACHE STRING "NOTSET")
option(SKUI_USE_PREBUILT_ZLIB "Use a prebuilt zlib" ${SKUI_USE_PREBUILT_3RDPARTY})
option(SKUI_USE_PREBUILT_LIBEXPAT "Use a prebuilt libexpat" ${SKUI_USE_PREBUILT_3RDPARTY})
option(SKUI_USE_PREBUILT_LIBPNG "Use a prebuilt libpng" ${SKUI_USE_PREBUILT_3RDPARTY})
option(SKUI_USE_PREBUILT_GIFLIB "Use a prebuilt giflib" ${SKUI_USE_PREBUILT_3RDPARTY})
option(SKUI_USE_PREBUILT_LIBJPEG_TURBO "Use a prebuilt libjpeg-turbo" ${SKUI_USE_PREBUILT_3RDPARTY})
option(SKUI_USE_PREBUILT_SKIA "Use a prebuilt Skia" ${SKUI_USE_PREBUILT_3RDPARTY})
option(SKUI_USE_PREBUILT_BOOST "Use a prebuilt Boost" ${SKUI_USE_PREBUILT_3RDPARTY})
option(SKUI_USE_SYSTEM_ZLIB "Use system zlib" OFF)
option(SKUI_USE_SYSTEM_LIBEXPAT "Use system libexpat" OFF)
option(SKUI_USE_SYSTEM_LIBPNG "Use system libpng" OFF)
option(SKUI_USE_SYSTEM_GIFLIB "Use system giflib" OFF)
option(SKUI_USE_SYSTEM_LIBJPEG_TURBO "Use system libjpeg-turbo" OFF)
option(SKUI_USE_SYSTEM_SKIA "Use system Skia library" OFF)
option(SKUI_USE_SYSTEM_BOOST "Use system Boost library" OFF)

include(3rdparty_options)

定義了一個函數exclude_from_build用來剔除不用的源碼文件,實現跨平臺。

# Boilerplate
function(exclude_from_build)
  set_source_files_properties(${ARGV} PROPERTIES HEADER_FILE_ONLY TRUE)
endfunction()

添加了core、css、graphics、gui、opengl、system幾個模塊

# skui itself
add_subdirectory(core)
add_subdirectory(css)
add_subdirectory(graphics)
add_subdirectory(gui)
add_subdirectory(opengl)
add_subdirectory(system)

最後添加例程和測試代碼

# skui examples
add_subdirectory(examples)

# skui tests
enable_testing()
add_subdirectory(tests)

2、cmake/toolchain_options.cmake

防止文件多次被調用

include_guard(GLOBAL)

裏面主要是針對一些平臺的編譯設置和優化

忽略編譯警告,去除不用的處理單元

if(CMAKE_COMPILER_IS_GNUCXX)
  set(CMAKE_CXX_FLAGS "-pedantic-errors -Wextra -Wconversion -Winit-self -Wmissing-include-dirs -Wstrict-aliasing -Werror ${CMAKE_CXX_FLAGS}")
  set(CMAKE_POSITION_INDEPENDENT_CODE ON)
......

if(GC_SECTIONS)
  if(MINGW OR UNIX AND NOT APPLE)
    message("#6")
    set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -ffunction-sections -fdata-sections")
    set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -ffunction-sections -fdata-sections")

    set(CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} -Wl,--gc-sections")
    set(CMAKE_SHARED_LINKER_FLAGS "${CMAKE_SHARED_LINKER_FLAGS} -Wl,--gc-sections")
  endif()
endif()

3、cmake/3rdparty_options.cmake

該目錄下是第三方的庫zlib、libexpat、libpng、giflib、jpeg-turbo、skia的預編譯,通過變量SKUI_USE_PREBUILT_3RDPARTY控制,默認OFF

zlib

if(SKUI_USE_PREBUILT_ZLIB)
  add_library(zlib INTERFACE)
  target_include_directories(zlib SYSTEM INTERFACE ${SKUI_PREBUILT_3RDPARTY_PATH}/zlib)
  target_link_libraries(zlib INTERFACE ${SKUI_PREBUILT_3RDPARTY_PATH}/${CMAKE_STATIC_LIBRARY_PREFIX}zlib${CMAKE_STATIC_LIBRARY_SUFFIX})
  set(ZLIB_FOUND TRUE)
elseif(SKUI_USE_SYSTEM_ZLIB)
  find_package(ZLIB REQUIRED)
  add_library(zlib INTERFACE)
  target_link_libraries(zlib INTERFACE ZLIB::ZLIB)

libexpat

.......

4、3rdparty/CMakeLists.txt

該目錄是第三方的庫zlib、libexpat、libpng、giflib、jpeg-turbo、skia的編譯部分,用來生成靜態庫

5、core/CMakeLists.txt

創建static library 名字叫core,編譯出來是libcore.so

add_library(core
            ${core_src}
            ${traits_src}
            ${utility_src})

添加source到core

set(core_src
    application.h++ application.c++
    bitflag.h++
    bounded_property.h++
    command.h++ command.c++
    command_queue.h++ command_queue.c++
    debug.h++
    event_loop.h++ event_loop.c++
    library.h++ library.c++ library_windows.c++ library_unix.c++
    path.h++
    property.h++
    proxy_map.h++
    proxy_property.h++
    signal.h++
    slot.h++
    string.h++
    trackable.h++ trackable.c++
    utility.h++ utility.c++
    value_ptr.h++
   )
set(traits_src
    traits/are_convertible.h++
    traits/are_same.h++
    traits/arity.h++
    traits/number_of_bits.h++
   )
set(utility_src
    utility/approximate_equal_to.h++
    utility/bound.h++
    utility/norm.h++
   )
......
add_library(core
            ${core_src}
            ${traits_src}
            ${utility_src})

針對操作系統剔除不需要的配置文件

if(NOT WIN32)
  exclude_from_build(
                     library_windows.c++
                    )
endif()
if(NOT UNIX)
  exclude_from_build(
                     library_unix.c++
                    )
  if(NOT APPLE)
  endif()
endif()

exclude_from_build是在源碼根目錄下定義的

function(exclude_from_build)
  set_source_files_properties(${ARGV} PROPERTIES HEADER_FILE_ONLY TRUE)
endfunction()

根據cmake官方文檔

HEADER_FILE_ONLY:源文件上的屬性,指示源文件是否是沒有關聯實現的頭文件。這是根據文件擴展名自動設置的,並且由CMake用於確定是否應計算某些依賴項信息。
通過將此屬性設置爲ON,即使它應該被編譯,因爲它是庫/可執行文件的源代碼的一部分,也可以禁用對給定源文件的編譯。

添加一些編譯配置,在下系統是ubuntu所以起作用的只有-pthread、-lstdc++fs,使用多線程和C++17擴展庫。

target_link_libraries(core PUBLIC $<$<PLATFORM_ID:Linux>:-pthread>
                                  $<$<CXX_COMPILER_ID:GNU>:-lstdc++fs>
                                  $<$<AND:$<PLATFORM_ID:Windows>,$<AND:$<CXX_COMPILER_ID:Clang>,$<NOT:$<STREQUAL:"x${CMAKE_CXX_SIMULATE_ID}","xMSVC">>>>:-lstdc++fs>
                                  $<$<AND:$<NOT:$<PLATFORM_ID:Windows>>,$<AND:$<CXX_COMPILER_ID:Clang>,$<AND:$<VERSION_GREATER_EQUAL:$<CXX_COMPILER_VERSION>,7>,$<VERSION_LESS:$<CXX_COMPILER_VERSION>,9>>>>:-lc++fs>
                                  $<$<AND:$<NOT:$<PLATFORM_ID:Windows>>,$<AND:$<CXX_COMPILER_ID:Clang>,$<VERSION_LESS:$<CXX_COMPILER_VERSION>,7>>>:-lc++experimental>
                                  $<$<AND:$<PLATFORM_ID:Darwin>,$<OR:$<CXX_COMPILER_ID:Clang>,$<CXX_COMPILER_ID:AppleClang>>>:-lc++fs>
                                  $<$<NOT:$<PLATFORM_ID:Windows>>:-ldl>)

其它幾個模塊如graphics和gui的cmake文件都差不多,不一一贅述。

6、examples/widget_gallery/CMakeLists.txt

這部分很簡單,只有widget_gallery.c++一個源文件。鏈接了core、gui兩個庫。這兩個庫是由core、gui模塊編譯出來的靜態庫。

set(widget_gallery_src
    widget_gallery.c++
   )

source_group("" FILES ${widget_gallery_src})

add_executable(widget_gallery WIN32 widget_gallery.c++)
target_link_libraries(widget_gallery core gui)
set_target_properties(widget_gallery PROPERTIES FOLDER examples)
發佈了83 篇原創文章 · 獲贊 44 · 訪問量 12萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章