chore(developer): Merge branch 'master' into fix/developer/12262-ensure-call-detects-invalid-store-in-kmcmplib-compiler

# Keyman Conventional Commit suggestions:
#
# - Link to a Sentry issue with git trailer:
#     Fixes: _MODULE_-_ID_
# - Give credit to co-authors:
#     Co-authored-by: _Name_ <_email_>
# - Use imperative, present tense ('attach' not 'attaches', 'attached' etc)
# - Don't include a period at the end of the title
# - Always include a blank line before trailers
# - More: https://github.com/keymanapp/keyman/wiki/Pull-Request-and-Commit-workflow-notes
This commit is contained in:
Dr Mark C. Sinclair 2024-08-26 10:06:51 +01:00
commit fca939b172
62 changed files with 733 additions and 1088 deletions

View file

@ -1,5 +1,25 @@
# Keyman Version History
## 18.0.97 alpha 2024-08-24
* refactor(linux): cleanup API of kvk2ldml.py (#12276)
* chore(common): adjust build settings for windows clean builds (#12264)
* chore(windows): remove remaining unused Makefiles (#12274)
* docs(developer): update build documentation to refer to build.sh (#12272)
## 18.0.96 alpha 2024-08-23
* fix(android): Fix navigation arrows in Info Activity for RTL (#12244)
* fix(web): fix documentation-keyboard spacebar-text scaling (#12232)
* fix(android): Use increment and decrement arrows on longpress delay menu (#12242)
* fix(android): Add RTL assets for adjusting keyboard height menu (#12261)
* chore(common): use `npm install` in emsdk update (#12269)
* docs: refresh windows.md (#12248)
## 18.0.95 alpha 2024-08-22
* chore(common): allow build agents to automatically select emsdk version, and enable support for 3.1.60+ (#12243)
## 18.0.94 alpha 2024-08-21
* fix(core): look for `emcc` instead of `emcc.py` (#12235)

View file

@ -1 +1 @@
18.0.95
18.0.98

Binary file not shown.

After

Width:  |  Height:  |  Size: 8.8 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 9.6 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 9.1 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 8.5 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 9.1 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 8.6 KiB

View file

@ -23,7 +23,7 @@
android:layout_marginStart="5dp"
android:layout_marginEnd="5dp"
android:contentDescription="@string/ic_delay_time_down"
android:src="@drawable/ic_light_dialog_textsize_down" />
android:src="@drawable/ic_action_decrement" />
<!-- Seekbar range 0 to 6 corresponds to longpress duration 300 ms to 1500 ms -->
<SeekBar
@ -43,7 +43,7 @@
android:layout_marginStart="5dp"
android:layout_marginEnd="5dp"
android:contentDescription="@string/ic_delay_time_up"
android:src="@drawable/ic_light_dialog_textsize_up" />
android:src="@drawable/ic_action_increment" />
</LinearLayout>

View file

@ -1,12 +1,12 @@
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical"
android:background="@color/ms_white"
tools:context=".InfoActivity" >
xmlns:tools="http://schemas.android.com/tools"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical"
android:background="@color/ms_white"
tools:context=".InfoActivity" >
<androidx.appcompat.widget.Toolbar
android:id="@+id/titlebar"
@ -15,25 +15,31 @@
android:layout_alignParentTop="true"
app:popupTheme="@style/ThemeOverlay.AppCompat.Light">
<!-- Navigation buttons -->
<ImageButton
android:id="@+id/back_button"
style="?android:attr/actionButtonStyle"
app:tint="@color/image_button_color"
<LinearLayout
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="start"
android:contentDescription="@string/label_back"
android:src="@drawable/ic_action_back" />
android:orientation="horizontal">
<ImageButton
android:id="@+id/forward_button"
style="?android:attr/actionButtonStyle"
app:tint="@color/image_button_color"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:contentDescription="@string/label_forward"
android:src="@drawable/ic_action_forward" />
<!-- Navigation buttons in a LinearLayout to mirror on RTL -->
<ImageButton
android:id="@+id/back_button"
style="?android:attr/actionButtonStyle"
app:tint="@color/image_button_color"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="start"
android:contentDescription="@string/label_back"
android:src="@drawable/ic_action_back" />
<ImageButton
android:id="@+id/forward_button"
style="?android:attr/actionButtonStyle"
app:tint="@color/image_button_color"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:contentDescription="@string/label_forward"
android:src="@drawable/ic_action_forward" />
</LinearLayout>
<ImageButton
android:id="@+id/close_button"

View file

@ -117,7 +117,7 @@ function notifyHost(event, params) {
function setLongpressDelay(delay) {
if (keyman.osk) {
keyman.osk.gestureParams.longpress.waitLength = delay;
console.debug('setLongpressDelay('+delay+')');
console_debug('setLongpressDelay('+delay+')');
} else {
window.console.log('setLongpressDelay error: keyman.osk undefined');
}
@ -304,7 +304,7 @@ function updateKMSelectionRange(start, end) {
console_debug('result:\n' + build_context_string(context));
} else {
console.debug('range unchanged');
console_debug('range unchanged');
}
}

View file

@ -7,3 +7,4 @@ delphi/**/*.~*
delphi/**/__recovery/
delphi/**/__history/
delphi/general/keymanversion_build.inc
delphi/ext/cef4delphi/packages/CEF4Delphi.res

View file

@ -1,299 +0,0 @@
# DEBUG=1
# TODO: this should be a shared Defines.mak for common,developer,windows. So we
# need to move any project-specific stuff into a defines-windows.mak,
# defines-etc.mak
#
# Paths
#
!IFNDEF KEYMAN_ROOT
!ERROR KEYMAN_ROOT must be defined!
!ENDIF
# TODO: COMMON_ROOT should be common\windows
COMMON_ROOT=$(KEYMAN_ROOT)\common\windows\delphi
WINDOWS_ROOT=$(KEYMAN_ROOT)\windows
OUTLIB=$(WINDOWS_ROOT)\lib
COMMON_OUTLIB=$(KEYMAN_ROOT)\windows\lib
COMMON_BIN=$(KEYMAN_ROOT)\windows\bin
# INCLUDE=$(ROOT)\src\global\inc;$(INCLUDE)
!IFDEF DEBUG
GO_FAST=1
MAKEFLAG_DEBUG="DEBUG=$(DEBUG)"
DELPHI_MSBUILD_FLAG_DEBUG="/p:Config=Debug"
!ELSE
!IFDEF TEAMCITY_PR_NUMBER
GO_FAST=1
!ENDIF
DELPHI_MSBUILD_FLAG_DEBUG="/p:Config=Release"
!ENDIF
!IFDEF USERDEFINES
MAKEFLAG_USERDEFINES="USERDEFINES=$(USERDEFINES)"
!ENDIF
!IFDEF SC_TIMESTAMP
MAKEFLAG_SC_TIMESTAMP="SC_TIMESTAMP=$(SC_TIMESTAMP)"
!ENDIF
!IFDEF BUILDHELP
MAKEFLAG_BUILDHELP="BUILDHELP=$(BUILDHELP)"
!ENDIF
!IFDEF LINT
MAKEFLAG_LINT="LINT=$(LINT)"
!ENDIF
!IFDEF NOUI
MAKEFLAG_QUIET="NOUI=$(NOUI)"
!ELSE
!IFDEF QUIET
MAKEFLAG_QUIET="QUIET=$(QUIET)"
!ENDIF
!ENDIF
!IFDEF RELEASE_OEM
MAKEFLAG_RELEASE_OEM="RELEASE_OEM=$(RELEASE_OEM)"
!ENDIF
#
# USERDEFINES allows the developer to specify overrides for various settings. We need a variable
# because Makefiles cannot test for file existence
#
# TODO: can we eliminate this?
!ifdef USERDEFINES
!include $(WINDOWS_ROOT)\src\UserDefines.mak
!endif
#
# Delphi Compiler Configuration - Delphi 10.3.2
#
!IFNDEF DELPHI_VERSION
DELPHI_VERSION=20.0
!ENDIF
DCC32PATH=C:\Program Files (x86)\Embarcadero\Studio\$(DELPHI_VERSION)\bin
#
# Pass local configuration through to sub-instances of MAKE
#
MAKE="nmake" /C $(MAKEFLAG_QUICK_BUILD_KEYMAN) $(MAKEFLAG_USERDEFINES) $(MAKEFLAG_DEBUG) $(MAKEFLAG_BUILDHELP) $(MAKEFLAG_BUILDRTF) $(MAKEFLAG_SC_TIMESTAMP) $(MAKEFLAG_LINT) $(MAKEFLAG_QUIET) $(MAKEFLAG_RELEASE_OEM)
#
# Delphi build commands
#
!IFDEF DEBUG
TARGET_PATH=Debug
!ELSE
TARGET_PATH=Release
!ENDIF
!IFDEF LINT
DELPHIWARNINGS=-W+MESSAGE_DIRECTIVE -W+IMPLICIT_STRING_CAST -W+IMPLICIT_STRING_CAST_LOSS -W+EXPLICIT_STRING_CAST -W+EXPLICIT_STRING_CAST_LOSS -W+CVT_WCHAR_TO_ACHAR -W+CVT_NARROWING_STRING_LOST -W+CVT_ACHAR_TO_WCHAR -W+CVT_WIDENING_STRING_LOST -W+UNICODE_TO_LOCALE -W+LOCALE_TO_UNICODE -W+IMPLICIT_VARIANTS
!ELSE
DELPHIWARNINGS=-W-MESSAGE_DIRECTIVE -W-IMPLICIT_STRING_CAST -W-IMPLICIT_STRING_CAST_LOSS -W-EXPLICIT_STRING_CAST -W-EXPLICIT_STRING_CAST_LOSS -W-CVT_WCHAR_TO_ACHAR -W-CVT_NARROWING_STRING_LOST -W-CVT_ACHAR_TO_WCHAR -W-CVT_WIDENING_STRING_LOST -W-UNICODE_TO_LOCALE -W-LOCALE_TO_UNICODE -W-IMPLICIT_VARIANTS -W-IMPLICIT_INTEGER_CAST_LOSS -W-IMPLICIT_CONVERSION_LOSS -W-COMBINING_SIGNED_UNSIGNED64 -W-COMBINING_SIGNED_UNSIGNED64
!ENDIF
DELPHIDPRPARAMS=-Q -B -GD -H -VT -^$C+ -^$D+ -^$J+ -^$L+ -^$O+ -^$Q- -^$R- -^$W+ -^$Y+ -E. $(DELPHIWARNINGS) -I$(DELPHIINCLUDES) -U$(DELPHIINCLUDES) -R$(DELPHIINCLUDES) -NSVcl;Vcl.Imaging;Vcl.Touch;Vcl.Samples;Vcl.Shell;System;Xml;Web;Soap;Winapi;System.Win -NU.\obj\Win32\$(TARGET_PATH) -E.\bin\Win32\$(TARGET_PATH)
DELPHIDPRPARAMS64=-Q -B -GD -H -VT -^$C+ -^$D+ -^$J+ -^$L+ -^$O+ -^$Q- -^$R- -^$W+ -^$Y+ -E. $(DELPHIWARNINGS) -I$(DELPHIINCLUDES) -U$(DELPHIINCLUDES) -R$(DELPHIINCLUDES) -NSVcl;Vcl.Imaging;Vcl.Touch;Vcl.Samples;Vcl.Shell;System;Xml;Web;Soap;Winapi;System.Win -NU.\obj\Win64\$(TARGET_PATH) -E.\bin\Win64\$(TARGET_PATH)
DELPHIDPKPARAMS=-Q -B -GD -VT -^$C+ -^$D+ -^$J+ -^$L+ -^$O+ -^$Q- -^$R- -^$W+ -^$Y+ -E. $(DELPHIWARNINGS) -I$(DELPHIINCLUDES) -U$(DELPHIINCLUDES) -R$(DELPHIINCLUDES) -NSVcl;Vcl.Imaging;Vcl.Touch;Vcl.Samples;Vcl.Shell;System;Xml;Web;Soap;Winapi;System.Win -LE$(OUTLIB) -LN$(OUTLIB) -NSData -NUobj\Win32\$(TARGET_PATH)
COMMON_DELPHIDPKPARAMS=-Q -B -GD -VT -^$C+ -^$D+ -^$J+ -^$L+ -^$O+ -^$Q- -^$R- -^$W+ -^$Y+ -E. $(DELPHIWARNINGS) -I$(DELPHIINCLUDES) -U$(DELPHIINCLUDES) -R$(DELPHIINCLUDES) -NSVcl;Vcl.Imaging;Vcl.Touch;Vcl.Samples;Vcl.Shell;System;Xml;Web;Soap;Winapi;System.Win -LE$(COMMON_OUTLIB) -LN$(COMMON_OUTLIB) -NSData -NUobj\Win32\$(TARGET_PATH)
# we are using cmd /c because dcc32/dcc64 are failing on direct execution
# from nmake
DCC32=cmd /c "$(DCC32PATH)\dcc32.exe" $(DELPHIDPRPARAMS)
DCC32DPK=cmd /c "$(DCC32PATH)\dcc32.exe" $(DELPHIDPKPARAMS)
COMMON_DCC32DPK=cmd /c "$(DCC32PATH)\dcc32.exe" $(COMMON_DELPHIDPKPARAMS)
DCC64=cmd /c "$(DCC32PATH)\dcc64.exe" $(DELPHIDPRPARAMS64) -N0x64\ -Ex64\
#
# Delphi MSBuild related commands and macros
#
DELPHI_MSBUILD="$(COMMON_ROOT)\tools\msbuild-wrapper.bat" "$(DCC32PATH)" $(DELPHI_MSBUILD_FLAG_DEBUG)
!IFDEF NODELPHI
DCC32=echo skipping
DCC32DPK=echo skipping
DCC64=echo skipping
DELPHI_MSBUILD=echo skipping
!ENDIF
# Visual C++ x86, x64
WIN32_TARGET_PATH=bin\Win32\$(TARGET_PATH)
X64_TARGET_PATH=bin\x64\$(TARGET_PATH)
# Delphi x86, x64
# WIN32_TARGET_PATH=...
WIN64_TARGET_PATH=bin\Win64\$(TARGET_PATH)
#
# Shared devtools app for common Delphi source manipulation
#
DEVTOOLS=$(COMMON_ROOT)\tools\devtools\$(WIN32_TARGET_PATH)\devtools.exe
#
# Other program build commands
#
BRCC32=rc.exe
HHC="C:\Program Files (x86)\HTML Help Workshop\hhc.exe"
NMAKE=nmake.exe
CL=cl.exe
MSBUILD=msbuild.exe
# /maxcpucount see https://devblogs.microsoft.com/cppblog/precompiled-header-pch-issues-and-recommendations/
MT=mt.exe
VCBUILD=error
!IFDEF DEBUG
MSBUILD_BUILD=/t:Build /p:Configuration=Debug
MSBUILD_CLEAN=/t:Clean /p:Configuration=Debug
!ELSE
MSBUILD_BUILD=/t:Rebuild /p:Configuration=Release
MSBUILD_CLEAN=/t:Clean /p:Configuration=Release
!ENDIF
COPY=copy
ISXBUILD=C:\PROGRA~1\INSTALLSHIELD\Express\System\IsExpCmdBld
WZZIPPATH="C:\program files\7-zip\7z.exe"
!IFDEF GO_FAST
WZZIP=$(WZZIPPATH) a -mx1
!ELSE
WZZIP=$(WZZIPPATH) a -mx9
!ENDIF
WZUNZIP=$(WZZIPPATH) e
# we are using cmd /c because tds2dbg is failing on direct execution
# from nmake
TDS2DBG=cmd /c $(KEYMAN_ROOT)\common\windows\bin\tools\tds2dbg
SENTRYTOOL=$(COMMON_ROOT)\tools\sentrytool\$(WIN32_TARGET_PATH)\sentrytool.exe
SENTRYTOOL_DELPHIPREP=$(SENTRYTOOL) delphiprep -r $(KEYMAN_ROOT) -i $(DELPHIINCLUDES)
WIXPATH="c:\program files (x86)\WiX Toolset v3.11\bin"
WIXCANDLE=$(WIXPATH)\candle.exe -wx -nologo
!IFDEF LINT
WIXLIGHTLINT=
!ELSE
# we suppress ICE82 because it reports spurious errors with merge module keymanengine to do with duplicate sequence numbers. Safely ignored.
WIXLIGHTLINT= -sice:ICE82 -sice:ICE80
!ENDIF
!IFDEF GO_FAST
# for debug builds, we turn off compression because it is so hideously slow
# for test builds, we also turn off compression
WIXLIGHTCOMPRESSION=-dcl:none
!ELSE
WIXLIGHTCOMPRESSION=-dcl:high
!ENDIF
WIXLIGHT=$(WIXPATH)\light.exe -wx -nologo $(WIXLIGHTLINT) $(WIXLIGHTCOMPRESSION)
WIXLIT=$(WIXPATH)\lit.exe -wx -nologo
WIXHEAT=$(WIXPATH)\heat.exe
LINKPATH=link.exe
#
# Certificates and code signing
#
!ifdef SIGNCODE_BUILD
MAKE=$(MAKE) "SIGNCODE_BUILD=$(SIGNCODE_BUILD)"
!else
MAKE=$(MAKE)
!endif
#
# To get a .pfx from a .spc and .pvk, run pvk2pfx.exe
#
!IFNDEF SC_PFX_SHA1
SC_PFX_SHA1="$(COMMON_ROOT)\tools\certificates\keymantest-sha1.pfx"
!ENDIF
!IFNDEF SC_PFX_SHA256
SC_PFX_SHA256="$(COMMON_ROOT)\tools\certificates\keymantest-sha256.pfx"
!ENDIF
!IFNDEF SC_URL
SC_URL="https://keyman.com/"
!ENDIF
!IFNDEF SC_PWD
SC_PWD=""
!ENDIF
SIGNCODE=@"$(KEYMAN_ROOT)\common\windows\signtime.bat" signtool.exe $(SC_PFX_SHA1) $(SC_PFX_SHA256) $(SC_URL) $(SC_PWD)
#
# On some computers, the PLATFORM environment variable is set to x86. This can break msbuild
# with our projects. This may be resolvable in the future, but for now the easy fix is ...
#
PLATFORM=Win32
#
# mkver commands. mkver determines tag from the local build environment variables
# in the same way as /resources/build/build-utils.sh.
#
!ifdef GIT_BASH_FOR_KEYMAN
MKVER_SH=$(GIT_BASH_FOR_KEYMAN) $(KEYMAN_ROOT)\common\windows\mkver.sh
!else
MKVER_SH=start /wait $(KEYMAN_ROOT)\common\windows\mkver.sh
!endif
MKVER_M=$(MKVER_SH) manifest.in manifest.xml
MKVER_U=$(MKVER_SH)
#
# Symstore
#
# KEYMAN_SYMSTOREPATH defaults to sibling folder "symbols". If it is not present,
# then we won't attempt to write symbols to the store.
!IFNDEF KEYMAN_SYMSTOREPATH
KEYMAN_SYMSTOREPATH=$(KEYMAN_ROOT)\..\symbols
!ENDIF
# Nearly matches algorithm from resources/build/build-utils.sh
# For now, we'll use it only for SYMSTORE, where it is for reference
# only. Thus using the variable name __VERSION_WITH_TAG. Issues:
# 1. always appends tier, even for stable
# 2. test builds will append a branch name for master/beta/stable-x.y
# 3. this is only available for `make symbols` (VERSION_WIN, VERSION_TIER
# are defined in Targets.mak only here)
# Fixing this properly would be possible but take a fair bit more
# work than I want to do just now. The intent is to make it possible to find
# symbols in the symstore index which we can purge later on.
__VERSION_WITH_TAG=$(VERSION_WIN)-$(VERSION_TIER)
!IFNDEF TEAMCITY_VERSION
__VERSION_WITH_TAG=$(__VERSION_WITH_TAG)-local
!ELSE
!IFDEF TEAMCITY_PR_NUMBER
__VERSION_WITH_TAG=$(__VERSION_WITH_TAG)-test-$(TEAMCITY_PR_NUMBER)
!ENDIF
!ENDIF
# This command depends on VERSION_WIN and VERSION_TIER being defined, through
# `make symbols` (i.e. don't call `make wrap-symbols`)
SYMSTORE="C:\Program Files (x86)\Windows Kits\10\Debuggers\x64\symstore.exe" add \
/s "$(KEYMAN_SYMSTOREPATH)" \
/v "$(VERSION_WIN)" \
/c "Version: $(__VERSION_WITH_TAG)" \
/compress /f
CLEAN=-del /S /Q

View file

@ -1,59 +0,0 @@
#
# Header.mak - used for makefiles which are in parent folders
#
HEADER_MAK=1
!IFNDEF TARGETS
!ERROR You must define the targets before including the Header.mak file!
!ENDIF
!IFNDEF KEYMAN_ROOT
!ERROR KEYMAN_ROOT must be defined!
!ENDIF
# This path will need to be updated if the root path changes
!include $(KEYMAN_ROOT)\common\windows\delphi\Defines.mak
#
# The targets build, signcode, symbols are standard
# targets for all projects
#
build: $(BUILDPREREQ)
$(MAKE) "TARGET=build" $(TARGETS)
!IFNDEF NOTARGET_SIGNCODE
signcode:
$(MAKE) "TARGET=signcode" $(TARGETS)
symbols:
$(MAKE) "TARGET=symbols" $(TARGETS)
!ELSE
signcode:
rem no signcode required
symbols:
rem no symbols required
!ENDIF
build-release:
!IFDEF RELEASE_TARGETS
$(MAKE) "TARGET=build-release" $(RELEASE_TARGETS)
!ELSE
@rem
!ENDIF
clean:
$(MAKE) "TARGET=clean" $(TARGETS) $(CLEANS)
install:
$(MAKE) "TARGET=install" $(TARGETS)
test-manifest:
!IFDEF MANIFESTS
$(MAKE) "TARGET=test-manifest" $(MANIFESTS)
!ELSE
$(MAKE) "TARGET=test-manifest" $(TARGETS)
!ENDIF

View file

@ -1,14 +0,0 @@
!CMDSWITCHES +S
def-clean:
$(CLEAN) *.err *.stat *.dproj.local *.Build.CppClean.Log *.suo *.jdbg *.dbg *.dcu *.~* *.dsk *.exe *.rsm *.ncb *.opt *.pch *.plg *.aps *.001 *.sbr *.dep *.drc *.bak *.pdb *.lib *.cod *.ilk *.tds vc80.idb *.map *.bsc version.res manifest.xml manifest.res >nul 2>nul
$(CLEAN) ExcMagic.Debug *.wixpdb *.identcache *.embed.manifest *.embed.manifest.res *.intermediate.manifest error.log >nul 2>nul
if exist bin rd /s/q bin
if exist obj rd /s/q obj
!CMDSWITCHES -S
# This virtual rule forces targets which are folders, e.g. `kmshell` to
# always execute
.virtual:
rem always execute

View file

@ -13,31 +13,6 @@
<PropertyGroup Condition="'$(Config)'=='Base' or '$(Base)'!=''">
<Base>true</Base>
</PropertyGroup>
<PropertyGroup Condition="('$(Platform)'=='Android' and '$(Base)'=='true') or '$(Base_Android)'!=''">
<Base_Android>true</Base_Android>
<CfgParent>Base</CfgParent>
<Base>true</Base>
</PropertyGroup>
<PropertyGroup Condition="('$(Platform)'=='Android64' and '$(Base)'=='true') or '$(Base_Android64)'!=''">
<Base_Android64>true</Base_Android64>
<CfgParent>Base</CfgParent>
<Base>true</Base>
</PropertyGroup>
<PropertyGroup Condition="('$(Platform)'=='iOSDevice32' and '$(Base)'=='true') or '$(Base_iOSDevice32)'!=''">
<Base_iOSDevice32>true</Base_iOSDevice32>
<CfgParent>Base</CfgParent>
<Base>true</Base>
</PropertyGroup>
<PropertyGroup Condition="('$(Platform)'=='iOSDevice64' and '$(Base)'=='true') or '$(Base_iOSDevice64)'!=''">
<Base_iOSDevice64>true</Base_iOSDevice64>
<CfgParent>Base</CfgParent>
<Base>true</Base>
</PropertyGroup>
<PropertyGroup Condition="('$(Platform)'=='iOSSimulator' and '$(Base)'=='true') or '$(Base_iOSSimulator)'!=''">
<Base_iOSSimulator>true</Base_iOSSimulator>
<CfgParent>Base</CfgParent>
<Base>true</Base>
</PropertyGroup>
<PropertyGroup Condition="('$(Platform)'=='Win32' and '$(Base)'=='true') or '$(Base_Win32)'!=''">
<Base_Win32>true</Base_Win32>
<CfgParent>Base</CfgParent>
@ -59,6 +34,12 @@
<CfgParent>Base</CfgParent>
<Base>true</Base>
</PropertyGroup>
<PropertyGroup Condition="('$(Platform)'=='Win32' and '$(Cfg_2)'=='true') or '$(Cfg_2_Win32)'!=''">
<Cfg_2_Win32>true</Cfg_2_Win32>
<CfgParent>Cfg_2</CfgParent>
<Cfg_2>true</Cfg_2>
<Base>true</Base>
</PropertyGroup>
<PropertyGroup Condition="'$(Base)'!=''">
<DCC_DcuOutput>.\obj\$(Platform)\$(Config)</DCC_DcuOutput>
<DCC_ExeOutput>.\$(Platform)\$(Config)</DCC_ExeOutput>
@ -77,23 +58,6 @@
<VerInfo_Locale>3081</VerInfo_Locale>
<VerInfo_Keys>CompanyName=;FileDescription=$(MSBuildProjectName);FileVersion=1.0.0.0;InternalName=;LegalCopyright=;LegalTrademarks=;OriginalFilename=;ProgramID=com.embarcadero.$(MSBuildProjectName);ProductName=$(MSBuildProjectName);ProductVersion=1.0.0.0;Comments=</VerInfo_Keys>
</PropertyGroup>
<PropertyGroup Condition="'$(Base_Android)'!=''">
<DCC_CBuilderOutput>None</DCC_CBuilderOutput>
<EnabledSysJars>android-support-v4.dex.jar;cloud-messaging.dex.jar;com-google-android-gms.play-services-ads-base.17.2.0.dex.jar;com-google-android-gms.play-services-ads-identifier.16.0.0.dex.jar;com-google-android-gms.play-services-ads-lite.17.2.0.dex.jar;com-google-android-gms.play-services-ads.17.2.0.dex.jar;com-google-android-gms.play-services-analytics-impl.16.0.8.dex.jar;com-google-android-gms.play-services-analytics.16.0.8.dex.jar;com-google-android-gms.play-services-base.16.0.1.dex.jar;com-google-android-gms.play-services-basement.16.2.0.dex.jar;com-google-android-gms.play-services-gass.17.2.0.dex.jar;com-google-android-gms.play-services-identity.16.0.0.dex.jar;com-google-android-gms.play-services-maps.16.1.0.dex.jar;com-google-android-gms.play-services-measurement-base.16.4.0.dex.jar;com-google-android-gms.play-services-measurement-sdk-api.16.4.0.dex.jar;com-google-android-gms.play-services-stats.16.0.1.dex.jar;com-google-android-gms.play-services-tagmanager-v4-impl.16.0.8.dex.jar;com-google-android-gms.play-services-tasks.16.0.1.dex.jar;com-google-android-gms.play-services-wallet.16.0.1.dex.jar;com-google-firebase.firebase-analytics.16.4.0.dex.jar;com-google-firebase.firebase-common.16.1.0.dex.jar;com-google-firebase.firebase-iid-interop.16.0.1.dex.jar;com-google-firebase.firebase-iid.17.1.1.dex.jar;com-google-firebase.firebase-measurement-connector.17.0.1.dex.jar;com-google-firebase.firebase-messaging.17.5.0.dex.jar;fmx.dex.jar;google-play-billing.dex.jar;google-play-licensing.dex.jar</EnabledSysJars>
</PropertyGroup>
<PropertyGroup Condition="'$(Base_Android64)'!=''">
<DCC_CBuilderOutput>None</DCC_CBuilderOutput>
<EnabledSysJars>android-support-v4.dex.jar;cloud-messaging.dex.jar;com-google-android-gms.play-services-ads-base.17.2.0.dex.jar;com-google-android-gms.play-services-ads-identifier.16.0.0.dex.jar;com-google-android-gms.play-services-ads-lite.17.2.0.dex.jar;com-google-android-gms.play-services-ads.17.2.0.dex.jar;com-google-android-gms.play-services-analytics-impl.16.0.8.dex.jar;com-google-android-gms.play-services-analytics.16.0.8.dex.jar;com-google-android-gms.play-services-base.16.0.1.dex.jar;com-google-android-gms.play-services-basement.16.2.0.dex.jar;com-google-android-gms.play-services-gass.17.2.0.dex.jar;com-google-android-gms.play-services-identity.16.0.0.dex.jar;com-google-android-gms.play-services-maps.16.1.0.dex.jar;com-google-android-gms.play-services-measurement-base.16.4.0.dex.jar;com-google-android-gms.play-services-measurement-sdk-api.16.4.0.dex.jar;com-google-android-gms.play-services-stats.16.0.1.dex.jar;com-google-android-gms.play-services-tagmanager-v4-impl.16.0.8.dex.jar;com-google-android-gms.play-services-tasks.16.0.1.dex.jar;com-google-android-gms.play-services-wallet.16.0.1.dex.jar;com-google-firebase.firebase-analytics.16.4.0.dex.jar;com-google-firebase.firebase-common.16.1.0.dex.jar;com-google-firebase.firebase-iid-interop.16.0.1.dex.jar;com-google-firebase.firebase-iid.17.1.1.dex.jar;com-google-firebase.firebase-measurement-connector.17.0.1.dex.jar;com-google-firebase.firebase-messaging.17.5.0.dex.jar;fmx.dex.jar;google-play-billing.dex.jar;google-play-licensing.dex.jar</EnabledSysJars>
</PropertyGroup>
<PropertyGroup Condition="'$(Base_iOSDevice32)'!=''">
<DCC_CBuilderOutput>None</DCC_CBuilderOutput>
</PropertyGroup>
<PropertyGroup Condition="'$(Base_iOSDevice64)'!=''">
<DCC_CBuilderOutput>None</DCC_CBuilderOutput>
</PropertyGroup>
<PropertyGroup Condition="'$(Base_iOSSimulator)'!=''">
<DCC_CBuilderOutput>None</DCC_CBuilderOutput>
</PropertyGroup>
<PropertyGroup Condition="'$(Base_Win32)'!=''">
<DCC_Namespace>Winapi;System.Win;Data.Win;Datasnap.Win;Web.Win;Soap.Win;Xml.Win;Bde;$(DCC_Namespace)</DCC_Namespace>
<BT_BuildType>Debug</BT_BuildType>
@ -113,6 +77,7 @@
<DCC_RemoteDebug>false</DCC_RemoteDebug>
<VerInfo_IncludeVerInfo>true</VerInfo_IncludeVerInfo>
<VerInfo_Locale>1033</VerInfo_Locale>
<DCC_HppOutput>..\..\lib</DCC_HppOutput>
</PropertyGroup>
<PropertyGroup Condition="'$(Cfg_2)'!=''">
<DCC_LocalDebugSymbols>false</DCC_LocalDebugSymbols>
@ -120,6 +85,11 @@
<DCC_SymbolReferenceInfo>0</DCC_SymbolReferenceInfo>
<DCC_DebugInformation>0</DCC_DebugInformation>
</PropertyGroup>
<PropertyGroup Condition="'$(Cfg_2_Win32)'!=''">
<DCC_HppOutput>..\..\lib</DCC_HppOutput>
<VerInfo_IncludeVerInfo>true</VerInfo_IncludeVerInfo>
<VerInfo_Locale>1033</VerInfo_Locale>
</PropertyGroup>
<ItemGroup>
<DelphiCompile Include="$(MainSource)">
<MainSource>MainSource</MainSource>
@ -164,8 +134,6 @@
<Source Name="MainSource">common_components.dpk</Source>
</Source>
<Excluded_Packages>
<Excluded_Packages Name="c:\projects\keyman\app\windows\lib\DCPdelphi2009.bpl">File c:\projects\keyman\app\windows\lib\DCPdelphi2009.bpl not found</Excluded_Packages>
<Excluded_Packages Name="c:\projects\keyman\app\windows\lib\delphiprojectmanager.bpl">File c:\projects\keyman\app\windows\lib\delphiprojectmanager.bpl not found</Excluded_Packages>
<Excluded_Packages Name="$(BDSBIN)\dcloffice2k260.bpl">Microsoft Office 2000 Sample Automation Server Wrapper Components</Excluded_Packages>
<Excluded_Packages Name="$(BDSBIN)\dclofficexp260.bpl">Microsoft Office XP Sample Automation Server Wrapper Components</Excluded_Packages>
</Excluded_Packages>
@ -944,13 +912,6 @@
<ProjectRoot Platform="Android64" Name="$(PROJECTNAME)"/>
</Deployment>
<Platforms>
<Platform value="Android">False</Platform>
<Platform value="Android64">False</Platform>
<Platform value="iOSDevice32">False</Platform>
<Platform value="iOSDevice64">False</Platform>
<Platform value="iOSSimulator">False</Platform>
<Platform value="OSX32">False</Platform>
<Platform value="OSX64">False</Platform>
<Platform value="Win32">True</Platform>
<Platform value="Win64">False</Platform>
</Platforms>

View file

@ -21,6 +21,8 @@ builder_describe_outputs \
function do_certificates() {
rm -f KeymanTestCA-sha1.* KeymanTest-sha1.* KeymanTest-sha256.* KeymanTestCA-sha256.*
source "$KEYMAN_ROOT/resources/build/win/visualstudio_environment.inc.sh"
makecert -r -pe -n "CN=Keyman Test CA SHA1" -ss CA -sr CurrentUser -a sha1 -cy authority -sky signature -sv KeymanTestCA-sha1.pvk KeymanTestCA-sha1.cer
certutil -user -addstore Root KeymanTestCA-sha1.cer
makecert -pe -n "CN=Keyman Test Certificate SHA1" -a sha1 -cy end -sky signature -ic KeymanTestCA-sha1.cer -iv KeymanTestCA-sha1.pvk -sv KeymanTest-sha1.pvk KeymanTest-sha1.cer

View file

@ -2,6 +2,42 @@
This is the current home for Keyman Developer.
## Build Prerequisites
* See [Windows Build Environment Configuration](../../docs/build/windows.md).
## Building Keyman Developer
1. Start 'Git Bash' (part of Git for Windows).
2. Run `developer/src/build.sh`.
3. Artifacts from a successful build will be placed in **developer/bin** folder.
*Note*: running `build.sh` will currently reset the packages and path settings
in your Delphi environment. If you use Delphi for other projects, you should
consider building Keyman under a login user dedicated to it, or in a VM.
Type `build.sh` to see build targets and actions. Common build actions are:
* `build.sh build`
: builds Keyman Developer
* `build.sh clean`
: remove temporary files and build artifacts
* `build.sh publish`
: makes a release of all Keyman Developer projects
* `build.sh install`
: install some or all components to Program Files (requires elevated command prompt).
### Building without Delphi
It is possible to build all components that do _not_ require Delphi. Currently a
few components are Delphi-based (TIKE, setup, a few others), but you may be able
to get away without building them. In this situation, we recommend copying the
relevant Delphi-built components into developer/bin folders from a compatible
installed version of Keyman Developer for testing and debugging purposes.
# Folders
## common
@ -106,4 +142,6 @@ testing and packing keyboards for distribution.
## tools
Various build-time tools for Keyman Developer.
Various build-time tools for Keyman Developer.

View file

@ -3,6 +3,23 @@ import { LDMLKeyboard, CompilerCallbacks } from "@keymanapp/developer-utils";
import { KeysCompiler } from "./keys.js";
import { LdmlCompilerMessages } from "./ldml-compiler-messages.js";
// This is a partial polyfill for findLast, so not polluting Array.prototype
// https://medium.com/@stheodorejohn/findlast-method-polyfill-in-javascript-bridging-browser-gaps-c3baf6aabae1
// TODO: remove and replace with Array.prototype.findLast when it is
// well-supported
function findLast(arr: any, callback: any) {
if (!arr) {
return undefined;
}
const len = arr.length >>> 0;
for (let i = len - 1; i >= 0; i--) {
if (callback(arr[i], i, arr)) {
return arr[i];
}
}
return undefined;
}
export class LdmlKeyboardVisualKeyboardCompiler {
public constructor(private callbacks: CompilerCallbacks) {
}
@ -57,7 +74,8 @@ export class LdmlKeyboardVisualKeyboardCompiler {
const keyId = key;
x++;
let keydef = source.keyboard3.keys?.key?.find(x => x.id == key);
//@ts-ignore
let keydef = findLast(source.keyboard3.keys?.key, x => x.id == key);
if (!keydef) {
this.callbacks.reportMessage(

View file

@ -9,6 +9,8 @@ import { KeymanFileTypes } from '@keymanapp/common-types';
describe('LexicalModelCompiler', function () {
let callbacks = new TestCompilerCallbacks();
this.timeout(5000);
// Try to compile ALL of the correct models.
const MODELS = [
'example.qaa.sencoten',

View file

@ -19,7 +19,7 @@ source "$KEYMAN_ROOT/resources/build/win/environment.inc.sh"
WIN32_TARGET="$WIN32_TARGET_PATH/tike.exe"
builder_describe_outputs \
configure:project /resources/build/win/delphi_environment_generated.inc.sh \
configure:project /developer/src/tike/xml/layoutbuilder/keymanweb-osk.ttf \
build:project /developer/src/tike/$WIN32_TARGET
#-------------------------------------------------------------------------------------------------------------------
@ -31,6 +31,7 @@ function do_configure() {
mkdir -p "$DEVELOPER_PROGRAM"
cp "$KEYMAN_ROOT/common/schemas/kps/kps.xsd" "$DEVELOPER_PROGRAM"
cp "$KEYMAN_ROOT/common/resources/fonts/keymanweb-osk.ttf" "$DEVELOPER_ROOT/src/tike/xml/layoutbuilder/keymanweb-osk.ttf"
run_in_vs_env rc icons.rc
}
function do_monaco_copy() {
@ -52,8 +53,6 @@ function do_monaco_copy() {
pushd "$DEVELOPER_ROOT/src/tike/xml/app/lib/sentry"
replaceVersionStrings_Mkver init.js.in init.js
popd
run_in_vs_env rc icons.rc
}
KEYMANCORE_DLL=keymancore-2.dll

View file

@ -63,17 +63,33 @@ See [node.md](node.md) for more information.
#### Emscripten
You'll also have to install `emscripten` (version 3.1.44 is known to work):
You'll also have to install `emscripten`:
```shell
git clone https://github.com/emscripten-core/emsdk.git
cd emsdk
./emsdk install 3.1.44
./emsdk activate 3.1.44
export EMSCRIPTEN_BASE=$(pwd)/upstream/emscripten
./emsdk install 3.1.58
./emsdk activate 3.1.58
export EMSCRIPTEN_BASE="$(pwd)/upstream/emscripten"
echo "export EMSCRIPTEN_BASE=\"$EMSCRIPTEN_BASE\"" >> .bashrc
```
**NOTE:** Don't put EMSDK on the path, i.e. don't source `emsdk_env.sh`.
> ![WARNING]
> Don't put EMSDK on the path, i.e. don't source `emsdk_env.sh`.
>
> Emscripten very unhelpfully overwrites `JAVA_HOME`, and adds its own
> versions of Python, Node and Java to the `PATH`. For best results, restart
> your shell after installing Emscripten so that you don't end up with the
> wrong versions.
**Optional environment variables**:
To let the Keyman build scripts control the version of Emscripten installed on
your computer:
```shell
export KEYMAN_USE_EMSDK=1
```
## Keyman Core

36
docs/build/macos.md vendored
View file

@ -91,16 +91,38 @@ See [node.md](node.md) for more information.
### emscripten
To install emscripten:
The recommended way to install emscripten is with the official method, as that
then allows the build scripts to select the appropriate version automatically.
```shell
brew install emscripten
To install emscripten, `cd` to an appropriate path, and then:
```bash
git clone https://github.com/emscripten-core/emsdk
cd emsdk
emsdk install 3.1.58
emsdk activate 3.1.58
export EMSCRIPTEN_BASE="$(pwd)/upstream/emscripten"
echo "export EMSCRIPTEN_BASE=\"$EMSCRIPTEN_BASE\"" >> .bashrc
```
Note: if you install emscripten with brew on macOS, only emscripten binaries are
added to the path via symlinks. This makes it reasonably safe to have emscripten
on the path, unlike on other platforms where emscripten also ends up adding its
versions of node, python, and other binaries to the path.
You will want to add `EMSCRIPTEN_BASE` to your .bashrc.
> ![WARNING]
> Don't put EMSDK on the path, i.e. don't source `emsdk_env.sh`.
>
> Emscripten very unhelpfully overwrites `JAVA_HOME`, and adds its own
> versions of Python, Node and Java to the `PATH`. For best results, restart
> your shell after installing Emscripten so that you don't end up with the
> wrong versions.
**Optional environment variables**:
To let the Keyman build scripts control the version of Emscripten installed on
your computer:
```shell
export KEYMAN_USE_EMSDK=1
```
## Keyman for iOS Dependencies

314
docs/build/windows.md vendored
View file

@ -6,13 +6,13 @@ On Windows, you can build the following projects:
* [Keyman for Android](#keyman-for-android)
* [Keyman for Windows](#keyman-for-windows)
* [Keyman Developer](#keyman-developer) (together with Keyman for Windows)
* [Keyman Developer](#keyman-developer)
* [KeymanWeb](#keymanweb)
The following libraries can also be built:
* Keyman Core (Windows, wasm targets) (aka core)
* Common/Web
* Keyman Core (Windows, wasm targets)
* Common libraries
The following projects **cannot** be built on Windows:
@ -63,10 +63,6 @@ Dependencies:
* [Base](#base-dependencies)
* [Windows Platform](#windows-platform-dependencies)
**Note**: Keyman for Windows is currently built together with Keyman Developer.
We are working on splitting these projects. For now, you will need the Keyman
Developer dependencies as well.
Building:
* [Building Keyman for Windows](../../windows/src/README.md)
@ -75,7 +71,7 @@ Building:
Dependencies:
* [Base](#base-dependencies)
* [Web](#web-dependencies)
* [Windows Platform](#windows-platform-dependencies)
* [Windows Platform](#windows-platform-dependencies) (optional, for Windows-only components)
Building:
* [Building Keyman Developer](../../windows/src/README.md)
@ -94,42 +90,19 @@ Building:
**Dependencies**:
* [Base](#base-dependencies)
* [Web](#web-dependencies)
**Additional requirements**:
* Android SDK
* Android Studio
* Ant
* Gradle
* Maven
* Optional: OpenJDK 11 (https://learn.microsoft.com/en-us/java/openjdk/download)
```ps1
# Elevated PowerShell
choco install android-sdk android-studio ant gradle maven
# optionally install sdk images
sdkmanager "system-images;android-33;google_apis;armeabi-v7a"
sdkmanager --update
sdkmanager --licenses
```
* Run Android Studio once after installation to install additional components
such as emulator images and SDK updates.
**Required environment variables**:
* [`JAVA_HOME`](#java_home)
**Optional environment variables**:
* [`JAVA_HOME_11`](#java_home)
* [Android](#android-dependencies)
Building:
* [Building Keyman for Android](../../android/README.md)
## Prerequisites
---
## Dependencies and Prerequisites
Many dependencies are only required for specific projects.
We prefer [Chocolatey](https://chocolatey.org/install) at present for
installation of dependencies. Chocolatey should be run in an elevated
installation of most dependencies. Chocolatey should be run in an elevated
PowerShell.
### Base Dependencies
@ -150,28 +123,36 @@ PowerShell.
# for *much* faster download, hide progress bar (PowerShell/PowerShell#2138)
$ProgressPreference = 'SilentlyContinue'
choco install git jq python ninja pandoc meson
refreshenv
```
**Environment variables**:
* [`KEYMAN_ROOT`](#keyman_root)
* `PATH`: add your Python scripts folder to your path: it will normally be `%appdata%\Python\Python310\Scripts`.
If you pull the entire `keyman.git` repo to `c:\keyman`, then the paths by
default will work without changes. Otherwise, you will need to set an
environment variable `KEYMAN_ROOT` to the root path of the Keyman repo. For
example:
```bat
SET KEYMAN_ROOT=c:\Projects\keyman\keyman
SET PATH=%path%;%appdata%\Python\Python310\Scripts
SETX KEYMAN_ROOT "c:\Projects\keyman\keyman"
```
To check whether environment variables are set, run `SET <variable>` in command
prompt.
> [!NOTE]
> The `SETX` command will set persistent environment variables but they do not
> impact the current shell environment. Start a new shell to see the variables.
You can use Windows Settings to add these environment variables permanently:
1. In Windows Search, type "environment" and select "Edit System Environment
Variables"
2. Click `Environment Variables...`
3. You can add or edit variables in either User or System settings, as you
prefer.
> [!TIP]
>
> To check whether environment variables are set, run `SET <variable>` in command
> prompt.
>
> You can alternatively use Windows Settings to add these environment variables
> permanently:
>
> 1. In Windows Search, type "environment" and select "Edit System Environment
> Variables"
> 2. Click `Environment Variables...`
> 3. You can add or edit variables in either User or System settings, as you
> prefer.
### Web Dependencies
@ -181,32 +162,46 @@ You can use Windows Settings to add these environment variables permanently:
* KeymanWeb
**Requirements**:
* emscripten 3.1.46 or later
* node.js 18+
* [openjdk 11](https://learn.microsoft.com/en-us/java/openjdk/download#openjdk-11)+
* Emscripten
* node.js
```ps1
# Elevated PowerShell
#### Emscripten
# for *much* faster download, hide progress bar (PowerShell/PowerShell#2138)
$ProgressPreference = 'SilentlyContinue'
In bash, run the following commands:
choco install emscripten --version 3.1.46
```bash
cd /c/Projects/keyman
git clone https://github.com/emscripten-core/emsdk
cd emsdk
emsdk install 3.1.58
emsdk activate 3.1.58
```
Note: emscripten very unhelpfully overwrites JAVA_HOME, and adds its own
versions of Python, Node and Java to the PATH. For best results, go ahead
and remove those paths from your PATH variable before continuing.
> ![WARNING]
> Emscripten very unhelpfully overwrites `JAVA_HOME`, and adds its own
> versions of Python, Node and Java to the `PATH`. For best results, restart
> your shell after installing Emscripten so that you don't end up with the
> wrong versions.
There is no need to add emscripten to the path in order to build Keyman.
However, you should set the EMSCRIPTEN_BASE variable to the path where `emcc`
can be found, but always in the upstream\emscripten subdirectory where you
installed emsdk (most likely %LocalAppData%\emsdk\upstream\emscripten)
However, you should set the `EMSCRIPTEN_BASE` variable to the path where `emcc`
can be found, in the `upstream\emscripten` subdirectory of where you installed
emsdk.
**Environment variables**:
* `EMSCRIPTEN_BASE`: `<your-emsdk-path>\upstream\emscripten`
After installing emscripten, you'll need to install node.js and openjdk.
```bat
SETX EMSCRIPTEN_BASE "<your-emsdk-path>\upstream\emscripten"
```
**Optional environment variables**:
To let the Keyman build scripts control the version of Emscripten
installed on your computer:
```bat
SETX KEYMAN_USE_EMSDK 1
```
#### node.js
@ -214,30 +209,22 @@ Our recommended way to install node.js is to use
[nvm-windows](https://github.com/coreybutler/nvm-windows). This makes it
easy to switch between versions of node.js.
Alternatively, use Powershell + Chocolatey to install node.js:
```ps1
# Elevated PowerShell
# for *much* faster download, hide progress bar (PowerShell/PowerShell#2138)
$ProgressPreference = 'SilentlyContinue'
choco install nodejs
```bat
nvm install 20.16.0
nvm use 20.16.0
```
See [node.md](node.md) for more information.
**Optional environment variables**:
#### openjdk
To let the Keyman build scripts control the version of node.js installed
and active on your computer:
Use Powershell + Chocolatey to install OpenJDK:
```ps1
# Elevated PowerShell
# for *much* faster download, hide progress bar (PowerShell/PowerShell#2138)
$ProgressPreference = 'SilentlyContinue'
choco install openjdk
```
```bat
SETX KEYMAN_USE_NVM 1
````
See [node.md](node.md) for more information, including automatic selection
of appropriate node versions during builds.
### Windows Platform Dependencies
@ -260,8 +247,7 @@ choco install openjdk
Start Delphi IDE once after installation as it will create various environment
files and take you through required registration.
* Note: It is possible to build all components that do _not_ require Delphi by
adding the environment variable `NODELPHI=1` before starting the build.
* Note: It is possible to build all components that do _not_ require Delphi.
Currently many components are Delphi-based, but if you are working just in
Keyman Core, the compiler, or Keyman Engine's C++ components, you may be
able to get away without building them. In this situation, we recommend
@ -273,10 +259,12 @@ choco install openjdk
```ps1
choco install visualstudio2019community visualstudio2019-workload-nativedesktop visualstudio2019buildtools
```
* Verify required build tools are installed
* Run `Visual Studio Installer`
* Check the `Individual components` tab
* Verify `MSVC v142 - VS 2019 c++ x64/x86 build tools (Latest)` is installed. If not, install it.
* Verify `MSVC v142 - VS 2019 c++ x64/x86 build tools (Latest)` is installed.
If not, install it.
Recommended: configure Visual Studio to use two-space tab stops:
1. Open the options dialog: Tools > Options.
@ -284,55 +272,15 @@ choco install openjdk
3. Change 'Tab size' to 2 and 'Indent size' to 2.
4. Select 'Insert spaces'.
* Windows SDK (C++ Desktop Development)
https://developer.microsoft.com/en-us/windows/downloads/windows-sdk/
**Required environment variables**:
* `PATH`
* Add the C:\Projects\keyman\keyman\windows\lib folder in the Keyman
* Add the `C:\Projects\keyman\keyman\windows\lib` folder in the Keyman
repository to your `PATH` environment variable. This is required for
Keyman's design-time packages to load in Delphi.
* [`KEYMAN_CEF4DELPHI_ROOT`](#keyman_cef4delphi_root)
**Optional environment variables**:
* [`GIT_BASH_FOR_KEYMAN`](#git_bash_for_keyman)
* [`USERDEFINES`](#userdefines)
```bat
SET KEYMAN_CEF4DELPHI_ROOT=c:\Projects\keyman\CEF4Delphi_Binary
SET GIT_BASH_FOR_KEYMAN="C:\Program Files\Git\bin\bash.exe" --init-file "c:\Program Files\Git\etc\profile" -l
```
**Additional requirements for release builds**:
* [Certificates](#certificates)
* [7-Zip](http://www.7-zip.org/), used for archiving build files
* [HTML Help Workshop](http://web.archive.org/web/20160201063255/http://download.microsoft.com/download/0/A/9/0A939EF6-E31C-430F-A3DF-DFAE7960D564/htmlhelp.exe) note: Microsoft no longer offer this download...
* [WiX 3.11.1](https://github.com/wixtoolset/wix3/releases/tag/wix3111rtm)
* [CEF4Delphi_Binary](https://github.com/keymanapp/CEF4Delphi_Binary) repository
```ps1
# Elevated PowerShell
choco install 7zip html-help-workshop
choco install wixtoolset --version=3.11.1
git clone https://github.com/keymanapp/CEF4Delphi_Binary C:\Projects\keyman\CEF4Delphi_Binary
```
## Certificates
In order to make a release build, you need to sign all the executables. See
[windows/src/README.md#Certificates](../../windows/src/README.md#Certificates)
for details on how to create test code signing certificates or specify your own
certificates for the build.
## Notes on Environment Variables
### KEYMAN_ROOT
If you pull the entire `keyman.git` repo to `c:\keyman`, then the paths by
default will work without changes. Otherwise, you will need to set an
environment variable `KEYMAN_ROOT` to the root path of the Keyman repo. For
example:
```bat
SET KEYMAN_ROOT=c:\projects\keyman\keyman
```
### KEYMAN_CEF4DELPHI_ROOT
@ -349,41 +297,85 @@ release build, the common/windows/cef-checkout.sh script will checkout the corre
branch of the repository automatically and extract any compressed files found in
it.
### GIT_BASH_FOR_KEYMAN
This environment variable is optional: the build will run bash in a separate
window in order to build KeymanWeb if it isn't present, but you'll lose logging
and have the annoyance of a window popping up halfway through the build. To
resolve both of those issues, set the environment variable to:
The [`KEYMAN_CEF4DELPHI_ROOT`](#keyman_cef4delphi_root) variable is
used to specify the path to the CEF4Delphi binaries.
```bat
SET GIT_BASH_FOR_KEYMAN="C:\Program Files\Git\bin\bash.exe" --init-file "c:\Program Files\Git\etc\profile" -l
SETX KEYMAN_CEF4DELPHI_ROOT "c:\Projects\keyman\CEF4Delphi_Binary"
```
You should verify the install location of Git on your computer as it may vary.
**Additional requirements for release builds**:
* [Certificates](#certificates)
* [7-Zip](http://www.7-zip.org/), used for archiving build files
* [HTML Help Workshop](http://web.archive.org/web/20160201063255/http://download.microsoft.com/download/0/A/9/0A939EF6-E31C-430F-A3DF-DFAE7960D564/htmlhelp.exe) note: Microsoft no longer offer this download...
* [WiX 3.11.1](https://github.com/wixtoolset/wix3/releases/tag/wix3111rtm)
* [CEF4Delphi_Binary](https://github.com/keymanapp/CEF4Delphi_Binary) repository
### USERDEFINES
You can specify defines that will not be added to the git repository and will be
used in the build in the UserDefines.mak file in the root folder. This is used
mostly for code signing certificates. If not specified, a test certificate will
be used to sign executables when you build a release.
To include UserDefines.mak in the build, use the command line parameter
`-DUSERDEFINES`. You can also set an environment variable `USERDEFINES=1` to get
the same result.
### JAVA_HOME
This environment variable tells Gradle what version of Java to use for building Keyman for Android.
**Multiple versions of Java:** If you need to build Keyman for Android 16.0 or older versions, you can set `JAVA_HOME_11` to the OpenJDK 11 path and `JAVA_HOME` to the OpenJDK 8 path. This will build both versions correctly from command line. But note that you do need to update your `JAVA_HOME` env var to the associated version before opening Android Studio and loading any Android projects. `JAVA_HOME_11` is mostly used by CI.
```bat
SET JAVA_HOME="path to OpenJDK 8"
SET JAVA_HOME_11="path to OpenJDK 11"
```ps1
# Elevated PowerShell
choco install 7zip html-help-workshop
choco install wixtoolset --version=3.11.1
git clone https://github.com/keymanapp/CEF4Delphi_Binary C:\Projects\keyman\CEF4Delphi_Binary
```
### Android dependencies
**Projects**:
* Keyman for Android
**Requirements**:
* Android SDK
* Android Studio
* Ant
* Gradle
* Maven
* JDK 11 (Temurin11)
#### JDK 11
Use Powershell + Chocolatey to install JDK 11:
```ps1
# Elevated PowerShell
# for *much* faster download, hide progress bar (PowerShell/PowerShell#2138)
$ProgressPreference = 'SilentlyContinue'
choco install temurin11
```
**Multiple versions of Java:** If you need to build Keyman for Android 16.0 or
older versions, you can set `JAVA_HOME_11` to the JDK 11 path and
`JAVA_HOME` to the JDK 8 path. This will build both versions correctly
from command line. But note that you do need to update your `JAVA_HOME` env
var to the associated version before opening Android Studio and loading any
Android projects. `JAVA_HOME_11` is mostly used by CI.
#### Android Studio and friends
```ps1
# Elevated PowerShell
choco install androidstudio ant gradle maven android-sdk
```
Start a new shell to get the new paths and then update Android SDKs:
```ps1
# optionally install sdk images
sdkmanager --update
# sdkmanager "system-images;android-33;google_apis;armeabi-v7a"
sdkmanager --licenses
```
* Run Android Studio once after installation to install additional components
such as emulator images and SDK updates.
## Certificates
In order to make a release build, you need to sign all the executables. See
[windows/src/README.md#Certificates](../../windows/src/README.md#Certificates)
for details on how to create test code signing certificates or specify your own
certificates for the build.
## Optional Tools
* sentry-cli (optional)

View file

@ -49,7 +49,6 @@ https://help.keyman.com/developer/engine/android/latest-version/
| KEYMAN Variable | Value |
|-----------------------------------|--------------|
| KEYMAN_DEFAULT_VERSION_UBUNTU_CONTAINER | noble |
| KEYMAN_MAX_VERSION_EMSCRIPTEN | 3.1.58 |
| KEYMAN_MIN_TARGET_VERSION_ANDROID | 5 |
| KEYMAN_MIN_TARGET_VERSION_CHROME | 95.0 |
| KEYMAN_MIN_TARGET_VERSION_IOS | 12.2 |
@ -58,7 +57,7 @@ https://help.keyman.com/developer/engine/android/latest-version/
| KEYMAN_MIN_TARGET_VERSION_WINDOWS | 10 |
| KEYMAN_MIN_VERSION_ANDROID_SDK | 21 |
| KEYMAN_MIN_VERSION_CPP | 17 |
| KEYMAN_MIN_VERSION_EMSCRIPTEN | 3.1.44 |
| KEYMAN_MIN_VERSION_EMSCRIPTEN | 3.1.58 |
| KEYMAN_MIN_VERSION_MESON | 1.0.0 |
| KEYMAN_MIN_VERSION_NODE_MAJOR | 20 |
| KEYMAN_MIN_VERSION_NPM | 10.5.1 |

View file

@ -831,12 +831,22 @@ public class Manager: NSObject, UIGestureRecognizerDelegate {
shared.copyUserDefaults(to: nonShared, withKeys: keysToCopy, shouldOverwrite: true)
do {
try shared.copyFiles(to: nonShared)
FontManager.shared.registerCustomFonts()
} catch {
let message = ("Failed to copy from shared container: \(error)")
os_log("%{public}s", log:KeymanEngineLogger.settings, type: .error, message)
SentryManager.capture(error, message:message)
}
// This operation has a surprisingly high cost and isn't critical
// for getting the keyboard loaded and available to the OS.
//
// We certainly want it done _soon_... but we don't want it to cause
// the primary, synchronous initialization call from the OS to run so
// long that the keyboard fails to start due to its enforced time
// constraints.
DispatchQueue.main.async {
FontManager.shared.registerCustomFonts()
}
}
}

View file

@ -26,6 +26,17 @@ public class FontManager {
fonts[url] = RegisteredFont(name: name, isRegistered: false)
return name
}
private func cachedFont(at url: URL) -> RegisteredFont? {
if let font = fonts[url] {
return font
}
guard let name = readFontName(at: url) else {
return nil
}
fonts[url] = RegisteredFont(name: name, isRegistered: false)
return fonts[url]
}
/// Registers all new fonts found in the font path. Call this after you have preloaded all your font files
/// with `preloadFontFile(atPath:shouldOverwrite:)`
@ -33,8 +44,50 @@ public class FontManager {
guard let keyboardDirs = Storage.active.keyboardDirs else {
return
}
var fontSet: Set<URL> = []
for dir in keyboardDirs {
registerFonts(in: dir)
fontSet = fontSet.union(listFonts(in: dir))
}
registerListedFonts(fontSet)
}
/**
* Iterates across all listed fonts, registering those not yet registered.
* Checks for, and filters out, any fonts already registered on the system.
* Also initializes the registration cache per URL if needed.
*/
private func registerListedFonts(_ initialFontSet: Set<URL>) {
// If we are unable to read the font file's properties sufficiently,
// skip it. We also don't need to register anything already registered or
// that cannot be registered due to loading/parsing errors.
//
// Calls to `cachedFont` after the `.filter` below may be assumed to have
// non-nil return values.
var fontSet = initialFontSet.filter { !(cachedFont(at: $0)?.isRegistered ?? true) }
// The prior line filters out any entries where cachedFont(at: $0) would be nil.
// Batch-lookups all fonts lacking cache-confirmation of prior registration.
var fontNamesToRegister = missingFonts(from: Set(fontSet.map { cachedFont(at: $0)!.name }))
for fontUrl in fontSet {
let fontName = cachedFont(at: fontUrl)!.name
guard fontNamesToRegister.contains(fontName) else {
let message = "Did not register font at \(fontUrl) because font name \(fontName) is already registered"
os_log("%{public}s", log:KeymanEngineLogger.resources, type: .info, message)
continue
}
let didRegister = _registerFont(at: fontUrl)
fonts[fontUrl] = RegisteredFont(name: fontName, isRegistered: didRegister)
// We no longer need to register a font with this name, so drop it from
// the set to register.
if didRegister {
fontNamesToRegister.remove(fontName)
}
}
}
@ -43,6 +96,8 @@ public class FontManager {
guard let keyboardDirs = Storage.active.keyboardDirs else {
return
}
// This doesn't use the expensive looped lookup operation seen in missingFonts,
// so there's no need to batch similar operations here.
for dir in keyboardDirs {
unregisterFonts(in: dir)
}
@ -63,44 +118,29 @@ public class FontManager {
}
return name as String
}
private func _registerFont(at url: URL) -> Bool {
var errorRef: Unmanaged<CFError>?
let fontName = fontName(at: url)!
let didRegister = CTFontManagerRegisterFontsForURL(url as CFURL, .none, &errorRef)
let error = errorRef?.takeRetainedValue() // Releases errorRef
if !didRegister {
let message = "Failed to register font \(fontName) at \(url) reason: \(String(describing: error))"
os_log("%{public}s", log:KeymanEngineLogger.resources, type: .error, message)
} else {
let message = "Registered font \(fontName) at \(url)"
os_log("%{public}s", log:KeymanEngineLogger.resources, type: .info, message)
}
return didRegister
}
/// - Parameters:
/// - url: URL of the font to register
/// - Returns: Font is registered.
public func registerFont(at url: URL) -> Bool {
let fontName: String
if let font = fonts[url] {
if font.isRegistered {
return true
}
fontName = font.name
} else {
guard let name = readFontName(at: url) else {
return false
}
fontName = name
}
let didRegister: Bool
if !fontExists(fontName) {
var errorRef: Unmanaged<CFError>?
didRegister = CTFontManagerRegisterFontsForURL(url as CFURL, .none, &errorRef)
let error = errorRef?.takeRetainedValue() // Releases errorRef
if !didRegister {
let message = "Failed to register font \(fontName) at \(url) reason: \(String(describing: error))"
os_log("%{public}s", log:KeymanEngineLogger.resources, type: .error, message)
} else {
let message = "Registered font \(fontName) at \(url)"
os_log("%{public}s", log:KeymanEngineLogger.resources, type: .info, message)
}
} else {
didRegister = false
let message = "Did not register font at \(url) because font name \(fontName) is already registered"
os_log("%{public}s", log:KeymanEngineLogger.resources, type: .info, message)
}
let font = RegisteredFont(name: fontName, isRegistered: didRegister)
fonts[url] = font
return didRegister
registerListedFonts([url])
return fonts[url]?.isRegistered ?? false
}
/// - Parameters:
@ -133,32 +173,53 @@ public class FontManager {
return font.isRegistered
}
public func registerFonts(in directory: URL) {
private func listFonts(in directory: URL) -> [URL] {
guard let urls = try? FileManager.default.contentsOfDirectory(at: directory, includingPropertiesForKeys: nil) else {
let message = "Could not list contents of directory \(directory)"
os_log("%{public}s", log:KeymanEngineLogger.resources, type: .error, message)
return
}
for url in urls where url.lastPathComponent.hasFontExtension {
_ = registerFont(at: url)
return []
}
return urls.filter { $0.lastPathComponent.hasFontExtension }
}
public func registerFonts(in directory: URL) {
let fontsToRegister = listFonts(in: directory)
registerListedFonts(Set(fontsToRegister))
}
public func unregisterFonts(in directory: URL, fromSystemOnly: Bool = true) {
guard let urls = try? FileManager.default.contentsOfDirectory(at: directory, includingPropertiesForKeys: nil) else {
let message = "Could not list contents of directory \(directory)"
os_log("%{public}s", log:KeymanEngineLogger.resources, type: .error, message)
return
}
for url in urls where url.lastPathComponent.hasFontExtension {
let fontsToUnregister = listFonts(in: directory)
for url in fontsToUnregister {
_ = unregisterFont(at: url, fromSystemOnly: fromSystemOnly)
}
}
private func fontExists(_ fontName: String) -> Bool {
return UIFont.familyNames.contains { familyName in
UIFont.fontNames(forFamilyName: familyName).contains(fontName)
/**
* Queries the system for existing registrations for the specified fonts with a single batch run.
* Only fonts that could not be found will be returned within the result set.
*/
private func missingFonts(from fontNames: Set<String>) -> Set<String> {
var fontsToFind = fontNames
UIFont.familyNames.forEach { familyName in
if fontsToFind.count == 0 {
return
}
let familyFonts = UIFont.fontNames(forFamilyName: familyName)
for font in familyFonts {
if fontsToFind.contains(font) {
fontsToFind.remove(font)
}
if fontsToFind.count == 0 {
break
}
}
}
return fontsToFind
}
}

View file

@ -164,43 +164,43 @@ VKey_to_Iso = {
}
def bytecheck(value, check):
def _bytecheck(value, check):
if bytes([value & check[0]]) == check:
return True
else:
return False
def get_nkey(file, fileContent, offset):
def _get_nkey(file, fileContent, offset):
nkey = NKey()
data = struct.unpack_from("<B2H", fileContent, offset)
nkey.flags = data[0]
nkey.hasBitmap = bytecheck(data[0], kvkkBitmap)
nkey.hasUnicode = bytecheck(data[0], kvkkUnicode)
nkey.hasBitmap = _bytecheck(data[0], kvkkBitmap)
nkey.hasUnicode = _bytecheck(data[0], kvkkUnicode)
nkey.shiftflags = data[1]
if data[1] == 0:
nkey.Normal = True
nkey.Shift = bytecheck(data[1], KVKS_SHIFT)
nkey.Ctrl = bytecheck(data[1], KVKS_CTRL)
nkey.Alt = bytecheck(data[1], KVKS_ALT)
nkey.LCtrl = bytecheck(data[1], KVKS_LCTRL)
nkey.RCtrl = bytecheck(data[1], KVKS_RCTRL)
nkey.LAlt = bytecheck(data[1], KVKS_LALT)
nkey.RAlt = bytecheck(data[1], KVKS_RALT)
nkey.Shift = _bytecheck(data[1], KVKS_SHIFT)
nkey.Ctrl = _bytecheck(data[1], KVKS_CTRL)
nkey.Alt = _bytecheck(data[1], KVKS_ALT)
nkey.LCtrl = _bytecheck(data[1], KVKS_LCTRL)
nkey.RCtrl = _bytecheck(data[1], KVKS_RCTRL)
nkey.LAlt = _bytecheck(data[1], KVKS_LALT)
nkey.RAlt = _bytecheck(data[1], KVKS_RALT)
nkey.VKey = data[2]
nkey.text, newoffset = get_nstring(file, fileContent, offset + struct.calcsize("<B2H"))
nkey.bitmap, newoffset = get_nbitmap(file, fileContent, newoffset)
nkey.text, newoffset = _get_nstring(file, fileContent, offset + struct.calcsize("<B2H"))
nkey.bitmap, newoffset = _get_nbitmap(file, fileContent, newoffset)
return nkey, newoffset
def get_nfont(file, fileContent, offset):
def _get_nfont(file, fileContent, offset):
nfont = NFont()
nfont.name, curoffset = get_nstring(file, fileContent, offset)
nfont.name, curoffset = _get_nstring(file, fileContent, offset)
data = struct.unpack_from("<L4B", fileContent, curoffset)
nfont.resv = data[4]
nfont.blue = data[1]
@ -210,7 +210,7 @@ def get_nfont(file, fileContent, offset):
return nfont, curoffset + struct.calcsize("<L4B")
def get_nstring(file, fileContent, offset):
def _get_nstring(file, fileContent, offset):
stringlength = struct.unpack_from("<H", fileContent, offset)
file.seek(offset + 2)
if stringlength[0] > 256:
@ -224,7 +224,7 @@ def get_nstring(file, fileContent, offset):
return stringdata.decode('utf-16'), offset + 2 + (2 * stringlength[0])
def get_nbitmap(file, fileContent, offset):
def _get_nbitmap(file, fileContent, offset):
bitmap = None
bitmaplength = struct.unpack_from("<I", fileContent, offset)
file.seek(offset + struct.calcsize("<I"))
@ -283,31 +283,31 @@ def print_kvk(kvkData, allkeys=False):
print(" text:", key.text)
def plus_join(modifier, name):
def _plus_join(modifier, name):
if modifier:
modifier = modifier + "+"
modifier = modifier + name
return modifier
def get_modifer(key):
def _get_modifer(key):
modifier = ""
if key.Normal:
return "None"
if key.Shift:
modifier = plus_join(modifier, "shift")
modifier = _plus_join(modifier, "shift")
if key.Ctrl:
modifier = plus_join(modifier, "ctrl")
modifier = _plus_join(modifier, "ctrl")
if key.Alt:
modifier = plus_join(modifier, "alt")
modifier = _plus_join(modifier, "alt")
if key.LCtrl:
modifier = plus_join(modifier, "ctrlL")
modifier = _plus_join(modifier, "ctrlL")
if key.RCtrl:
modifier = plus_join(modifier, "ctrlR")
modifier = _plus_join(modifier, "ctrlR")
if key.LAlt:
modifier = plus_join(modifier, "altL")
modifier = _plus_join(modifier, "altL")
if key.RAlt:
modifier = plus_join(modifier, "altR")
modifier = _plus_join(modifier, "altR")
return modifier
@ -315,7 +315,7 @@ def convert_ldml(kvkData):
keymaps = {}
for key in kvkData.Keys:
modifier = get_modifer(key)
modifier = _get_modifer(key)
if modifier in keymaps:
keymaps[modifier] = keymaps[modifier] + (key,)
else:
@ -381,20 +381,20 @@ def parse_kvk_file(kvkfile):
kvkstart = struct.unpack_from("<4s4cc", fileContent, 0)
kvkData.version = (kvkstart[1], kvkstart[2], kvkstart[3], kvkstart[4])
kvkData.flags = kvkstart[5]
kvkData.key102 = bytecheck(kvkData.flags[0], kvkk102key)
kvkData.DisplayUnderlying = bytecheck(kvkData.flags[0], kvkkDisplayUnderlying)
kvkData.UseUnderlying = bytecheck(kvkData.flags[0], kvkkUseUnderlying)
kvkData.AltGr = bytecheck(kvkData.flags[0], kvkkAltGr)
kvkData.key102 = _bytecheck(kvkData.flags[0], kvkk102key)
kvkData.DisplayUnderlying = _bytecheck(kvkData.flags[0], kvkkDisplayUnderlying)
kvkData.UseUnderlying = _bytecheck(kvkData.flags[0], kvkkUseUnderlying)
kvkData.AltGr = _bytecheck(kvkData.flags[0], kvkkAltGr)
kvkData.AssociatedKeyboard, newoffset = get_nstring(file, fileContent, struct.calcsize("<4s4cc"))
kvkData.AnsiFont, newoffset = get_nfont(file, fileContent, newoffset)
kvkData.UnicodeFont, newoffset = get_nfont(file, fileContent, newoffset)
kvkData.AssociatedKeyboard, newoffset = _get_nstring(file, fileContent, struct.calcsize("<4s4cc"))
kvkData.AnsiFont, newoffset = _get_nfont(file, fileContent, newoffset)
kvkData.UnicodeFont, newoffset = _get_nfont(file, fileContent, newoffset)
numkeys = struct.unpack_from("I", fileContent, newoffset)
kvkData.KeyCount = numkeys[0]
newoffset = newoffset + struct.calcsize("I")
for num in range(numkeys[0]):
nkey, newoffset = get_nkey(file, fileContent, newoffset)
nkey, newoffset = _get_nkey(file, fileContent, newoffset)
nkey.number = num
kvkData.Keys.append(nkey)
except Exception as e:

View file

@ -36,7 +36,7 @@
<key>CFBundlePackageType</key>
<string>APPL</string>
<key>CFBundleShortVersionString</key>
<string>Keyman $(PRODUCT_VERSION) for macOS</string>
<string>$(PRODUCT_VERSION)</string>
<key>CFBundleSignature</key>
<string>????</string>
<key>CFBundleURLTypes</key>

View file

@ -16,6 +16,7 @@ NS_ASSUME_NONNULL_BEGIN
@property (readonly) NSString *clientApplicationId;
-(instancetype)initWithClient:(id) client applicationId:(NSString *)appId;
-(NSString *)description;
-(void)checkCompliance:(id) client;
-(void) checkComplianceAfterInsert:(id) client delete:(NSString *)textToDelete insert:(NSString *)textToInsert;
-(BOOL)isComplianceUncertain;

View file

@ -73,7 +73,7 @@ NSString *const kKMLegacyApps = @"KMLegacyApps";
-(NSString *)description
{
return [NSString stringWithFormat:@"complianceUncertain: %d, hasCompliantSelectionApi: %d, canReadText: %d, canReplaceText: %d, mustBackspaceUsingEvents: %d, clientAppId: %@, client: %@", self.complianceUncertain, self.hasCompliantSelectionApi, [self canReadText], [self canReplaceText], [self mustBackspaceUsingEvents], _clientApplicationId, _client];
return [NSString stringWithFormat:@"complianceUncertain: %d, hasCompliantSelectionApi: %d, canReadText: %d, canReplaceText: %d, mustBackspaceUsingEvents: %d, clientApplicationId: %@, client: %@", self.complianceUncertain, self.hasCompliantSelectionApi, [self canReadText], [self canReplaceText], [self mustBackspaceUsingEvents], _clientApplicationId, _client];
}
/** test to see if the API selectedRange functions properly for the text input client */

View file

@ -15,23 +15,27 @@
#import "TextApiCompliance.h"
KMInputMethodEventHandler *testEventHandler = nil;
id testClient = nil;
@interface InputMethodTests : XCTestCase
@end
@interface KMInputMethodEventHandler (Testing)
@property (nonatomic, retain) TextApiCompliance* apiCompliance;
@property (nonatomic, retain) NSString* clientApplicationId;
@property BOOL contextChanged;
- (instancetype)initWithClient:(NSString *)clientAppId client:(id) sender;
- (NSRange) calculateInsertRangeForDeletedText:(NSString*)textToDelete selectionRange:(NSRange) selection;
- (void)checkTextApiCompliance:(id)client;
@end
@implementation InputMethodTests
- (void)setUp {
id client = [[AppleCompliantTestClient alloc] init];
testClient = [[AppleCompliantTestClient alloc] init];
NSString *clientAppId = @"com.compliant.app";
testEventHandler = [[KMInputMethodEventHandler alloc]initWithClient:clientAppId client:client];
testEventHandler = [[KMInputMethodEventHandler alloc]initWithClient:clientAppId client:testClient];
}
- (void)tearDown {
@ -85,4 +89,43 @@ KMInputMethodEventHandler *testEventHandler = nil;
XCTAssertTrue(correctResult, @"insert or replacement range expected to be {1,2}");
}
/**
* test compliance check of a KMInputMethodEventHandler with a nil client application ID
* not sure if this can ever happen, but the lifecycle of the input method is not 100% clear,
* and we would like this scenario, if it can occur, to not result in a crash
*/
- (void)testCheckCompliance_withUnknownApplicationId_createsComplianceObject {
id client = [[AppleCompliantTestClient alloc] init];
KMInputMethodEventHandler *eventHandler = [[KMInputMethodEventHandler alloc]initWithClient:nil client:client];
[eventHandler checkTextApiCompliance:client];
XCTAssertNotNil(eventHandler.apiCompliance, @"apiCompliance object was not created");
}
- (void)testCheckCompliance_withNilComplianceObject_createsComplianceObject {
[testEventHandler checkTextApiCompliance:testClient];
XCTAssertNotNil(testEventHandler.apiCompliance, @"apiCompliance object was not created");
}
- (void)testCheckCompliance_withChangedClientApplicationId_createsNewComplianceObject {
// first call causes textApiCompliance object to be created
[testEventHandler checkTextApiCompliance:testClient];
TextApiCompliance *originalComplianceObject = testEventHandler.apiCompliance;
testEventHandler.clientApplicationId = @"com.different.app";
// second call causes new textApiCompliance object to be created due to stale application ID
[testEventHandler checkTextApiCompliance:testClient];
XCTAssertNotEqualObjects(originalComplianceObject, testEventHandler.apiCompliance, @"New TextApiCompliance object not created for new client application ID");
}
- (void)testCheckCompliance_withContextChanged_createsNewComplianceObject {
// first call causes textApiCompliance object to be created
[testEventHandler checkTextApiCompliance:testClient];
TextApiCompliance *originalComplianceObject = testEventHandler.apiCompliance;
testEventHandler.contextChanged = YES;
// second call causes new textApiCompliance object to be created due to setting contextChanged flag
[testEventHandler checkTextApiCompliance:testClient];
XCTAssertNotEqualObjects(originalComplianceObject, testEventHandler.apiCompliance, @"New TextApiCompliance object not created after contextChanged flag set");
}
@end

View file

@ -17,7 +17,7 @@
<key>CFBundlePackageType</key>
<string>FMWK</string>
<key>CFBundleShortVersionString</key>
<string>Keyman Engine $(PRODUCT_VERSION) for macOS</string>
<string>$(PRODUCT_VERSION)</string>
<key>CFBundleSignature</key>
<string>????</string>
<key>CFBundleVersion</key>

View file

@ -23,8 +23,10 @@ source "$KEYMAN_ROOT/resources/build/win/environment_generated.inc.sh"
WINDOWS_ROOT="$KEYMAN_ROOT/windows"
WINDOWS_PROGRAM_APP="$WINDOWS_ROOT/bin/desktop"
WINDOWS_PROGRAM_ENGINE="$WINDOWS_ROOT/bin/engine"
WINDOWS_PROGRAM_SUPPORT="$WINDOWS_ROOT/bin/support"
WINDOWS_DEBUGPATH_APP="$WINDOWS_ROOT/debug/desktop"
WINDOWS_DEBUGPATH_ENGINE="$WINDOWS_ROOT/debug/engine"
WINDOWS_DEBUGPATH_SUPPORT="$WINDOWS_ROOT/debug/suppor"
COMMON_ROOT="$KEYMAN_ROOT/common/windows/delphi"
OUTLIB="$WINDOWS_ROOT/lib"
@ -141,6 +143,8 @@ create-windows-output-folders() {
mkdir -p "$OUTLIB"
mkdir -p "$WINDOWS_PROGRAM_APP"
mkdir -p "$WINDOWS_PROGRAM_ENGINE"
mkdir -p "$WINDOWS_PROGRAM_SUPPORT"
mkdir -p "$WINDOWS_DEBUGPATH_APP"
mkdir -p "$WINDOWS_DEBUGPATH_ENGINE"
mkdir -p "$WINDOWS_DEBUGPATH_SUPPORT"
}

View file

@ -69,5 +69,7 @@ _select_emscripten_version_with_emsdk() {
git pull
./emsdk install "$KEYMAN_MIN_VERSION_EMSCRIPTEN"
./emsdk activate "$KEYMAN_MIN_VERSION_EMSCRIPTEN"
cd upstream/emscripten
npm install
popd > /dev/null
}

View file

@ -1239,6 +1239,7 @@ export default class VisualKeyboard extends EventEmitter<EventMap> implements Ke
const groupStyle = getComputedStyle(this.layerGroup.element);
const isInDOM = computedStyle.height != '' && computedStyle.height != 'auto';
const isGroupInDOM = groupStyle.height != '' && groupStyle.height != 'auto';
if (computedStyle.border) {
this._borderWidth = new ParsedLengthStyle(computedStyle.borderWidth).val;
@ -1251,10 +1252,11 @@ export default class VisualKeyboard extends EventEmitter<EventMap> implements Ke
this._computedHeight = this.height;
} else if (isInDOM) {
this._computedWidth = parseInt(computedStyle.width, 10);
if (!this._computedWidth) {
this._computedWidth = parseInt(groupStyle.width, 10);
}
this._computedHeight = parseInt(computedStyle.height, 10);
} else if (isGroupInDOM) {
// May occur for documentation-keyboards, which are detached from their VisualKeyboard base.
this._computedWidth = parseInt(groupStyle.width, 10);
this._computedHeight = parseInt(groupStyle.height, 10);
} else {
// Cannot perform layout operations!
return;
@ -1597,6 +1599,16 @@ export default class VisualKeyboard extends EventEmitter<EventMap> implements Ke
// the page.
kbdObj.appendStyleSheet();
// Unset the width + height we used thus far; this method's consumer may choose to rescale
// the returned element. If so, we don't want to use our outdated value by mistake.
//
// While `kbdObj.setSize()` could be used in theory, it _also_ unsets the element styling.
// We actually wish to _leave_ this styling in place - one of our parameters is `height`, and
// it should remain in place in the styling on the output element as the default in case
// the consumer _doesn't_ add styling afterward.
delete kbdObj._width;
delete kbdObj._height;
return classWrapper;
}

View file

@ -34,3 +34,8 @@ keyman-windows-coverity.tgz
# This file is still generated by devtools. TODO: eliminate in future
PathDefines.mak
# .res files, generated during build
desktop/kmshell/kmshell.res
engine/keyman/keyman.res
engine/keyman32/version64.res

View file

@ -1,40 +1,39 @@
# Keyman for Windows and Keyman Developer
# Keyman for Windows
## Build Prerequisites
* See [Windows Build Environment Configuration](../../docs/build/windows.md).
## Building Keyman for Windows and Keyman Developer
## Building Keyman for Windows
1. Start 'Developer Command Prompt for VS 2019'.
2. Run `nmake build` from the **windows/src** folder.
1. Start 'Git Bash' (part of Git for Windows).
2. Run `windows/src/build.sh`.
3. Artifacts from a successful build will be placed in **windows/bin** folder.
*Note*: running `nmake build` will currently reset the packages and path settings
*Note*: running `build.sh` will currently reset the packages and path settings
in your Delphi environment. If you use Delphi for other projects, you should
consider building Keyman under a login user dedicated to it, or in a VM.
Type `nmake` to see build targets. Common build targets are:
Type `build.sh` to see build targets and actions. Common build actions are:
* `nmake build`
: builds Keyman for Windows and Keyman Developer
* `build.sh build`
: builds Keyman for Windows
* `nmake clean`
* `build.sh clean`
: remove temporary files and build artifacts
* `nmake release`
* `build.sh publish`
: makes a release of all Keyman Windows projects
* `nmake install`
* `build.sh install`
: install some or all components to Program Files (requires elevated command prompt).
### Building without Delphi
It is possible to build all components that do _not_ require Delphi by adding
the environment variable `NODELPHI=1` before starting the build. Currently many
components are Delphi-based, but if you are working just in Keyman Core, the
compiler, or Keyman Engine's C++ components, you may be able to get away without
building them. In this situation, we recommend copying the relevant Delphi-built
It is possible to build all components that do _not_ require Delphi. Currently
many components are Delphi-based, but if you are working just in Keyman Core, or
Keyman Engine's C++ components, you may be able to get away without building
them. In this situation, we recommend copying the relevant Delphi-built
components into windows/bin folders from a compatible installed version of
Keyman for testing and debugging purposes.
@ -45,8 +44,8 @@ build, you will need to obtain valid code signing certificates. See
Certificates, below. Official release builds for Keyman are built in the Keyman
project's CI environment.
1. Start 'Developer Command Prompt for VS 2019'.
2. Run `nmake release` from the **windows/src** folder.
1. Start 'Git Bash'.
2. Run `windows/src/build.sh publish`.
3. Artifacts from a successful build will be placed in **windows/release**
folder.
4. **buildtools/help-keyman-com.sh** will push updated documentation to
@ -65,7 +64,7 @@ globally trusted. The environment variables `SC_PFX_SHA1` and `SC_PFX_SHA256`
can be set to custom certificate paths.
The Keyman repo can build test certificates for you. To build your own, run
`./build.sh certificates` from **common/windows/delphi/tools/certificates** to
`./common/windows/delphi/tools/certificates/build.sh certificates` to
build and install your own local root CA "**KeymanTestCA**" certificates. If you
specify a password for the certificate, you'll need to set that in the
environment variable `SC_PWD`.
@ -76,7 +75,7 @@ You do not need to install the **KeymanTest** certificates, only the
**KeymanTestCA** certificates.
If you have not already installed the **KeymanTestCA** certificates using the
`nmake` command above, to manually install the Keyman **KeymanTestCA**
`build.sh` command above, to manually install the Keyman **KeymanTestCA**
certificates, do the following in **common/windows/delphi/tools/certificates**:
1. Open the certificate and click 'Install certificate...' to open the

View file

@ -18,6 +18,7 @@ builder_describe \
":engine Keyman Engine for Windows" \
":desktop Keyman for Windows" \
":components=global/delphi Delphi components" \
":support Support tools" \
":test=test/unit-tests Shared unit tests" \
":fv=../../oem/firstvoices/windows/src/inst OEM FirstVoices for Windows app"

View file

@ -8,6 +8,7 @@ THIS_SCRIPT="$(readlink -f "${BASH_SOURCE[0]}")"
builder_describe "Keyman main host process (32-bit)" \
@/common/include \
@/common/windows/delphi \
@/windows/src/global/delphi \
clean configure build test publish install debug-manifest
builder_parse "$@"

View file

@ -1,38 +0,0 @@
#
# Support Makefile
#
!ifdef NODELPHI
TARGETS=etl2log texteditor
!else
TARGETS=oskbulkrenderer etl2log texteditor
!endif
CLEANS=clean-support
!include ..\Header.mak
# ----------------------------------------------------------------------
oskbulkrenderer: .virtual
cd $(ROOT)\src\support\oskbulkrenderer
$(MAKE) $(TARGET)
etl2log: .virtual
cd $(ROOT)\src\support\etl2log
$(MAKE) $(TARGET)
texteditor: .virtual
cd $(ROOT)\src\support\texteditor
$(MAKE) $(TARGET)
# ----------------------------------------------------------------------
clean-support:
cd $(ROOT)\src\support
-del version.txt
!include ..\Target.mak
# ----------------------------------------------------------------------
# EOF
# ----------------------------------------------------------------------

22
windows/src/support/build.sh Executable file
View file

@ -0,0 +1,22 @@
#!/usr/bin/env bash
## START STANDARD BUILD SCRIPT INCLUDE
# adjust relative paths as necessary
THIS_SCRIPT="$(readlink -f "${BASH_SOURCE[0]}")"
. "${THIS_SCRIPT%/*}/../../../resources/build/builder.inc.sh"
## END STANDARD BUILD SCRIPT INCLUDE
builder_describe \
"Keyman for Windows support tools" \
\
clean \
configure \
build \
test \
\
:oskbulkrenderer \
:etl2log \
:texteditor
builder_parse "$@"
builder_run_child_actions clean configure build test publish install

View file

@ -1,20 +0,0 @@
#
# charident Makefile
#
!include ..\..\Defines.mak
build: version.res dirs
$(DCC32) charident.dpr
$(COPY) charident.exe $(PROGRAM)\support
clean: def-clean
signcode:
$(SIGNCODE) /d "Character Identifier" $(PROGRAM)\support\charident.exe
wrap-symbols:
$(SYMSTORE) $(PROGRAM)\support\charident.exe /t keyman-windows
#TODO: $(SYMSTORE) $(DEBUGPATH)\support\charident.dbg /t keyman-windows
!include ..\..\Target.mak

View file

@ -1,22 +0,0 @@
#
# etl2log Makefile
#
!include ..\..\Defines.mak
build: version.res dirs
$(MSBUILD) etl2log.vcxproj $(MSBUILD_BUILD)
$(COPY) $(WIN32_TARGET_PATH)\etl2log.exe $(PROGRAM)\support
$(COPY) $(WIN32_TARGET_PATH)\etl2log.pdb $(DEBUGPATH)\support
clean: def-clean
$(MSBUILD) etl2log.vcxproj $(MSBUILD_CLEAN)
signcode:
$(SIGNCODE) /d "Keyman Engine Tools" $(PROGRAM)\support\etl2log.exe
wrap-symbols:
$(SYMSTORE) $(PROGRAM)\support\etl2log.exe /t keyman-windows
$(SYMSTORE) $(DEBUGPATH)\support\etl2log.pdb /t keyman-windows
!include ..\..\Target.mak

View file

@ -0,0 +1,40 @@
#!/usr/bin/env bash
## START STANDARD BUILD SCRIPT INCLUDE
# adjust relative paths as necessary
THIS_SCRIPT="$(readlink -f "${BASH_SOURCE[0]}")"
. "${THIS_SCRIPT%/*}/../../../../resources/build/builder.inc.sh"
## END STANDARD BUILD SCRIPT INCLUDE
builder_describe "etl2log" \
clean configure build test
builder_parse "$@"
#-------------------------------------------------------------------------------------------------------------------
source "$KEYMAN_ROOT/resources/build/win/environment.inc.sh"
WIN32_TARGET="$WIN32_TARGET_PATH/etl2log.exe"
builder_describe_outputs \
configure:project /resources/build/win/delphi_environment_generated.inc.sh \
build:project /windows/src/support/etl2log/$WIN32_TARGET
#-------------------------------------------------------------------------------------------------------------------
function do_clean() {
vs_msbuild etl2log.vcxproj //t:Clean
clean_windows_project_files
}
function do_build() {
create-windows-output-folders
build_version.res
vs_msbuild etl2log.vcxproj //t:Build "//p:Platform=Win32"
cp "$WIN32_TARGET" "$WINDOWS_PROGRAM_SUPPORT"
cp "$WIN32_TARGET_PATH/etl2log.pdb" "$WINDOWS_DEBUGPATH_SUPPORT"
}
builder_run_action clean:project do_clean
builder_run_action configure:project configure_windows_build_environment
builder_run_action build:project do_build
# builder_run_action test:project do_test

View file

@ -1,21 +0,0 @@
#
# KDebug Makefile
#
!include ..\..\Defines.mak
!ifdef DEBUG
NMCFG=kdebug - Win32 Debug
!else
NMCFG=kdebug - Win32 Release
!endif
install: dirs build
build: version.res
$(NMAKE) /f kdebug.mak "CFG=$(NMCFG)"
clean: def-clean
$(NMAKE) /f kdebug.mak "CFG=$(NMCFG)" CLEAN
!include ..\..\Target.mak

View file

@ -1,15 +0,0 @@
#
# Keycodetester Makefile
#
!include ..\..\Defines.mak
install: dirs build
$(COPY) keycodetester.exe $(PROGRAM)\bldutil
build:
$(DCC32) keycodetester.dpr
clean: def-clean
!include ..\..\Target.mak

View file

@ -1,24 +0,0 @@
#
# TODO: remove this project
#
!include ..\..\Defines.mak
build:
# version.res
$(DCC32) km_yim.dpr
rem $(TDSPACK) $(PROGRAM)\desktop\km_yim.exe km_yim.tds
rem $(TDS2DBG) $(PROGRAM)\desktop\km_yim.exe
$(WZZIP) inst_km_yim.zip km_yim.exe
# $(WZSE) inst_km_yim -setup -t inst_km_yim.dialog.txt -st "Tavultesoft Keyman Desktop Yahoo Messenger Addin" -c km_yim.exe
clean: def-clean
if exist inst_km_yim.zip del inst_km_yim.zip
signcode:
$(SIGNCODE) /d "Tavultesoft Keyman Desktop Yahoo Messenger Addin" inst_km_yim.exe
wrap-symbols:
rem
!include ..\..\Target.mak

View file

@ -1,19 +0,0 @@
#
# TODO: remove this project
#
!include ..\..\Defines.mak
build: version.res manifest.res
$(DCC32) kmkb0045.dpr
$(SENTRYTOOL_DELPHIPREP) kmkb0045.exe -dpr kmkb0045.dpr
$(TDS2DBG) kmkb0045.exe
$(COPY) kmkb0045.exe $(PROGRAM)\support
clean: def-clean
signcode:
$(SIGNCODE) /d "Tavultesoft KMKB0045" $(PROGRAM)\support\kmkb0045.exe
!include ..\..\Target.mak

View file

@ -1,24 +0,0 @@
#
# oskbulkrenderer Makefile
#
!include ..\..\Defines.mak
build: version.res dirs
$(DELPHI_MSBUILD) oskbulkrenderer.dproj "/p:Platform=Win32"
$(SENTRYTOOL_DELPHIPREP) $(WIN32_TARGET_PATH)\oskbulkrenderer.exe -dpr oskbulkrenderer.dpr
$(TDS2DBG) $(WIN32_TARGET_PATH)\oskbulkrenderer.exe
$(COPY) $(WIN32_TARGET_PATH)\oskbulkrenderer.exe $(PROGRAM)\support
if exist $(WIN32_TARGET_PATH)\oskbulkrenderer.dbg $(COPY) $(WIN32_TARGET_PATH)\oskbulkrenderer.dbg $(DEBUGPATH)\support
clean: def-clean
-rd /s/q Win32
signcode:
rem Not signing this utility
wrap-symbols:
@rem
!include ..\..\Target.mak

View file

@ -0,0 +1,39 @@
#!/usr/bin/env bash
## START STANDARD BUILD SCRIPT INCLUDE
# adjust relative paths as necessary
THIS_SCRIPT="$(readlink -f "${BASH_SOURCE[0]}")"
. "${THIS_SCRIPT%/*}/../../../../resources/build/builder.inc.sh"
## END STANDARD BUILD SCRIPT INCLUDE
builder_describe "oskbuildrenderer" \
clean configure build test
builder_parse "$@"
#-------------------------------------------------------------------------------------------------------------------
source "$KEYMAN_ROOT/resources/build/win/environment.inc.sh"
WIN32_TARGET="$WIN32_TARGET_PATH/oskbulkrenderer.exe"
builder_describe_outputs \
configure:project /resources/build/win/delphi_environment_generated.inc.sh \
build:project /windows/src/support/oskbulkrenderer/$WIN32_TARGET
#-------------------------------------------------------------------------------------------------------------------
function do_clean() {
clean_windows_project_files
}
function do_build() {
create-windows-output-folders
build_version.res
delphi_msbuild oskbulkrenderer.dproj "//p:Platform=Win32"
cp "$WIN32_TARGET" "$WINDOWS_PROGRAM_SUPPORT"
}
builder_run_action clean:project do_clean
builder_run_action configure:project configure_windows_build_environment
builder_run_action build:project do_build
# builder_run_action test:project do_test

View file

@ -1,15 +0,0 @@
#
# richedit_examine Makefile
#
!include ..\..\Defines.mak
install: dirs build
$(COPY) richedit_examine.exe $(PROGRAM)\bldutil
build: version.res
$(DCC32) richedit_examine.dpr
clean: def-clean
!include ..\..\Target.mak

View file

@ -1,36 +0,0 @@
#
# Keyman Text Editor Makefile
#
!include ..\..\Defines.mak
build:
$(MSBUILD) editor.vcxproj $(MSBUILD_BUILD) /p:Platform=x86
$(MSBUILD) editor.vcxproj $(MSBUILD_BUILD) /p:Platform=x64
$(COPY) $(WIN32_TARGET_PATH)\editor32.exe $(PROGRAM)\support
$(COPY) $(WIN32_TARGET_PATH)\editor32.pdb $(DEBUGPATH)\support
$(COPY) $(X64_TARGET_PATH)\editor64.exe $(PROGRAM)\support
$(COPY) $(X64_TARGET_PATH)\editor64.pdb $(DEBUGPATH)\support
clean: def-clean
$(MSBUILD) $(MSBUILD_CLEAN) editor.sln
signcode:
$(SIGNCODE) /d "Text Editor for testing Keyman" $(PROGRAM)\support\editor32.exe
$(SIGNCODE) /d "Text Editor for testing Keyman" $(PROGRAM)\support\editor64.exe
install:
$(COPY) $(PROGRAM)\support\editor32.exe "$(INSTALLPATH_KEYMANENGINE)"
$(COPY) $(PROGRAM)\support\editor64.exe "$(INSTALLPATH_KEYMANENGINE)"
wrap-symbols:
$(SYMSTORE) $(PROGRAM)\support\editor32.exe /t keyman-windows
$(SYMSTORE) $(PROGRAM)\support\editor64.exe /t keyman-windows
$(SYMSTORE) $(DEBUGPATH)\support\editor32.pdb /t keyman-windows
$(SYMSTORE) $(DEBUGPATH)\support\editor64.pdb /t keyman-windows
!include ..\..\Target.mak
# ----------------------------------------------------------------------
# EOF
# ----------------------------------------------------------------------

View file

@ -0,0 +1,44 @@
#!/usr/bin/env bash
## START STANDARD BUILD SCRIPT INCLUDE
# adjust relative paths as necessary
THIS_SCRIPT="$(readlink -f "${BASH_SOURCE[0]}")"
. "${THIS_SCRIPT%/*}/../../../../resources/build/builder.inc.sh"
## END STANDARD BUILD SCRIPT INCLUDE
builder_describe "texteditor" \
clean configure build test
builder_parse "$@"
#-------------------------------------------------------------------------------------------------------------------
source "$KEYMAN_ROOT/resources/build/win/environment.inc.sh"
WIN32_TARGET="$WIN32_TARGET_PATH/editor32.exe"
X64_TARGET="$X64_TARGET_PATH/editor64.exe"
builder_describe_outputs \
configure:project /resources/build/win/delphi_environment_generated.inc.sh \
build:project /windows/src/support/texteditor/$WIN32_TARGET
#-------------------------------------------------------------------------------------------------------------------
function do_clean() {
vs_msbuild Editor.vcxproj //t:Clean
clean_windows_project_files
}
function do_build() {
create-windows-output-folders
# build_version.res
vs_msbuild Editor.vcxproj //t:Build "//p:Platform=Win32"
vs_msbuild Editor.vcxproj //t:Build "//p:Platform=x64"
cp "$WIN32_TARGET" "$WINDOWS_PROGRAM_SUPPORT"
cp "$X64_TARGET" "$WINDOWS_PROGRAM_SUPPORT"
cp "$WIN32_TARGET_PATH/editor32.pdb" "$WINDOWS_DEBUGPATH_SUPPORT"
cp "$X64_TARGET_PATH/editor64.pdb" "$WINDOWS_DEBUGPATH_SUPPORT"
}
builder_run_action clean:project do_clean
builder_run_action configure:project configure_windows_build_environment
builder_run_action build:project do_build
# builder_run_action test:project do_test

View file

@ -1,15 +0,0 @@
#
# windowinfo Makefile
#
!include ..\..\Defines.mak
install: dirs build
$(COPY) windowinfo.exe $(PROGRAM)\bldutil
build: version.res
$(DCC32) windowinfo.dpr
clean: def-clean
!include ..\..\Target.mak

View file

@ -1,26 +0,0 @@
#
# Integration Tests Makefile.
#
# ----------------------------------------------------------------------
TARGETS=keymanapi
test:
$(MAKE) "TARGET=test" $(TARGETS)
!include ..\..\Header.mak
# ----------------------------------------------------------------------
keymanapi:
cd $(ROOT)\src\test\integration-tests\keymanapi
$(MAKE) $(TARGET)
# ----------------------------------------------------------------------
!include ..\..\Target.mak
# ----------------------------------------------------------------------
# EOF
# ----------------------------------------------------------------------

View file

@ -1,23 +0,0 @@
#
# Integration tests for keymanapi
#
!include ..\..\..\Defines.mak
!ifdef EXCLUDE_ELEVATED
TEST_MODE=--exclude:Elevated
!endif
test: build
$(WIN32_TARGET_PATH)\keymanapi_test.exe -b -exit:continue $(TEST_MODE)
$(WIN64_TARGET_PATH)\keymanapi_test.exe -b -exit:continue $(TEST_MODE)
build:
$(DELPHI_MSBUILD) "/p:Platform=Win32" keymanapi_test.dproj
$(DELPHI_MSBUILD) "/p:Platform=Win64" keymanapi_test.dproj
clean: def-clean
-rd /s/q Win32
-rd /s/q Win64
!include ..\..\..\Target.mak

View file

@ -1,16 +0,0 @@
#
# REGRESSIONTEST Makefile
#
!include ..\..\Defines.mak
build: dirs
$(DCC32) regressiontest.dpr
$(COPY) regressiontest.exe $(PROGRAM)\support
clean: def-clean
cd tests
$(MAKE) clean
!include ..\..\Target.mak

View file

@ -1,11 +0,0 @@
!include ..\..\..\Defines.mak
all:
for %d in (*.kmn) do $(PROGRAM)\bin\kmc.cmd build "%d"
.kmn.kmx:
&$(PROGRAM)\bin\kmc.cmd build $**
clean:
-del *.kmx

View file

@ -1,18 +0,0 @@
#
# test_httpuploader Makefile
#
!include ..\..\Defines.mak
build: version.res manifest.res
$(DCC32) test_httpuploader.dpr
icons:
rc icons.rc
clean: def-clean
signcode:
rem no signcode
!include ..\..\Target.mak