Skip to content

Commit

Permalink
build: add cmake support
Browse files Browse the repository at this point in the history
  • Loading branch information
ksqsf committed Nov 10, 2024
1 parent 9373cf2 commit 10a85e7
Show file tree
Hide file tree
Showing 23 changed files with 270 additions and 13 deletions.
19 changes: 19 additions & 0 deletions .github/workflows/cmake-ci.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
name: cmake ci
on: [workflow_dispatch]
jobs:
build:
runs-on: macos-14
steps:
- name: Checkout last commit
uses: actions/checkout@v4
with:
submodules: recursive
- name: Configure build environment
run: |
brew install ninja rsync
- name: Build
run: |
make -Clibrime deps
bash librime/install-plugins.sh hchunhui/librime-lua lotem/librime-octagram rime/librime-predict
cmake -S. -Bbuild -GNinja -DCMAKE_OSX_DEPLOYMENT_TARGET=13 -DCMAKE_BUILD_TYPE=Release
ninja -Cbuild
20 changes: 10 additions & 10 deletions Assets.xcassets/RimeIcon.appiconset/Contents.json
Original file line number Diff line number Diff line change
@@ -1,61 +1,61 @@
{
"images" : [
{
"filename" : "rime-16 1.png",
"filename" : "icon-16x16.png",
"idiom" : "mac",
"scale" : "1x",
"size" : "16x16"
},
{
"filename" : "rime-32 1.png",
"filename" : "icon-16x16@2.png",
"idiom" : "mac",
"scale" : "2x",
"size" : "16x16"
},
{
"filename" : "rime-32.png",
"filename" : "icon-32x32.png",
"idiom" : "mac",
"scale" : "1x",
"size" : "32x32"
},
{
"filename" : "rime-64.png",
"filename" : "icon-32x32@2.png",
"idiom" : "mac",
"scale" : "2x",
"size" : "32x32"
},
{
"filename" : "rime-128.png",
"filename" : "icon-128x128.png",
"idiom" : "mac",
"scale" : "1x",
"size" : "128x128"
},
{
"filename" : "rime-256.png",
"filename" : "icon-128x128@2.png",
"idiom" : "mac",
"scale" : "2x",
"size" : "128x128"
},
{
"filename" : "rime-256.png",
"filename" : "icon-256x256.png",
"idiom" : "mac",
"scale" : "1x",
"size" : "256x256"
},
{
"filename" : "rime-512.png",
"filename" : "icon-256x256@2.png",
"idiom" : "mac",
"scale" : "2x",
"size" : "256x256"
},
{
"filename" : "rime-512.png",
"filename" : "icon-512x512.png",
"idiom" : "mac",
"scale" : "1x",
"size" : "512x512"
},
{
"filename" : "rime-1024.png",
"filename" : "icon-512x512@2.png",
"idiom" : "mac",
"scale" : "2x",
"size" : "512x512"
Expand Down
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
95 changes: 95 additions & 0 deletions CMakeLists.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,95 @@
cmake_minimum_required(VERSION 3.30)
project(squirrel VERSION 1.0.2 LANGUAGES CXX Swift)

list(APPEND CMAKE_MODULE_PATH "${CMAKE_CURRENT_SOURCE_DIR}/cmake")

# ##############################################################################
# Options
# ##############################################################################
set(DEV_ID "UNSET" CACHE STRING "Dev ID for code-signing")
set(SIGN_KEY "UNSET" CACHE STRING "Sign key for code-signing")
option(FIXUP_WHEN_BUILD "Fix-up the app bundle in build time" ON)

if(NOT (DEV_ID STREQUAL "UNSET") AND (SIGN_KEY STREQUAL "UNSET"))
set(SIGN_KEY "Developer ID Application: ${DEV_ID}")
endif()

# ##############################################################################
# Dependencies
# ##############################################################################
include(AddSparkle)
include(AddRime)

# ##############################################################################
# Squirrel.app
# ##############################################################################
file(GLOB SRCS "${PROJECT_SOURCE_DIR}/Sources/*.swift")
add_executable(Squirrel MACOSX_BUNDLE ${SRCS})
target_compile_options(Squirrel PRIVATE
-import-objc-header "${PROJECT_SOURCE_DIR}/Sources/Squirrel-Bridging-Header.h"
-enable-bare-slash-regex
)
target_include_directories(Squirrel PRIVATE
"${PROJECT_SOURCE_DIR}/Sources"
"${PROJECT_SOURCE_DIR}/librime/src"
)
target_link_libraries(Squirrel PRIVATE rime Sparkle)

set(BUNDLE_PATH "${PROJECT_BINARY_DIR}/Squirrel.app")
set(BUNDLE_CONTENTS_DIR "${BUNDLE_PATH}/Contents")
set(BUNDLE_BIN_DIR "${BUNDLE_CONTENTS_DIR}/MacOS")
set(BUNDLE_RESOURCES_DIR "${BUNDLE_CONTENTS_DIR}/Resources")
set(BUNDLE_FRAMEWORKS_DIR "${BUNDLE_CONTENTS_DIR}/Frameworks")
set(BUNDLE_SHARED_SUPPORT_DIR "${BUNDLE_CONTENTS_DIR}/SharedSupport")

set_target_properties(Squirrel PROPERTIES
MACOSX_BUNDLE_GUI_IDENTIFIER im.rime.inputmethod.Squirrel
MACOSX_BUNDLE_BUNDLE_VERSION ${CMAKE_PROJECT_VERSION}
)

# Copy additional binaries
file(GLOB RIME_PROGRAMS "${CMAKE_BINARY_DIR}/librime/bin/rime_*")
add_custom_command(TARGET Squirrel POST_BUILD
COMMAND cp -a "${CMAKE_BINARY_DIR}/librime/bin/rime_*" ${BUNDLE_BIN_DIR})

# Copy resources
add_subdirectory(resources)

# Copy built-in schemas
add_subdirectory(data)

# Copy linked frameworks and libraries
add_custom_command(TARGET Squirrel POST_BUILD
COMMAND rsync -a "${CMAKE_CURRENT_BINARY_DIR}/librime/lib/" "${BUNDLE_FRAMEWORKS_DIR}"
--exclude pkgconfig
)
add_custom_command(TARGET Squirrel POST_BUILD
COMMAND rsync -a "${CMAKE_BINARY_DIR}/Sparkle.framework"
"${BUNDLE_FRAMEWORKS_DIR}"
--exclude=Headers --exclude=PrivateHeaders --exclude=Modules
)

# Fix linking so that the bundle is standalone
set(FIXUP_SCRIPT ${CMAKE_CURRENT_BINARY_DIR}/fixup.cmake)
set(FIXUP_DIRS "${BUNDLE_FRAMEWORKS_DIR}")
file(WRITE ${FIXUP_SCRIPT} "
include(BundleUtilities)
file(GLOB PLUGINS ${BUNDLE_FRAMEWORKS_DIR}/rime-plugins/*.dylib)
fixup_bundle(\"${BUNDLE_PATH}\" \"\${PLUGINS}\" \"${FIXUP_DIRS}\")
")
if(${FIXUP_WHEN_BUILD})
add_custom_command(TARGET Squirrel POST_BUILD
COMMAND ${CMAKE_COMMAND} -P ${FIXUP_SCRIPT}
)
endif()

# Install (for development)
set(CMAKE_SKIP_RPATH TRUE) # done by fixup_bundle
install(SCRIPT ${FIXUP_SCRIPT})
install(CODE "execute_process(COMMAND ${CMAKE_COMMAND} --build ${CMAKE_BINARY_DIR} --target sign)")
install(TARGETS Squirrel BUNDLE DESTINATION "/Library/Input\ Methods")

# ##############################################################################
# Distribution
# ##############################################################################
add_subdirectory(package)
22 changes: 22 additions & 0 deletions INSTALL.md
Original file line number Diff line number Diff line change
Expand Up @@ -182,3 +182,25 @@ make clean-package
If you want to clean all above, do all.
That's it, a verbal journal. Thanks for riming with Squirrel.
## Build with CMake
Alternatively, Squirrel can be built with CMake.
(Note that universal binaries are not supported, and Xcode command line tools are still required.)
```sh
# Prepare librime
make -Clibrime deps
bash librime/install-plugins.sh hchunhui/librime-lua lotem/librime-octagram rime/librime-predict # and more...
# Build squirrel
cmake -S. -GNinja -Bbuild -DCMAKE_BUILD_TYPE=Release -DCMAKE_OSX_DEPLOYMENT_TARGET=13.0 -DDEV_ID='YourDevID'
cd build
ninja # Create build/Squirrel.app
ninja sign # Code-sign build/Squirrel.app (*)
ninja package # Create package/Squirrel.pkg (*)
ninja install # Directly install to '/Library/Input Methods' (*)
```
(*) `sign`, `install`, and `package` require code-signing `DEV_ID` or `SIGN_KEY` to be set. `SIGN_KEY` will take precedence over `DEV_ID`.
2 changes: 1 addition & 1 deletion action-install.sh
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@
set -e

rime_version=latest
rime_git_hash=24f0f7b
rime_git_hash=0cf0e63
sparkle_version=2.6.2

rime_archive="rime-${rime_git_hash}-macOS-universal.tar.bz2"
Expand Down
22 changes: 22 additions & 0 deletions cmake/AddRime.cmake
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
include(ExternalProject)

ExternalProject_Add(BuildRime
SOURCE_DIR "${PROJECT_SOURCE_DIR}/librime"
INSTALL_DIR "${PROJECT_BINARY_DIR}/librime"
CMAKE_ARGS -DCMAKE_INSTALL_PREFIX=<INSTALL_DIR>
-DCMAKE_BUILD_TYPE=Release
-DCMAKE_OSX_DEPLOYMENT_TARGET=${CMAKE_OSX_DEPLOYMENT_TARGET}
-DCMAKE_OSX_ARCHITECTURES=${CMAKE_OSX_ARCHITECTURES}
-DBUILD_MERGED_PLUGINS=OFF
-DENABLE_EXTERNAL_PLUGINS=ON
-DBUILD_TEST=OFF
)

add_library(rime INTERFACE)
add_dependencies(rime BuildRime)
target_include_directories(rime INTERFACE "${PROJECT_BINARY_DIR}/librime/include")
target_link_directories(rime INTERFACE "${PROJECT_BINARY_DIR}/librime/lib/")
target_link_libraries(rime INTERFACE -lrime)

find_path(X11Keysym X11/keysym.h)
target_include_directories(rime INTERFACE ${X11Keysym})
18 changes: 18 additions & 0 deletions cmake/AddSparkle.cmake
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
include(ExternalProject)

ExternalProject_Add(BuildSparkle
SOURCE_DIR "${PROJECT_SOURCE_DIR}/Sparkle"

CONFIGURE_COMMAND ""

BUILD_COMMAND xcodebuild -project "<SOURCE_DIR>/Sparkle.xcodeproj" -scheme Sparkle -configuration Release
BUILD_IN_SOURCE TRUE

# Install Sparkle.framework
INSTALL_COMMAND cp -a "<SOURCE_DIR>/build/Release/Sparkle.framework" "${CMAKE_BINARY_DIR}"
)

add_library(Sparkle INTERFACE)
add_dependencies(Sparkle BuildSparkle)
target_include_directories(Sparkle INTERFACE "${CMAKE_BINARY_DIR}/Sparkle.framework/Headers")
target_link_libraries(Sparkle INTERFACE "${CMAKE_BINARY_DIR}/Sparkle.framework")
10 changes: 10 additions & 0 deletions cmake/AppleUtils.cmake
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
macro(process_xcstrings path outdir)
get_filename_component(basename ${path} NAME_WLE)
set(target ${outdir}/en.lproj/${basename}.strings)
add_custom_command(
OUTPUT ${target}
COMMAND xcrun xcstringstool compile ${path} --output-directory ${outdir}
COMMENT "Process ${basename}.xcstrings"
)
add_custom_target(xcstrings_${basename} ALL DEPENDS ${target})
endmacro()
21 changes: 21 additions & 0 deletions data/CMakeLists.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
set(OUTDIR "${BUNDLE_SHARED_SUPPORT_DIR}")

# ##############################################################################
# Plum
# ##############################################################################
add_custom_command(
OUTPUT "${OUTDIR}/default.yaml"
COMMAND make "OUTPUT=${OUTDIR}" -C "${PROJECT_SOURCE_DIR}/plum"
COMMENT "plum: update default schemas")
add_custom_target(plum-data ALL
DEPENDS "${OUTDIR}/default.yaml")

# ##############################################################################
# OpenCC
# ##############################################################################
add_custom_command(
OUTPUT "${OUTDIR}/opencc/s2t.json"
COMMAND ${CMAKE_COMMAND} -E copy_directory ${PROJECT_SOURCE_DIR}/librime/share/opencc ${OUTDIR}/opencc
COMMENT "opencc: copy data")
add_custom_target(opencc-data ALL
DEPENDS "${OUTDIR}/opencc/s2t.json")
2 changes: 1 addition & 1 deletion librime
12 changes: 12 additions & 0 deletions package/CMakeLists.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
add_custom_target(sign
COMMAND codesign --deep --force --options runtime --timestamp --verbose
--entitlements "${PROJECT_SOURCE_DIR}/resources/Squirrel.entitlements"
--sign "${SIGN_KEY}" "${BUNDLE_PATH}"
DEPENDS Squirrel
)

add_custom_target(package
COMMAND ./make_package
WORKING_DIRECTORY "${CMAKE_CURRENT_SOURCE_DIR}"
DEPENDS sign
)
9 changes: 8 additions & 1 deletion package/make_package
Original file line number Diff line number Diff line change
Expand Up @@ -7,9 +7,16 @@ INSTALL_LOCATION='/Library/Input Methods'
cd "$(dirname $0)"
source common.sh

if [ -e "${PROJECT_ROOT}/build/Squirrel.app" ]; then
ROOT=`mktemp -d`
cp -a "${PROJECT_ROOT}/build/Squirrel.app" "$ROOT"
else
ROOT="${PROJECT_ROOT}/${DERIVED_DATA_PATH}/Build/Products/Release"
fi

pkgbuild \
--info PackageInfo \
--root "${PROJECT_ROOT}/${DERIVED_DATA_PATH}/Build/Products/Release" \
--root "$ROOT" \
--filter '.*\.swiftmodule$' \
--component-plist Squirrel-component.plist \
--identifier "${BUNDLE_IDENTIFIER}" \
Expand Down
31 changes: 31 additions & 0 deletions resources/CMakeLists.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
# Info.plist
file(READ "${CMAKE_CURRENT_SOURCE_DIR}/Info.plist" INFO_PLIST)
string(REPLACE "$(PRODUCT_BUNDLE_IDENTIFIER)" "@MACOSX_BUNDLE_GUI_IDENTIFIER@" INFO_PLIST "${INFO_PLIST}")
string(REPLACE "$(CURRENT_PROJECT_VERSION)" "@MACOSX_BUNDLE_BUNDLE_VERSION@" INFO_PLIST "${INFO_PLIST}")
file(WRITE "${CMAKE_CURRENT_BINARY_DIR}/Info.plist" "${INFO_PLIST}")
set_target_properties(Squirrel PROPERTIES
MACOSX_BUNDLE_INFO_PLIST ${CMAKE_CURRENT_BINARY_DIR}/Info.plist
)

# Static resources
set(FILES
${PROJECT_SOURCE_DIR}/README.md
${PROJECT_SOURCE_DIR}/LICENSE.txt
rime.pdf
)
foreach(f ${FILES})
get_filename_component(filename ${f} NAME)
configure_file(${f} ${BUNDLE_RESOURCES_DIR}/${filename} COPYONLY)
endforeach()

# Localization
include(AppleUtils)
process_xcstrings(${CMAKE_CURRENT_SOURCE_DIR}/Localizable.xcstrings ${BUNDLE_RESOURCES_DIR})
process_xcstrings(${CMAKE_CURRENT_SOURCE_DIR}/InfoPlist.xcstrings ${BUNDLE_RESOURCES_DIR})

# RimeIcon.icns
add_custom_command(
OUTPUT ${BUNDLE_RESOURCES_DIR}/RimeIcon.icns
COMMAND ${CMAKE_COMMAND} -E copy_directory ${PROJECT_SOURCE_DIR}/Assets.xcassets/RimeIcon.appiconset ${CMAKE_BINARY_DIR}/RimeIcon.iconset && iconutil -c icns ${CMAKE_BINARY_DIR}/RimeIcon.iconset -o ${BUNDLE_RESOURCES_DIR}/RimeIcon.icns
)
add_custom_target(RimeIcon.icns ALL DEPENDS ${BUNDLE_RESOURCES_DIR}/RimeIcon.icns)

0 comments on commit 10a85e7

Please sign in to comment.