feat(developer): compile kmn files with kmc in tike

This commit is contained in:
Marc Durdin 2023-09-01 20:40:16 +04:00
parent 41f370ede6
commit 44d57e8041
5 changed files with 15 additions and 136 deletions

View file

@ -3,6 +3,7 @@ import { platform } from 'os';
import { KmnCompiler } from '@keymanapp/kmc-kmn';
import { CompilerOptions, CompilerCallbacks, KeymanFileTypes } from '@keymanapp/common-types';
import { BuildActivity } from './BuildActivity.js';
import * as fs from 'fs';
export class BuildKmnKeyboard extends BuildActivity {
public get name(): string { return 'Keyman keyboard'; }
@ -21,7 +22,12 @@ export class BuildKmnKeyboard extends BuildActivity {
}
infile = getPosixAbsolutePath(infile);
try {
fs.mkdirSync(path.dirname(options.outFile), {recursive: true});
} catch(e) {
// TODO: error
return false;
}
return compiler.run(infile, options);
}
}

View file

@ -29,8 +29,6 @@ uses
Keyman.Developer.System.Project.ProjectFile;
type
TProjectFileActionCompileSuccessEvent = procedure(Sender: TObject; const SourceFilename, DestFilename: string) of object;
TShellProjectFile = class(TProjectFile)
protected
function GetRelativeOrder: Integer; override;
@ -38,12 +36,8 @@ type
end;
TOpenableProjectFile = class(TShellProjectFile)
private
class var FOnCompileSuccess: TProjectFileActionCompileSuccessEvent;
protected
function GetRelativeOrder: Integer; override;
public
class property OnCompileSuccess: TProjectFileActionCompileSuccessEvent read FOnCompileSuccess write FOnCompileSuccess;
end;
implementation

View file

@ -14,13 +14,10 @@ uses
type
TkmnProjectFileAction = class(TkmnProjectFile)
private
function CompileVisualKeyboard(const AKVKSourceFile, AKVKTargetFile: string): Boolean;
procedure CheckFilenameConventions;
public
function CompileKeyboard: Boolean;
function Clean: Boolean;
function DoSetCompilerOptions(addVersion,
useLegacyCompiler: Boolean): Boolean;
end;
implementation
@ -31,41 +28,10 @@ uses
System.Variants,
Winapi.Windows,
CompileKeymanWeb,
compile,
Keyman.Developer.System.Project.ProjectLog,
Keyman.System.KeyboardUtils,
VisualKeyboard;
function TkmnProjectFileAction.CompileVisualKeyboard(const AKVKSourceFile, AKVKTargetFile: string): Boolean;
begin
with TVisualKeyboard.Create do
try
try
LoadFromFile(AKVKSourceFile);
except
on E:Exception do
begin
OwnerProject.Log(plsError, AKVKSourceFile, 'Invalid visual keyboard: '+E.Message, CERR_ERROR, 0);
Exit(False);
end;
end;
if not SameFileName(AKVKSourceFile, AKVKTargetFile) then
try
Header.AssociatedKeyboard := ChangeFileExt(ExtractFileName(Self.FileName), '');
SaveToFile(AKVKTargetFile, kvksfBinary);
except
on E:Exception do
begin
OwnerProject.Log(plsError, AKVKSourceFile, 'Could not save visual keyboard '+AKVKSourceFile+' to '+AKVKTargetFile+': '+E.ClassName+','+E.Message, CERR_ERROR, 0);
Exit(False);
end;
end;
finally
Free;
end;
Result := True;
end;
Keyman.Developer.System.KmcWrapper;
function TkmnProjectFileAction.Clean: Boolean;
var
@ -80,8 +46,8 @@ begin
begin
FJS := TKeyboardUtils.GetKeymanWebCompiledFileName(FileName);
CleanFile(FJS); // keyboard-x.y.js
CleanFile(ChangeFileExt(FJS, '') + '_load.js'); // keyboard-x.y_load.js
CleanFile(ChangeFileExt(FJS, '.json'), True); // keyboard-x.y_load.js
// CleanFile(ChangeFileExt(FJS, '') + '_load.js'); // keyboard-x.y_load.js
// CleanFile(ChangeFileExt(FJS, '.json'), True); // keyboard-x.y_load.js
end;
Result := True;
@ -108,99 +74,15 @@ begin
end;
end;
function TkmnProjectFileAction.DoSetCompilerOptions(addVersion: Boolean; useLegacyCompiler: Boolean): Boolean;
var
options: COMPILER_OPTIONS;
begin
TProject.CompilerMessageFile := Self;
options.dwSize := sizeof(COMPILER_OPTIONS);
options.ShouldAddCompilerVersion := addVersion;
// TODO: useLegacyCompiler means we switch to kmcmpdll vs kmc
if not SetCompilerOptions(@options, ProjectCompilerMessage) then
begin
Log(plsFatal, 'Unable to set compiler options', CERR_FATAL, 0);
Exit(False);
end;
Result := True;
end;
function TkmnProjectFileAction.CompileKeyboard: Boolean;
var
KMXFileName: String;
FOutFileName: string;
ckw: TCompileKeymanWeb;
FKVKSourceFile: string;
FKVKTargetFile: string;
TargetNames: string;
w: TKmcWrapper;
begin
TProject.CompilerMessageFile := Self;
HasCompileWarning := False; // I4706
FKVKSourceFile := ExtractFilePath(FileName) + ExtractFileName(KVKFileName);
FKVKTargetFile := OwnerProject.GetTargetFileName(ChangeFileExt(FKVKSourceFile, '.kvk'), FileName, FileVersion);
w := TKmcWrapper.Create;
try
CheckFilenameConventions;
if Targets * KMXKeymanTargets <> [] then
begin
TargetNames := KeymanTargetsToNames(Targets * KMXKeymanTargets);
Log(plsInfo, Format('Compiling ''%s'' %sfor %s...', [Filename, IfThen(Debug, 'with debug symbols ', ''), TargetNames]), 0, 0);
//compile the keyboard
KMXFileName := TargetFileName;
ForceDirectories(ExtractFileDir(KMXFileName));
//KMXFileName := ChangeFileExt(FileName, '.kmx');
Result := CompileKeyboardFile(PChar(FileName), PChar(KMXFileName), Debug,
OwnerProject.Options.CompilerWarningsAsErrors, OwnerProject.Options.WarnDeprecatedCode, // I4865 // I4866
ProjectCompilerMessage) > 0;
if Result then
begin
if KVKFileName <> '' then
Result := CompileVisualKeyboard(FKVKSourceFile, FKVKTargetFile);
end;
if HasCompileWarning and (WarnAsError or OwnerProject.Options.CompilerWarningsAsErrors) then Result := False; // I4706
if Result
then Log(plsSuccess, Format('''%s'' was compiled successfully for %s to ''%s''.', [FileName, TargetNames, KMXFileName]), 0, 0) // I4504
else Log(plsFailure, Format('''%s'' was not compiled successfully for %s.', [FileName, TargetNames]), 0, 0); // I4504
end
else
Result := True; // I4564
// compile keyboard to web
if Result and (Targets * KMWKeymanTargets <> []) then
begin
TargetNames := KeymanTargetsToNames(Targets * KMWKeymanTargets);
Log(plsInfo, Format('Compiling ''%s'' %sfor %s...', [Filename, IfThen(Debug, 'with debug symbols ', ''), TargetNames]), 0, 0);
ckw := TCompileKeymanWeb.Create;
try
FOutFilename := JSTargetFileName;
ForceDirectories(ExtractFileDir(FOutFileName));
if KVKFileName <> '' then
Result := CompileVisualKeyboard(FKVKSourceFile, FKVKTargetFile);
if Result then
Result := ckw.Compile(OwnerProject, FileName, FOutFileName, Debug, ProjectCompilerMessageW); // I3681 // I4140 // I4865 // I4866
if HasCompileWarning and (WarnAsError or OwnerProject.Options.CompilerWarningsAsErrors) then Result := False; // I4706
if Result
then Log(plsSuccess, Format('''%s'' was compiled successfully for %s to ''%s''.', [FileName, TargetNames, FOutFileName]), 0, 0) // I4504
else Log(plsFailure, Format('''%s'' was not compiled successfully for %s.', [FileName, TargetNames]), 0, 0); // I4504
if Result and Assigned(OnCompileSuccess) then
OnCompileSuccess(Self, FileName, FOutFileName);
finally
ckw.Free;
end;
end;
Result := w.Compile(Self, FileName, TargetFilename, Debug);
finally
TProject.CompilerMessageFile := nil;
w.Free;
end;
end;

View file

@ -39,7 +39,7 @@ var
begin
w := TKmcWrapper.Create;
try
Result := w.Compile(Self, FileName, OutputFilename, False);
Result := w.Compile(Self, FileName, TargetFilename, False);
// TODO(lowpri): FDebug flag
finally
w.Free;

View file

@ -131,9 +131,6 @@ begin
frmMessages.DoShowForm;
Result :=
// Note: we do not surface the ability to exclude version information from
// the TIKE compiler; this must be done from kmcomp.exe.
ProjectFile.DoSetCompilerOptions(True, FKeymanDeveloperOptions.UseLegacyCompiler) and
ProjectFile.CompileKeyboard;
if Result and