mirror of
https://github.com/msojocs/wx-compiler.git
synced 2025-07-19 00:00:04 +08:00
feat: wine
This commit is contained in:
parent
8758b0b7b3
commit
62be301f09
1
.gitignore
vendored
1
.gitignore
vendored
@ -1,4 +1,5 @@
|
||||
build
|
||||
cache
|
||||
test/*.json
|
||||
wcc.exe.c
|
||||
|
||||
|
18
.vscode/settings.json
vendored
18
.vscode/settings.json
vendored
@ -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",
|
||||
|
@ -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
3
src/nwjs/.gitignore
vendored
Normal file
@ -0,0 +1,3 @@
|
||||
node
|
||||
lib
|
||||
nw-headers-v*.tar.gz
|
93
src/nwjs/CMakeLists.txt
Normal file
93
src/nwjs/CMakeLists.txt
Normal 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
168
src/nwjs/config/wcc.cc
Normal 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
0
src/nwjs/config/wcsc.cc
Normal file
30
src/nwjs/include/wcc.hh
Normal file
30
src/nwjs/include/wcc.hh
Normal 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
73
src/nwjs/wcc.cpp
Normal 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
70
test/node-gyp/binding.cc
Normal 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
14
test/node-gyp/binding.gyp
Normal 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
10
test/node-gyp/build.sh
Executable 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
|
16
test/node-gyp/package.json
Normal file
16
test/node-gyp/package.json
Normal 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
1261
test/node-gyp/pnpm-lock.yaml
generated
Normal file
File diff suppressed because it is too large
Load Diff
0
test/runner/nwjs/linux.ts
Normal file
0
test/runner/nwjs/linux.ts
Normal file
13
test/runner/nwjs/package.nw/index.html
Normal file
13
test/runner/nwjs/package.nw/index.html
Normal 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>
|
83
test/runner/nwjs/package.nw/main.js
Normal file
83
test/runner/nwjs/package.nw/main.js
Normal 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)
|
5
test/runner/nwjs/package.nw/package.json
Normal file
5
test/runner/nwjs/package.nw/package.json
Normal file
@ -0,0 +1,5 @@
|
||||
{
|
||||
"name": "helloworld",
|
||||
"main": "main.js",
|
||||
"show": "false"
|
||||
}
|
4
test/runner/nwjs/package.nw/wcc/lib/index.js
Normal file
4
test/runner/nwjs/package.nw/wcc/lib/index.js
Normal file
@ -0,0 +1,4 @@
|
||||
module.exports = {
|
||||
wcc: require('./wcc'),
|
||||
wcsc: require('./wcsc')
|
||||
}
|
@ -0,0 +1,2 @@
|
||||
[ZoneTransfer]
|
||||
ZoneId=3
|
1134
test/runner/nwjs/package.nw/wcc/lib/util.js
Normal file
1134
test/runner/nwjs/package.nw/wcc/lib/util.js
Normal file
File diff suppressed because it is too large
Load Diff
@ -0,0 +1,2 @@
|
||||
[ZoneTransfer]
|
||||
ZoneId=3
|
94
test/runner/nwjs/package.nw/wcc/lib/wcc.js
Normal file
94
test/runner/nwjs/package.nw/wcc/lib/wcc.js
Normal 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
|
@ -0,0 +1,2 @@
|
||||
[ZoneTransfer]
|
||||
ZoneId=3
|
92
test/runner/nwjs/package.nw/wcc/lib/wcsc.js
Normal file
92
test/runner/nwjs/package.nw/wcc/lib/wcsc.js
Normal 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
|
@ -0,0 +1,2 @@
|
||||
[ZoneTransfer]
|
||||
ZoneId=3
|
18
test/runner/nwjs/package.nw/wcc/package.json
Normal file
18
test/runner/nwjs/package.nw/wcc/package.json
Normal 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"
|
||||
}
|
||||
}
|
@ -0,0 +1,2 @@
|
||||
[ZoneTransfer]
|
||||
ZoneId=3
|
0
test/runner/nwjs/windows.ts
Normal file
0
test/runner/nwjs/windows.ts
Normal file
5
test/runner/nwjs/wine.sh
Normal file
5
test/runner/nwjs/wine.sh
Normal 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
|
||||
|
Loading…
x
Reference in New Issue
Block a user