diff --git a/.github/workflows/release-atomui-native.yml b/.github/workflows/release-atomui-native.yml new file mode 100644 index 000000000..54d4edeb6 --- /dev/null +++ b/.github/workflows/release-atomui-native.yml @@ -0,0 +1,60 @@ +name: AtomUI.Native Release Pipeline +on: + workflow_dispatch: + inputs: + TargetBranch: + description: 'Target branch to build' + type: string + default: 'develop' + BuildConfiguration: + description: 'Build configuration' + type: string + default: 'Release' + PublishToNuget: + description: 'Publish to nuget.org' + type: boolean + default: false +env: + SOURCE_DIR: ${{ github.workspace }} + NATIVE_LIB_SRC_DIR: ${{ github.workspace }}/nativelibs + BUILD_DIR: ${{ github.workspace }}/build + BASE_OUTPUT_DIR: ${{ github.workspace }}/output + MAC_OUTPUT_DIR: ${{ github.workspace }}/osx + LINUX_OUTPUT_DIR: ${{ github.workspace }}/linux + WIN_ARM64_OUTPUT_DIR: ${{ github.workspace }}/win_arm64 + LOCAL_NUGET_DIR: ${{ github.workspace }}/nuget + +jobs: + BuildAtomUINativeLinux: + name: Build AtomUINative for Linux X86_64 + runs-on: qinware-ubuntu-latest + steps: + - name: Checkout code + uses: actions/checkout@v4.2.2 + with: + ref: ${{ inputs.TargetBranch }} + - name: Install dependencies + run: | + sudo apt update + sudo apt install -y build-essential libxcb1-dev libxcb-shape0-dev + wget -O - https://apt.kitware.com/keys/kitware-archive-latest.asc 2>/dev/null | \ + gpg --dearmor - | \ + sudo tee /usr/share/keyrings/kitware-archive-keyring.gpg >/dev/null + echo "deb [signed-by=/usr/share/keyrings/kitware-archive-keyring.gpg] https://apt.kitware.com/ubuntu/ noble main" | \ + sudo tee /etc/apt/sources.list.d/kitware.list >/dev/null + sudo apt update + sudo apt install -y cmake + cmake --version + sudo apt install clang + clang --version + - name: Build for x86_64 + run: | + cmake -B $env:BUILD_DIR -S $env:NATIVE_LIB_SRC_DIR -DCMAKE_INSTALL_PREFIX="$env:LINUX_OUTPUT_DIR" -DCMAKE_BUILD_TYPE=${{ inputs.BuildConfiguration }} + cmake --build $env:BUILD_DIR + cmake --install $env:BUILD_DIR --config ${{ inputs.BuildConfiguration }} + - name: Upload linux x86_64 artifact + id: artifact + uses: actions/upload-artifact@v4.6.2 + with: + name: AtomUINativeLinux + path: ${{ env.LINUX_OUTPUT_DIR }} \ No newline at end of file diff --git a/.github/workflows/release-atomui.yml b/.github/workflows/release-atomui.yml index 6b2ebbe6c..6a21e041a 100644 --- a/.github/workflows/release-atomui.yml +++ b/.github/workflows/release-atomui.yml @@ -21,11 +21,13 @@ env: BASE_OUTPUT_DIR: ${{ github.workspace }}/output MAC_OUTPUT_DIR: ${{ github.workspace }}/osx LINUX_OUTPUT_DIR: ${{ github.workspace }}/linux + WIN_ARM64_OUTPUT_DIR: ${{ github.workspace }}/win_arm64 LOCAL_NUGET_DIR: ${{ github.workspace }}/nuget jobs: BuildAtomUINativeMacOS: name: Build AtomUINative for macOS runs-on: macos-latest + if: ${{ false }} steps: - name: Checkout code uses: actions/checkout@v4.2.2 @@ -63,6 +65,7 @@ jobs: BuildAtomUINativeLinux: name: Build AtomUINative for Linux runs-on: qinware-ubuntu-latest + if: ${{ false }} steps: - name: Checkout code uses: actions/checkout@v4.2.2 @@ -91,10 +94,71 @@ jobs: with: name: AtomUINativeLinux path: ${{ env.LINUX_OUTPUT_DIR }} + + BuildAtomUINativeWindowsArm64: + name: Build AtomUINative for Windows Arm64 + runs-on: windows-11-arm + steps: + - name: Checkout code + uses: actions/checkout@v4.2.2 + with: + ref: ${{ inputs.TargetBranch }} + - name: Setup MSYS2 environment + shell: pwsh + run: | + $systemPath="C:/" + $msysPath = "C:/msys64" + + # Download and install Msys2 for ARM64 + $installerUrl = "https://github.com/msys2/msys2-installer/releases/download/2025-06-22/msys2-base-x86_64-20250622.tar.xz" + $installerPath = "$env:TEMP\msys2-arm64.tar.xz" + + # Download the installer + Invoke-WebRequest -Uri $installerUrl -OutFile $installerPath + + # Extract Msys2 + $tarPath = "$env:TEMP\msys2-arm64.tar" + # Extract using 7-Zip (available on GitHub runners) + & 7z e "$installerPath" -o"$env:TEMP" -y + & 7z x "$tarPath" -o"$systemPath" -y + $bashPath = Join-Path $msysPath "usr\bin\bash.exe" + + # Initialize Msys2 + & $bashPath -lc "pacman-key --init" + & $bashPath -lc "pacman-key --populate msys2" + + # 更新系统 (分两步执行更可靠) + & $bashPath -lc "pacman -Syuu --noconfirm --needed --noprogressbar" + & $bashPath -lc "pacman -Su --noconfirm --needed --noprogressbar" + $env:MSYSTEM = "CLANGARM64" + $env:MSYSTEM_CARCH = "aarch64" + $env:MSYSTEM_CHOST = "aarch64-w64-mingw32" + $env:MSYSTEM_PREFIX = "/clangarm64" + $env:CHERE_INVOKING = "1" + $env:PATH = "$msysPath/clangarm64/bin;$msysPath/usr/bin;$env:PATH" + + # Update PATH for subsequent steps + Add-Content $env:GITHUB_PATH "$msysPath/clangarm64/bin" + Add-Content $env:GITHUB_PATH "$msysPath/usr/bin" + + Write-Host "Msys2 installed and initialized successfully" + + # Install required packages + & "$bashPath" -lc "pacman -S mingw-w64-clang-aarch64-clang --noconfirm" + & "$bashPath" -lc "pacman -S mingw-w64-clang-aarch64-cmake --noconfirm" + + - name: Build for Windows Arm64 + run: | + New-Item -Path "$env:BUILD_DIR" -ItemType Directory -Force + cmake -B "$env:BUILD_DIR" -S "$env:NATIVE_LIB_SRC_DIR" -DCMAKE_INSTALL_PREFIX="$env:WIN_ARM64_OUTPUT_DIR" -DCMAKE_BUILD_TYPE=${{ inputs.BuildConfiguration }} -G Ninja + cmake --build "$env:BUILD_DIR" + cmake --install "$env:BUILD_DIR" --config ${{ inputs.BuildConfiguration }} + BuildAtomUINuget: name: Build AtomUI NuGet packages runs-on: windows-latest + if: ${{ false }} needs: - BuildAtomUINativeMacOS - BuildAtomUINativeLinux diff --git a/AtomUI.sln b/AtomUI.sln index 99be658fb..61534873f 100644 --- a/AtomUI.sln +++ b/AtomUI.sln @@ -31,8 +31,6 @@ Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Build", "Build", "{5EB2524C build\AtomUINativePackageInfo.props = build\AtomUINativePackageInfo.props EndProjectSection EndProject -Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "AtomUI.Native", "src\AtomUI.Native\AtomUI.Native.csproj", "{90F1E4BC-4513-450E-B2B8-C64A779C8A0D}" -EndProject Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "AtomUI", "packages\AtomUI\AtomUI.csproj", "{EF9E3D8A-7D43-42A4-839E-5B20553B1B72}" EndProject Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "AtomUI.Generator", "src\AtomUI.Generator\AtomUI.Generator.csproj", "{2AAAF06F-B1D1-4B3F-885A-F0C329F31C78}" @@ -69,10 +67,6 @@ Global {796AC3CF-7A12-4183-9096-291738A62292}.Debug|Any CPU.Build.0 = Debug|Any CPU {796AC3CF-7A12-4183-9096-291738A62292}.Release|Any CPU.ActiveCfg = Release|Any CPU {796AC3CF-7A12-4183-9096-291738A62292}.Release|Any CPU.Build.0 = Release|Any CPU - {90F1E4BC-4513-450E-B2B8-C64A779C8A0D}.Debug|Any CPU.ActiveCfg = Debug|Any CPU - {90F1E4BC-4513-450E-B2B8-C64A779C8A0D}.Debug|Any CPU.Build.0 = Debug|Any CPU - {90F1E4BC-4513-450E-B2B8-C64A779C8A0D}.Release|Any CPU.ActiveCfg = Release|Any CPU - {90F1E4BC-4513-450E-B2B8-C64A779C8A0D}.Release|Any CPU.Build.0 = Release|Any CPU {EF9E3D8A-7D43-42A4-839E-5B20553B1B72}.Debug|Any CPU.ActiveCfg = Debug|Any CPU {EF9E3D8A-7D43-42A4-839E-5B20553B1B72}.Debug|Any CPU.Build.0 = Debug|Any CPU {EF9E3D8A-7D43-42A4-839E-5B20553B1B72}.Release|Any CPU.ActiveCfg = Release|Any CPU diff --git a/Directory.Packages.props b/Directory.Packages.props index 6a7396312..23ac7c91d 100644 --- a/Directory.Packages.props +++ b/Directory.Packages.props @@ -29,6 +29,10 @@ + + + + diff --git a/build/Version.props b/build/Version.props index b69284eba..5486ff59d 100644 --- a/build/Version.props +++ b/build/Version.props @@ -3,6 +3,7 @@ $(NoWarn);CS7035 11.3.2 0.1.0 + 0.1.0 diff --git a/nativelibs/CMakeLists.txt b/nativelibs/CMakeLists.txt new file mode 100644 index 000000000..f912ebdb4 --- /dev/null +++ b/nativelibs/CMakeLists.txt @@ -0,0 +1,88 @@ +# This source file is part of the atomui project +# +# Copyright (c) 2017 - 2022 qinware, All rights reserved. +# Copyright (c) 2017 - 2022 chinboy +# +# See https://qinware.com/LICENSE.txt for license information +# +# Created by chinboy on 2025/01/10. + +cmake_minimum_required(VERSION 3.28) +set(CMAKE_DISABLE_IN_SOURCE_BUILD YES) + +project(nativelibs) +set(CMAKE_CXX_STANDARD 20) +set(CMAKE_CXX_STANDARD_REQUIRED ON) +set(CMAKE_CXX_EXTENSIONS OFF) +set(CMAKE_CXX_VISIBILITY_PRESET hidden) +set(CMAKE_C_STANDARD 11) +set(CMAKE_OSX_DEPLOYMENT_TARGET 11) # 目前先支持到 11 +set_property(GLOBAL PROPERTY JOB_POOLS "${CMAKE_JOB_POOLS}") + +# setup some important path +set(ATOMUI_SOURCE_DIR "${CMAKE_CURRENT_SOURCE_DIR}") # --src-root +set(ATOMUI_BINARY_DIR "${CMAKE_CURRENT_BINARY_DIR}") # --prefix +set(ATOMUI_CMAKE_MODULES_DIR "${ATOMUI_SOURCE_DIR}/cmake/modules") +set(ATOMUI_INCLUDE_DIR "${ATOMUI_SOURCE_DIR}/include") +set(ATOMUI_BINARY_INCLUDE_DIR "${CMAKE_CURRENT_BINARY_DIR}/include") # --includedir +set(ATOMUI_TEST_DIR "${ATOMUI_SOURCE_DIR}/tests") +set(ATOMUI_TEST_BIN_DIR "tests/bin") +set(ATOMUI_SYSTEM_NAME ${CMAKE_HOST_SYSTEM_NAME}) +string(TOLOWER ${ATOMUI_SYSTEM_NAME} ATOMUI_SYSTEM_NORMAL_NAME) + +# Add path for custom CMake modules. +list(APPEND CMAKE_MODULE_PATH + "${CMAKE_CURRENT_SOURCE_DIR}/cmake" + "${ATOMUI_CMAKE_MODULES_DIR}" +) + +include(MetaInfo) +include(FeatureSummary) + +project(${ATOMUI_PACKAGE_NAME} LANGUAGES C CXX + VERSION ${ATOMUI_VERSION_MAJOR}.${ATOMUI_VERSION_MINOR}.${ATOMUI_VERSION_PATCH}) + +if(NOT CMAKE_BUILD_TYPE) + set(CMAKE_BUILD_TYPE Debug CACHE STRING "Build type" FORCE) +endif() + +if (CMAKE_BUILD_TYPE STREQUAL "Debug") + set(ATOMUI_DEBUG_BUILD ON) +endif() + +if (${CMAKE_HOST_SYSTEM_NAME} STREQUAL Linux) + set(LINUX ON) +endif() + +string(TOLOWER ${CMAKE_BUILD_TYPE} ATOMUI_BUILD_TYPE) +if (CMAKE_BUILD_TYPE AND + NOT ATOMUI_BUILD_TYPE MATCHES "^(debug|release|relwithdebinfo|minsizerel)$") + message(FATAL_ERROR "Invalid value for CMAKE_BUILD_TYPE: ${CMAKE_BUILD_TYPE}") +endif() + +option(ATOMUI_WITH_DEBUG_CMAKE "Enabled CMake project debugging functionality (e.g. source file disk checking)" OFF) +option(ATOMUI_BUILD_UNITTESTS "Generate build targets for the atomui library unittests." ON) + +set(CMAKE_INCLUDE_CURRENT_DIR ON) + +include(Utils) +include(HandleRequirePackages) +include(HandleAppPath) +include(TargetUtils) +include(TestUtils) + +include_directories(${ATOMUI_SOURCE_DIR} + ${ATOMUI_INCLUDE_DIR} + ${ATOMUI_INCLUDE_DIR}/atomui + ${ATOMUI_BINARY_INCLUDE_DIR} + ${ATOMUI_BINARY_INCLUDE_DIR}/atomui + ${CMAKE_CURRENT_BINARY_DIR}) + +if (ATOMUI_BUILD_UNITTESTS) + enable_testing() +endif() + +add_subdirectory(include/atomui) +add_subdirectory(src) + +include(SummaryOutput) \ No newline at end of file diff --git a/nativelibs/cmake/modules/AddCustomCommandTarget.cmake b/nativelibs/cmake/modules/AddCustomCommandTarget.cmake new file mode 100644 index 000000000..ca4453c54 --- /dev/null +++ b/nativelibs/cmake/modules/AddCustomCommandTarget.cmake @@ -0,0 +1,173 @@ +# This source file is part of the atomui project +# +# Copyright (c) 2017 - 2022 qinware, All rights reserved. +# Copyright (c) 2017 - 2022 chinboy +# +# See https://qinware.com/LICENSE.txt for license information +# +# Created by chinboy on 2025/01/10. + +include(CMakeParseArguments) +include(Utils) + +# Populate the variable 'args' in the parent scope with a keyword +# argument list. We read the variables options, ${k}_keyword, and +# ACCT_${k} from the parent scope, for each ${k} in the list of +# keyword names other than COMMAND accepted by +# add_custom_command_target. +# +# ${k}_keyword must expand to ${k} if ${k} was passed to +# add_custom_command_target, and be empty otherwise. +# +# ACCT_${k} must expand to the list of arguments to +# add_custom_command_target marked by ${k}, and be empty otherwise. +# +function(_make_acct_argument_list) + set(args) + foreach(k ${ARGN}) + if(${k} IN_LIST options) + list(APPEND args ${${k}_keyword}) + else() + list(APPEND args ${${k}_keyword} ${ACCT_${k}}) + endif() + endforeach() + set(args ${args} PARENT_SCOPE) +endfunction() + +# Add a custom command/target pair. Use this instead of +# add_custom_command because it provides proper dependency tracking +# when used with parallel builds and the 'Unix Makefiles' generator. +# See https://www.cmake.org/Bug/view.php?id=10082 +# +# The CMake documentation for add_custom_command quoth, +# +# "Do not list the output in more than one independent target that +# may build in parallel or the two instances of the rule may +# conflict (instead use add_custom_target to drive the command and +# make the other targets depend on that one)." +# +# This function implements the suggested pattern. +# +# add_custom_command_target( +# dependency_out_var_name +# +# COMMAND command1 [ARGS] [args1...] +# [COMMAND command2 [ARGS] [args2...] ...] +# +# OUTPUT output1 [output2 ...] +# [MAIN_DEPENDENCY depend] +# [DEPENDS [depends...]] +# [IMPLICIT_DEPENDS depend1 +# [ depend2] ...] +# [WORKING_DIRECTORY dir] +# [COMMENT comment] [VERBATIM] [APPEND] +# [ALL] +# [SOURCES src1 [src2...]]) +# +# dependency_out_var_name is the name of a variable, to be set in the +# parent scope with the name of a target that all targets using the +# OUTPUT should depend on. For example: +# +# add_custom_command_target( +# TheDependency +# COMMAND echo "int main() {}" ">" z.c +# OUTPUT z.c +# VERBATIM +# DEPENDS z.c.gyb) +# +# add_executable(exe1 z.c) +# add_dependencies(exe1 ${TheDependency}) +# add_executable(exe2 z.c) +# add_dependencies(exe2 ${TheDependency}) +# +# **Note1**: all COMMAND arguments must immediately follow +# dependency_out_var_name or this function will misbehave. +# +# **Note2**: any subdirectories that define targets dependent on +# OUTPUT ${o} should invoke: +# +# set_source_files_properties(${o} PROPERTIES GENERATED true) +# +# All arguments other than ALL, SOURCES, and dependency_out_var_name +# are forwarded to add_custom_command; arguments ALL, SOURCES, and +# WORKING_DIRECTORY are forwarded to add_custom_target. See the +# documentation of those functions for a description of all arguments. +# +# How This Function Works +# +# CMake offers one way to add new build rules: add_custom_command. +# Most people, however, overlook its actual semantics. +# add_custom_command does *not* create a target. The CMake +# documentation declareth, +# +# "A target created in the same directory (CMakeLists.txt file) that +# specifies any output of the custom command as a source file is +# given a rule to generate the file using the command at build +# time." +# +# Therefore, when two targets built in parallel depend on an output of +# the same custom command, they may race to rebuild that output. +# Hilarity ensues. You might not notice this effect depending on the +# generator you use, but it happens with 'Unix Makefiles'. +# +# By injecting a target into the dependency graph between the custom +# command output and any targets that depend on that output, we force +# the output to be built before starting on any of its dependent +# targets. + +function(add_custom_command_target dependency_out_var_name) + # Parse the arguments. We don't look for COMMAND arguments because + # they don't follow the pattern supported by cmake_parse_arguments. + # As a result, they end up in ACCT_UNPARSED_ARGUMENTS and are + # forwarded verbatim. + set(options ALL VERBATIM APPEND IDEMPOTENT EXCLUDE_FROM_ALL) + set(single_value_args + MAIN_DEPENDENCY WORKING_DIRECTORY COMMENT CUSTOM_TARGET_NAME) + set(multi_value_args OUTPUT DEPENDS IMPLICIT_DEPENDS SOURCES) + cmake_parse_arguments( + ACCT # prefix + "${options}" "${single_value_args}" "${multi_value_args}" ${ARGN}) + set(ACCT_COMMANDS ${ACCT_UNPARSED_ARGUMENTS}) + + if("${ACCT_CUSTOM_TARGET_NAME}" STREQUAL "") + # CMake doesn't allow '/' characters in filenames, so replace them with '-' + list(GET ACCT_OUTPUT 0 output_filename) + string(REPLACE "${CMAKE_BINARY_DIR}/" "" target_name "${output_filename}") + string(REPLACE "${CMAKE_SOURCE_DIR}/" "" target_name "${target_name}") + string(REPLACE "${CMAKE_CFG_INTDIR}/" "" target_name "${target_name}") + string(REPLACE "/" "-" target_name "${target_name}") + else() + set(target_name "${ACCT_CUSTOM_TARGET_NAME}") + endif() + + if((NOT ACCT_IDEMPOTENT) OR (ACCT_IDEMPOTENT AND NOT TARGET "${target_name}")) + # For each keyword argument k that was passed to this function, set + # ${k}_keyword to ${k}. That will allow us to use the incantation + # '${${k}_keyword} ${ACCT_${k}}' to forward the arguments on. + foreach(var ${options} ${single_value_args} ${multi_value_args}) + atomui_translate_flag(ACCT_${var} ${var} ${var}_keyword) + endforeach() + + _make_acct_argument_list( + OUTPUT MAIN_DEPENDENCY DEPENDS + IMPLICIT_DEPENDS WORKING_DIRECTORY COMMENT VERBATIM APPEND) + add_custom_command(${ACCT_COMMANDS} ${args}) + + _make_acct_argument_list(ALL WORKING_DIRECTORY SOURCES) + add_custom_target( + "${target_name}" ${args} + DEPENDS ${ACCT_OUTPUT} + COMMENT "${ACCT_OUTPUT}") + set_target_properties( + "${target_name}" PROPERTIES + FOLDER "add_custom_command_target artifacts") + if (ACCT_EXCLUDE_FROM_ALL) + set_target_properties( + "${target_name}" PROPERTIES + EXCLUDE_FROM_ALL TRUE) + endif() + endif() + + # "Return" the name of the custom target + set("${dependency_out_var_name}" "${target_name}" PARENT_SCOPE) +endfunction() \ No newline at end of file diff --git a/nativelibs/cmake/modules/FindGoogleTest.cmake b/nativelibs/cmake/modules/FindGoogleTest.cmake new file mode 100644 index 000000000..2839a6b89 --- /dev/null +++ b/nativelibs/cmake/modules/FindGoogleTest.cmake @@ -0,0 +1,125 @@ +# This source file is part of the atomui project +# +# Copyright (c) 2017 - 2022 qinware, All rights reserved. +# Copyright (c) 2017 - 2022 chinboy +# +# See https://qinware.com/LICENSE.txt for license information +# +# Created by chinboy on 2025/01/10. +# +# FindGoogleTest +# ----------------- +# +# Try to locate the GoogleTest source files, and then build them as a +# static library. +# +# The ``GOOGLETEST_DIR`` (CMake or Environment) variable should be used +# to pinpoint the GoogleTest source files. +# +# If found, this will define the following variables: +# +# ``GoogleTest_FOUND`` +# True if the GoogleTest source package has been found. +# +# ``GoogleTest`` +# Target compiled as static library. +# + +find_path(GOOGLE_TEST_INCLUDE_DIR + NAMES gtest/gtest.h + PATH_SUFFIXES googletest/include + HINTS + "${GOOGLETEST_DIR}" ENV GOOGLETEST_DIR + "${PROJECT_SOURCE_DIR}/googletest" + "${PROJECT_SOURCE_DIR}/../googletest" + "${PROJECT_SOURCE_DIR}/../../googletest" + "${PROJECT_SOURCE_DIR}/thirdparty/googletest" +) + +find_path(GOOGLE_TEST_SRC_ALL + NAMES gtest-all.cc + PATH_SUFFIXES googletest/src + HINTS + "${GOOGLETEST_DIR}" ENV GOOGLETEST_DIR + "${PROJECT_SOURCE_DIR}/googletest" + "${PROJECT_SOURCE_DIR}/../googletest" + "${PROJECT_SOURCE_DIR}/../../googletest" + "${PROJECT_SOURCE_DIR}/thirdparty/googletest" +) + +find_path(GOOGLE_MOCK_INCLUDE_DIR + NAMES gmock/gmock.h + PATH_SUFFIXES googlemock/include + HINTS + "${GOOGLETEST_DIR}" ENV GOOGLETEST_DIR + "${PROJECT_SOURCE_DIR}/googletest" + "${PROJECT_SOURCE_DIR}/../googletest" + "${PROJECT_SOURCE_DIR}/../../googletest" + "${PROJECT_SOURCE_DIR}/thirdparty/googletest" +) + +find_path(GOOGLE_MOCK_SRC_ALL + NAMES gmock-all.cc + PATH_SUFFIXES googlemock/src + HINTS + "${GOOGLETEST_DIR}" ENV GOOGLETEST_DIR + "${PROJECT_SOURCE_DIR}/googletest" + "${PROJECT_SOURCE_DIR}/../googletest" + "${PROJECT_SOURCE_DIR}/../../googletest" + "${PROJECT_SOURCE_DIR}/thirdparty/googletest" +) + +include(FindPackageHandleStandardArgs) +find_package_handle_standard_args(GoogleTest + DEFAULT_MSG + GOOGLE_TEST_INCLUDE_DIR GOOGLE_MOCK_INCLUDE_DIR + GOOGLE_TEST_SRC_ALL GOOGLE_MOCK_SRC_ALL +) +find_package(Threads REQUIRED) + +if(GoogleTest_FOUND AND NOT TARGET GoogleTest) + add_library(GoogleTest STATIC + "${GOOGLE_TEST_SRC_ALL}/gtest-all.cc" + "${GOOGLE_MOCK_SRC_ALL}/gmock-all.cc" + ) + target_include_directories(GoogleTest + PUBLIC + "${GOOGLE_TEST_INCLUDE_DIR}" + "${GOOGLE_MOCK_INCLUDE_DIR}" + PRIVATE + "${GOOGLE_TEST_SRC_ALL}/.." + "${GOOGLE_MOCK_SRC_ALL}/.." + ) + target_compile_definitions(GoogleTest + PRIVATE + GTEST_HAS_STD_INITIALIZER_LIST_ + GTEST_LANG_CXX11 + GTEST_HAS_STD_TUPLE_ + GTEST_HAS_STD_TYPE_TRAITS_ + GTEST_HAS_STD_FUNCTION_ + GTEST_HAS_RTTI + GTEST_HAS_STD_BEGIN_AND_END_ + GTEST_HAS_STD_UNIQUE_PTR_ + GTEST_HAS_EXCEPTIONS + GTEST_HAS_STREAM_REDIRECTION + GTEST_HAS_TYPED_TEST + GTEST_HAS_TYPED_TEST_P + GTEST_HAS_PARAM_TEST + GTEST_HAS_DEATH_TEST + ) + set_target_properties(GoogleTest PROPERTIES AUTOMOC OFF AUTOUIC OFF) + set_property(TARGET GoogleTest PROPERTY POSITION_INDEPENDENT_CODE ON) + target_compile_definitions(GoogleTest PUBLIC GOOGLE_TEST_IS_FOUND) + target_link_libraries(GoogleTest Threads::Threads) +endif() + +mark_as_advanced( + GOOGLE_TEST_INCLUDE_DIR + GOOGLE_MOCK_INCLUDE_DIR + GOOGLE_TEST_SRC_ALL + GOOGLE_MOCK_SRC_ALL) + +include(FeatureSummary) +set_package_properties(GoogleTest PROPERTIES + URL "https://github.com/google/googletest" + DESCRIPTION "Google Testing and Mocking Framework") \ No newline at end of file diff --git a/nativelibs/cmake/modules/HandleAppPath.cmake b/nativelibs/cmake/modules/HandleAppPath.cmake new file mode 100644 index 000000000..1a675edd1 --- /dev/null +++ b/nativelibs/cmake/modules/HandleAppPath.cmake @@ -0,0 +1,54 @@ +# This source file is part of the atomui project +# +# Copyright (c) 2017 - 2022 qinware, All rights reserved. +# Copyright (c) 2017 - 2022 chinboy +# +# See https://qinware.com/LICENSE.txt for license information +# +# Created by chinboy on 2025/01/10. + +if (WIN32) + set(_ATOMUI_APP_PATH "bin") + set(_ATOMUI_APP_TARGET "${ATOMUI_PACKAGE_NAME}") + + set(_ATOMUI_LIBRARY_BASE_PATH "lib") + set(_ATOMUI_LIBRARY_PATH "${_ATOMUI_LIBRARY_BASE_PATH}") + set(_ATOMUI_LIBEXEC_PATH "bin") + set(_ATOMUI_DATA_PATH "share/${ATOMUI_PACKAGE_NAME}") + set(_ATOMUI_BIN_PATH "bin") + set(_ATOMUI_LIBRARY_ARCHIVE_PATH "${_ATOMUI_BIN_PATH}") +else () + include(GNUInstallDirs) + set(_ATOMUI_APP_PATH "${CMAKE_INSTALL_BINDIR}") + set(_ATOMUI_APP_TARGET "${ATOMUI_PACKAGE_NAME}") + + set(_ATOMUI_LIBRARY_BASE_PATH "${CMAKE_INSTALL_LIBDIR}") + set(_ATOMUI_LIBRARY_PATH "${_ATOMUI_LIBRARY_BASE_PATH}") + set(_ATOMUI_LIBEXEC_PATH "${CMAKE_INSTALL_LIBEXECDIR}") + set(_ATOMUI_DATA_PATH "${CMAKE_INSTALL_DATAROOTDIR}/${ATOMUI_PACKAGE_NAME}") + set(_ATOMUI_BIN_PATH "${CMAKE_INSTALL_BINDIR}") + set(_ATOMUI_LIBRARY_ARCHIVE_PATH "${_ATOMUI_LIBRARY_PATH}") +endif () + +if (APPLE) + set(_RPATH_BASE "@executable_path") + set(_LIB_RPATH "@loader_path") +elseif (WIN32) + set(_RPATH_BASE "") + set(_LIB_RPATH "") +else () + set(_RPATH_BASE "\$ORIGIN") + set(_LIB_RPATH "\$ORIGIN;") +endif () + +set(ATOMUI_APP_PATH "${_ATOMUI_APP_PATH}") # The target path of the ATOMUI application (relative to CMAKE_INSTALL_PREFIX). +set(ATOMUI_APP_TARGET "${_ATOMUI_APP_TARGET}") # The ATOMUI application name. +set(ATOMUI_LIBRARY_BASE_PATH "${_ATOMUI_LIBRARY_BASE_PATH}") # The ATOMUI library base path (relative to CMAKE_INSTALL_PREFIX). +set(ATOMUI_LIBRARY_PATH "${_ATOMUI_LIBRARY_PATH}") # The ATOMUI library path (relative to CMAKE_INSTALL_PREFIX). +set(ATOMUI_LIBRARY_ARCHIVE_PATH "${_ATOMUI_LIBRARY_ARCHIVE_PATH}") # The ATOMUI library archive path (relative to CMAKE_INSTALL_PREFIX). +set(ATOMUI_LIBEXEC_PATH "${_ATOMUI_LIBEXEC_PATH}") # The ATOMUI libexec path (relative to CMAKE_INSTALL_PREFIX). +set(ATOMUI_DATA_PATH "${_ATOMUI_DATA_PATH}") # The ATOMUI data path (relative to CMAKE_INSTALL_PREFIX). +set(ATOMUI_BIN_PATH "${_ATOMUI_BIN_PATH}") # The ATOMUI bin path (relative to CMAKE_INSTALL_PREFIX). + +file(RELATIVE_PATH RELATIVE_LIBEXEC_PATH "/${ATOMUI_BIN_PATH}" "/${ATOMUI_LIBEXEC_PATH}") +file(RELATIVE_PATH RELATIVE_DATA_PATH "/${ATOMUI_BIN_PATH}" "/${ATOMUI_DATA_PATH}") \ No newline at end of file diff --git a/nativelibs/cmake/modules/HandleRequirePackages.cmake b/nativelibs/cmake/modules/HandleRequirePackages.cmake new file mode 100644 index 000000000..f2f502c6d --- /dev/null +++ b/nativelibs/cmake/modules/HandleRequirePackages.cmake @@ -0,0 +1,42 @@ +# This source file is part of the atomui project +# +# Copyright (c) 2017 - 2022 qinware, All rights reserved. +# Copyright (c) 2017 - 2022 chinboy +# +# See https://qinware.com/LICENSE.txt for license information +# +# Created by chinboy on 2025/01/10. + +if (APPLE) + find_library(FWCoreFoundation CoreFoundation) + find_library(FWCoreServices CoreServices) + find_library(FWFoundation Foundation) + find_library(FWAppKit AppKit) + find_library(FWIOKit IOKit) + find_library(FWSecurity Security) + find_library(FWSystemConfiguration SystemConfiguration) + find_library(FWWebKit WebKit) +endif() + +if(LINUX) + # 查找必需的 XCB 组件 + find_package(PkgConfig REQUIRED) + pkg_check_modules(XCB REQUIRED IMPORTED_TARGET + xcb + xcb-shape + ) +endif() + +if(WIN32) + # 设置共享库不添加前缀 + set(CMAKE_SHARED_LIBRARY_PREFIX "") + set(CMAKE_SHARED_LIBRARY_SUFFIX ".dll") + + # 设置静态库不添加前缀 + set(CMAKE_STATIC_LIBRARY_PREFIX "") + set(CMAKE_STATIC_LIBRARY_SUFFIX ".lib") + + # 可选:确保导入库也保持一致命名 + set(CMAKE_IMPORT_LIBRARY_PREFIX "") + set(CMAKE_IMPORT_LIBRARY_SUFFIX ".lib") +endif() \ No newline at end of file diff --git a/nativelibs/cmake/modules/ImportThirdparty.cmake b/nativelibs/cmake/modules/ImportThirdparty.cmake new file mode 100644 index 000000000..b0c790721 --- /dev/null +++ b/nativelibs/cmake/modules/ImportThirdparty.cmake @@ -0,0 +1,14 @@ +# This source file is part of the atomui project +# +# Copyright (c) 2017 - 2022 qinware, All rights reserved. +# Copyright (c) 2017 - 2022 chinboy +# +# See https://qinware.com/LICENSE.txt for license information +# +# Created by chinboy on 2025/01/10. + +include(ExternalProject) + +if (ATOMUI_BUILD_UNITTESTS) + find_package(GoogleTest REQUIRED) +endif() \ No newline at end of file diff --git a/nativelibs/cmake/modules/MetaInfo.cmake b/nativelibs/cmake/modules/MetaInfo.cmake new file mode 100644 index 000000000..32f86ecb1 --- /dev/null +++ b/nativelibs/cmake/modules/MetaInfo.cmake @@ -0,0 +1,43 @@ +# This source file is part of the atomui project +# +# Copyright (c) 2017 - 2022 qinware, All rights reserved. +# Copyright (c) 2017 - 2022 chinboy +# +# See https://qinware.com/LICENSE.txt for license information +# +# Created by chinboy on 2025/01/10. + +if(NOT DEFINED ATOMUI_VERSION_MAJOR) + set(ATOMUI_VERSION_MAJOR 0) +endif() +if(NOT DEFINED ATOMUI_VERSION_MINOR) + set(ATOMUI_VERSION_MINOR 1) +endif() +if(NOT DEFINED ATOMUI_VERSION_PATCH) + set(ATOMUI_VERSION_PATCH 0) +endif() +if(NOT DEFINED ATOMUI_VERSION_BUILD) + set(ATOMUI_VERSION_BUILD "") +endif() + +if (NOT ATOMUI_PACKAGE_VERSION) + set(ATOMUI_PACKAGE_VERSION "${ATOMUI_VERSION_MAJOR}.${ATOMUI_VERSION_MINOR}.${ATOMUI_VERSION_PATCH}-${ATOMUI_VERSION_BUILD}") +endif() + +if (NOT ATOMUI_VERSION) + set(ATOMUI_VERSION "${ATOMUI_VERSION_MAJOR}.${ATOMUI_VERSION_MINOR}.${ATOMUI_VERSION_PATCH}") +endif() + +set(ATOMUI_VERSION_COMPAT ${ATOMUI_VERSION}) + +math(EXPR ATOMUI_VERSION_ID ${ATOMUI_VERSION_MAJOR}*10000+${ATOMUI_VERSION_MINOR}*100+${ATOMUI_VERSION_PATCH}) + +set(ATOMUI_COMPAT_VERSION ${ATOMUI_VERSION}) +set(ATOMUI_PACKAGE_NAME atomui) +set(ATOMUI_PACKAGE_CASED_NAME AtomUI) +set(ATOMUI_PACKAGE_STRING "${ATOMUI_PACKAGE_NAME} ${ATOMUI_PACKAGE_VERSION}") +set(ATOMUI_PACKAGE_BUGREPORT "https://qinware.com/bugs/") +set(ATOMUI_DISPLAY_NAME "AtomUI") +set(ATOMUI_COPYRIGHT_YEAR "2025") +set(ATOMUI_COMPANY_NAME "Qinware") +set(ATOMUI_COPYRIGHT "Copyright Qinware Technologies Ltd. (c) 2018-2025") \ No newline at end of file diff --git a/nativelibs/cmake/modules/SummaryOutput.cmake b/nativelibs/cmake/modules/SummaryOutput.cmake new file mode 100644 index 000000000..fb82fa38c --- /dev/null +++ b/nativelibs/cmake/modules/SummaryOutput.cmake @@ -0,0 +1,35 @@ +# This source file is part of the atomui project +# +# Copyright (c) 2017 - 2022 qinware, All rights reserved. +# Copyright (c) 2017 - 2022 chinboy +# +# See https://qinware.com/LICENSE.txt for license information +# +# Created by chinboy on 2025/01/10. +# +message(STATUS "--------------------------------------------------------------------------------------") +message(STATUS "Thank for using AtomUI project, have a lot of fun!") +message(STATUS "--------------------------------------------------------------------------------------") + +message(STATUS "CMAKE_INSTALL_PREFIX: ${CMAKE_INSTALL_PREFIX}") +message(STATUS "CMAKE_BUILD_TYPE: ${CMAKE_BUILD_TYPE}") +message(STATUS "PROJECT_BINARY_DIR: ${PROJECT_BINARY_DIR}") +message(STATUS "PROJECT_SOURCE_DIR: ${PROJECT_SOURCE_DIR}") +message(STATUS "CMAKE_ROOT: ${CMAKE_ROOT}") +message(STATUS "CMAKE_SYSTEM: ${CMAKE_SYSTEM}") +message(STATUS "CMAKE_SYSTEM_PROCESSOR: ${CMAKE_SYSTEM_PROCESSOR}") +message(STATUS "CMAKE_SKIP_RPATH: ${CMAKE_SKIP_RPATH}") +message(STATUS "CMAKE_VERBOSE_MAKEFILE: ${CMAKE_VERBOSE_MAKEFILE}") +message(STATUS "CMAKE_C_COMPILER: ${CMAKE_C_COMPILER}") +message(STATUS "CMAKE_C_COMPILER_VERSION: ${CMAKE_C_COMPILER_VERSION}") +message(STATUS "CMAKE_C_FLAGS: ${CMAKE_C_FLAGS}") +message(STATUS "CMAKE_CXX_COMPILER: ${CMAKE_CXX_COMPILER}") +message(STATUS "CMAKE_CXX_COMPILER_VERSION: ${CMAKE_CXX_COMPILER_VERSION}") +message(STATUS "CMAKE_CXX_FLAGS: ${CMAKE_CXX_FLAGS}") +message(STATUS "CMAKE_EXE_LINKER_FLAGS: ${CMAKE_EXE_LINKER_FLAGS}") +message(STATUS "--------------------------------------------------------------------------------------") + +feature_summary(INCLUDE_QUIET_PACKAGES WHAT + PACKAGES_FOUND PACKAGES_NOT_FOUND + ENABLED_FEATURES DISABLED_FEATURES +) \ No newline at end of file diff --git a/nativelibs/cmake/modules/TargetUtils.cmake b/nativelibs/cmake/modules/TargetUtils.cmake new file mode 100644 index 000000000..c6bb788b9 --- /dev/null +++ b/nativelibs/cmake/modules/TargetUtils.cmake @@ -0,0 +1,386 @@ +# This source file is part of the atomui project +# +# Copyright (c) 2017 - 2022 qinware, All rights reserved. +# Copyright (c) 2017 - 2022 chinboy +# +# See https://qinware.com/LICENSE.txt for license information +# +# Created by chinboy on 2025/01/10. + +include_guard(GLOBAL) + +# If we provide a list of plugins, executables, libraries, then the BUILD__BY_DEFAULT will be set to OFF +# and for every element we set BUILD__ to ON +# e.g. BUILD_PLUGINS=Core;TextEditor will result in BUILD_PLUGINS_BY_DEFAULT=OFF and BUILD_PLUGIN_CORE=ON and BUILD_PLUGIN_TEXTEDITOR ON + +function(atomui_check_default_values_for_list list_type) + set(PLUGINS_single plugin) + set(EXECUTABLES_single executable) + set(LIBRARIES_single library) + set(TESTS_single test) + + if (NOT DEFINED ATOMUI_BUILD_${list_type}) + return() + endif () + + set(ATOMUI_BUILD_${list_type}_BY_DEFAULT OFF CACHE BOOL "" FORCE) + + foreach (element ${ATOMUI_BUILD_${list_type}}) + string(TOUPPER "${${list_type}_single}_${element}" upper_element) + set(ATOMUI_BUILD_${upper_element} ON CACHE BOOL "Build ${${list_type}_single} ${element}.") + endforeach () +endfunction() + +atomui_check_default_values_for_list(EXECUTABLES) +atomui_check_default_values_for_list(LIBRARIES) +atomui_check_default_values_for_list(TESTS) + +function(atomui_library_enabled varName name) + if (NOT (name IN_LIST __ATOMUI_LIBRARIES)) + message(FATAL_ERROR "atomui_library_enabled: Unknown library target \"${name}\"") + endif () + if (TARGET ${name}) + set(${varName} ON PARENT_SCOPE) + else () + set(${varName} OFF PARENT_SCOPE) + endif () +endfunction() + +function(atomui_output_binary_dir varName) + if (ATOMUI_MERGE_BINARY_DIR) + set(${varName} ${ATOMUI_BINARY_DIR} PARENT_SCOPE) + else () + set(${varName} ${PROJECT_BINARY_DIR} PARENT_SCOPE) + endif () +endfunction() + +function(atomui_source_dir varName) + if (ATOMUI_MERGE_BINARY_DIR) + set(${varName} ${ATOMUI_SOURCE_DIR} PARENT_SCOPE) + else () + set(${varName} ${PROJECT_SOURCE_DIR} PARENT_SCOPE) + endif () +endfunction() + +function(atomui_add_library name) + cmake_parse_arguments(_arg "STATIC;OBJECT;FEATURE_INFO" + "DESTINATION;COMPONENT;SOURCES_PREFIX;BUILD_DEFAULT" + "CONDITION;DEPENDS;PUBLIC_DEPENDS;DEFINES;PUBLIC_DEFINES;INCLUDES;PUBLIC_INCLUDES;SOURCES;PROPERTIES" ${ARGN} + ) + + set(default_defines_copy ${DEFAULT_DEFINES}) + + if (${_arg_UNPARSED_ARGUMENTS}) + message(FATAL_ERROR "atomui_add_library had unparsed arguments") + endif () + + atomui_update_cached_list(__ATOMUI_LIBRARIES "${name}") + + atomui_condition_info(_extra_text _arg_CONDITION) + if (NOT _arg_CONDITION) + set(_arg_CONDITION ON) + endif () + + add_feature_info("Library ${name}" ON "${_extra_text}") + + set(library_type SHARED) + if (_arg_STATIC) + set(library_type STATIC) + endif () + if (_arg_OBJECT) + set(library_type OBJECT) + endif () + + add_library(${name} ${library_type}) + add_library(AtomUI::${name} ALIAS ${name}) + + string(TOUPPER "ATOMUI_LIBRARY" EXPORT_SYMBOL) + + if (ATOMUI_WITH_TESTS) + set(TEST_DEFINES WITH_TESTS SRCDIR="${CMAKE_CURRENT_SOURCE_DIR}") + endif () + + if (_arg_STATIC AND UNIX) + # not added by Qt if reduce_relocations is turned off for it + set_target_properties(${name} PROPERTIES POSITION_INDEPENDENT_CODE ON) + endif () + + atomui_extend_target(${name} + SOURCES_PREFIX ${_arg_SOURCES_PREFIX} + SOURCES ${_arg_SOURCES} + INCLUDES ${_arg_INCLUDES} + PUBLIC_INCLUDES ${_arg_PUBLIC_INCLUDES} + DEFINES ${EXPORT_SYMBOL} ${default_defines_copy} ${_arg_DEFINES} ${TEST_DEFINES} + PUBLIC_DEFINES ${_arg_PUBLIC_DEFINES} + DEPENDS ${_arg_DEPENDS} ${IMPLICIT_DEPENDS} + PUBLIC_DEPENDS ${_arg_PUBLIC_DEPENDS} + ) + + # everything is different with SOURCES_PREFIX + if (NOT _arg_SOURCES_PREFIX) + target_include_directories(${name} + PRIVATE + "$" + PUBLIC + "$" + "$" + "$" + ) + endif () + + set(_DESTINATION "${ATOMUI_BIN_PATH}") + if (_arg_DESTINATION) + set(_DESTINATION "${_arg_DESTINATION}") + endif () + + atomui_output_binary_dir(_output_binary_dir) + string(REGEX MATCH "^[0-9]*" ATOMUI_VERSION_MAJOR ${ATOMUI_VERSION}) + + set_target_properties(${name} PROPERTIES + LINK_DEPENDS_NO_SHARED ON + SOURCES_DIR "${CMAKE_CURRENT_SOURCE_DIR}" + MACHO_CURRENT_VERSION ${ATOMUI_VERSION} + MACHO_COMPATIBILITY_VERSION ${ATOMUI_VERSION_COMPAT} + CXX_EXTENSIONS OFF + CXX_VISIBILITY_PRESET hidden + VISIBILITY_INLINES_HIDDEN ON + BUILD_RPATH "${_LIB_RPATH};${CMAKE_BUILD_RPATH}" + INSTALL_RPATH "${_LIB_RPATH};${CMAKE_INSTALL_RPATH}" + RUNTIME_OUTPUT_DIRECTORY "${_output_binary_dir}/${_DESTINATION}" + LIBRARY_OUTPUT_DIRECTORY "${_output_binary_dir}/${ATOMUI_LIBRARY_PATH}" + ARCHIVE_OUTPUT_DIRECTORY "${_output_binary_dir}/${ATOMUI_LIBRARY_ARCHIVE_PATH}" + ${_arg_PROPERTIES} + ) + + unset(NAMELINK_OPTION) + if (library_type STREQUAL "SHARED") + set(NAMELINK_OPTION NAMELINK_SKIP) + endif () + + unset(COMPONENT_OPTION) + if (_arg_COMPONENT) + set(COMPONENT_OPTION "COMPONENT" "${_arg_COMPONENT}") + endif () + + install(TARGETS ${name} + EXPORT ATOMUI + RUNTIME + DESTINATION "${_DESTINATION}" + ${COMPONENT_OPTION} + OPTIONAL + LIBRARY + DESTINATION "${ATOMUI_LIBRARY_PATH}" + ${NAMELINK_OPTION} + ${COMPONENT_OPTION} + OPTIONAL + OBJECTS + DESTINATION "${ATOMUI_LIBRARY_PATH}" + COMPONENT Devel EXCLUDE_FROM_ALL + ARCHIVE + DESTINATION "${ATOMUI_LIBRARY_ARCHIVE_PATH}" + COMPONENT Devel EXCLUDE_FROM_ALL + OPTIONAL + ) + + if (ATOMUI_WITH_SANITIZE) + atomui_enable_sanitize(${SANITIZE_FLAGS}) + endif () + + if (NAMELINK_OPTION) + install(TARGETS ${name} + LIBRARY + DESTINATION "${ATOMUI_LIBRARY_PATH}" + NAMELINK_ONLY + COMPONENT Devel EXCLUDE_FROM_ALL + OPTIONAL + ) + endif () +endfunction() + +function(atomui_extend_library target_name) + atomui_library_enabled(_library_enabled ${target_name}) + if (NOT _library_enabled) + return() + endif () + atomui_extend_target(${target_name} ${ARGN}) +endfunction() + +function(atomui_extend_test target_name) + if (NOT (target_name IN_LIST __ATOMUI_TESTS)) + message(FATAL_ERROR "atomui_extend_test: Unknown test target \"${target_name}\"") + endif () + if (TARGET ${target_name}) + atomui_extend_target(${target_name} ${ARGN}) + endif () +endfunction() + +function(atomui_add_executable name) + cmake_parse_arguments(_arg "" + "DESTINATION;COMPONENT;BUILD_DEFAULT" + "CONDITION;DEPENDS;DEFINES;INCLUDES;SOURCES;PROPERTIES" ${ARGN}) + + if (${_arg_UNPARSED_ARGUMENTS}) + message(FATAL_ERROR "atomui_add_executable had unparsed arguments!") + endif () + set(default_defines_copy ${DEFAULT_DEFINES}) + atomui_update_cached_list(__ATOMUI_EXECUTABLES "${name}") + + if (NOT _arg_CONDITION) + set(_arg_CONDITION ON) + endif () + + string(TOUPPER "ATOMUI_BUILD_EXECUTABLE_${name}" _build_executable_var) + if (DEFINED _arg_BUILD_DEFAULT) + set(_build_executable_default ${_arg_BUILD_DEFAULT}) + else () + set(_build_executable_default ${ATOMUI_BUILD_EXECUTABLES_BY_DEFAULT}) + endif () + if (DEFINED ENV{${_build_executable_var}}) + set(_build_executable_default "$ENV{${_build_executable_var}}") + endif () + set(${_build_executable_var} "${_build_executable_default}" CACHE BOOL "Build executable ${name}.") + + if ((${_arg_CONDITION}) AND ${_build_executable_var}) + set(_executable_enabled ON) + else () + set(_executable_enabled OFF) + endif () + if (NOT _executable_enabled) + return() + endif () + + set(_DESTINATION "${ATOMUI_LIBEXEC_PATH}") + if (_arg_DESTINATION) + set(_DESTINATION "${_arg_DESTINATION}") + endif () + + set(_EXECUTABLE_PATH "${_DESTINATION}") + if (APPLE) + # path of executable might be inside app bundle instead of DESTINATION directly + cmake_parse_arguments(_prop "" "MACOSX_BUNDLE;OUTPUT_NAME" "" "${_arg_PROPERTIES}") + if (_prop_MACOSX_BUNDLE) + set(_BUNDLE_NAME "${name}") + if (_prop_OUTPUT_NAME) + set(_BUNDLE_NAME "${_prop_OUTPUT_NAME}") + endif () + set(_BUNDLE_CONTENTS_PATH "${_DESTINATION}/${_BUNDLE_NAME}.app/Contents") + set(_EXECUTABLE_PATH "${_BUNDLE_CONTENTS_PATH}/MacOS") + set(_EXECUTABLE_FILE_PATH "${_EXECUTABLE_PATH}/${_BUNDLE_NAME}") + set(_BUNDLE_INFO_PLIST "${_BUNDLE_CONTENTS_PATH}/Info.plist") + endif () + endif () + + if (ATOMUI_WITH_TESTS) + set(TEST_DEFINES WITH_TESTS SRCDIR="${CMAKE_CURRENT_SOURCE_DIR}") + endif () + + add_executable("${name}" ${_arg_SOURCES}) + + atomui_extend_target("${name}" + INCLUDES "${CMAKE_BINARY_DIR}/src" ${_arg_INCLUDES} + DEFINES ${default_defines_copy} ${TEST_DEFINES} ${_arg_DEFINES} + DEPENDS ${_arg_DEPENDS} ${IMPLICIT_DEPENDS} + ) + + file(RELATIVE_PATH relative_lib_path "/${_EXECUTABLE_PATH}" "/${ATOMUI_LIBRARY_PATH}") + + set(build_rpath "${_RPATH_BASE}/${relative_lib_path}") + set(install_rpath "${_RPATH_BASE}/${relative_lib_path}") + if (NOT WIN32 AND NOT APPLE) + set(install_rpath "${install_rpath};") + endif () + set(build_rpath "${build_rpath};${CMAKE_BUILD_RPATH}") + set(install_rpath "${install_rpath};${CMAKE_INSTALL_RPATH}") + + atomui_output_binary_dir(_output_binary_dir) + set_target_properties("${name}" PROPERTIES + LINK_DEPENDS_NO_SHARED ON + BUILD_RPATH "${build_rpath}" + INSTALL_RPATH "${install_rpath}" + RUNTIME_OUTPUT_DIRECTORY "${_output_binary_dir}/${_DESTINATION}" + CXX_EXTENSIONS OFF + CXX_VISIBILITY_PRESET hidden + VISIBILITY_INLINES_HIDDEN ON + ${_arg_PROPERTIES} + ) +endfunction() + +function(atomui_extend_executable name) + if (NOT (name IN_LIST __ATOMUI_EXECUTABLES)) + message(FATAL_ERROR "atomui_extend_executable: Unknown executable target \"${name}\"") + endif () + if (TARGET ${name}) + atomui_extend_target(${name} ${ARGN}) + endif () +endfunction() + +function(atomui_copy_to_builddir custom_target_name) + cmake_parse_arguments(_arg "CREATE_SUBDIRS" "DESTINATION" "FILES;DIRECTORIES" ${ARGN}) + set(timestampFiles) + + atomui_output_binary_dir(_output_binary_dir) + set(allFiles ${_arg_FILES}) + + foreach (srcFile ${_arg_FILES}) + string(MAKE_C_IDENTIFIER "${srcFile}" destinationTimestampFilePart) + set(destinationTimestampFileName "${CMAKE_CURRENT_BINARY_DIR}/.${destinationTimestampFilePart}_timestamp") + list(APPEND timestampFiles "${destinationTimestampFileName}") + + if (IS_ABSOLUTE "${srcFile}") + set(srcPath "") + else () + get_filename_component(srcPath "${srcFile}" DIRECTORY) + endif () + + add_custom_command(OUTPUT "${destinationTimestampFileName}" + COMMAND "${CMAKE_COMMAND}" -E make_directory "${_output_binary_dir}/${_arg_DESTINATION}/${srcPath}" + COMMAND "${CMAKE_COMMAND}" -E copy "${srcFile}" "${_output_binary_dir}/${_arg_DESTINATION}/${srcPath}" + COMMAND "${CMAKE_COMMAND}" -E touch "${destinationTimestampFileName}" + WORKING_DIRECTORY "${CMAKE_CURRENT_SOURCE_DIR}" + COMMENT "Copy ${srcFile} into build directory" + DEPENDS "${srcFile}" + VERBATIM + ) + endforeach () + + foreach (srcDirectory ${_arg_DIRECTORIES}) + string(MAKE_C_IDENTIFIER "${srcDirectory}" destinationTimestampFilePart) + set(destinationTimestampFileName "${CMAKE_CURRENT_BINARY_DIR}/.${destinationTimestampFilePart}_timestamp") + list(APPEND timestampFiles "${destinationTimestampFileName}") + set(destinationDirectory "${_output_binary_dir}/${_arg_DESTINATION}") + + if (_arg_CREATE_SUBDIRS) + set(destinationDirectory "${destinationDirectory}/${srcDirectory}") + endif () + + file(GLOB_RECURSE filesToCopy "${srcDirectory}/*") + list(APPEND allFiles ${filesToCopy}) + add_custom_command(OUTPUT "${destinationTimestampFileName}" + COMMAND "${CMAKE_COMMAND}" -E copy_directory "${srcDirectory}" "${destinationDirectory}" + COMMAND "${CMAKE_COMMAND}" -E touch "${destinationTimestampFileName}" + WORKING_DIRECTORY "${CMAKE_CURRENT_SOURCE_DIR}" + COMMENT "Copy ${srcDirectory}/ into build directory" + DEPENDS ${filesToCopy} + VERBATIM + ) + endforeach () + + add_custom_target("${custom_target_name}" ALL DEPENDS ${timestampFiles} + SOURCES ${allFiles}) +endfunction() + +function(atomui_add_public_header header) + if (NOT IS_ABSOLUTE ${header}) + set(header "${CMAKE_CURRENT_SOURCE_DIR}/${header}") + endif () + + atomui_source_dir(atomui_source_dir) + get_filename_component(source_dir ${header} DIRECTORY) + file(RELATIVE_PATH include_dir_relative_path "${atomui_source_dir}" "${source_dir}") + + install( + FILES ${header} + DESTINATION "${IDE_HEADER_INSTALL_PATH}/${include_dir_relative_path}" + COMPONENT Devel EXCLUDE_FROM_ALL + ) +endfunction() \ No newline at end of file diff --git a/nativelibs/cmake/modules/TestUtils.cmake b/nativelibs/cmake/modules/TestUtils.cmake new file mode 100644 index 000000000..dd02fe3fc --- /dev/null +++ b/nativelibs/cmake/modules/TestUtils.cmake @@ -0,0 +1,130 @@ +# This source file is part of the atomui project +# +# Copyright (c) 2017 - 2022 qinware, All rights reserved. +# Copyright (c) 2017 - 2022 chinboy +# +# See https://qinware.com/LICENSE.txt for license information +# +# Created by chinboy on 2025/01/10. + +# Generic support for adding a unittest. +function(atomui_add_unittest test_suite test_name) + cmake_parse_arguments(_arg "GTEST;MANUALTEST" "TIMEOUT" + "DEFINES;DEPENDS;INCLUDES;SOURCES;EXPLICIT_MOC;CONDITION;LINK_LIBS" ${ARGN}) + if ($_arg_UNPARSED_ARGUMENTS) + message(FATAL_ERROR "atomui_add_unittest had unparsed arguments!") + endif () + + atomui_update_cached_list(__ATOMUI_TESTS "${test_name}") + set(_link_libs ${ATOMUI_LINK_COMPONENTS}) + if (_arg_LINK_LIBS) + atomui_merge_list(_link_libs _arg_LINK_LIBS) + endif () + + if (NOT _arg_CONDITION) + set(_arg_CONDITION ON) + endif () + + if (NOT _arg_GTEST) + set(_arg_GTEST ON) + endif () + + if (NOT ATOMUI_BUILD_TESTS) + set(EXCLUDE_FROM_ALL ON) + endif () + + foreach (dependency ${_arg_DEPENDS}) + if (NOT TARGET ${dependency} AND NOT _arg_GTEST) + if (ATOMUI_WITH_DEBUG_CMAKE) + message(STATUS "'${dependency}' is not a target") + endif () + return() + endif () + endforeach () + + if (SUPPORTS_VARIADIC_MACROS_FLAG) + list(APPEND ATOMUI_COMPILE_FLAGS "-Wno-variadic-macros") + endif () + + # Some parts of gtest rely on this GNU extension, don't warn on it. + if (SUPPORTS_GNU_ZERO_VARIADIC_MACRO_ARGUMENTS_FLAG) + list(APPEND ATOMUI_COMPILE_FLAGS "-Wno-gnu-zero-variadic-macro-arguments") + endif () + + set(TEST_DEFINES SRCDIR="${CMAKE_CURRENT_SOURCE_DIR}") + + # relax cast requirements for tests + set(default_defines_copy ${DEFAULT_DEFINES}) + file(RELATIVE_PATH _RPATH "/${ATOMUI_BIN_PATH}" "/${ATOMUI_LIBRARY_PATH}") + + atomui_add_executable(${test_name} + DESTINATION ${ATOMUI_TEST_BIN_DIR} + SKIP_INSTALL + SOURCES ${_arg_SOURCES}) + + # The runtime benefits of LTO don't outweight the compile time costs for tests. + if (ATOMUI_ENABLE_LTO) + if ((UNIX OR MINGW) AND LINKER_IS_LLD) + set_property(TARGET ${test_name} APPEND_STRING PROPERTY + LINK_FLAGS " -Wl,--lto-O0") + elseif (LINKER_IS_LLD_LINK) + set_property(TARGET ${test_name} APPEND_STRING PROPERTY + LINK_FLAGS " /opt:lldlto=0") + endif () + endif () + + atomui_extend_target(${test_name} + DEPENDS ${_arg_DEPENDS} ${IMPLICIT_DEPENDS} + INCLUDES ${ATOMUI_BINARY_INCLUDE_DIR} ${ATOMUI_INCLUDE_DIR} ${_arg_INCLUDES} + DEFINES ${_arg_DEFINES} ${TEST_DEFINES} ${default_defines_copy} + ) + + set_target_properties(${test_name} PROPERTIES + LINK_DEPENDS_NO_SHARED ON + CXX_VISIBILITY_PRESET hidden + VISIBILITY_INLINES_HIDDEN ON + BUILD_RPATH "${_RPATH_BASE}/${_RPATH};${CMAKE_BUILD_RPATH}" + INSTALL_RPATH "${_RPATH_BASE}/${_RPATH};${CMAKE_INSTALL_RPATH}" + ) + + # libpthreads overrides some standard library symbols, so main + # executable must be linked with it in order to provide consistent + # API for all shared libaries loaded by this executable. + if (_arg_GTEST) + list(APPEND _link_libs + GoogleTest + # GTest::gtest_main + # GTest::gtest + # GTest::gmock + # GTest::gmock_main + ${ATOMUI_PTHREAD_LIB}) + endif () + + target_link_libraries(${test_name} PRIVATE ${_link_libs}) + if (ATOMUI_COMPILE_FLAGS) + target_compile_options(${test_name} PRIVATE ${ATOMUI_COMPILE_FLAGS}) + endif () + + if (NOT TARGET ${test_suite}) + add_custom_target("${test_suite}") + set_target_properties(${test_suite} PROPERTIES FOLDER "Tests") + endif () + + add_dependencies(${test_suite} ${test_name}) + # 现在直接通过源码编译的方式引入 + # add_dependencies(${test_name} thirdparty_gtest) + get_target_property(test_suite_folder ${test_suite} FOLDER) + if (test_suite_folder) + set_property(TARGET ${test_name} PROPERTY FOLDER "${test_suite_folder}") + endif () + + if (NOT _arg_GTEST AND NOT _arg_MANUALTEST) + add_test(NAME ${test_name} COMMAND ${test_name}) + if (DEFINED _arg_TIMEOUT) + set(timeout_option TIMEOUT ${_arg_TIMEOUT}) + else () + set(timeout_option) + endif () + atomui_finalize_test_setup(${test_name} ${timeout_option}) + endif () +endfunction() \ No newline at end of file diff --git a/nativelibs/cmake/modules/Utils.cmake b/nativelibs/cmake/modules/Utils.cmake new file mode 100644 index 000000000..b9fb464ce --- /dev/null +++ b/nativelibs/cmake/modules/Utils.cmake @@ -0,0 +1,617 @@ +# This source file is part of the atomui project +# +# Copyright (c) 2017 - 2022 qinware, All rights reserved. +# Copyright (c) 2017 - 2022 chinboy +# +# See https://qinware.com/LICENSE.txt for license information +# +# Created by chinboy on 2025/01/10. + +include_guard(GLOBAL) +include(CheckCSourceCompiles) +include(CheckCCompilerFlag) +include(CheckCXXCompilerFlag) +include(CheckSymbolExists) + +# handle SCCACHE hack +# SCCACHE does not work with the /Zi option, which makes each compilation write debug info +# into the same .pdb file - even with /FS, which usually makes this work in the first place. +# Replace /Zi with /Z7, which leaves the debug info in the object files until link time. +# This increases memory usage, disk space usage and linking time, so should only be +# enabled if necessary. +# Must be called after project(...). +function(ATOMUI_WIN_HANDLE_sccache_support) + if (MSVC AND WITH_SCCACHE_SUPPORT) + foreach (config DEBUG RELWITHDEBINFO) + foreach (lang C CXX) + set(flags_var "CMAKE_${lang}_FLAGS_${config}") + string(REPLACE "/Zi" "/Z7" ${flags_var} "${${flags_var}}") + set(${flags_var} "${${flags_var}}" PARENT_SCOPE) + endforeach () + endforeach () + endif () +endfunction() + +function(atomui_enable_release_for_debug_configuration) + if (MSVC) + string(REPLACE "/Od" "/O2" CMAKE_CXX_FLAGS_DEBUG "${CMAKE_CXX_FLAGS_DEBUG}") + string(REPLACE "/Ob0" "/Ob1" CMAKE_CXX_FLAGS_DEBUG "${CMAKE_CXX_FLAGS_DEBUG}") + string(REPLACE "/RTC1" "" CMAKE_CXX_FLAGS_DEBUG "${CMAKE_CXX_FLAGS_DEBUG}") + else () + set(CMAKE_CXX_FLAGS_DEBUG "${CMAKE_CXX_FLAGS_DEBUG} -O2") + endif () + set(CMAKE_CXX_FLAGS_DEBUG "${CMAKE_CXX_FLAGS_DEBUG}" PARENT_SCOPE) +endfunction() + +function(atomui_enable_sanitize _sanitize_flags) + if (CMAKE_CXX_COMPILER_ID MATCHES "Clang" OR CMAKE_CXX_COMPILER_ID STREQUAL "GNU") + set(CMAKE_CXX_FLAGS_DEBUG "${CMAKE_CXX_FLAGS_DEBUG} -fsanitize=${_sanitize_flags}") + endif () + set(CMAKE_CXX_FLAGS_DEBUG "${CMAKE_CXX_FLAGS_DEBUG}" PARENT_SCOPE) +endfunction() + +function(atomui_update_cached_list name value) + set(_tmp_list "${${name}}") + list(APPEND _tmp_list "${value}") + set("${name}" "${_tmp_list}" CACHE INTERNAL "*** Internal ***") +endfunction() + +function(atomui_set_public_headers target sources) + foreach (source IN LISTS sources) + if (source MATCHES "\.h$|\.hpp$") + atomui_add_public_header(${source}) + endif () + endforeach () +endfunction() + +function(atomui_set_public_includes target includes) + foreach (inc_dir IN LISTS includes) + if (NOT IS_ABSOLUTE ${inc_dir}) + set(inc_dir "${CMAKE_CURRENT_SOURCE_DIR}/${inc_dir}") + endif () + file(RELATIVE_PATH include_dir_relative_path ${PROJECT_SOURCE_DIR} ${inc_dir}) + target_include_directories(${target} PUBLIC + $ + $ + ) + endforeach () +endfunction() + +function(atomui_finalize_test_setup test_name) + cmake_parse_arguments(_arg "" "TIMEOUT" "" ${ARGN}) + if (DEFINED _arg_TIMEOUT) + set(timeout ${_arg_TIMEOUT}) + else () + set(timeout 5) + endif () + # Never translate tests: + set_tests_properties(${name} + PROPERTIES + TIMEOUT ${timeout} + ) + + if (WIN32) + list(APPEND env_path $ENV{PATH}) + list(APPEND env_path ${CMAKE_BINARY_DIR}/${_ATOMUI_PLUGIN_PATH}) + list(APPEND env_path ${CMAKE_BINARY_DIR}/${_ATOMUI_BIN_PATH}) + + string(REPLACE "/" "\\" env_path "${env_path}") + string(REPLACE ";" "\\;" env_path "${env_path}") + + set_tests_properties(${test_name} PROPERTIES ENVIRONMENT "PATH=${env_path}") + endif () +endfunction() + +function(atomui_check_disabled_targets target_name dependent_targets) + foreach (dependency IN LISTS ${dependent_targets}) + foreach (type PLUGIN LIBRARY) + string(TOUPPER "BUILD_${type}_${dependency}" build_target) + if (DEFINED ${build_target} AND NOT ${build_target}) + message(SEND_ERROR "Target ${name} depends on ${dependency} which was disabled via ${build_target} set to ${${build_target}}") + endif () + endforeach () + endforeach () +endfunction() + +function(atomui_add_depends target_name) + cmake_parse_arguments(_arg "" "" "PRIVATE;PUBLIC" ${ARGN}) + if (${_arg_UNPARSED_ARGUMENTS}) + message(FATAL_ERROR "atomui_add_depends had unparsed arguments") + endif () + + atomui_check_disabled_targets(${target_name} _arg_PRIVATE) + atomui_check_disabled_targets(${target_name} _arg_PUBLIC) + + set(depends "${_arg_PRIVATE}") + set(public_depends "${_arg_PUBLIC}") + + get_target_property(target_type ${target_name} TYPE) + if (NOT target_type STREQUAL "OBJECT_LIBRARY") + target_link_libraries(${target_name} PRIVATE ${depends} PUBLIC ${public_depends}) + else () + list(APPEND object_lib_depends ${depends}) + list(APPEND object_public_depends ${public_depends}) + endif () + + foreach (obj_lib IN LISTS object_lib_depends) + target_compile_options(${target_name} PRIVATE $) + target_compile_definitions(${target_name} PRIVATE $) + target_include_directories(${target_name} PRIVATE $) + endforeach () + foreach (obj_lib IN LISTS object_public_depends) + target_compile_options(${target_name} PUBLIC $) + target_compile_definitions(${target_name} PUBLIC $) + target_include_directories(${target_name} PUBLIC $) + endforeach () +endfunction() + +function(atomui_find_dependent_plugins varName) + set(_RESULT ${ARGN}) + + foreach (i ${ARGN}) + get_property(_dep TARGET "${i}Plugin" PROPERTY _arg_DEPENDS) + if (_dep) + atomui_find_dependent_plugins(_REC ${_dep}) + list(APPEND _RESULT ${_REC}) + endif () + endforeach () + + if (_RESULT) + list(REMOVE_DUPLICATES _RESULT) + list(SORT _RESULT) + endif () + + set("${varName}" ${_RESULT} PARENT_SCOPE) +endfunction() + +function(atomui_condition_info varName condition) + if (NOT ${condition}) + set(${varName} "" PARENT_SCOPE) + else () + string(REPLACE ";" " " _contents "${${condition}}") + set(${varName} "with CONDITION ${_contents}" PARENT_SCOPE) + endif () +endfunction() + +function(atomui_extend_target target_name) + cmake_parse_arguments(_arg + "" + "SOURCES_PREFIX;SOURCES_PREFIX_FROM_TARGET;FEATURE_INFO" + "CONDITION;DEPENDS;PUBLIC_DEPENDS;DEFINES;PUBLIC_DEFINES;INCLUDES;PUBLIC_INCLUDES;SOURCES;PROPERTIES" + ${ARGN} + ) + + if (${_arg_UNPARSED_ARGUMENTS}) + message(FATAL_ERROR "atomui_extend_target had unparsed arguments") + endif () + + atomui_condition_info(_extra_text _arg_CONDITION) + if (NOT _arg_CONDITION) + set(_arg_CONDITION ON) + endif () + if (${_arg_CONDITION}) + set(_feature_enabled ON) + else () + set(_feature_enabled OFF) + endif () + if (_arg_FEATURE_INFO) + add_feature_info(${_arg_FEATURE_INFO} _feature_enabled "${_extra_text}") + endif () + if (NOT _feature_enabled) + return() + endif () + + if (_arg_SOURCES_PREFIX_FROM_TARGET) + if (NOT TARGET ${_arg_SOURCES_PREFIX_FROM_TARGET}) + return() + else () + get_target_property(_arg_SOURCES_PREFIX ${_arg_SOURCES_PREFIX_FROM_TARGET} SOURCES_DIR) + endif () + endif () + + atomui_add_depends(${target_name} + PRIVATE ${_arg_DEPENDS} + PUBLIC ${_arg_PUBLIC_DEPENDS} + ) + target_compile_definitions(${target_name} + PRIVATE ${_arg_DEFINES} + PUBLIC ${_arg_PUBLIC_DEFINES} + ) + target_include_directories(${target_name} PRIVATE ${_arg_INCLUDES}) + + atomui_set_public_includes(${target_name} "${_arg_PUBLIC_INCLUDES}") + + if (_arg_SOURCES_PREFIX) + foreach (source IN LISTS _arg_SOURCES) + list(APPEND prefixed_sources "${_arg_SOURCES_PREFIX}/${source}") + endforeach () + + if (NOT IS_ABSOLUTE ${_arg_SOURCES_PREFIX}) + set(_arg_SOURCES_PREFIX "${CMAKE_CURRENT_SOURCE_DIR}/${_arg_SOURCES_PREFIX}") + endif () + target_include_directories(${target_name} PRIVATE $) + + set(_arg_SOURCES ${prefixed_sources}) + endif () + target_sources(${target_name} PRIVATE ${_arg_SOURCES}) + + atomui_set_public_headers(${target_name} "${_arg_SOURCES}") + + if (_arg_PROPERTIES) + set_target_properties(${target_name} PROPERTIES ${_arg_PROPERTIES}) + endif () +endfunction() + +# list functions +function(atomui_list_subtract lhs rhs result_var_name) + set(result) + foreach (item IN LISTS lhs) + if (NOT "${item}" IN_LIST rhs) + list(APPEND result "${item}") + endif () + endforeach () + set("${result_var_name}" "${result}" PARENT_SCOPE) +endfunction() + +function(atomui_list_intersect lhs rhs result_var_name) + set(result) + foreach (item IN LISTS lhs) + if ("${item}" IN_LIST rhs) + list(APPEND result "${item}") + endif () + endforeach () + set("${result_var_name}" "${result}" PARENT_SCOPE) +endfunction() + +function(atomui_list_union lhs rhs result_var_name) + set(result) + foreach (item IN LISTS lhs rhs) + if (NOT "${item}" IN_LIST result) + list(APPEND result "${item}") + endif () + endforeach () + set("${result_var_name}" "${result}" PARENT_SCOPE) +endfunction() + +function(_list_add_string_suffix input_list suffix result_var_name) + set(result) + foreach (element ${input_list}) + list(APPEND result "${element}${suffix}") + endforeach () + set("${result_var_name}" "${result}" PARENT_SCOPE) +endfunction() + +function(_list_escape_for_shell input_list result_var_name) + set(result "") + foreach (element ${input_list}) + string(REPLACE " " "\\ " element "${element}") + set(result "${result}${element} ") + endforeach () + set("${result_var_name}" "${result}" PARENT_SCOPE) +endfunction() + +function(atomui_list_replace input_list old new) + set(replaced_list) + foreach (item ${${input_list}}) + if (${item} STREQUAL ${old}) + list(APPEND replaced_list ${new}) + else () + list(APPEND replaced_list ${item}) + endif () + endforeach () + set("${input_list}" "${replaced_list}" PARENT_SCOPE) +endfunction() + +macro(atomui_merge_list target list) + foreach (_listItem ${${list}}) + list(APPEND ${target} ${_listItem}) + endforeach () + if (target) + list(REMOVE_DUPLICATES ${target}) + endif () +endmacro() + +function(atomui_precondition var) + cmake_parse_arguments( + PRECONDITION # prefix + "NEGATE" # options + "MESSAGE" # single-value args + "" # multi-value args + ${ARGN}) + + if (PRECONDITION_NEGATE) + if (${var}) + if (PRECONDITION_MESSAGE) + message(FATAL_ERROR "Error! ${PRECONDITION_MESSAGE}") + else () + message(FATAL_ERROR "Error! Variable ${var} is true or not empty. The value of ${var} is ${${var}}.") + endif () + endif () + else () + if (NOT ${var}) + if (PRECONDITION_MESSAGE) + message(FATAL_ERROR "Error! ${PRECONDITION_MESSAGE}") + else () + message(FATAL_ERROR "Error! Variable ${var} is false, empty or not set.") + endif () + endif () + endif () +endfunction() + +# Assert is 'NOT ${LHS} ${OP} ${RHS}' is true. +function(atomui_precondition_binary_op OP LHS RHS) + cmake_parse_arguments( + PRECONDITIONBINOP # prefix + "NEGATE" # options + "MESSAGE" # single-value args + "" # multi-value args + ${ARGN}) + + if (PRECONDITIONBINOP_NEGATE) + if (${LHS} ${OP} ${RHS}) + if (PRECONDITIONBINOP_MESSAGE) + message(FATAL_ERROR "Error! ${PRECONDITIONBINOP_MESSAGE}") + else () + message(FATAL_ERROR "Error! ${LHS} ${OP} ${RHS} is true!") + endif () + endif () + else () + if (NOT ${LHS} ${OP} ${RHS}) + if (PRECONDITIONBINOP_MESSAGE) + message(FATAL_ERROR "Error! ${PRECONDITIONBINOP_MESSAGE}") + else () + message(FATAL_ERROR "Error! ${LHS} ${OP} ${RHS} is false!") + endif () + endif () + endif () +endfunction() + +# Translate a yes/no variable to the presence of a given string in a +# variable. +# +# Usage: +# atomui_translate_flag(is_set flag_name var_name) +# +# If is_set is true, sets ${var_name} to ${flag_name}. Otherwise, +# unsets ${var_name}. +function(atomui_translate_flag is_set flag_name var_name) + if (${is_set}) + set("${var_name}" "${flag_name}" PARENT_SCOPE) + else () + set("${var_name}" "" PARENT_SCOPE) + endif () +endfunction() + +macro(atomui_translate_flags prefix options) + foreach (var ${options}) + atomui_translate_flag("${${prefix}_${var}}" "${var}" "${prefix}_${var}_keyword") + endforeach () +endmacro() + +# Set ${outvar} to ${${invar}}, asserting if ${invar} is not set. +function(atomui_precondition_translate_flag invar outvar) + atomui_precondition(${invar}) + set(${outvar} "${${invar}}" PARENT_SCOPE) +endfunction() + +# Set variable to value if value is not null or false. Otherwise set variable to +# default_value. +function(atomui_set_with_default variable value) + cmake_parse_argument( + SWD + "" + "DEFAULT" + "" ${ARGN}) + atomui_precondition(SWD_DEFAULT + MESSAGE "Must specify a default argument") + if (value) + set(${variable} ${value} PARENT_SCOPE) + else () + set(${variable} ${SWD_DEFAULT} PARENT_SCOPE) + endif () +endfunction() + +function(atomui_dump_vars) + set(ATOMUI_STDLIB_GLOBAL_CMAKE_CACHE) + get_cmake_property(variableNames VARIABLES) + foreach (variableName ${variableNames}) + if (variableName MATCHES "^ATOMUI") + set(ATOMUI_STDLIB_GLOBAL_CMAKE_CACHE "${ATOMUI_STDLIB_GLOBAL_CMAKE_CACHE}set(${variableName} \"${${variableName}}\")\n") + message("set(${variableName} \"${${variableName}}\")") + endif () + endforeach () +endfunction() + +# +# Look for either a program in execute_process()'s path or for a hardcoded path. +# Find a program's version and set it in the parent scope. +# Replace newlines with spaces so it prints on one line. +# +function(atomui_find_version cmd flag find_in_path) + if (find_in_path) + message(STATUS "Finding installed version for: ${cmd}") + else () + message(STATUS "Finding version for: ${cmd}") + endif () + execute_process( + COMMAND ${cmd} ${flag} + OUTPUT_VARIABLE out + OUTPUT_STRIP_TRAILING_WHITESPACE) + if (NOT out) + if (find_in_path) + message(STATUS "tried to find version for ${cmd}, but ${cmd} not found in path, continuing") + else () + message(FATAL_ERROR "tried to find version for ${cmd}, but ${cmd} not found") + endif () + else () + string(REPLACE "\n" " " out2 ${out}) + message(STATUS "Found version: ${out2}") + endif () + message(STATUS "") +endfunction() + +function(atomui_append_flag value) + foreach (variable ${ARGN}) + set(${variable} "${${variable}} ${value}" PARENT_SCOPE) + endforeach (variable) +endfunction() + +function(atomui_append_flag_if condition value) + if (${condition}) + foreach (variable ${ARGN}) + set(${variable} "${${variable}} ${value}" PARENT_SCOPE) + endforeach (variable) + endif () +endfunction() + +macro(atomui_add_flag_if_supported flag name) + check_c_compiler_flag("-Werror ${flag}" "C_SUPPORTS_${name}") + atomui_append_flag_if("C_SUPPORTS_${name}" "${flag}" CMAKE_C_FLAGS) + check_cxx_compiler_flag("-Werror ${flag}" "CXX_SUPPORTS_${name}") + atomui_append_flag_if("CXX_SUPPORTS_${name}" "${flag}" CMAKE_CXX_FLAGS) +endmacro() + +function(atomui_add_flag_or_print_warning flag name) + check_c_compiler_flag("-Werror ${flag}" "C_SUPPORTS_${name}") + check_cxx_compiler_flag("-Werror ${flag}" "CXX_SUPPORTS_${name}") + if (C_SUPPORTS_${name} AND CXX_SUPPORTS_${name}) + message(STATUS "Building with ${flag}") + set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} ${flag}" PARENT_SCOPE) + set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} ${flag}" PARENT_SCOPE) + set(CMAKE_ASM_FLAGS "${CMAKE_ASM_FLAGS} ${flag}" PARENT_SCOPE) + else () + message(WARNING "${flag} is not supported.") + endif () +endfunction() + +function(atomui_add_files target) + list(REMOVE_AT ARGV 0) + foreach (file ${ARGV}) + list(APPEND ${target} ${CMAKE_CURRENT_SOURCE_DIR}/${file}) + endforeach () + set(${target} ${${target}} PARENT_SCOPE) +endfunction() + +function(atomui_generate_header_guard filename output) + string(TOUPPER ${filename} filename) + string(REPLACE "." "_" filename ${filename}) + string(REPLACE "/" "_" filename ${filename}) + set(${output} HAVE_${filename} PARENT_SCOPE) +endfunction() + +function(atomui_define_have name) + atomui_generate_header_guard(${name} haveName) + set(${haveName} ON PARENT_SCOPE) +endfunction() + +macro(atomui_find_parent_dir path output) + get_filename_component(${output} ${path} ABSOLUTE) + get_filename_component(${output} ${${output}} DIRECTORY) +endmacro() + +macro(atomui_add_rt_require_lib name) + list(APPEND ATOMUI_RT_REQUIRE_LIBS ${name}) + if (NOT ${CMAKE_CURRENT_SOURCE_DIR} STREQUAL ${CMAKE_SOURCE_DIR}) + set(ATOMUI_RT_REQUIRE_LIBS ${ATOMUI_RT_REQUIRE_LIBS} PARENT_SCOPE) + endif () +endmacro() + +macro(atomui_check_library_exists library function location variable) + check_library_exists("${library}" "${function}" "${location}" "${variable}") + if (${${variable}}) + set(ATOMUI_${variable} ON) + endif () +endmacro() + +macro(atomui_check_symbol_exists symbol files variable) + check_symbol_exists("${symbol}" "${files}" "${variable}") + if (${${variable}}) + set(ATOMUI_${variable} ON) + endif () +endmacro() + +# Beware that there is no implementation of remove_llvm_definitions. + +macro(atomui_add_definitions) + # We don't want no semicolons on ATOMUI_DEFINITIONS: + foreach (arg ${ARGN}) + if (DEFINED ATOMUI_DEFINITIONS) + set(ATOMUI_DEFINITIONS "${ATOMUI_DEFINITIONS} ${arg}") + else () + set(ATOMUI_DEFINITIONS ${arg}) + endif () + endforeach (arg) + add_definitions(${ARGN}) +endmacro() + +macro(atomui_check_headers) + foreach (_filename ${ARGV}) + atomui_generate_header_guard(${_filename} _guardName) + check_include_file(${_filename} ${_guardName}) + if (${${_guardName}}) + set(ATOMUI_${_guardName} ON) + endif () + endforeach () +endmacro() + +macro(atomui_check_funcs) + foreach (_func ${ARGV}) + string(TOUPPER ${_func} upcase) + check_function_exists(${_func} HAVE_${upcase}) + if (${HAVE_${upcase}}) + set(ATOMUI_HAVE_${upcase} ON) + endif () + endforeach () +endmacro() + +# Set each output directory according to ${CMAKE_CONFIGURATION_TYPES}. +# Note: Don't set variables CMAKE_*_OUTPUT_DIRECTORY any more, +# or a certain builder, for eaxample, msbuild.exe, would be confused. +function(atomui_set_output_directory target) + cmake_parse_arguments(ARG "" "BINARY_DIR;LIBRARY_DIR" "" ${ARGN}) + + # module_dir -- corresponding to LIBRARY_OUTPUT_DIRECTORY. + # It affects output of add_library(MODULE). + if (WIN32 OR CYGWIN) + # DLL platform + set(module_dir ${ARG_BINARY_DIR}) + else () + set(module_dir ${ARG_LIBRARY_DIR}) + endif () + if (NOT "${CMAKE_CFG_INTDIR}" STREQUAL ".") + foreach (build_mode ${CMAKE_CONFIGURATION_TYPES}) + string(TOUPPER "${build_mode}" CONFIG_SUFFIX) + if (ARG_BINARY_DIR) + string(REPLACE ${CMAKE_CFG_INTDIR} ${build_mode} bi ${ARG_BINARY_DIR}) + set_target_properties(${target} PROPERTIES "RUNTIME_OUTPUT_DIRECTORY_${CONFIG_SUFFIX}" ${bi}) + endif () + if (ARG_LIBRARY_DIR) + string(REPLACE ${CMAKE_CFG_INTDIR} ${build_mode} li ${ARG_LIBRARY_DIR}) + set_target_properties(${target} PROPERTIES "ARCHIVE_OUTPUT_DIRECTORY_${CONFIG_SUFFIX}" ${li}) + endif () + if (module_dir) + string(REPLACE ${CMAKE_CFG_INTDIR} ${build_mode} mi ${module_dir}) + set_target_properties(${target} PROPERTIES "LIBRARY_OUTPUT_DIRECTORY_${CONFIG_SUFFIX}" ${mi}) + endif () + endforeach () + else () + if (ARG_BINARY_DIR) + set_target_properties(${target} PROPERTIES RUNTIME_OUTPUT_DIRECTORY ${ARG_BINARY_DIR}) + endif () + if (ARG_LIBRARY_DIR) + set_target_properties(${target} PROPERTIES ARCHIVE_OUTPUT_DIRECTORY ${ARG_LIBRARY_DIR}) + endif () + if (module_dir) + set_target_properties(${target} PROPERTIES LIBRARY_OUTPUT_DIRECTORY ${module_dir}) + endif () + endif () +endfunction() + +function(atomui_set_if_target var target) + if (TARGET "${target}") + set(_result ON) + else () + set(_result OFF) + endif () + set(${var} "${_result}" PARENT_SCOPE) +endfunction() \ No newline at end of file diff --git a/nativelibs/include/atomui/CMakeLists.txt b/nativelibs/include/atomui/CMakeLists.txt new file mode 100644 index 000000000..9a2bb089a --- /dev/null +++ b/nativelibs/include/atomui/CMakeLists.txt @@ -0,0 +1,10 @@ +# This source file is part of the atomui project +# +# Copyright (c) 2017 - 2022 qinware, All rights reserved. +# Copyright (c) 2017 - 2022 chinboy +# +# See https://qinware.com/LICENSE.txt for license information +# +# Created by chinboy on 2025/01/10. + +configure_file(Config.h.in ${CMAKE_CURRENT_BINARY_DIR}/Config.h ESCAPE_QUOTES) \ No newline at end of file diff --git a/nativelibs/include/atomui/Config.h.in b/nativelibs/include/atomui/Config.h.in index e3843b630..c9ec209c1 100644 --- a/nativelibs/include/atomui/Config.h.in +++ b/nativelibs/include/atomui/Config.h.in @@ -11,14 +11,14 @@ #include "atomui/Compiler.h" -#define ATOMUI_VERSION_MAJOR ${VERSION_MAJOR} -#define ATOMUI_VERSION_MINOR ${VERSION_MINOR} -#define ATOMUI_VERSION_PATCH ${VERSION_ALTER} -#define ATOMUI_VERSION_BUILD ${VERSION_BUILD} +#define ATOMUI_VERSION_MAJOR ${PROJECT_VERSION_MAJOR} +#define ATOMUI_VERSION_MINOR ${PROJECT_VERSION_MINOR} +#define ATOMUI_VERSION_PATCH ${PROJECT_VERSION_PATCH} +#define ATOMUI_VERSION_BUILD "${ATOMUI_VERSION_BUILD}" namespace atomui { -const char ATOMUI_VERSION_LONG[] = "${VERSION}"; +const char ATOMUI_VERSION_LONG[] = "${PROJECT_VERSION}"; const char ATOMUI_AUTHOR[] = "Qinware Technologies Ltd."; const char ATOMUI_YEAR[] = "${ATOMUI_COPYRIGHT_YEAR}"; diff --git a/nativelibs/src/CMakeLists.txt b/nativelibs/src/CMakeLists.txt new file mode 100644 index 000000000..17599c868 --- /dev/null +++ b/nativelibs/src/CMakeLists.txt @@ -0,0 +1,37 @@ +# This source file is part of the atomui project +# +# Copyright (c) 2017 - 2022 qinware, All rights reserved. +# Copyright (c) 2017 - 2022 chinboy +# +# See https://qinware.com/LICENSE.txt for license information +# +# Created by chinboy on 2025/01/10. + +atomui_add_library(AtomUINative + BUILD_DEFAULT + SOURCES + Global.cpp + bridge/WindowUtils.cpp + ${ATOMUI_INCLUDE_DIR}/atomui/WindowUtils.h +) + +atomui_extend_library(AtomUINative CONDITION APPLE + SOURCES + macos/WindowUtils.mm + DEPENDS + ${FWFoundation} ${FWAppKit} +) + +atomui_extend_library(AtomUINative CONDITION WIN32 + SOURCES + windows/WindowUtils.cpp +) + +atomui_extend_library(AtomUINative CONDITION LINUX + SOURCES + linux/WindowUtils.cpp + DEPENDS + PkgConfig::XCB + INCLUDES ${XCB_INCLUDE_DIRS} +) + diff --git a/packages/AtomUI/AtomUI.csproj b/packages/AtomUI/AtomUI.csproj index 122839372..b905eb5ce 100644 --- a/packages/AtomUI/AtomUI.csproj +++ b/packages/AtomUI/AtomUI.csproj @@ -1,7 +1,5 @@  - - $(AtomUIDevelopTargetFramework);$(AtomUIProductionTargetFramework) enable @@ -38,9 +36,6 @@ $(IncludeAssets) - - $(IncludeAssets) - $(IncludeAssets) @@ -59,16 +54,9 @@ - - - $(OutputPathWithoutFramework)/$(AtomUINativeWindowsX64DeployPath)/$(AtomUINativeWindowsArtifactName) - $(OutputPathWithoutFramework)/$(AtomUINativeMacOSDeployPath)/$(AtomUINativeMacOSArtifactName) - $(OutputPathWithoutFramework)/$(AtomUINativeLinuxX64DeployPath)/$(AtomUINativeLinuxArtifactName) - - $(TargetsForTfmSpecificContentInPackage);IncludeReferencedProjectInPackage @@ -86,36 +74,13 @@ - - - - - $(AtomUINativeMacOSDeployPath)/$(AtomUINativeMacOSArtifactName) - $(AtomUINativeMacOSDeployPath) - true - PreserveNewest - - - $(AtomUINativeWindowsX64DeployPath)/$(AtomUINativeWindowsArtifactName) - $(AtomUINativeWindowsX64DeployPath) - true - PreserveNewest - - - - $(AtomUINativeLinuxX64DeployPath)/$(AtomUINativeLinuxArtifactName) - $(AtomUINativeLinuxX64DeployPath) - true - PreserveNewest - - + + + diff --git a/scripts/BuildAtomUINative.ps1 b/scripts/BuildAtomUINative.ps1 index ed2d29437..9b791004d 100644 --- a/scripts/BuildAtomUINative.ps1 +++ b/scripts/BuildAtomUINative.ps1 @@ -38,24 +38,22 @@ $env:XMAKE_COLORTERM = 'nocolor' $buildType = $buildType.ToLower() if ($IsWindows) { - xmake config --toolchain=clang --project=$sourceDir --builddir=$buildDir -p msys -a x86_64 -m $buildType -v - xmake build - xmake install --installdir=$installPrefix - Copy-Item -Path $installPrefix/x86_64/lib/$libName -Destination $deployDir + + cmake -B $buildDir -S $sourceDir -DCMAKE_INSTALL_PREFIX="$installPrefix" -DCMAKE_BUILD_TYPE="$buildType" -G Ninja + cmake --build $buildDir + cmake --install $buildDir --config $buildType + Copy-Item -Path $installPrefix/bin/$libName -Destination $deployDir + } elseif ($IsMacOS) { - xmake config --project=$sourceDir --builddir=$buildDir -p macosx -a arm64 -m $buildType - xmake build - xmake install --installdir=$installPrefix - xmake config --project=$sourceDir --builddir=$buildDir -p macosx -a x86_64 -m $buildType - xmake build - xmake install --installdir=$installPrefix - Write-Output "generate universal binary" - lipo -create $installPrefix/arm64/lib/$libName $installPrefix/x86_64/lib/$libName -output $deployDir/$libName + cmake -B $buildDir -S $sourceDir -DCMAKE_INSTALL_PREFIX="$installPrefix" -DCMAKE_BUILD_TYPE="$buildType" -G Ninja -DCMAKE_OSX_ARCHITECTURES="arm64;x86_64" + cmake --build $buildDir + cmake --install $buildDir --config $buildType + Copy-Item -Path $installPrefix/lib/$libName -Destination $deployDir } elseif ($IsLinux) { - xmake config --project=$sourceDir --builddir=$buildDir -p linux -a x86_64 -m $buildType - xmake build - xmake install --installdir=$installPrefix - Copy-Item -Path $installPrefix/x86_64/lib/$libName -Destination $deployDir + cmake -B $buildDir -S $sourceDir -DCMAKE_INSTALL_PREFIX="$installPrefix" -DCMAKE_BUILD_TYPE="$buildType" + cmake --build $buildDir + cmake --install $buildDir --config $buildType + Copy-Item -Path $installPrefix/lib/$libName -Destination $deployDir } else { $osInfo = $PSVersionTable.OS throw "Unsupported operating system: $osInfo. Only supported on Windows, Linux or macOS." diff --git a/scripts/PublishToLocalSources.ps1 b/scripts/PublishToLocalSources.ps1 index 913176c28..aabbc745a 100644 --- a/scripts/PublishToLocalSources.ps1 +++ b/scripts/PublishToLocalSources.ps1 @@ -42,6 +42,10 @@ function Push-NuGetPackages { } } +dotnet build -v diag --configuration $buildType ../src/AtomUI.Native/AtomUI.Native.csproj +dotnet pack --no-build --configuration $buildType ../src/AtomUI.Native/AtomUI.Native.csproj -v:diag +Push-NuGetPackages -Source $localSourcesDir + dotnet build -v diag --configuration $buildType ../packages/AtomUI/AtomUI.csproj dotnet pack --no-build --configuration $buildType ../packages/AtomUI/AtomUI.csproj dotnet pack --no-build --configuration $buildType ../src/AtomUI.IconPkg.Generator/AtomUI.IconPkg.Generator.csproj diff --git a/src/AtomUI.Base/AtomUI.Base.csproj b/src/AtomUI.Base/AtomUI.Base.csproj index 93a216ecf..7a64efe6e 100644 --- a/src/AtomUI.Base/AtomUI.Base.csproj +++ b/src/AtomUI.Base/AtomUI.Base.csproj @@ -9,6 +9,7 @@ + @@ -19,9 +20,5 @@ - - - - diff --git a/src/AtomUI.Controls/GeneratedFiles/AtomUI.Generator/AtomUI.Generator.TokenResourceKeyGenerator/TokenResourceConst.g.cs b/src/AtomUI.Controls/GeneratedFiles/AtomUI.Generator/AtomUI.Generator.TokenResourceKeyGenerator/TokenResourceConst.g.cs index 634926319..517a743fc 100644 --- a/src/AtomUI.Controls/GeneratedFiles/AtomUI.Generator/AtomUI.Generator.TokenResourceKeyGenerator/TokenResourceConst.g.cs +++ b/src/AtomUI.Controls/GeneratedFiles/AtomUI.Generator/AtomUI.Generator.TokenResourceKeyGenerator/TokenResourceConst.g.cs @@ -88,18 +88,6 @@ namespace AtomUI.Theme.Styling public static readonly TokenResourceKey TextFontWeight = new TokenResourceKey("Badge.TextFontWeight"); } - public static class ButtonSpinnerTokenKey - { - public static readonly TokenResourceKey ControlWidth = new TokenResourceKey("ButtonSpinner.ControlWidth"); - public static readonly TokenResourceKey FilledHandleBg = new TokenResourceKey("ButtonSpinner.FilledHandleBg"); - public static readonly TokenResourceKey HandleActiveBg = new TokenResourceKey("ButtonSpinner.HandleActiveBg"); - public static readonly TokenResourceKey HandleBg = new TokenResourceKey("ButtonSpinner.HandleBg"); - public static readonly TokenResourceKey HandleBorderColor = new TokenResourceKey("ButtonSpinner.HandleBorderColor"); - public static readonly TokenResourceKey HandleHoverColor = new TokenResourceKey("ButtonSpinner.HandleHoverColor"); - public static readonly TokenResourceKey HandleIconSize = new TokenResourceKey("ButtonSpinner.HandleIconSize"); - public static readonly TokenResourceKey HandleWidth = new TokenResourceKey("ButtonSpinner.HandleWidth"); - } - public static class ButtonTokenKey { public static readonly TokenResourceKey BorderColorDisabled = new TokenResourceKey("Button.BorderColorDisabled"); @@ -151,6 +139,18 @@ namespace AtomUI.Theme.Styling public static readonly TokenResourceKey TextHoverBg = new TokenResourceKey("Button.TextHoverBg"); } + public static class ButtonSpinnerTokenKey + { + public static readonly TokenResourceKey ControlWidth = new TokenResourceKey("ButtonSpinner.ControlWidth"); + public static readonly TokenResourceKey FilledHandleBg = new TokenResourceKey("ButtonSpinner.FilledHandleBg"); + public static readonly TokenResourceKey HandleActiveBg = new TokenResourceKey("ButtonSpinner.HandleActiveBg"); + public static readonly TokenResourceKey HandleBg = new TokenResourceKey("ButtonSpinner.HandleBg"); + public static readonly TokenResourceKey HandleBorderColor = new TokenResourceKey("ButtonSpinner.HandleBorderColor"); + public static readonly TokenResourceKey HandleHoverColor = new TokenResourceKey("ButtonSpinner.HandleHoverColor"); + public static readonly TokenResourceKey HandleIconSize = new TokenResourceKey("ButtonSpinner.HandleIconSize"); + public static readonly TokenResourceKey HandleWidth = new TokenResourceKey("ButtonSpinner.HandleWidth"); + } + public static class CalendarTokenKey { public static readonly TokenResourceKey CellActiveWithRangeBg = new TokenResourceKey("Calendar.CellActiveWithRangeBg"); diff --git a/src/AtomUI.Native/AtomUI.Native.csproj b/src/AtomUI.Native/AtomUI.Native.csproj index 4ed852468..3f135787f 100644 --- a/src/AtomUI.Native/AtomUI.Native.csproj +++ b/src/AtomUI.Native/AtomUI.Native.csproj @@ -5,6 +5,7 @@ enable enable true + true @@ -16,13 +17,20 @@ + + $(OutputPathWithoutFramework)/$(AtomUINativeWindowsX64DeployPath)/$(AtomUINativeWindowsArtifactName) + $(OutputPathWithoutFramework)/$(AtomUINativeWindowsArm64DeployPath)/$(AtomUINativeWindowsArtifactName) + $(OutputPathWithoutFramework)/$(AtomUINativeMacOSDeployPath)/$(AtomUINativeMacOSArtifactName) + $(OutputPathWithoutFramework)/$(AtomUINativeLinuxX64DeployPath)/$(AtomUINativeLinuxArtifactName) + + $([System.IO.Path]::Combine($(MSBuildProjectDirectory), $(IntermediateOutputPathWithoutFramework), 'AtomUINative')) $([System.IO.Path]::GetFullPath('$(MSBuildProjectDirectory)/../../nativelibs')) $([System.IO.Path]::GetFullPath('$(OutputPathWithoutFramework)')) $(OutputPathWithoutFramework)/$(AtomUINativeDeployPath) $([System.IO.Path]::GetFullPath('$(MSBuildProjectDirectory)/../../scripts/BuildAtomUINative.ps1')) - + $(AtomUINavtiveBuildPath)/.native_compiled @@ -44,6 +52,7 @@ + $([System.Environment]::ProcessorCount) - + @@ -63,7 +72,40 @@ - + + + + $(AtomUINativeMacOSDeployPath)/$(AtomUINativeMacOSArtifactName) + $(AtomUINativeMacOSDeployPath) + true + PreserveNewest + + + $(AtomUINativeWindowsX64DeployPath)/$(AtomUINativeWindowsArtifactName) + $(AtomUINativeWindowsX64DeployPath) + true + PreserveNewest + + + + $(AtomUINativeWindowsArm64DeployPath)/$(AtomUINativeWindowsArtifactName) + $(AtomUINativeWindowsArm64DeployPath) + true + PreserveNewest + + + + $(AtomUINativeLinuxX64DeployPath)/$(AtomUINativeLinuxArtifactName) + $(AtomUINativeLinuxX64DeployPath) + true + PreserveNewest + + + \ No newline at end of file