diff --git a/.gitignore b/.gitignore index 9654a3c6a..568870213 100644 --- a/.gitignore +++ b/.gitignore @@ -1,6 +1,8 @@ .DS_* ._* *.AppImage +*.app +*.dmg *.directory *.swp *.swo diff --git a/Makefile b/Makefile index 570806983..e323a0972 100644 --- a/Makefile +++ b/Makefile @@ -14,7 +14,7 @@ endif # releases do not contain tests and misc data IS_RELEASE := $(if $(or $(EMULATE_READER),$(WIN32)),,1) -IS_RELEASE := $(if $(or $(IS_RELEASE),$(APPIMAGE),$(DEBIAN)),1,) +IS_RELEASE := $(if $(or $(IS_RELEASE),$(APPIMAGE),$(DEBIAN),$(MACOS)),1,) ANDROID_ARCH?=arm # Use the git commit count as the (integer) Android version code @@ -50,6 +50,7 @@ CERVANTES_DIR=$(PLATFORM_DIR)/cervantes DEBIAN_DIR=$(PLATFORM_DIR)/debian KINDLE_DIR=$(PLATFORM_DIR)/kindle KOBO_DIR=$(PLATFORM_DIR)/kobo +MACOS_DIR=$(PLATFORM_DIR)/mac POCKETBOOK_DIR=$(PLATFORM_DIR)/pocketbook REMARKABLE_DIR=$(PLATFORM_DIR)/remarkable SONY_PRSTUX_DIR=$(PLATFORM_DIR)/sony-prstux @@ -399,6 +400,15 @@ debianupdate: all rm -rf \ $(INSTALL_DIR)/debian/usr/lib/koreader/{ota,cache,clipboard,screenshots,spec,tools,resources/fonts,resources/icons/src} +macosupdate: all + mkdir -p \ + $(INSTALL_DIR)/bundle/Contents/MacOS \ + $(INSTALL_DIR)/bundle/Contents/Resources + + cp $(MACOS_DIR)/koreader.sh $(INSTALL_DIR)/bundle/Contents/MacOS/koreader + cp resources/koreader.icns $(INSTALL_DIR)/bundle/Contents/Resources/icon.icns + cp -LR $(INSTALL_DIR)/koreader $(INSTALL_DIR)/bundle/Contents/Resources + REMARKABLE_PACKAGE:=koreader-remarkable$(KODEDUG_SUFFIX)-$(VERSION).zip REMARKABLE_PACKAGE_OTA:=koreader-remarkable$(KODEDUG_SUFFIX)-$(VERSION).targz remarkableupdate: all @@ -518,6 +528,9 @@ else ifeq ($(TARGET), debian-armel) else ifeq ($(TARGET), debian-armhf) make debianupdate $(CURDIR)/platform/debian/do_debian_package.sh $(INSTALL_DIR) armhf +else ifeq ($(TARGET), macos) + make macosupdate + $(CURDIR)/platform/mac/do_mac_bundle.sh $(INSTALL_DIR) endif androiddev: androidupdate diff --git a/base b/base index 0c326d6ee..b4124d64d 160000 --- a/base +++ b/base @@ -1 +1 @@ -Subproject commit 0c326d6eee1447dca6af507ea921551c06610f2d +Subproject commit b4124d64d4ea4403438f5a79e048f50e2f481f40 diff --git a/frontend/device/sdl/device.lua b/frontend/device/sdl/device.lua index 0a53a72b3..4bd0cd41a 100644 --- a/frontend/device/sdl/device.lua +++ b/frontend/device/sdl/device.lua @@ -18,13 +18,7 @@ end -- open is the macOS counterpart local function hasMacOpen() - local std_out = io.popen("open") - local all = nil - if std_out ~= nil then - all = std_out:read() - std_out:close() - end - return all ~= nil + return os.execute("open >/dev/null 2>&1") == 256 end -- get the name of the binary used to open links @@ -86,7 +80,11 @@ local Device = Generic:new{ openLink = function(self, link) local enabled, tool = getLinkOpener() if not enabled or not tool or not link or type(link) ~= "string" then return end - return os.execute('env -u LD_LIBRARY_PATH '..tool.." '"..link.."'") == 0 + if jit.os == "OSX" then + return os.execute(tool .. " '" .. link .. "'") == 0 + else + return os.execute('env -u LD_LIBRARY_PATH '..tool.." '"..link.."'") == 0 + end end, canExternalDictLookup = yes, getExternalDictLookupList = getExternalDicts, @@ -135,6 +133,11 @@ local Linux = Device:new{ isDesktop = yes, } +local Mac = Device:new{ + model = "Mac", + isDesktop = yes, +} + local UbuntuTouch = Device:new{ model = "UbuntuTouch", hasFrontlight = yes, @@ -356,7 +359,11 @@ end if os.getenv("APPIMAGE") then return AppImage elseif os.getenv("KO_MULTIUSER") then - return Linux + if jit.os == "OSX" then + return Mac + else + return Linux + end elseif os.getenv("UBUNTU_APPLICATION_ISOLATION") then return UbuntuTouch else diff --git a/kodev b/kodev index adfb9a1a8..b989678ed 100755 --- a/kodev +++ b/kodev @@ -1,5 +1,12 @@ #!/usr/bin/env bash +is_mac() { + if [ "$(uname -s)" != "Darwin" ]; then + echo "You need a mac to build this package" + exit 1 + fi +} + CURDIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)" VERSION=$(git describe HEAD) # Only append date if we're not on a whole version, like v2018.11 @@ -125,6 +132,7 @@ SUPPORTED_TARGETS=" debian Debian package for current arch debian-armel Debian package for generic armel devices debian-armhf Debian package for generic armhf devices + macos MacOS app bundle. You need a mac to build this package emu (*default) If no TARGET is given, assume emulator win32 " @@ -243,6 +251,11 @@ ${SUPPORTED_TARGETS}" make TARGET=debian-armhf assert_ret_zero $? ;; + macos) + is_mac + make TARGET=macos + assert_ret_zero $? + ;; win32) make TARGET=win32 assert_ret_zero $? @@ -335,6 +348,10 @@ ${SUPPORTED_TARGETS}" debian-armhf) make TARGET=debian-armhf clean ;; + macos) + is_mac + make TARGET=macos clean + ;; win32) make TARGET=win32 clean ;; @@ -468,6 +485,11 @@ ${SUPPORTED_RELEASE_TARGETS}" kodev-build debian-armhf make TARGET=debian-armhf update ;; + macos) + is_mac + kodev-build macos + make TARGET=macos update + ;; *) echo "Unsupported target for release: $1." echo "${RELEASE_HELP_MSG}" diff --git a/platform/mac/do_mac_bundle.sh b/platform/mac/do_mac_bundle.sh new file mode 100755 index 000000000..93e925093 --- /dev/null +++ b/platform/mac/do_mac_bundle.sh @@ -0,0 +1,106 @@ +#!/bin/bash +# Script to generate mac application bundles for KOReader + +command_exists() { + type "$1" >/dev/null 2>/dev/null +} + +if [ -z "${1}" ]; then + echo "${0}: can't find KOReader build, please specify a path" + exit 1 +else + INSTALL_DIR="${1}" + VERSION="$(cut -f2 -dv "${1}/koreader/git-rev" | cut -f1,2 -d-)" +fi + +cat <"${INSTALL_DIR}/bundle/Contents/Info.plist" + + + + + CFBundleGetInfoString + KOReader + CFBundleExecutable + koreader + CFBundleIdentifier + koreader.rocks + CFBundleName + KOReader + CFBundleShortVersionString + ${VERSION} + CFBundleInfoDictionaryVersion + 6.0 + CFBundlePackageType + APPL + CFBundleIconFile + icon + + +EOF + +APP_PATH="${INSTALL_DIR}/bundle" +APP_BUNDLE="${INSTALL_DIR}/../KOReader" + +# Use otool to change rpath of libraries. +# Along with libs, serialize.so in common also needs to be fixed +pushd "${INSTALL_DIR}/bundle/Contents/Resources/koreader" || exit 1 +for directory in common libs; do + directoryName=$(basename "${directory}") + echo "Checking ${directory}" + pushd "${directory}" || exit 1 + for libToCheck in *.so *.dylib; do + # there may be more than one library to fix, so get all of them and iterate + libsToChange=$(otool -L "${libToCheck}" | grep "Users.*x86_64" | tr -s " " | cut -f1 -d" ") + if [ -z "${libsToChange}" ]; then + echo "Nothing to do, skipping ${libToCheck}" + else + for libToChange in ${libsToChange}; do + fileNameOfLibToChange=$(basename "${libToChange}") + if [ "${libToCheck}" = "${fileNameOfLibToChange}" ]; then + echo "Skipping recursive ${libToChange} ${libToCheck}" + else + echo "Fixing ${libToCheck} ${libToChange}" + install_name_tool -change "${libToChange}" "${directoryName}/${fileNameOfLibToChange}" "${libToCheck}" + fi + done + fi + done + popd || exit 1 +done +popd || exit 1 + +# remove things from the bundle +rm -rf \ + "${APP_PATH}/Contents/Resources/koreader/cache" \ + "${APP_PATH}/Contents/Resources/koreader/clipboard" \ + "${APP_PATH}/Contents/Resources/koreader/history" \ + "${APP_PATH}/Contents/Resources/koreader/ota" \ + "${APP_PATH}/Contents/Resources/koreader/resources/fonts" \ + "${APP_PATH}/Contents/Resources/koreader/resources/icons/src" \ + "${APP_PATH}/Contents/Resources/koreader/resources/kobo-touch.probe.png" \ + "${APP_PATH}/Contents/Resources/koreader/resources/koreader.icns" \ + "${APP_PATH}/Contents/Resources/koreader/rocks/bin" \ + "${APP_PATH}/Contents/Resources/koreader/rocks/lib/luarocks" \ + "${APP_PATH}/Contents/Resources/koreader/screenshots" \ + "${APP_PATH}/Contents/Resources/koreader/spec" \ + "${APP_PATH}/Contents/Resources/koreader/tools" \ + "${APP_PATH}/Contents/Resources/koreader/README.md" + +mv \ + "${APP_PATH}/Contents/Resources/koreader/COPYING" \ + "${APP_PATH}/Contents/Resources/COPYING" + +ln -s /usr/bin/tar "${APP_PATH}/Contents/Resources/koreader/tar" + +# package as DMG if create-dmg is available +# reduces size from 80MB to 40MB +mv "${APP_PATH}" "${APP_BUNDLE}.app" +if command_exists "create-dmg"; then + # create KOReader-$VERSION.dmg with KOReader.app inside + create-dmg "${APP_BUNDLE}.app" --overwrite + # create-dmg fails because we omit codesign + exit 0 +else + # rename as KOReader-$VERSION.app + mv -v "${APP_BUNDLE}.app" "${APP_BUNDLE}-${VERSION}.app" +fi diff --git a/platform/mac/koreader.sh b/platform/mac/koreader.sh new file mode 100755 index 000000000..62f158b2a --- /dev/null +++ b/platform/mac/koreader.sh @@ -0,0 +1,21 @@ +#!/bin/bash +export LC_ALL="en_US.UTF-8" + +# writable storage: ${HOME}/.config/koreader. +export KO_MULTIUSER=1 + +# working directory of koreader +KOREADER_DIR="${0%/*}/../Resources/koreader" + +# we're always starting from our working directory +cd "${KOREADER_DIR}" || exit +RETURN_VALUE=85 +while [ ${RETURN_VALUE} -eq 85 ]; do + ./reader.lua "${ARGS}" + RETURN_VALUE=$? +done + +# remove the flag to avoid emulator confusion +export -n KO_MULTIUSER + +exit ${RETURN_VALUE} diff --git a/plugins/evernote.koplugin/main.lua b/plugins/evernote.koplugin/main.lua index e6f1ceadf..c1a861444 100644 --- a/plugins/evernote.koplugin/main.lua +++ b/plugins/evernote.koplugin/main.lua @@ -85,6 +85,7 @@ function EvernoteExporter:readyToExport() end function EvernoteExporter:migrateClippings() + if jit.os == "OSX" then return end local old_dir = util.joinPath(util.realpath(util.joinPath(self.path, "..")), "evernote.sdr") if lfs.attributes(old_dir, "mode") == "directory" then diff --git a/resources/koreader.icns b/resources/koreader.icns new file mode 100644 index 000000000..97dd63f0b Binary files /dev/null and b/resources/koreader.icns differ