Skip to content

Commit

Permalink
Merge pull request #416 from crypto-chassis/develop
Browse files Browse the repository at this point in the history
Release
  • Loading branch information
cryptochassis committed Aug 13, 2023
2 parents 9685adf + 4af5c66 commit a59cbe3
Show file tree
Hide file tree
Showing 30 changed files with 610 additions and 28 deletions.
12 changes: 12 additions & 0 deletions .github/workflows/test.yml
Expand Up @@ -157,6 +157,13 @@ jobs:
)
endif()
- name: Install node-gyp
shell: cmake -P {0}
run: |
execute_process(
COMMAND npm install -g node-gyp
)
- name: Configure
shell: cmake -P {0}
run: |
Expand Down Expand Up @@ -190,9 +197,11 @@ jobs:
if ("$ENV{GITHUB_EVENT_NAME}" STREQUAL "push")
set(ENV{CMAKE_BUILD_TYPE} "Release")
set(ENV{DOTNET_BUILD_CONFIGURATION} "Release")
set(ENV{NODE_GYP_BUILD_MODE} "release")
else()
set(ENV{CMAKE_BUILD_TYPE} "Debug")
set(ENV{DOTNET_BUILD_CONFIGURATION} "Debug")
set(ENV{NODE_GYP_BUILD_MODE} "debug")
endif()
execute_process(
Expand Down Expand Up @@ -233,11 +242,14 @@ jobs:
-DBUILD_PYTHON=ON
-DBUILD_JAVA=ON
-DBUILD_CSHARP=ON
# -DBUILD_GO=ON
# -DBUILD_JAVASCRIPT=ON
-DBUILD_TEST=ON
-S binding
-B binding/build
-D CMAKE_BUILD_TYPE=$ENV{CMAKE_BUILD_TYPE}
-D DOTNET_BUILD_CONFIGURATION=$ENV{DOTNET_BUILD_CONFIGURATION}
-D NODE_GYP_BUILD_MODE=$ENV{NODE_GYP_BUILD_MODE}
-G Ninja
-D CMAKE_MAKE_PROGRAM=ninja
# -D CMAKE_C_COMPILER_LAUNCHER=ccache
Expand Down
2 changes: 2 additions & 0 deletions .gitignore
Expand Up @@ -150,3 +150,5 @@ docs/_build/
.venv/
target/
obj/
node_modules/
package-lock.json
26 changes: 19 additions & 7 deletions README.md
Expand Up @@ -51,7 +51,7 @@
<!-- END doctoc generated TOC please keep comment here to allow auto update -->
# ccapi
* A header-only C++ library for streaming market data and executing trades directly from cryptocurrency exchanges (i.e. the connections are between your server and the exchange server without anything in-between).
* Bindings for other languages such as Python, Java, C#, and Go are provided.
* Bindings for other languages such as Python, Java, C#, Go, and Javascript are provided.
* Code closely follows Bloomberg's API: https://www.bloomberg.com/professional/support/api-library/.
* It is ultra fast thanks to very careful optimizations: move semantics, regex optimization, locality of reference, lock contention minimization, etc.
* Supported exchanges:
Expand Down Expand Up @@ -109,7 +109,7 @@
mkdir binding/build
cd binding/build
rm -rf * (if rebuild from scratch)
cmake -DBUILD_PYTHON=ON -DBUILD_VERSION=1.0.0 .. (Use -DBUILD_JAVA=ON if the target language is Java, -DBUILD_CSHARP=ON if the target language is C#, -DBUILD_GO=ON if the target language is Go)
cmake -DBUILD_PYTHON=ON -DBUILD_VERSION=1.0.0 .. (Use -DBUILD_JAVA=ON if the target language is Java, -DBUILD_CSHARP=ON if the target language is C#, -DBUILD_GO=ON if the target language is Go, -DBUILD_JAVASCRIPT=ON if the target language is Javascript)
cmake --build .
```
* The packaged build artifacts are located in the `binding/build/<language>/packaging/<BUILD_VERSION>` directory. SWIG generated raw files and build artifacts are located in the `binding/build/<language>/ccapi_binding_<language>` directory.
Expand All @@ -122,6 +122,8 @@ cmake --build .
* "‘_PyObject_GC_UNTRACK’ was not declared in this scope". If you use Python >= 3.8, please use SWIG >= 4.0.
* Java:
* "Could NOT find JNI (missing: JAVA_INCLUDE_PATH JAVA_INCLUDE_PATH2 JAVA_AWT_INCLUDE_PATH)". Check that the environment variable `JAVA_HOME` is correct.
* Javascript:
* "Check for node-gyp Program: not found". You can install node-gyp using npm: `npm install -g node-gyp`

## Constants
[`include/ccapi_cpp/ccapi_macro.h`](include/ccapi_cpp/ccapi_macro.h)
Expand Down Expand Up @@ -190,6 +192,16 @@ go build .
* Troubleshoot:
* Some C/C++ header files not found. Check that you sourced the export_compiler_options.sh file which provides important environment variables needed by the cgo tool.

[Javascript](binding/javascript/example)
* Javascript API is nearly identical to C++ API and covers nearly all the functionalities from C++ API.
* Build and install the Javascript binding as shown [above](#non-c).
* Inside a concrete example directory (e.g. binding/javascript/example/market_data_simple_subscription), run
```
rm -rf node_modules (if rebuild from scratch)
npm install
node index.js
```

## Documentations

### Simple Market Data
Expand All @@ -200,7 +212,7 @@ For a specific exchange and instrument, get recents trades.

**Code 1:**

[C++](example/src/market_data_simple_request/main.cpp) / [Python](binding/python/example/market_data_simple_request/main.py) / [Java](binding/java/example/market_data_simple_request/Main.java) / [C#](binding/csharp/example/market_data_simple_request/MainProgram.cs) / [Go](binding/go/example/market_data_simple_request/main.go)
[C++](example/src/market_data_simple_request/main.cpp) / [Python](binding/python/example/market_data_simple_request/main.py) / [Java](binding/java/example/market_data_simple_request/Main.java) / [C#](binding/csharp/example/market_data_simple_request/MainProgram.cs) / [Go](binding/go/example/market_data_simple_request/main.go) / [Javascript](binding/javascript/example/market_data_simple_request/index.js)
```
#include "ccapi_cpp/ccapi_session.h"
namespace ccapi {
Expand Down Expand Up @@ -273,7 +285,7 @@ For a specific exchange and instrument, whenever the best bid's or ask's price o

**Code 2:**

[C++](example/src/market_data_simple_subscription/main.cpp) / [Python](binding/python/example/market_data_simple_subscription/main.py) / [Java](binding/java/example/market_data_simple_subscription/Main.java) / [C#](binding/csharp/example/market_data_simple_subscription/MainProgram.cs) / [Go](binding/go/example/market_data_simple_subscription/main.go)
[C++](example/src/market_data_simple_subscription/main.cpp) / [Python](binding/python/example/market_data_simple_subscription/main.py) / [Java](binding/java/example/market_data_simple_subscription/Main.java) / [C#](binding/csharp/example/market_data_simple_subscription/MainProgram.cs) / [Go](binding/go/example/market_data_simple_subscription/main.go) / [Javascript](binding/javascript/example/market_data_simple_subscription/index.js)
```
#include "ccapi_cpp/ccapi_session.h"
namespace ccapi {
Expand Down Expand Up @@ -447,7 +459,7 @@ For a specific exchange and instrument, submit a simple limit order.

**Code 1:**

[C++](example/src/execution_management_simple_request/main.cpp) / [Python](binding/python/example/execution_management_simple_request/main.py) / [Java](binding/java/example/execution_management_simple_request/Main.java) / [C#](binding/csharp/example/execution_management_simple_request/MainProgram.cs) / [Go](binding/go/example/execution_management_simple_request/main.go)
[C++](example/src/execution_management_simple_request/main.cpp) / [Python](binding/python/example/execution_management_simple_request/main.py) / [Java](binding/java/example/execution_management_simple_request/Main.java) / [C#](binding/csharp/example/execution_management_simple_request/MainProgram.cs) / [Go](binding/go/example/execution_management_simple_request/main.go) / [Javascript](binding/javascript/example/execution_management_simple_request/index.js)
```
#include "ccapi_cpp/ccapi_session.h"
namespace ccapi {
Expand Down Expand Up @@ -537,7 +549,7 @@ For a specific exchange and instrument, receive order updates.

**Code 2:**

[C++](example/src/execution_management_simple_subscription/main.cpp) / [Python](binding/python/example/execution_management_simple_subscription/main.py) / [Java](binding/java/example/execution_management_simple_subscription/Main.java) / [C#](binding/csharp/example/execution_management_simple_subscription/MainProgram.cs) / [Go](binding/go/example/execution_management_simple_subscription/main.go)
[C++](example/src/execution_management_simple_subscription/main.cpp) / [Python](binding/python/example/execution_management_simple_subscription/main.py) / [Java](binding/java/example/execution_management_simple_subscription/Main.java) / [C#](binding/csharp/example/execution_management_simple_subscription/MainProgram.cs) / [Go](binding/go/example/execution_management_simple_subscription/main.go) / [Javascript](binding/javascript/example/execution_management_simple_subscription/index.js)
```
#include "ccapi_cpp/ccapi_session.h"
namespace ccapi {
Expand Down Expand Up @@ -780,7 +792,7 @@ For a specific exchange and instrument, submit a simple limit order.

**Code:**

[C++](example/src/fix_simple/main.cpp) / [Python](binding/python/example/fix_simple/main.py) / [Java](binding/java/example/fix_simple/Main.java) / [C#](binding/csharp/example/fix_simple/MainProgram.cs) / [Go](binding/go/example/fix_simple/main.go)
[C++](example/src/fix_simple/main.cpp) / [Python](binding/python/example/fix_simple/main.py) / [Java](binding/java/example/fix_simple/Main.java) / [C#](binding/csharp/example/fix_simple/MainProgram.cs) / [Go](binding/go/example/fix_simple/main.go) / [Javascript](binding/javascript/example/fix_simple/index.js)
```
#include "ccapi_cpp/ccapi_session.h"
namespace ccapi {
Expand Down
2 changes: 1 addition & 1 deletion binding/csharp/example/fix_simple/MainProgram.cs
Expand Up @@ -16,7 +16,7 @@ class MyEventHandler : ccapi.EventHandler {
param.Add(new ccapi.PairIntString(40, "2"));
param.Add(new ccapi.PairIntString(59, "1"));
request.AppendParamFix(param);
session.SendRequest(request);
session.SendRequestByFix(request);
}
} else if (event_.GetType_() == ccapi.Event.Type.FIX) {
System.Console.WriteLine(string.Format("Received an event of type FIX:\n{0}", event_.ToStringPretty(2, 2)));
Expand Down
2 changes: 1 addition & 1 deletion binding/go/CMakeLists.txt
Expand Up @@ -22,7 +22,7 @@ set(GO_PACKAGE "ccapi")
file(MAKE_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR}/${SWIG_TARGET_NAME})

add_custom_target(${SWIG_TARGET_NAME} ALL
COMMAND ${SWIG_EXECUTABLE} -outcurrentdir -c++ -go -package ${GO_PACKAGE} -I${CCAPI_PROJECT_DIR}/include ${SWIG_INTERFACE}
COMMAND ${SWIG_EXECUTABLE} -outcurrentdir -c++ -go -intgosize 64 -package ${GO_PACKAGE} -I${CCAPI_PROJECT_DIR}/include ${SWIG_INTERFACE}
WORKING_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR}/${SWIG_TARGET_NAME}
)
add_dependencies(${SWIG_TARGET_NAME} boost rapidjson hffix)
Expand Down
2 changes: 1 addition & 1 deletion binding/go/example/fix_simple/main.go
Expand Up @@ -41,7 +41,7 @@ func (*MyEventHandler) ProcessEvent(event ccapi.Event, session ccapi.Session) bo
param.Add(aParam)
}
request.AppendParamFix(param)
session.SendRequest(request)
session.SendRequestByFix(request)
}
} else if event.GetType() == ccapi.EventType_FIX {
fmt.Printf("Received an event of type FIX:\n%s\n", event.ToStringPretty(2, 2))
Expand Down
18 changes: 9 additions & 9 deletions binding/go/example/market_data_simple_subscription/main.go
Expand Up @@ -21,18 +21,18 @@ func (*MyEventHandler) ProcessEvent(event ccapi.Event, session ccapi.Session) bo
elementList := message.GetElementList()
for j := 0; j < int(elementList.Size()); j++ {
element := elementList.Get(j)
nameValueMap := element.GetNameValueMap()
if nameValueMap.Has_key("BID_PRICE") {
fmt.Printf(" %s = %s\n", "BID_PRICE", nameValueMap.Get("BID_PRICE"))
elementNameValueMap := element.GetNameValueMap()
if elementNameValueMap.Has_key("BID_PRICE") {
fmt.Printf(" BID_PRICE = %s\n", elementNameValueMap.Get("BID_PRICE"))
}
if nameValueMap.Has_key("BID_SIZE") {
fmt.Printf(" %s = %s\n", "BID_SIZE", nameValueMap.Get("BID_SIZE"))
if elementNameValueMap.Has_key("BID_SIZE") {
fmt.Printf(" BID_SIZE = %s\n", elementNameValueMap.Get("BID_SIZE"))
}
if nameValueMap.Has_key("ASK_PRICE") {
fmt.Printf(" %s = %s\n", "ASK_PRICE", nameValueMap.Get("ASK_PRICE"))
if elementNameValueMap.Has_key("ASK_PRICE") {
fmt.Printf(" ASK_PRICE = %s\n", elementNameValueMap.Get("ASK_PRICE"))
}
if nameValueMap.Has_key("ASK_SIZE") {
fmt.Printf(" %s = %s\n", "ASK_SIZE", nameValueMap.Get("ASK_SIZE"))
if elementNameValueMap.Has_key("ASK_SIZE") {
fmt.Printf(" ASK_SIZE = %s\n", elementNameValueMap.Get("ASK_SIZE"))
}
}
}
Expand Down
7 changes: 0 additions & 7 deletions binding/go/test/go.mod

This file was deleted.

2 changes: 1 addition & 1 deletion binding/java/example/fix_simple/Main.java
Expand Up @@ -29,7 +29,7 @@ public boolean processEvent(Event event, Session session) {
param.add(new PairIntString(40, "2"));
param.add(new PairIntString(59, "1"));
request.appendParamFix(param);
session.sendRequest(request);
session.sendRequestByFix(request);
}
} else if (event.getType() == Event.Type.FIX) {
System.out.println(String.format("Received an event of type FIX:\n%s", event.toStringPretty(2, 2)));
Expand Down
130 changes: 130 additions & 0 deletions binding/javascript/CMakeLists.txt
@@ -0,0 +1,130 @@
set(NAME binding_${LANG})
project(${NAME})
set(SWIG_TARGET_NAME ccapi_${NAME})

# Find javascript cli
find_program(NODE_EXECUTABLE NAMES node REQUIRED)
if(NOT NODE_EXECUTABLE)
message(FATAL_ERROR "Check for node Program: not found")
else()
message(STATUS "Found node Program: ${NODE_EXECUTABLE}")
endif()

execute_process(
COMMAND ${NODE_EXECUTABLE} -v
OUTPUT_VARIABLE NODE_EXECUTABLE_VERSION
OUTPUT_STRIP_TRAILING_WHITESPACE
)
message(STATUS "node version: ${NODE_EXECUTABLE_VERSION}")

find_program(NODE_GYP_EXECUTABLE NAMES node-gyp REQUIRED)
if(NOT NODE_GYP_EXECUTABLE)
message(FATAL_ERROR "Check for node-gyp Program: not found")
else()
message(STATUS "Found node-gyp Program: ${NODE_EXECUTABLE}")
endif()

execute_process(
COMMAND ${NODE_GYP_EXECUTABLE} -v
OUTPUT_VARIABLE NODE_GYP_EXECUTABLE_VERSION
OUTPUT_STRIP_TRAILING_WHITESPACE
)
message(STATUS "node-gyp version: ${NODE_GYP_EXECUTABLE_VERSION}")

file(MAKE_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR}/${SWIG_TARGET_NAME})
set(BINDING_GYP_CFLAGS_CC_LIST "")
set(BINDING_GYP_LDFLAGS_LIST "")
set(BINDING_GYP_DEFINES_LIST "")
list(APPEND BINDING_GYP_CFLAGS_CC_LIST -std=c++17 -fPIC -Wno-deprecated-declarations)
if("${CMAKE_BUILD_TYPE}" STREQUAL "Debug")
list(APPEND BINDING_GYP_CFLAGS_CC_LIST -g)
list(APPEND BINDING_GYP_LDFLAGS_LIST -g)
else()
list(APPEND BINDING_GYP_CFLAGS_CC_LIST -O3 -DNDEBUG)
endif()
if(CMAKE_CXX_COMPILER_ID STREQUAL "GNU")
list(APPEND BINDING_GYP_CFLAGS_CC_LIST -pthread)
endif()
list(APPEND BINDING_GYP_DEFINES_LIST CCAPI_ENABLE_SERVICE_MARKET_DATA CCAPI_ENABLE_SERVICE_EXECUTION_MANAGEMENT CCAPI_ENABLE_SERVICE_FIX CCAPI_ENABLE_EXCHANGE_COINBASE CCAPI_ENABLE_EXCHANGE_GEMINI CCAPI_ENABLE_EXCHANGE_KRAKEN CCAPI_ENABLE_EXCHANGE_KRAKEN_FUTURES CCAPI_ENABLE_EXCHANGE_BITSTAMP CCAPI_ENABLE_EXCHANGE_BITFINEX CCAPI_ENABLE_EXCHANGE_BITMEX CCAPI_ENABLE_EXCHANGE_BINANCE_US CCAPI_ENABLE_EXCHANGE_BINANCE CCAPI_ENABLE_EXCHANGE_BINANCE_MARGIN CCAPI_ENABLE_EXCHANGE_BINANCE_USDS_FUTURES CCAPI_ENABLE_EXCHANGE_BINANCE_COIN_FUTURES CCAPI_ENABLE_EXCHANGE_HUOBI CCAPI_ENABLE_EXCHANGE_HUOBI_USDT_SWAP CCAPI_ENABLE_EXCHANGE_HUOBI_COIN_SWAP CCAPI_ENABLE_EXCHANGE_OKX CCAPI_ENABLE_EXCHANGE_ERISX CCAPI_ENABLE_EXCHANGE_KUCOIN CCAPI_ENABLE_EXCHANGE_KUCOIN_FUTURES CCAPI_ENABLE_EXCHANGE_DERIBIT CCAPI_ENABLE_EXCHANGE_GATEIO CCAPI_ENABLE_EXCHANGE_GATEIO_PERPETUAL_FUTURES CCAPI_ENABLE_EXCHANGE_CRYPTOCOM CCAPI_ENABLE_EXCHANGE_BYBIT CCAPI_ENABLE_EXCHANGE_BYBIT_DERIVATIVES CCAPI_ENABLE_EXCHANGE_ASCENDEX CCAPI_ENABLE_EXCHANGE_BITGET CCAPI_ENABLE_EXCHANGE_BITGET_FUTURES CCAPI_ENABLE_EXCHANGE_BITMART CCAPI_ENABLE_EXCHANGE_MEXC CCAPI_ENABLE_EXCHANGE_MEXC_FUTURES CCAPI_ENABLE_EXCHANGE_WHITEBIT)
if(CCAPI_ENABLE_LOG_ERROR)
list(APPEND BINDING_GYP_DEFINES_LIST CCAPI_ENABLE_LOG_ERROR)
endif()
if(CCAPI_ENABLE_LOG_WARN)
list(APPEND BINDING_GYP_DEFINES_LIST CCAPI_ENABLE_LOG_WARN)
endif()
if(CCAPI_ENABLE_LOG_INFO)
list(APPEND BINDING_GYP_DEFINES_LIST CCAPI_ENABLE_LOG_INFO)
endif()
if(CCAPI_ENABLE_LOG_DEBUG)
list(APPEND BINDING_GYP_DEFINES_LIST CCAPI_ENABLE_LOG_DEBUG)
endif()
if(CCAPI_ENABLE_LOG_TRACE)
list(APPEND BINDING_GYP_DEFINES_LIST CCAPI_ENABLE_LOG_TRACE)
endif()
list(JOIN BINDING_GYP_CFLAGS_CC_LIST "\",\"" BINDING_GYP_CFLAGS_CC)
message(STATUS "BINDING_GYP_CFLAGS_CC: ${BINDING_GYP_CFLAGS_CC}")
list(JOIN BINDING_GYP_LDFLAGS_LIST "\",\"" BINDING_GYP_LDFLAGS)
message(STATUS "BINDING_GYP_LDFLAGS: ${BINDING_GYP_LDFLAGS}")
list(JOIN BINDING_GYP_DEFINES_LIST "\",\"" BINDING_GYP_DEFINES)
message(STATUS "BINDING_GYP_DEFINES: ${BINDING_GYP_DEFINES}")

configure_file(
${CMAKE_CURRENT_SOURCE_DIR}/binding.gyp.in
${CMAKE_CURRENT_BINARY_DIR}/${SWIG_TARGET_NAME}/binding.gyp
@ONLY)
if(NOT NODE_GYP_BUILD_MODE)
set(NODE_GYP_BUILD_MODE "release" CACHE STRING
"Choose the type of build, options are: debug, release."
FORCE)
endif()
if("${NODE_GYP_BUILD_MODE}" STREQUAL "release")
set(NODE_GYP_BUILD_DIR "build/Release")
else()
set(NODE_GYP_BUILD_DIR "build/Debug")
endif()
message(STATUS "NODE_GYP_BUILD_MODE: ${NODE_GYP_BUILD_MODE}")
add_custom_target(${SWIG_TARGET_NAME} ALL
COMMAND ${SWIG_EXECUTABLE} -outcurrentdir -c++ -javascript -node -I${CCAPI_PROJECT_DIR}/include ${SWIG_INTERFACE}
COMMAND ${CMAKE_COMMAND} -E copy ${CMAKE_SOURCE_DIR}/ccapi_logger.cpp .
COMMAND ${NODE_GYP_EXECUTABLE} --${NODE_GYP_BUILD_MODE} clean configure build
WORKING_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR}/${SWIG_TARGET_NAME}
)
add_dependencies(${SWIG_TARGET_NAME} boost rapidjson hffix)

set(PACKAGING_DIR packaging)
set(PACKAGING_DIR_FULL ${CMAKE_CURRENT_BINARY_DIR}/${PACKAGING_DIR}/${BUILD_VERSION})
file(MAKE_DIRECTORY ${PACKAGING_DIR_FULL})
set(JAVASCRIPT_PACKAGING_TARGET_NAME ${LANG}_${PACKAGING_DIR})
configure_file(
${CMAKE_CURRENT_SOURCE_DIR}/package.json.in
${PACKAGING_DIR_FULL}/package.json
@ONLY)
add_custom_target(${JAVASCRIPT_PACKAGING_TARGET_NAME} ALL
COMMAND ${CMAKE_COMMAND} -E copy ${CMAKE_CURRENT_BINARY_DIR}/${SWIG_TARGET_NAME}/${NODE_GYP_BUILD_DIR}/index.node ${PACKAGING_DIR_FULL}
WORKING_DIRECTORY ${PACKAGING_DIR_FULL}
)
add_dependencies(${JAVASCRIPT_PACKAGING_TARGET_NAME} ${SWIG_TARGET_NAME})

# Test
if(BUILD_TEST)
set(TEST_DIR ${CMAKE_CURRENT_BINARY_DIR}/test)
find_program(NPM_EXECUTABLE NAMES npm REQUIRED)
if(NOT NPM_EXECUTABLE)
message(FATAL_ERROR "Check for npm Program: not found")
else()
message(STATUS "Found npm Program: ${NPM_EXECUTABLE}")
endif()
file(COPY test DESTINATION ${TEST_DIR})
set(JAVASCRIPT_TEST_TARGET_NAME javascript_test_test)
set(JAVASCRIPT_TEST_BUILD_DIRECTORY ${TEST_DIR}/test)
file(MAKE_DIRECTORY ${JAVASCRIPT_TEST_BUILD_DIRECTORY})
add_custom_target(${JAVASCRIPT_TEST_TARGET_NAME} ALL
COMMAND ${CMAKE_COMMAND} -E rm -rf node_modules
COMMAND ${NPM_EXECUTABLE} install ${PACKAGING_DIR_FULL}
WORKING_DIRECTORY ${JAVASCRIPT_TEST_BUILD_DIRECTORY}
)
add_dependencies(${JAVASCRIPT_TEST_TARGET_NAME} ${JAVASCRIPT_PACKAGING_TARGET_NAME})
add_test(NAME javascript_test
COMMAND ${NODE_EXECUTABLE} index.js
WORKING_DIRECTORY ${JAVASCRIPT_TEST_BUILD_DIRECTORY})
endif()

0 comments on commit a59cbe3

Please sign in to comment.