Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
34 commits
Select commit Hold shift + click to select a range
5a43728
fxFindModule: support ../../ as well as ./ and ../
dckc Sep 21, 2019
db40005
add -p x-cli-lin to build simple CLI tools on linux
warner Dec 6, 2018
02b0249
example of a simple command-line tool
warner Dec 6, 2018
3855817
lin_xs_cli: require -> import for main
dckc Nov 23, 2019
9f8aa37
cli-lin: include xsBigInt
dckc Nov 23, 2019
b4a147e
x-cli-lin.mk: C_FLAGS -> XS_C_FLAGS (?)
dckc Nov 23, 2019
b1e2d0c
x-cli-lin: get resources, mc.config.js working
dckc Nov 23, 2019
9b7cb22
export mxPromiseStatus() as fxPromiseIsPending()
dckc Dec 27, 2019
0a6c7e5
http: some support for http upgrade, e.g. websockets
dckc Jan 2, 2020
6d143e4
http: support async replies
dckc Jan 3, 2020
774f920
export mxRejectedStatus as fxPromiseIsRejected()
dckc Jan 11, 2020
9ec77c2
websockets work-around: socket tx buffer 1k -> 4k
dckc Jan 16, 2020
0fa36ea
Merge branch 'promise-pending' into cli-lin
dckc Jan 28, 2020
65212d2
lin_xs_cli: run event loop after calling main()
dckc Dec 26, 2019
6714f67
build-release github workflow for headless linux SDK
dckc Dec 27, 2019
f2a75c0
move headless build target to makefiles/lin
dckc Dec 30, 2019
fc1f1bd
install libgtk-3-dev
dckc Jan 2, 2020
332fbdf
try apt update before installing libgtk-3-dev
dckc Jan 18, 2020
c2caa12
fxFindModule: support ../../ as well as ./ and ../
dckc Sep 21, 2019
f8710ac
http: some support for http upgrade, e.g. websockets
dckc Jan 2, 2020
54ad05e
http: support async replies
dckc Jan 3, 2020
e8c337a
websockets work-around: socket tx buffer 1k -> 4k
dckc Jan 16, 2020
2814d92
Merge branch 'find-mod-grandparent' into cli-lin
dckc Jan 28, 2020
c5abcd4
Merge branch 'http-async-ws' into cli-lin
dckc Jan 28, 2020
e3d70c0
Merge branch 'public' into ag-linux-cli
dckc May 5, 2020
080f59a
lin_xs_cli: send progress diagnostics to stderr
dckc Jul 21, 2020
c7cb9e8
lin_xs_cli: skip check for non-promise
dckc Aug 9, 2020
d5b9a11
Merge branch 'public' into ag-linux-cli
dckc Aug 13, 2020
b94970c
lin_xs_cli: fxAbort() takes a status arg now
dckc Aug 13, 2020
4842c46
reduce ci scope to smoke test
dckc Aug 13, 2020
a1691ec
skip debug build in headless
dckc Aug 22, 2020
4dcdcff
x-cli-lin: use release tools (xsc, ...)
dckc Aug 22, 2020
8b81b50
Merge branch 'public' into ag-linux-cli
dckc Oct 13, 2020
b3e3b1e
mconfig: supply RESOURCES_DIR for x-cli-lin
dckc Oct 13, 2020
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
32 changes: 32 additions & 0 deletions .github/workflows/smoke-test.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
name: build and smoke test moddable SDK for linux CLI (x-cli-lin)

on: [push]

jobs:
build:

runs-on: ubuntu-latest

steps:
- uses: actions/checkout@v1
- name: Install libgtk-3-dev
run: |
sudo apt-get -y update
sudo apt-get -y install libgtk-3-dev
- name: build moddable headless tools
run: |
export MODDABLE=$PWD
export XS_DIR=$MODDABLE/xs
cd $MODDABLE/build/makefiles/lin
make headless
- name: check that helloworld builds
run: |
export MODDABLE=$PWD
export PATH=$MODDABLE/build/bin/lin/release:$PATH
cd $MODDABLE/examples/helloworld
mcconfig -m -p x-cli-lin
# ISSUE: support scripts with no main()?
# $MODDABLE/build/bin/lin/release/helloworld
test -x $MODDABLE/build/bin/lin/release/helloworld
mcconfig -d -m -p x-cli-lin
test -x $MODDABLE/build/bin/lin/debug/helloworld
8 changes: 7 additions & 1 deletion build/makefiles/lin/makefile
Original file line number Diff line number Diff line change
Expand Up @@ -42,7 +42,13 @@ release:
make GOAL=release -f simulator.mk
make GOAL=release -f tools.mk
$(MODDABLE)/build/bin/lin/release/mcconfig -m -p x-lin $(MODDABLE)/tools/xsbug/manifest.json


headless:
make GOAL=release -f $(XS_DIR)/makefiles/lin/xsc.mk
make GOAL=release -f $(XS_DIR)/makefiles/lin/xsid.mk
make GOAL=release -f $(XS_DIR)/makefiles/lin/xsl.mk
make GOAL=release -f tools.mk

clean:
make clean -f $(XS_DIR)/makefiles/lin/xsc.mk
make clean -f $(XS_DIR)/makefiles/lin/xsid.mk
Expand Down
11 changes: 11 additions & 0 deletions examples/cli/main.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
trace("top-level executes\n");

export default function main(argv) {
let three = 1 + 2;
let message = "Hello, world";
trace("Hello world, 1+2=" + three + "\n");
trace(`1+2=${1+2}`);
if (argv.length) {
trace("argv[0]: " + argv[0] + "\n");
}
}
8 changes: 8 additions & 0 deletions examples/cli/manifest.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
{
"include": "$(MODDABLE)/examples/manifest_base.json",
"modules": {
"*": [
"./main"
]
},
}
89 changes: 47 additions & 42 deletions modules/network/http/http.js
Original file line number Diff line number Diff line change
Expand Up @@ -549,6 +549,10 @@ function server(message, value, etc) {
delete this.line;

let request = this.callback(Server.headersComplete); // headers complete... let's see what to do with the request body
if ('upgrade' === request) {
return;
}

if (false === request)
delete this.total; // ignore request body and just send response

Expand Down Expand Up @@ -651,53 +655,54 @@ function server(message, value, etc) {
let first;

if (7 === this.state) {
let response = this.callback(Server.prepareResponse); // prepare response

let parts = [];
let status = (!response || (undefined === response.status)) ? 200 : response.status;
let message = (!response || (undefined === response.reason)) ? reason(status) : response.reason.toString();
parts.push("HTTP/1.1 ", status.toString(), " ", message, "\r\n",
"connection: ", "close\r\n");

if (response) {
let byteLength;

for (let i = 0, headers = response.headers; headers && (i < headers.length); i += 2) {
parts.push(headers[i], ": ", headers[i + 1].toString(), "\r\n");
if ("content-length" == headers[i].toLowerCase())
byteLength = parseInt(headers[i + 1]);
}
let responseP = Promise.resolve(this.callback(Server.prepareResponse)); // prepare response
responseP.then(response => {
let parts = [];
let status = (!response || (undefined === response.status)) ? 200 : response.status;
let message = (!response || (undefined === response.reason)) ? reason(status) : response.reason.toString();
parts.push("HTTP/1.1 ", status.toString(), " ", message, "\r\n",
"connection: ", "close\r\n");

if (response) {
let byteLength;

for (let i = 0, headers = response.headers; headers && (i < headers.length); i += 2) {
parts.push(headers[i], ": ", headers[i + 1].toString(), "\r\n");
if ("content-length" == headers[i].toLowerCase())
byteLength = parseInt(headers[i + 1]);
}

this.body = response.body;
if (true === response.body) {
if (undefined === byteLength) {
this.flags = 2;
parts.push("transfer-encoding: chunked\r\n");
this.body = response.body;
if (true === response.body) {
if (undefined === byteLength) {
this.flags = 2;
parts.push("transfer-encoding: chunked\r\n");
}
else
this.flags = 4;
}
else {
this.flags = 1;
let count = 0;
if (this.body)
count = ("string" === typeof this.body) ? this.body.length : this.body.byteLength; //@@ utf-8 hell
parts.push("content-length: ", count.toString(), "\r\n");
}
else
this.flags = 4;
}
else {
this.flags = 1;
let count = 0;
if (this.body)
count = ("string" === typeof this.body) ? this.body.length : this.body.byteLength; //@@ utf-8 hell
parts.push("content-length: ", count.toString(), "\r\n");
}
}
else
parts.push("content-length: 0\r\n");
parts.push("\r\n");
socket.write.apply(socket, parts);
else
parts.push("content-length: 0\r\n");
parts.push("\r\n");
socket.write.apply(socket, parts);

this.state = 8;
first = true;
this.state = 8;
first = true;

if (this.body && (true !== this.body)) {
let count = ("string" === typeof this.body) ? this.body.length : this.body.byteLength;
if (count > (socket.write() - ((2 & this.flags) ? 8 : 0)))
return;
}
if (this.body && (true !== this.body)) {
let count = ("string" === typeof this.body) ? this.body.length : this.body.byteLength;
if (count > (socket.write() - ((2 & this.flags) ? 8 : 0)))
return;
}
});
}
if (8 === this.state) {
let body = this.body;
Expand Down
2 changes: 1 addition & 1 deletion modules/network/socket/lin/modSocket.c
Original file line number Diff line number Diff line change
Expand Up @@ -43,7 +43,7 @@
#define kRAW (2)

#define kRxBufferSize 1024
#define kTxBufferSize 1024
#define kTxBufferSize 4096

typedef struct xsSocketRecord xsSocketRecord;
typedef xsSocketRecord *xsSocket;
Expand Down
4 changes: 1 addition & 3 deletions tools/mcconfig.js
Original file line number Diff line number Diff line change
Expand Up @@ -1078,7 +1078,7 @@ export default class extends Tool {
var file = new XcodeFile(path, this);
file.generate(this);
}
else if (this.platform == "x-lin") {
else if (this.platform == "x-lin" || this.platform == "x-lin-cli" ) {
this.dataPath = this.resourcesPath = this.tmpPath + this.slash + "resources";
this.createDirectory(this.resourcesPath);
}
Expand All @@ -1094,8 +1094,6 @@ export default class extends Tool {
this.dataPath = this.resourcesPath = this.tmpPath + this.slash + "resources";
this.createDirectory(this.resourcesPath);
}
else if (this.platform.startsWith("x-cli-")) {
}
else {
var folder = "mc", file;
this.createDirectory(this.modulesPath + this.slash + folder);
Expand Down
174 changes: 174 additions & 0 deletions tools/mcconfig/make.x-cli-lin.mk
Original file line number Diff line number Diff line change
@@ -0,0 +1,174 @@
#
# Copyright (c) 2016-2017 Moddable Tech, Inc.
#
# This file is part of the Moddable SDK Tools.
#
# The Moddable SDK Tools is free software: you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation, either version 3 of the License, or
# (at your option) any later version.
#
# The Moddable SDK Tools is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with the Moddable SDK Tools. If not, see <http://www.gnu.org/licenses/>.
#

PKGCONFIG = $(shell which pkg-config)
GLIB_COMPILE_RESOURCES = $(shell $(PKGCONFIG) --variable=glib_compile_resources gio-2.0)

ifeq ($(DEBUG),1)
LIB_DIR = $(BUILD_DIR)/tmp/lin/debug/lib
else
ifeq ($(INSTRUMENT),1)
LIB_DIR = $(BUILD_DIR)/tmp/lin/instrument/lib
else
LIB_DIR = $(BUILD_DIR)/tmp/lin/release/lib
endif
endif

XS_DIRECTORIES = \
$(XS_DIR)/includes \
$(XS_DIR)/platforms \
$(XS_DIR)/sources

XS_HEADERS = \
$(XS_DIR)/platforms/lin_xs.h \
$(XS_DIR)/platforms/xsPlatform.h \
$(XS_DIR)/includes/xs.h \
$(XS_DIR)/includes/xsmc.h \
$(XS_DIR)/sources/xsCommon.h \
$(XS_DIR)/sources/xsAll.h \
$(XS_DIR)/sources/xsScript.h

XS_OBJECTS = \
$(LIB_DIR)/lin_xs.c.o \
$(LIB_DIR)/xsAll.c.o \
$(LIB_DIR)/xsAPI.c.o \
$(LIB_DIR)/xsArguments.c.o \
$(LIB_DIR)/xsArray.c.o \
$(LIB_DIR)/xsAtomics.c.o \
$(LIB_DIR)/xsBigInt.c.o \
$(LIB_DIR)/xsBoolean.c.o \
$(LIB_DIR)/xsCode.c.o \
$(LIB_DIR)/xsCommon.c.o \
$(LIB_DIR)/xsDataView.c.o \
$(LIB_DIR)/xsDate.c.o \
$(LIB_DIR)/xsDebug.c.o \
$(LIB_DIR)/xsError.c.o \
$(LIB_DIR)/xsFunction.c.o \
$(LIB_DIR)/xsGenerator.c.o \
$(LIB_DIR)/xsGlobal.c.o \
$(LIB_DIR)/xsJSON.c.o \
$(LIB_DIR)/xsLexical.c.o \
$(LIB_DIR)/xsMapSet.c.o \
$(LIB_DIR)/xsMarshall.c.o \
$(LIB_DIR)/xsMath.c.o \
$(LIB_DIR)/xsMemory.c.o \
$(LIB_DIR)/xsModule.c.o \
$(LIB_DIR)/xsNumber.c.o \
$(LIB_DIR)/xsObject.c.o \
$(LIB_DIR)/xsPlatforms.c.o \
$(LIB_DIR)/xsProfile.c.o \
$(LIB_DIR)/xsPromise.c.o \
$(LIB_DIR)/xsProperty.c.o \
$(LIB_DIR)/xsProxy.c.o \
$(LIB_DIR)/xsRegExp.c.o \
$(LIB_DIR)/xsRun.c.o \
$(LIB_DIR)/xsScope.c.o \
$(LIB_DIR)/xsScript.c.o \
$(LIB_DIR)/xsSourceMap.c.o \
$(LIB_DIR)/xsString.c.o \
$(LIB_DIR)/xsSymbol.c.o \
$(LIB_DIR)/xsSyntaxical.c.o \
$(LIB_DIR)/xsTree.c.o \
$(LIB_DIR)/xsType.c.o \
$(LIB_DIR)/xsdtoa.c.o \
$(LIB_DIR)/xsmc.c.o \
$(LIB_DIR)/xsre.c.o

HEADERS += $(XS_HEADERS)

C_DEFINES = \
-DXS_ARCHIVE=1 \
-DINCLUDE_XSPLATFORM=1 \
-DXSPLATFORM=\"lin_xs.h\" \
-DmxRun=1 \
-DmxParse=1 \
-DmxNoFunctionLength=1 \
-DmxNoFunctionName=1 \
-DmxHostFunctionPrimitive=1 \
-DmxFewGlobalsTable=1
ifeq ($(INSTRUMENT),1)
C_DEFINES += -DMODINSTRUMENTATION=1 -DmxInstrument=1
endif
C_INCLUDES += $(DIRECTORIES)
C_INCLUDES += $(foreach dir,$(XS_DIRECTORIES) $(TMP_DIR),-I$(dir))

XS_C_FLAGS = -fPIC -shared -c $(shell $(PKGCONFIG) --cflags gio-2.0)
ifeq ($(DEBUG),)
XS_C_FLAGS += -D_RELEASE=1 -O3
else
XS_C_FLAGS += -D_DEBUG=1 -DmxDebug=1 -g -O0 -Wall -Wextra -Wno-missing-field-initializers -Wno-unused-parameter
# C_FLAGS += -DMC_MEMORY_DEBUG=1
endif
C_FLAGS = $(XS_C_FLAGS)

LINK_LIBRARIES = -lm -lc $(shell $(PKGCONFIG) --libs gio-2.0)

# LINK_FLAGS = -arch i386
LINK_FLAGS = -fPIC

XSC = $(BUILD_DIR)/bin/lin/release/xsc
XSID = $(BUILD_DIR)/bin/lin/release/xsid
XSL = $(BUILD_DIR)/bin/lin/release/xsl
MCREZ = $(BUILD_DIR)/bin/lin/release/mcrez

VPATH += $(XS_DIRECTORIES)

.PHONY: all

all: $(LIB_DIR) $(BIN_DIR)/$(NAME)

$(LIB_DIR):
mkdir -p $(LIB_DIR)

$(TMP_DIR)/lin_xs_cli.c: $(XS_DIR)/platforms/lin_xs_cli.c
cp $^ $@

$(TMP_DIR)/lin_xs_cli.o: $(TMP_DIR)/lin_xs_cli.c $(TMP_DIR)/mc.xs.h $(XS_HEADERS)
@echo "# copy" $(<F)
$(CC) $(C_DEFINES) $(C_INCLUDES) $(C_FLAGS) $< -o $@

$(BIN_DIR)/$(NAME): $(TMP_DIR)/lin_xs_cli.o $(XS_OBJECTS) $(TMP_DIR)/mc.xs.c.o $(TMP_DIR)/mc.resources.c.o $(OBJECTS)
@echo "# cc" $(@F)
$(CC) $(LINK_FLAGS) $^ $(LINK_LIBRARIES) -o $@

$(XS_OBJECTS) : $(XS_HEADERS)
$(LIB_DIR)/%.c.o: %.c
@echo "# cc" $(<F)
$(CC) $(C_DEFINES) $(C_INCLUDES) $(XS_C_FLAGS) $< -o $@

$(TMP_DIR)/mc.xs.c.o: $(TMP_DIR)/mc.xs.c $(HEADERS)
@echo "# cc" $(<F)
$(CC) $(C_DEFINES) $(C_INCLUDES) $(C_FLAGS) $< -o $@

$(TMP_DIR)/mc.xs.c $(TMP_DIR)/mc.xs.h: $(MODULES) $(MANIFEST)
@echo "# xsl modules"
$(XSL) -b $(MODULES_DIR) -o $(TMP_DIR) $(PRELOADS) $(CREATION) $(MODULES)

$(TMP_DIR)/mc.resources.c.o: $(TMP_DIR)/mc.resources.c
@echo "# cc" $(<F)
$(CC) $(C_DEFINES) $(C_INCLUDES) $(XS_C_FLAGS) $< -o $@

$(TMP_DIR)/mc.resources.c: $(DATA) $(RESOURCES) $(MANIFEST)
@echo "# mcrez resources"
$(MCREZ) $(DATA) $(RESOURCES) -o $(TMP_DIR) -r mc.resources.c

MAKEFLAGS += --jobs
ifneq ($(VERBOSE),1)
MAKEFLAGS += --silent
endif
1 change: 1 addition & 0 deletions xs/platforms/lin_xs.c
Original file line number Diff line number Diff line change
Expand Up @@ -71,6 +71,7 @@ void fxDeleteMachinePlatform(txMachine* the)

void fxQueuePromiseJobs(txMachine* the)
{
the->promiseJobsFlag = 1;
GSource* idle_source = g_idle_source_new();
g_source_set_callback(idle_source, fxQueuePromiseJobsCallback, the, NULL);
g_source_set_priority(idle_source, G_PRIORITY_DEFAULT);
Expand Down
1 change: 1 addition & 0 deletions xs/platforms/lin_xs.h
Original file line number Diff line number Diff line change
Expand Up @@ -88,6 +88,7 @@ extern void fxQueueWorkerJob(void* machine, void* job);
void* waiterCondition; \
void* waiterData; \
void* waiterLink; \
gboolean promiseJobsFlag; \
GMainContext* workerContext; \
GMutex workerMutex; \
txWorkerJob* workerQueue;
Expand Down
Loading