mirror of
https://github.com/taigrr/wails.git
synced 2026-04-08 16:11:37 -07:00
Compare commits
8 Commits
v2.0.0-alp
...
v2.0.0-alp
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
cf23bffc67 | ||
|
|
d70f6fffe7 | ||
|
|
54c99fc386 | ||
|
|
86c1ea5e6a | ||
|
|
b394c1914c | ||
|
|
91c2ddf155 | ||
|
|
712ad96d2a | ||
|
|
86b4a4f2f5 |
@@ -39,6 +39,9 @@ func AddBuildSubcommand(app *clir.Cli, w io.Writer) {
|
||||
compilerCommand := "go"
|
||||
command.StringFlag("compiler", "Use a different go compiler to build, eg go1.15beta1", &compilerCommand)
|
||||
|
||||
compress := false
|
||||
command.BoolFlag("compress", "Compress final binary", &compress)
|
||||
|
||||
// Setup Platform flag
|
||||
platform := runtime.GOOS
|
||||
command.StringFlag("platform", "Platform to target", &platform)
|
||||
@@ -114,6 +117,10 @@ func AddBuildSubcommand(app *clir.Cli, w io.Writer) {
|
||||
return fmt.Errorf("platform %s is not supported", platform)
|
||||
}
|
||||
|
||||
if compress && platform == "darwin/universal" {
|
||||
println("Warning: compress flag unsupported for universal binaries. Ignoring.")
|
||||
compress = false
|
||||
}
|
||||
// Create BuildOptions
|
||||
buildOptions := &build.Options{
|
||||
Logger: logger,
|
||||
@@ -127,6 +134,7 @@ func AddBuildSubcommand(app *clir.Cli, w io.Writer) {
|
||||
KeepAssets: keepAssets,
|
||||
AppleIdentity: appleIdentity,
|
||||
Verbosity: verbosity,
|
||||
Compress: compress,
|
||||
}
|
||||
|
||||
// Calculate platform and arch
|
||||
@@ -147,10 +155,12 @@ func AddBuildSubcommand(app *clir.Cli, w io.Writer) {
|
||||
}
|
||||
|
||||
// Write out the system information
|
||||
fmt.Fprintf(w, "\n")
|
||||
fmt.Fprintf(w, "App Type: \t%s\n", buildOptions.OutputType)
|
||||
fmt.Fprintf(w, "Platform: \t%s\n", buildOptions.Platform)
|
||||
fmt.Fprintf(w, "Arch: \t%s\n", buildOptions.Arch)
|
||||
fmt.Fprintf(w, "Compiler: \t%s\n", buildOptions.Compiler)
|
||||
fmt.Fprintf(w, "Compress: \t%t\n", buildOptions.Compress)
|
||||
fmt.Fprintf(w, "Build Mode: \t%s\n", buildModeText)
|
||||
fmt.Fprintf(w, "Package: \t%t\n", buildOptions.Pack)
|
||||
fmt.Fprintf(w, "Clean Build Dir: \t%t\n", buildOptions.CleanBuildDirectory)
|
||||
|
||||
@@ -1,3 +1,3 @@
|
||||
package main
|
||||
|
||||
var version = "v2.0.0-alpha.58"
|
||||
var version = "v2.0.0-alpha.61"
|
||||
|
||||
@@ -1049,22 +1049,26 @@ void SetDebug(void *applicationPointer, int flag) {
|
||||
void AddContextMenu(struct Application *app, const char *contextMenuJSON) {
|
||||
// Guard against calling during shutdown
|
||||
if( app->shuttingDown ) return;
|
||||
|
||||
AddContextMenuToStore(app->contextMenuStore, contextMenuJSON);
|
||||
ON_MAIN_THREAD (
|
||||
AddContextMenuToStore(app->contextMenuStore, contextMenuJSON);
|
||||
);
|
||||
}
|
||||
|
||||
void UpdateContextMenu(struct Application *app, const char* contextMenuJSON) {
|
||||
// Guard against calling during shutdown
|
||||
if( app->shuttingDown ) return;
|
||||
|
||||
UpdateContextMenuInStore(app->contextMenuStore, contextMenuJSON);
|
||||
ON_MAIN_THREAD(
|
||||
UpdateContextMenuInStore(app->contextMenuStore, contextMenuJSON);
|
||||
);
|
||||
}
|
||||
|
||||
void AddTrayMenu(struct Application *app, const char *trayMenuJSON) {
|
||||
// Guard against calling during shutdown
|
||||
if( app->shuttingDown ) return;
|
||||
|
||||
AddTrayMenuToStore(TrayMenuStoreSingleton, trayMenuJSON);
|
||||
ON_MAIN_THREAD(
|
||||
AddTrayMenuToStore(TrayMenuStoreSingleton, trayMenuJSON);
|
||||
);
|
||||
}
|
||||
|
||||
void SetTrayMenu(struct Application *app, const char* trayMenuJSON) {
|
||||
@@ -1372,211 +1376,6 @@ void parseMenuRole(struct Application *app, id parentMenu, JsonNode *item) {
|
||||
|
||||
}
|
||||
|
||||
id parseTextMenuItem(struct Application *app, id parentMenu, const char *title, const char *menuid, bool disabled, const char *acceleratorkey, const char **modifiers, const char *menuCallback) {
|
||||
id item = ALLOC("NSMenuItem");
|
||||
id wrappedId = ((id(*)(id, SEL, const char*))objc_msgSend)(c("NSValue"), s("valueWithPointer:"), menuid);
|
||||
msg_id(item, s("setRepresentedObject:"), wrappedId);
|
||||
|
||||
id key = processAcceleratorKey(acceleratorkey);
|
||||
((id(*)(id, SEL, id, SEL, id))objc_msgSend)(item, s("initWithTitle:action:keyEquivalent:"), str(title),
|
||||
s(menuCallback), key);
|
||||
|
||||
msg_bool(item, s("setEnabled:"), !disabled);
|
||||
msg_reg(item, s("autorelease"));
|
||||
|
||||
// Process modifiers
|
||||
if( modifiers != NULL ) {
|
||||
unsigned long modifierFlags = parseModifiers(modifiers);
|
||||
msg_int(item, s("setKeyEquivalentModifierMask:"), modifierFlags);
|
||||
}
|
||||
msg_id(parentMenu, s("addItem:"), item);
|
||||
|
||||
return item;
|
||||
}
|
||||
|
||||
id parseCheckboxMenuItem(struct Application *app, id parentmenu, const char
|
||||
*title, const char *menuid, bool disabled, bool checked, const char *key,
|
||||
struct hashmap_s *menuItemMap, const char *checkboxCallbackFunction) {
|
||||
id item = ALLOC("NSMenuItem");
|
||||
|
||||
// Store the item in the menu item map
|
||||
hashmap_put(menuItemMap, (char*)menuid, strlen(menuid), item);
|
||||
|
||||
id wrappedId = msg_id(c("NSValue"), s("valueWithPointer:"), (id)menuid);
|
||||
msg_id(item, s("setRepresentedObject:"), wrappedId);
|
||||
((id(*)(id, SEL, id, SEL, id))objc_msgSend)(item, s("initWithTitle:action:keyEquivalent:"), str(title), s(checkboxCallbackFunction), str(key));
|
||||
msg_bool(item, s("setEnabled:"), !disabled);
|
||||
msg_reg(item, s("autorelease"));
|
||||
msg_int(item, s("setState:"), (checked ? NSControlStateValueOn : NSControlStateValueOff));
|
||||
msg_id(parentmenu, s("addItem:"), item);
|
||||
return item;
|
||||
}
|
||||
|
||||
id parseRadioMenuItem(struct Application *app, id parentmenu, const char *title,
|
||||
const char *menuid, bool disabled, bool checked, const char *acceleratorkey,
|
||||
struct hashmap_s *menuItemMap, const char *radioCallbackFunction) {
|
||||
id item = ALLOC("NSMenuItem");
|
||||
|
||||
// Store the item in the menu item map
|
||||
hashmap_put(menuItemMap, (char*)menuid, strlen(menuid), item);
|
||||
|
||||
id wrappedId = msg_id(c("NSValue"), s("valueWithPointer:"), (id)menuid);
|
||||
msg_id(item, s("setRepresentedObject:"), wrappedId);
|
||||
|
||||
id key = processAcceleratorKey(acceleratorkey);
|
||||
|
||||
((id(*)(id, SEL, id, SEL, id))objc_msgSend)(item, s("initWithTitle:action:keyEquivalent:"), str(title), s(radioCallbackFunction), key);
|
||||
|
||||
msg_bool(item, s("setEnabled:"), !disabled);
|
||||
msg_reg(item, s("autorelease"));
|
||||
msg_int(item, s("setState:"), (checked ? NSControlStateValueOn : NSControlStateValueOff));
|
||||
|
||||
msg_id(parentmenu, s("addItem:"), item);
|
||||
return item;
|
||||
|
||||
}
|
||||
|
||||
void parseMenuItem(struct Application *app, id parentMenu, JsonNode *item,
|
||||
struct hashmap_s *menuItemMap, const char *checkboxCallbackFunction, const char
|
||||
*radioCallbackFunction, const char *menuCallbackFunction) {
|
||||
|
||||
// Check if this item is hidden and if so, exit early!
|
||||
bool hidden = false;
|
||||
getJSONBool(item, "Hidden", &hidden);
|
||||
if( hidden ) {
|
||||
return;
|
||||
}
|
||||
|
||||
// Get the role
|
||||
JsonNode *role = json_find_member(item, "Role");
|
||||
if( role != NULL ) {
|
||||
parseMenuRole(app, parentMenu, role);
|
||||
return;
|
||||
}
|
||||
|
||||
// Check if this is a submenu
|
||||
JsonNode *submenu = json_find_member(item, "SubMenu");
|
||||
if( submenu != NULL ) {
|
||||
// Get the label
|
||||
JsonNode *menuNameNode = json_find_member(item, "Label");
|
||||
const char *name = "";
|
||||
if ( menuNameNode != NULL) {
|
||||
name = menuNameNode->string_;
|
||||
}
|
||||
|
||||
id thisMenuItem = createMenuItemNoAutorelease(str(name), NULL, "");
|
||||
id thisMenu = createMenu(str(name));
|
||||
|
||||
msg_id(thisMenuItem, s("setSubmenu:"), thisMenu);
|
||||
msg_id(parentMenu, s("addItem:"), thisMenuItem);
|
||||
|
||||
// Loop over submenu items
|
||||
JsonNode *item;
|
||||
json_foreach(item, submenu) {
|
||||
// Get item label
|
||||
parseMenuItem(app, thisMenu, item, menuItemMap, checkboxCallbackFunction, radioCallbackFunction, menuCallbackFunction);
|
||||
}
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
// This is a user menu. Get the common data
|
||||
// Get the label
|
||||
const char *label = getJSONString(item, "Label");
|
||||
if ( label == NULL) {
|
||||
label = "(empty)";
|
||||
}
|
||||
|
||||
const char *menuid = getJSONString(item, "ID");
|
||||
if ( menuid == NULL) {
|
||||
menuid = "";
|
||||
}
|
||||
|
||||
bool disabled = false;
|
||||
getJSONBool(item, "Disabled", &disabled);
|
||||
|
||||
// Get the Accelerator
|
||||
JsonNode *accelerator = json_find_member(item, "Accelerator");
|
||||
const char *acceleratorkey = NULL;
|
||||
const char **modifiers = NULL;
|
||||
|
||||
// If we have an accelerator
|
||||
if( accelerator != NULL ) {
|
||||
// Get the key
|
||||
acceleratorkey = getJSONString(accelerator, "Key");
|
||||
// Check if there are modifiers
|
||||
JsonNode *modifiersList = json_find_member(accelerator, "Modifiers");
|
||||
if ( modifiersList != NULL ) {
|
||||
// Allocate an array of strings
|
||||
int noOfModifiers = json_array_length(modifiersList);
|
||||
|
||||
// Do we have any?
|
||||
if (noOfModifiers > 0) {
|
||||
modifiers = malloc(sizeof(const char *) * (noOfModifiers + 1));
|
||||
JsonNode *modifier;
|
||||
int count = 0;
|
||||
// Iterate the modifiers and save a reference to them in our new array
|
||||
json_foreach(modifier, modifiersList) {
|
||||
// Get modifier name
|
||||
modifiers[count] = modifier->string_;
|
||||
count++;
|
||||
}
|
||||
// Null terminate the modifier list
|
||||
modifiers[count] = NULL;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// Get the Type
|
||||
JsonNode *type = json_find_member(item, "Type");
|
||||
if( type != NULL ) {
|
||||
|
||||
if( STREQ(type->string_, "Text")) {
|
||||
parseTextMenuItem(app, parentMenu, label, menuid, disabled, acceleratorkey, modifiers, menuCallbackFunction);
|
||||
}
|
||||
else if ( STREQ(type->string_, "Separator")) {
|
||||
addSeparator(parentMenu);
|
||||
}
|
||||
else if ( STREQ(type->string_, "Checkbox")) {
|
||||
// Get checked state
|
||||
bool checked = false;
|
||||
getJSONBool(item, "Checked", &checked);
|
||||
|
||||
parseCheckboxMenuItem(app, parentMenu, label, menuid, disabled, checked, "", menuItemMap, checkboxCallbackFunction);
|
||||
}
|
||||
else if ( STREQ(type->string_, "Radio")) {
|
||||
// Get checked state
|
||||
bool checked = false;
|
||||
getJSONBool(item, "Checked", &checked);
|
||||
|
||||
parseRadioMenuItem(app, parentMenu, label, menuid, disabled, checked, "", menuItemMap, radioCallbackFunction);
|
||||
}
|
||||
|
||||
if ( modifiers != NULL ) {
|
||||
free(modifiers);
|
||||
}
|
||||
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
void parseMenu(struct Application *app, id parentMenu, JsonNode *menu, struct hashmap_s *menuItemMap, const char *checkboxCallbackFunction, const char *radioCallbackFunction, const char *menuCallbackFunction) {
|
||||
JsonNode *items = json_find_member(menu, "Items");
|
||||
if( items == NULL ) {
|
||||
// Parse error!
|
||||
Fatal(app, "Unable to find Items in Menu");
|
||||
return;
|
||||
}
|
||||
|
||||
// Iterate items
|
||||
JsonNode *item;
|
||||
json_foreach(item, items) {
|
||||
// Get item label
|
||||
parseMenuItem(app, parentMenu, item, menuItemMap, checkboxCallbackFunction, radioCallbackFunction, menuCallbackFunction);
|
||||
}
|
||||
}
|
||||
|
||||
void dumpMemberList(const char *name, id *memberList) {
|
||||
void *member = memberList[0];
|
||||
int count = 0;
|
||||
@@ -1589,43 +1388,6 @@ void dumpMemberList(const char *name, id *memberList) {
|
||||
printf("]\n");
|
||||
}
|
||||
|
||||
void processRadioGroup(JsonNode *radioGroup, struct hashmap_s *menuItemMap,
|
||||
struct hashmap_s *radioGroupMap) {
|
||||
|
||||
int groupLength;
|
||||
getJSONInt(radioGroup, "Length", &groupLength);
|
||||
JsonNode *members = json_find_member(radioGroup, "Members");
|
||||
JsonNode *member;
|
||||
|
||||
// Allocate array
|
||||
size_t arrayLength = sizeof(id)*(groupLength+1);
|
||||
id memberList[arrayLength];
|
||||
|
||||
// Build the radio group items
|
||||
int count=0;
|
||||
json_foreach(member, members) {
|
||||
// Get menu by id
|
||||
id menuItem = (id)hashmap_get(menuItemMap, (char*)member->string_, strlen(member->string_));
|
||||
// Save Member
|
||||
memberList[count] = menuItem;
|
||||
count = count + 1;
|
||||
}
|
||||
// Null terminate array
|
||||
memberList[groupLength] = 0;
|
||||
|
||||
// dumpMemberList("memberList", memberList);
|
||||
|
||||
// Store the members
|
||||
json_foreach(member, members) {
|
||||
// Copy the memberList
|
||||
char *newMemberList = (char *)malloc(arrayLength);
|
||||
memcpy(newMemberList, memberList, arrayLength);
|
||||
// add group to each member of group
|
||||
hashmap_put(radioGroupMap, member->string_, strlen(member->string_), newMemberList);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
// updateMenu replaces the current menu with the given one
|
||||
void updateMenu(struct Application *app, const char *menuAsJSON) {
|
||||
Debug(app, "Menu is now: %s", menuAsJSON);
|
||||
@@ -1649,7 +1411,9 @@ void SetApplicationMenu(struct Application *app, const char *menuAsJSON) {
|
||||
}
|
||||
|
||||
// Update menu
|
||||
updateMenu(app, menuAsJSON);
|
||||
ON_MAIN_THREAD (
|
||||
updateMenu(app, menuAsJSON);
|
||||
);
|
||||
}
|
||||
|
||||
void processDialogIcons(struct hashmap_s *hashmap, const unsigned char *dialogIcons[]) {
|
||||
|
||||
@@ -617,14 +617,13 @@ id createAttributedString(const char* title, const char* fontName, int fontSize,
|
||||
(CGFloat)a / (CGFloat)255.0);
|
||||
id NSForegroundColorAttributeName = lookupStringConstant(str("NSForegroundColorAttributeName"));
|
||||
msg_id_id(dictionary, s("setObject:forKey:"), colour, NSForegroundColorAttributeName);
|
||||
msg_reg(colour, s("autorelease"));
|
||||
}
|
||||
}
|
||||
|
||||
id attributedString = ALLOC("NSMutableAttributedString");
|
||||
msg_id_id(attributedString, s("initWithString:attributes:"), str(title), dictionary);
|
||||
msg_reg(attributedString, s("autorelease"));
|
||||
msg_reg(dictionary, s("release"));
|
||||
msg_reg(dictionary, s("autorelease"));
|
||||
return attributedString;
|
||||
}
|
||||
|
||||
@@ -695,38 +694,6 @@ void processMenuItem(Menu *menu, id parentMenu, JsonNode *item) {
|
||||
return;
|
||||
}
|
||||
|
||||
// Check if this is a submenu
|
||||
JsonNode *submenu = json_find_member(item, "SubMenu");
|
||||
if( submenu != NULL ) {
|
||||
// Get the label
|
||||
JsonNode *menuNameNode = json_find_member(item, "Label");
|
||||
const char *name = "";
|
||||
if ( menuNameNode != NULL) {
|
||||
name = menuNameNode->string_;
|
||||
}
|
||||
|
||||
id thisMenuItem = createMenuItemNoAutorelease(str(name), NULL, "");
|
||||
id thisMenu = createMenu(str(name));
|
||||
|
||||
msg_id(thisMenuItem, s("setSubmenu:"), thisMenu);
|
||||
msg_id(parentMenu, s("addItem:"), thisMenuItem);
|
||||
|
||||
JsonNode *submenuItems = json_find_member(submenu, "Items");
|
||||
// If we have no items, just return
|
||||
if ( submenuItems == NULL ) {
|
||||
return;
|
||||
}
|
||||
|
||||
// Loop over submenu items
|
||||
JsonNode *item;
|
||||
json_foreach(item, submenuItems) {
|
||||
// Get item label
|
||||
processMenuItem(menu, thisMenu, item);
|
||||
}
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
// This is a user menu. Get the common data
|
||||
// Get the label
|
||||
const char *label = getJSONString(item, "Label");
|
||||
@@ -792,9 +759,36 @@ void processMenuItem(Menu *menu, id parentMenu, JsonNode *item) {
|
||||
// Get the Type
|
||||
JsonNode *type = json_find_member(item, "Type");
|
||||
if( type != NULL ) {
|
||||
if( STREQ(type->string_, "Text") || STREQ(type->string_, "Submenu")) {
|
||||
id thisMenuItem = processTextMenuItem(menu, parentMenu, label, menuid, disabled, acceleratorkey, modifiers, tooltip, image, fontName, fontSize, RGBA, templateImage, alternate);
|
||||
|
||||
if( STREQ(type->string_, "Text")) {
|
||||
processTextMenuItem(menu, parentMenu, label, menuid, disabled, acceleratorkey, modifiers, tooltip, image, fontName, fontSize, RGBA, templateImage, alternate);
|
||||
// Check if this node has a submenu
|
||||
JsonNode *submenu = json_find_member(item, "SubMenu");
|
||||
if( submenu != NULL ) {
|
||||
// Get the label
|
||||
JsonNode *menuNameNode = json_find_member(item, "Label");
|
||||
const char *name = "";
|
||||
if ( menuNameNode != NULL) {
|
||||
name = menuNameNode->string_;
|
||||
}
|
||||
|
||||
id thisMenu = createMenu(str(name));
|
||||
|
||||
msg_id(thisMenuItem, s("setSubmenu:"), thisMenu);
|
||||
|
||||
JsonNode *submenuItems = json_find_member(submenu, "Items");
|
||||
// If we have no items, just return
|
||||
if ( submenuItems == NULL ) {
|
||||
return;
|
||||
}
|
||||
|
||||
// Loop over submenu items
|
||||
JsonNode *item;
|
||||
json_foreach(item, submenuItems) {
|
||||
// Get item label
|
||||
processMenuItem(menu, thisMenu, item);
|
||||
}
|
||||
}
|
||||
}
|
||||
else if ( STREQ(type->string_, "Separator")) {
|
||||
addSeparator(parentMenu);
|
||||
@@ -813,7 +807,6 @@ void processMenuItem(Menu *menu, id parentMenu, JsonNode *item) {
|
||||
|
||||
processRadioMenuItem(menu, parentMenu, label, menuid, disabled, checked, "");
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
if ( modifiers != NULL ) {
|
||||
|
||||
@@ -10,6 +10,8 @@ import (
|
||||
"runtime"
|
||||
"strings"
|
||||
|
||||
"github.com/pkg/errors"
|
||||
|
||||
"github.com/leaanthony/slicer"
|
||||
"github.com/wailsapp/wails/v2/internal/assetdb"
|
||||
"github.com/wailsapp/wails/v2/internal/fs"
|
||||
@@ -291,6 +293,27 @@ func (b *BaseBuilder) CompileProject(options *Options) error {
|
||||
return fmt.Errorf("%s\n%s", err, string(stde.Bytes()))
|
||||
}
|
||||
|
||||
if !options.Compress {
|
||||
return nil
|
||||
}
|
||||
|
||||
// Do we have upx installed?
|
||||
if !shell.CommandExists("upx") {
|
||||
println("Warning: Cannot compress binary: upx not found")
|
||||
return nil
|
||||
}
|
||||
|
||||
if verbose {
|
||||
println(" Compressing with:", "upx", "--best", "--no-color", "--no-progress", options.CompiledBinary)
|
||||
}
|
||||
|
||||
output, err := exec.Command(options.BuildDirectory, "upx", "--best", "--no-color", "--no-progress", options.CompiledBinary).Output()
|
||||
if err != nil {
|
||||
return errors.Wrap(err, "Error during compression:")
|
||||
}
|
||||
if verbose {
|
||||
println(output)
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
|
||||
@@ -42,8 +42,9 @@ type Options struct {
|
||||
BuildDirectory string // Directory to use for building the application
|
||||
CleanBuildDirectory bool // Indicates if the build directory should be cleaned before building
|
||||
CompiledBinary string // Fully qualified path to the compiled binary
|
||||
KeepAssets bool // /Keep the generated assets/files
|
||||
KeepAssets bool // Keep the generated assets/files
|
||||
Verbosity int // Verbosity level (0 - silent, 1 - default, 2 - verbose)
|
||||
Compress bool // Compress the final binary
|
||||
AppleIdentity string
|
||||
}
|
||||
|
||||
@@ -130,6 +131,7 @@ func Build(options *Options) (string, error) {
|
||||
// Build amd64 first
|
||||
options.Arch = "amd64"
|
||||
options.OutputFile = amd64Filename
|
||||
options.CleanBuildDirectory = false
|
||||
if options.Verbosity == VERBOSE {
|
||||
println()
|
||||
println(" Building AMD64 Target:", filepath.Join(options.BuildDirectory, options.OutputFile))
|
||||
@@ -141,6 +143,7 @@ func Build(options *Options) (string, error) {
|
||||
// Build arm64
|
||||
options.Arch = "arm64"
|
||||
options.OutputFile = arm64Filename
|
||||
options.CleanBuildDirectory = false
|
||||
if options.Verbosity == VERBOSE {
|
||||
println(" Building ARM64 Target:", filepath.Join(options.BuildDirectory, options.OutputFile))
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user