feat: wine

This commit is contained in:
msojocs 2024-07-03 22:59:39 +08:00
parent 8758b0b7b3
commit 62be301f09
30 changed files with 3219 additions and 6 deletions

1
.gitignore vendored
View File

@ -1,4 +1,5 @@
build
cache
test/*.json
wcc.exe.c

18
.vscode/settings.json vendored
View File

@ -54,7 +54,23 @@
"ratio": "cpp",
"mutex": "cpp",
"thread": "cpp",
"variant": "cpp"
"variant": "cpp",
"hash_map": "cpp",
"hash_set": "cpp",
"bitset": "cpp",
"charconv": "cpp",
"cinttypes": "cpp",
"compare": "cpp",
"concepts": "cpp",
"forward_list": "cpp",
"list": "cpp",
"unordered_set": "cpp",
"ranges": "cpp",
"shared_mutex": "cpp",
"span": "cpp",
"stop_token": "cpp",
"cfenv": "cpp",
"typeindex": "cpp"
},
"cmake.debugConfig": {
"cwd": "/home/msojocs/github/wx-compiler/test/spec/issue/102/wxapp",

View File

@ -1,17 +1,13 @@
cmake_minimum_required(VERSION 3.0.0)
project(wx_complier VERSION 0.1.0 LANGUAGES C CXX)
set(CMAKE_CXX_STANDARD 11)
set(CMAKE_CXX_STANDARD 14)
set(CMAKE_EXPORT_COMPILE_COMMANDS ON)
# set (CMAKE_CXX_STANDARD 14)
# set(CMAKE_VERBOSE_MAKEFILE ON)
# message("before: ${CMAKE_CXX_FLAGS_DEBUG}")
# set(CMAKE_CXX_FLAGS_DEBUG "${CMAKE_CXX_FLAGS_DEBUG} -O1")
# message("after: ${CMAKE_CXX_FLAGS_DEBUG}")
include(CTest)
enable_testing()
add_executable(wcc
src/wcc.cpp
src/include/wxml.h
@ -99,9 +95,13 @@ add_executable(test1
# src/wxml/expr_lib/transit_table.cpp
# )
include(CTest)
enable_testing()
add_test(transit_table_test
$<TARGET_FILE:transit_table>
)
set(CPACK_PROJECT_NAME ${PROJECT_NAME})
set(CPACK_PROJECT_VERSION ${PROJECT_VERSION})
include(CPack)
add_subdirectory(./src/nwjs)

3
src/nwjs/.gitignore vendored Normal file
View File

@ -0,0 +1,3 @@
node
lib
nw-headers-v*.tar.gz

93
src/nwjs/CMakeLists.txt Normal file
View File

@ -0,0 +1,93 @@
set(NW_VERSION "0.55.0")
message("current dir: ${CMAKE_CURRENT_SOURCE_DIR}")
if(NOT EXISTS "${CMAKE_CURRENT_SOURCE_DIR}/cache/nw-headers-v${NW_VERSION}.tar.gz")
execute_process(
COMMAND wget -c -O nw-headers-v${NW_VERSION}.tar.gz.tmp https://dl.nwjs.io/v${NW_VERSION}/nw-headers-v${NW_VERSION}.tar.gz;
COMMAND mv nw-headers-v${NW_VERSION}.tar.gz.tmp nw-headers-v${NW_VERSION}.tar.gz;
WORKING_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR}/cache
OUTPUT_VARIABLE CMAKE_JS_VERSION
OUTPUT_STRIP_TRAILING_WHITESPACE
)
endif()
execute_process(COMMAND rm -rf ${CMAKE_CURRENT_SOURCE_DIR}/node WORKING_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR})
if(NOT EXISTS "${CMAKE_CURRENT_SOURCE_DIR}/node")
execute_process(COMMAND tar -zxf nw-headers-v${NW_VERSION}.tar.gz -C ${CMAKE_CURRENT_SOURCE_DIR} WORKING_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR}/cache)
endif()
# if(NOT EXISTS "${CMAKE_CURRENT_SOURCE_DIR}/lib/node-v${NW_VERSION}.lib")
# execute_process(
# COMMAND wget -c -O node-v${NW_VERSION}.lib.tmp https://dl.nwjs.io/v${NW_VERSION}/node.lib;
# COMMAND mv node-v${NW_VERSION}.lib.tmp node-v${NW_VERSION}.lib;
# WORKING_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR}/lib
# OUTPUT_VARIABLE CMAKE_JS_VERSION
# OUTPUT_STRIP_TRAILING_WHITESPACE
# )
# endif()
# if(NOT EXISTS "${CMAKE_CURRENT_SOURCE_DIR}/lib/nw-v${NW_VERSION}.lib")
# execute_process(
# COMMAND wget -c -O nw-v${NW_VERSION}.lib.tmp https://dl.nwjs.io/v${NW_VERSION}/nw.lib;
# COMMAND mv nw-v${NW_VERSION}.lib.tmp nw-v${NW_VERSION}.lib;
# WORKING_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR}/lib
# OUTPUT_VARIABLE CMAKE_JS_VERSION
# OUTPUT_STRIP_TRAILING_WHITESPACE
# )
# endif()
include_directories(node/src)
include_directories(node/include/node)
include_directories(node/deps/v8/include)
include_directories(node/deps/uv/include)
add_library(wcc_node
SHARED
./wcc.cpp
./include/wcc.hh
./config/wcc.cc
../include/wxml.h
../include/night.h
../wcc/usage.cpp
../wxa/wxa.cpp
../wxml/rewrite.cpp
../wxml/name_allocator.cpp
../wxml/string_templating/common.cpp
../wxml/string_templating/token.cpp
../wxml/dom_lib/rvm_op_code_position_recorder.cpp
../wxml/dom_lib/rvm_op_code_position.cpp
../wxml/dom_lib/parse_exception.cpp
../wxml/dom_lib/token.cpp
../wxml/dom_lib/common.cpp
../wxml/dom_lib/machine.cpp
../wxml/dom_lib/tokenizer.cpp
../wxml/dom_lib/parser.cpp
../night/night.cpp
../night/ns_ast_parse.cpp
../night/ns_compile_js.cpp
../night/ns_node.cpp
../night/ns_sourcemap.cpp
../night/ns_stream.cpp
../night/ns_token.cpp
../night/ns_god/ns_god.cpp
../night/str/str.cpp
../wxml/rpx.cpp
../wxml/expr_lib/base.cpp
../wxml/expr_lib/bnf.cpp
../wxml/expr_lib/common.cpp
../wxml/expr_lib/expr_syntax_tree.cpp
../wxml/expr_lib/parser.cpp
../wxml/expr_lib/token.cpp
../wxml/expr_lib/tokenizer.cpp
../wxml/expr_lib/transit_table.cpp
../wxml/compiler.cpp
../wxml/dom_lib/str_cache.cpp
../wxml/dom_lib/wxml_dom.cpp
../utils/json.cpp
../utils/string_utils.cpp
../utils/file.cpp
)
# DV8_COMPRESS_POINTERS: IsString
target_compile_options(wcc_node PRIVATE "-DNODE_GYP_MODULE_NAME=binding" "-DUSING_UV_SHARED=1" "-DUSING_V8_SHARED=1" "-DV8_DEPRECATION_WARNINGS=1" "-DV8_DEPRECATION_WARNINGS" "-DV8_REVERSE_JSARGS" "-D_GLIBCXX_USE_CXX11_ABI=1" "-D_LIBCPP_HAS_NO_VENDOR_AVAILABILITY_ANNOTATIONS" "-D_LARGEFILE_SOURCE" "-D_FILE_OFFSET_BITS=64" "-DV8_COMPRESS_POINTERS" "-DV8_31BIT_SMIS_ON_64BIT_ARCH" "-D__STDC_FORMAT_MACROS" "-DOPENSSL_NO_PINSHARED" "-DOPENSSL_THREADS" "-DOPENSSL_NO_ASM" "-DBUILDING_NODE_EXTENSION")
set_target_properties(wcc_node PROPERTIES RUNTIME_OUTPUT_DIRECTORY /home/msojocs/github/wx-compiler/cache/package.nw)
set_target_properties(wcc_node PROPERTIES PREFIX "" SUFFIX ".node")
# target_link_libraries(wcc_node ${CMAKE_CURRENT_SOURCE_DIR}/lib/nw-v${NW_VERSION}.lib)
# target_link_libraries(wcc_node ${CMAKE_CURRENT_SOURCE_DIR}/lib/node-v${NW_VERSION}.lib)

168
src/nwjs/config/wcc.cc Normal file
View File

@ -0,0 +1,168 @@
#include "../include/wcc.hh"
namespace wcc_options
{
using v8::Local;
using v8::NewStringType;
using v8::String;
using v8::Value;
bool get_boolean_property(v8::Isolate *isolate, v8::Local<v8::Object> &src, const char *property_name, bool &out_value)
{
v8::Local<v8::String> key = v8::String::NewFromUtf8(isolate, property_name, v8::NewStringType::kNormal).ToLocalChecked();
v8::Local<v8::Value> value;
v8::Local<v8::Context> context = isolate->GetCurrentContext();
if (!src->Get(context, key).ToLocal(&value))
{
isolate->ThrowException(v8::String::NewFromUtf8(isolate, ("Failed to get '" + std::string(property_name) + "' property").c_str(), v8::NewStringType::kNormal).ToLocalChecked());
return false;
}
if (!value->IsBoolean())
{
isolate->ThrowException(v8::String::NewFromUtf8(isolate, ("The '" + std::string(property_name) + "' property must be a boolean").c_str(), v8::NewStringType::kNormal).ToLocalChecked());
return false;
}
out_value = value->BooleanValue(isolate);
return true;
}
bool get_string_property(v8::Isolate *isolate, v8::Local<v8::Object> &src, const char *property_name, std::string &out_value)
{
v8::Local<v8::String> key = v8::String::NewFromUtf8(isolate, property_name, v8::NewStringType::kNormal).ToLocalChecked();
v8::Local<v8::Value> value;
v8::Local<v8::Context> context = isolate->GetCurrentContext();
if (!src->Get(context, key).ToLocal(&value))
{
isolate->ThrowException(v8::String::NewFromUtf8(isolate, ("Failed to get '" + std::string(property_name) + "' property").c_str(), v8::NewStringType::kNormal).ToLocalChecked());
return false;
}
if (!value->IsString())
{
isolate->ThrowException(v8::String::NewFromUtf8(isolate, ("The '" + std::string(property_name) + "' property must be a string").c_str(), v8::NewStringType::kNormal).ToLocalChecked());
return false;
}
v8::String::Utf8Value utf8Value(isolate, value);
std::string str(*utf8Value, utf8Value.length());
out_value = str;
return true;
}
bool get_vector_string_property(v8::Isolate *isolate, v8::Local<v8::Object> &src, const char *property_name, std::vector<std::string> &out_value)
{
v8::Local<v8::String> key = v8::String::NewFromUtf8(isolate, property_name, v8::NewStringType::kNormal).ToLocalChecked();
v8::Local<v8::Value> value;
v8::Local<v8::Context> context = isolate->GetCurrentContext();
if (!src->Get(context, key).ToLocal(&value))
{
isolate->ThrowException(v8::String::NewFromUtf8(isolate, ("Failed to get '" + std::string(property_name) + "' property").c_str(), v8::NewStringType::kNormal).ToLocalChecked());
return false;
}
if (!value->IsArray())
{
isolate->ThrowException(v8::String::NewFromUtf8(isolate, ("The '" + std::string(property_name) + "' property must be a array").c_str(), v8::NewStringType::kNormal).ToLocalChecked());
return false;
}
auto arr = value.As<v8::Array>();
for (int i=0; i < arr->Length(); i++)
{
v8::Local<v8::Value> v;
if (!arr->Get(context, i).ToLocal(&v))
{
isolate->ThrowException(v8::String::NewFromUtf8(isolate, ("Failed to get '" + std::string(property_name) + "' property").c_str(), v8::NewStringType::kNormal).ToLocalChecked());
return false;
}
if (!v->IsString())
{
isolate->ThrowException(v8::String::NewFromUtf8(isolate, ("The '" + std::string(property_name) + std::string("[") + std::to_string(i) +"]' property must be a string").c_str(), v8::NewStringType::kNormal).ToLocalChecked());
return false;
}
v8::String::Utf8Value utf8Value(isolate, v);
std::string str(*utf8Value, utf8Value.length());
out_value.emplace_back(str);
}
return true;
}
bool get_map_string_property(v8::Isolate *isolate, v8::Local<v8::Object> &src, const char *property_name, std::map<std::string, std::string> &out_value)
{
v8::Local<v8::String> key = v8::String::NewFromUtf8(isolate, property_name, v8::NewStringType::kNormal).ToLocalChecked();
v8::Local<v8::Value> value;
v8::Local<v8::Context> context = isolate->GetCurrentContext();
if (!src->Get(context, key).ToLocal(&value))
{
isolate->ThrowException(v8::String::NewFromUtf8(isolate, ("Failed to get '" + std::string(property_name) + "' property").c_str(), v8::NewStringType::kNormal).ToLocalChecked());
return false;
}
if (!value->IsObject())
{
isolate->ThrowException(v8::String::NewFromUtf8(isolate, ("The '" + std::string(property_name) + "' property must be a object").c_str(), v8::NewStringType::kNormal).ToLocalChecked());
return false;
}
auto obj = value.As<v8::Object>();
auto keys = obj->GetPropertyNames(context).ToLocalChecked();
for (int i = 0; i < keys->Length(); i++)
{
// key
v8::Local<v8::Value> k;
if (!keys->Get(context, i).ToLocal(&k))
{
isolate->ThrowException(v8::String::NewFromUtf8(isolate, ("Failed to get '" + std::string(property_name) + "' property").c_str(), v8::NewStringType::kNormal).ToLocalChecked());
return false;
}
if (!k->IsString())
{
isolate->ThrowException(v8::String::NewFromUtf8(isolate, ("The '" + std::string(property_name) + std::string("[") + std::to_string(i) +"]' property must be a string").c_str(), v8::NewStringType::kNormal).ToLocalChecked());
return false;
}
// value
v8::Local<v8::Value> v;
if (!obj->Get(context, k).ToLocal(&v))
{
isolate->ThrowException(v8::String::NewFromUtf8(isolate, ("Failed to get '" + std::string(property_name) + "' property").c_str(), v8::NewStringType::kNormal).ToLocalChecked());
return false;
}
if (!v->IsString())
{
isolate->ThrowException(v8::String::NewFromUtf8(isolate, ("The '" + std::string(property_name) + std::string("[") + std::to_string(i) +"]' property must be a string").c_str(), v8::NewStringType::kNormal).ToLocalChecked());
return false;
}
v8::String::Utf8Value utf8Value(isolate, k);
std::string kr(*utf8Value, utf8Value.length());
v8::String::Utf8Value utf8Value2(isolate, v);
std::string vr(*utf8Value2, utf8Value2.length());
out_value.emplace(kr, vr);
}
return true;
}
bool parse_wcc_options(v8::Isolate *isolate, v8::Local<v8::Object> &src, WCCOptions *result)
{
Local<v8::Context> context = isolate->GetCurrentContext();
bool ret = get_boolean_property(isolate, src, "verbose", result->verbose) &&
get_boolean_property(isolate, src, "debug", result->debug) &&
get_boolean_property(isolate, src, "debugWXS", result->debugWXS) &&
get_boolean_property(isolate, src, "showNewTree", result->showNewTree) &&
get_boolean_property(isolate, src, "isPlugin", result->isPlugin) &&
get_boolean_property(isolate, src, "addTestAttre", result->addTestAttre) &&
get_boolean_property(isolate, src, "independent", result->independent) &&
get_boolean_property(isolate, src, "isCut", result->isCut) &&
get_boolean_property(isolate, src, "lazyload", result->lazyload) &&
get_string_property(isolate, src, "genfuncname", result->genfuncname) &&
get_string_property(isolate, src, "cwd", result->cwd) &&
get_string_property(isolate, src, "wxmlCompileConfig", result->wxmlCompileConfig) &&
get_string_property(isolate, src, "wxmlCompileConfigSplit", result->wxmlCompileConfigSplit) &&
get_string_property(isolate, src, "lazyloadConfig", result->lazyloadConfig) &&
get_vector_string_property(isolate, src, "files", result->files) &&
get_vector_string_property(isolate, src, "contents", result->contents) &&
get_map_string_property(isolate, src, "replaceContent", result->replaceContent);
return ret;
}
}

0
src/nwjs/config/wcsc.cc Normal file
View File

30
src/nwjs/include/wcc.hh Normal file
View File

@ -0,0 +1,30 @@
#ifndef __WCC_HH__
#define __WCC_HH__
#include <vector>
#include <string>
#include <map>
#include <node.h>
struct WCCOptions
{
std::vector<std::string> files;
std::vector<std::string> contents;
std::map<std::string, std::string> replaceContent;
bool verbose = false;
bool debug = false;
bool debugWXS = false;
bool showNewTree = false;
bool isPlugin = false;
bool addTestAttre = false;
bool independent = false;
std::string genfuncname;
bool isCut;
std::string cwd;
bool lazyload = false;
std::string wxmlCompileConfig;
std::string wxmlCompileConfigSplit;
std::string lazyloadConfig;
};
bool parse_wcc_options(v8::Isolate *isolate, v8::Local<v8::Object> &src, WCCOptions *result);
#endif

73
src/nwjs/wcc.cpp Normal file
View File

@ -0,0 +1,73 @@
// hello.cc
#include <node.h>
#include "../include/wxml.h"
#include "./include/wcc.hh"
namespace wx_compiler
{
using v8::Function;
using v8::FunctionCallbackInfo;
using v8::FunctionTemplate;
using v8::Isolate;
using v8::Local;
using v8::NewStringType;
using v8::Object;
using v8::String;
using v8::Value;
void Compiler(const FunctionCallbackInfo<Value> &args)
{
Isolate *isolate = args.GetIsolate();
v8::HandleScope scope(isolate); // Ensure we have a proper handle scope.
// Check if the first argument is an object.
if (args.Length() < 1 || !args[0]->IsObject())
{
isolate->ThrowException(String::NewFromUtf8(isolate, "Argument must be an object", NewStringType::kNormal).ToLocalChecked());
return;
}
// Cast the first argument to an Object.
Local<v8::Context> context = isolate->GetCurrentContext();
Local<Object> obj = args[0]->ToObject(context).ToLocalChecked();
WCCOptions options;
if(!parse_wcc_options(isolate, obj, &options))
{
// 选项解析失败
return;
}
// TODO: 解析成功,开始编译
// Convert the "msg" property to a C++ string and return it.
// String::Utf8Value utf8(isolate, value);
// args.GetReturnValue().Set(String::NewFromUtf8(isolate, *utf8, NewStringType::kNormal).ToLocalChecked());
}
void Initialize(Local<Object> exports, Local<Object> module)
{
Isolate *isolate = exports->GetIsolate();
auto context = isolate->GetCurrentContext();
std::string versionInfo;
WXML::Compiler::GetVersionInfo(versionInfo, "global");
// Set the module.exports to be a function
Local<FunctionTemplate> tpl = FunctionTemplate::New(isolate, Compiler);
Local<Function> fn = tpl->GetFunction(context).ToLocalChecked();
// Set the 'version' property on the function
fn->Set(context, String::NewFromUtf8(isolate, "version", NewStringType::kNormal).ToLocalChecked(),
String::NewFromUtf8(isolate, versionInfo.c_str(), NewStringType::kNormal).ToLocalChecked())
.Check();
module->Set(context, String::NewFromUtf8(isolate, "exports", NewStringType::kNormal).ToLocalChecked(), fn).Check();
}
NODE_MODULE(NODE_GYP_MODULE_NAME, Initialize)
} // namespace demo

70
test/node-gyp/binding.cc Normal file
View File

@ -0,0 +1,70 @@
// hello.cc
#include <node.h>
// #include "../include/wxml.h"
namespace demo
{
using v8::FunctionCallbackInfo;
using v8::FunctionTemplate;
using v8::Isolate;
using v8::Local;
using v8::Object;
using v8::NewStringType;
using v8::String;
using v8::Value;
void MsgMethod(const FunctionCallbackInfo<Value> &args) {
Isolate *isolate = args.GetIsolate();
v8::HandleScope scope(isolate); // Ensure we have a proper handle scope.
// Check if the first argument is an object.
if (args.Length() < 1 || !args[0]->IsObject()) {
isolate->ThrowException(String::NewFromUtf8(isolate, "Argument must be an object", NewStringType::kNormal).ToLocalChecked());
return;
}
// Cast the first argument to an Object.
Local<v8::Context> context = isolate->GetCurrentContext();
Local<Object> obj = args[0]->ToObject(context).ToLocalChecked();
// Get the "msg" property from the object.
Local<String> key = String::NewFromUtf8(isolate, "msg", NewStringType::kNormal).ToLocalChecked();
Local<Value> value;
if (!obj->Get(context, key).ToLocal(&value)) {
isolate->ThrowException(String::NewFromUtf8(isolate, "Failed to get 'msg' property", NewStringType::kNormal).ToLocalChecked());
return;
}
if (!value->IsString()) {
isolate->ThrowException(String::NewFromUtf8(isolate, "The 'msg' property must be a string", NewStringType::kNormal).ToLocalChecked());
return;
}
// Now we can safely check if value is a string and print the message.
printf("get msg2\n");
printf("get msg3 %d\n", value->IsString());
// Convert the "msg" property to a C++ string and return it.
String::Utf8Value utf8(isolate, value);
args.GetReturnValue().Set(String::NewFromUtf8(isolate, *utf8, NewStringType::kNormal).ToLocalChecked());
}
void Initialize(Local<Object> exports, Local<Object> module)
{
Isolate* isolate = exports->GetIsolate();
auto context = isolate->GetCurrentContext();
// std::string versionInfo;
// WXML::Compiler::GetVersionInfo(versionInfo, "global");
module->Set(context, String::NewFromUtf8(isolate, "exports", NewStringType::kNormal).ToLocalChecked(),
FunctionTemplate::New(isolate, MsgMethod)->GetFunction(context).ToLocalChecked()).Check();
auto _ = exports->Set(context, String::NewFromUtf8(isolate, "version", NewStringType::kNormal).ToLocalChecked(),
String::NewFromUtf8(isolate, "v1.0.0", NewStringType::kNormal).ToLocalChecked());
}
NODE_MODULE(NODE_GYP_MODULE_NAME, Initialize)
} // namespace demo

14
test/node-gyp/binding.gyp Normal file
View File

@ -0,0 +1,14 @@
{
'defines': [ 'V8_DEPRECATION_WARNINGS=1' ],
'conditions': [
[ 'OS in "linux freebsd openbsd solaris android aix os400 cloudabi"', {
'cflags': ['-Wno-cast-function-type'],
}],
],
'targets': [
{
'target_name': 'binding',
'sources': [ 'binding.cc' ],
}
]
}

10
test/node-gyp/build.sh Executable file
View File

@ -0,0 +1,10 @@
export npm_config_target=0.55.0
# Setup build architecture, ia32 or x64
export npm_config_arch=x64
export npm_config_target_arch=x64
# Setup env for modules built with node-pre-gyp
export npm_config_runtime=node-webkit
export npm_config_build_from_source=true
# Setup nw-gyp as node-gyp
export npm_config_node_gyp=$(which nw-gyp)
nw-gyp rebuild --loglevel verbose

View File

@ -0,0 +1,16 @@
{
"name": "node-gyp",
"version": "1.0.0",
"description": "",
"main": "index.js",
"scripts": {
"test": "echo \"Error: no test specified\" && exit 1"
},
"keywords": [],
"author": "",
"license": "ISC",
"dependencies": {
"node-gyp": "^10.1.0",
"nw-gyp": "^3.6.6"
}
}

1261
test/node-gyp/pnpm-lock.yaml generated Normal file

File diff suppressed because it is too large Load Diff

View File

View File

@ -0,0 +1,13 @@
<!DOCTYPE html>
<html>
<head>
<title>Hello World!</title>
</head>
<body>
<h1>Hello World!</h1>
<script>
// require('nw.gui').Window.get().showDevTools();
</script>
</body>
</html>

View File

@ -0,0 +1,83 @@
// initialize your app
// and ...
console.log("main.js");
const fs = require("fs");
console.log("fs:", fs);
const wcc = require("./wcc");
console.log("wcc:", wcc);
const { createServer } = require("http");
const HOST = "0.0.0.0";
const PORT = "8083";
const Handle = {
/**
*
* @param {IncomingMessage} req
* @returns
*/
readBody: (req) => {
return new Promise((resolve, reject) => {
let body = "";
req.on("data", (d) => {
body += d;
});
req.on("end", () => {
resolve(body);
});
});
},
};
const server = createServer(async (req, resp) => {
// the first param is status code it returns
// and the second param is response header info
try {
console.log("server is working...");
if(req.url?.includes("close"))
{
nw.App.quit()
}
const body = JSON.parse(await Handle.readBody(req));
let result = {};
if (req.url?.includes("wcc")) {
result = await wcc.wcc(body);
} else if (req.url?.includes("wcsc")){
result = await wcc.wcsc(body);
}
if (typeof result != 'string')
{
// JSON
resp.writeHead(200, { "Content-Type": "application/json" });
resp.end(JSON.stringify(result));
}
else
{
// call end method to tell server that the request has been fulfilled
resp.writeHead(200, { "Content-Type": "text/plain" });
resp.end(result);
}
} catch (e) {
console.error('server error:', e)
resp.writeHead(500, { "Content-Type": "text/plain" });
resp.end("server error:" + e);
}
});
server.listen(PORT, HOST, (error) => {
if (error) {
console.log("Something wrong: ", error);
return;
}
console.log(`server is listening on http://${HOST}:${PORT} ...`);
});
// nw.Window.open("index.html", {}, function (win) {});
// nw.process.exit(0)
// process.exit(0)

View File

@ -0,0 +1,5 @@
{
"name": "helloworld",
"main": "main.js",
"show": "false"
}

View File

@ -0,0 +1,4 @@
module.exports = {
wcc: require('./wcc'),
wcsc: require('./wcsc')
}

View File

@ -0,0 +1,2 @@
[ZoneTransfer]
ZoneId=3

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,2 @@
[ZoneTransfer]
ZoneId=3

View File

@ -0,0 +1,94 @@
const util = require('./util')
const path = require('path')
let wcc
function loadWccAddon() {
if (wcc) return
wcc = require('../build/Release/wcc.node')
}
const fs = util.fs
exports = async function (options) {
loadWccAddon()
if (!options) throw Error('options is required')
const lazyload = !!options.lazyloadConfig
options = Object.assign(
{
files: [],
contents: [],
replaceContent: {},
verbose: false,
debug: false,
debugWXS: false,
showNewTree: false,
isPlugin: false,
addTestAttre: false,
independent: false,
genfuncname: '$gwx',
isCut: false,
cwd: process.cwd,
debug: false,
lazyload,
lazyloadConfig: '',
},
options,
)
return new Promise(async (resolve, reject) => {
let st = Date.now()
// 获取文件内容
if (!options.contents.length) {
const tasks = options.files.map((file) => {
if (typeof options.replaceContent[file] === 'string') {
return options.replaceContent[file]
}
return fs.readFile(path.resolve(options.cwd, file), 'utf8')
})
options.contents = await Promise.all(tasks) || []
}
// console.log('wcc get files', Date.now() - st, options.contents)
let result
try {
result = wcc(options)
} catch(errmsg) {
reject(new Error(errmsg))
return
}
console.log('wcc get compile', Date.now() - st)
if (options.output) {
const output = path.resolve(options.cwd, options.output)
const dir = path.dirname(output)
if (lazyload) {
// lazyload 为 true时wcc 返回值是个对象, 需要序列化一下
result = JSON.stringify(result)
}
try {
await fs.stat(dir)
} catch (e) {
await fs.mkdir(dir, {
recursive: true,
})
}
await fs.writeFile(output, result, 'utf8')
}
console.log('wcc get output', Date.now() - st)
resolve(result)
})
}
Object.defineProperty(exports, 'version', {
get() {
loadWccAddon()
return wcc.version
},
})
module.exports = exports

View File

@ -0,0 +1,2 @@
[ZoneTransfer]
ZoneId=3

View File

@ -0,0 +1,92 @@
const util = require('./util')
const path = require('path')
const fs = util.fs
let wcsc
function loadWcscAddon() {
if (wcsc) return
wcsc = require('../build/Release/wcsc.node')
}
function tranWcscResultToObject(resultStr) {
const resultArr = resultStr.split('=')
const result = {}
for (let i = 0, len = resultArr.length; i < len && resultArr[i + 1]; i += 2) {
result[resultArr[i]] = resultArr[i + 1]
}
return result
}
exports = async function (options) {
loadWcscAddon()
if (!options) throw Error('options is required')
// avoid undefined or null
if (typeof options.subPackage !== 'string') {
delete options.subPackage
}
if (typeof options.lazyload !== 'boolean') {
delete options.lazyload
}
options = Object.assign(
{
files: [],
contents: [],
pageCount: 0,
cwd: process.cwd,
replaceContent: {},
debug: false,
classPrefix: '',
lazyload: false,
},
options,
)
if (!options.contents.length) {
const tasks = options.files.map((file) => {
if (typeof options.replaceContent[file] === 'string') {
return options.replaceContent[file]
}
return fs.readFile(path.resolve(options.cwd, file), 'utf8')
})
options.contents = await Promise.all(tasks) || []
}
let wccResult
try {
wccResult = wcsc(options)
} catch (errmsg) {
throw new Error(errmsg)
}
const result = options.lazyload ? wccResult : tranWcscResultToObject(wccResult)
if (options.output) {
const output = path.resolve(options.cwd, options.output)
const dir = path.dirname(output)
try {
await fs.stat(dir)
} catch (e) {
await fs.mkdir(dir, {
recursive: true,
})
}
await fs.writeFile(output, JSON.stringify(result, null, 2), 'utf8')
}
return result
}
Object.defineProperty(exports, 'version', {
get() {
loadWcscAddon()
return wcsc.version
},
})
module.exports = exports

View File

@ -0,0 +1,2 @@
[ZoneTransfer]
ZoneId=3

View File

@ -0,0 +1,18 @@
{
"name": "miniprogram-wcc",
"version": "0.0.1",
"description": "WCC node C++ addon",
"main": "lib/index.js",
"scripts": {
"rebuild": "node-gyp rebuild",
"build": "node-gyp build",
"test": "node ./test/wcc/index && node ./test/wcsc/index",
"format": "prettier *.js test/*.js scripts/*.js --write"
},
"author": "coverguo",
"license": "MIT",
"devDependencies": {
"licia": "^1.21.2",
"node-gyp": "^7.0.0"
}
}

View File

@ -0,0 +1,2 @@
[ZoneTransfer]
ZoneId=3

View File

5
test/runner/nwjs/wine.sh Normal file
View File

@ -0,0 +1,5 @@
#!/bin/bash
# 代码里不要启动gui
docker run -it --volume=.:/c --env=USE_XVFB=yes --env=XVFB_SERVER=:95 --env=XVFB_SCREEN=0 --env=XVFB_RESOLUTION=320x240x8 --env=DISPLAY=:95 --rm --hostname=DESKTOP-1TV4OAG --name=wine --shm-size=1g --workdir=/home/wineuser --env=TZ=Asia/Shanghai --volume=winehome:/home/wineuser -p 8083:8083 scottyhardy/docker-wine:latest wine /c/nwjs-sdk-v0.55.0-win-x64/nw.exe