Skip to content

Commit 6737c3b

Browse files
committed
cross-platform: Fix external build break and add native testing
We have been keep breaking the native sample project. Fixing the break and adding a native test to make sure we do not break it again
1 parent bb44f40 commit 6737c3b

File tree

7 files changed

+307
-34
lines changed

7 files changed

+307
-34
lines changed

.gitignore

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -56,6 +56,6 @@ install_manifest.txt
5656
# additional *nix generated files
5757
*.a
5858
*.gch
59+
*.o
5960
Makefile
6061
pal/src/config.h
61-

bin/ch/WScriptJsrt.cpp

Lines changed: 97 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -18,19 +18,24 @@
1818
// otherwise, i.e. android system can be marked as posix? etc..
1919
#ifdef _WIN32
2020
#define DEST_PLATFORM_TEXT "win32"
21-
#elif defined(__APPLE__)
21+
#else // ! _WIN32
22+
#if defined(__APPLE__)
23+
#include <mach-o/dyld.h> // _NSGetExecutablePath
2224
#ifdef __IOS__
2325
#define DEST_PLATFORM_TEXT "ios"
24-
#else
26+
#else // ! iOS
2527
#define DEST_PLATFORM_TEXT "darwin"
26-
#endif
28+
#endif // iOS ?
2729
#elif defined(__ANDROID__)
30+
#include <unistd.h> // readlink
2831
#define DEST_PLATFORM_TEXT "android"
2932
#elif defined(__linux__)
33+
#include <unistd.h> // readlink
3034
#define DEST_PLATFORM_TEXT "posix"
3135
#elif defined(__FreeBSD__) || defined(__unix__)
3236
#define DEST_PLATFORM_TEXT "bsd"
33-
#endif
37+
#endif // FreeBSD or unix ?
38+
#endif // _WIN32 ?
3439

3540
MessageQueue* WScriptJsrt::messageQueue = nullptr;
3641
std::map<std::string, JsModuleRecord> WScriptJsrt::moduleRecordMap;
@@ -715,9 +720,76 @@ bool WScriptJsrt::InstallObjectsOnObject(JsValueRef object, const char* name, Js
715720
return true;
716721
}
717722

723+
#define SET_BINARY_PATH_ERROR_MESSAGE(path, msg) \
724+
str_len = (int) strlen(msg); \
725+
memcpy(path, msg, (size_t)str_len); \
726+
path[str_len] = char(0)
727+
728+
void GetBinaryLocation(char *path, const uint32_t size)
729+
{
730+
AssertMsg(size > 512 && path != nullptr, "Min path buffer size 512 and path can not be nullptr");
731+
#ifdef _WIN32
732+
LPWSTR wpath = (WCHAR*)malloc(sizeof(WCHAR) * size);
733+
int str_len;
734+
if (!wpath)
735+
{
736+
SET_BINARY_PATH_ERROR_MESSAGE(path, "GetBinaryLocation: GetModuleFileName has failed. OutOfMemory!");
737+
return;
738+
}
739+
str_len = GetModuleFileNameW(NULL, wpath, size);
740+
if (str_len <= 0)
741+
{
742+
SET_BINARY_PATH_ERROR_MESSAGE(path, "GetBinaryLocation: GetModuleFileName has failed.");
743+
return;
744+
}
745+
wpath[str_len] = WCHAR(0);
746+
747+
str_len = WideCharToMultiByte(CP_UTF8, 0, wpath, -1, path, size, NULL, NULL);
748+
if (str_len <= 0)
749+
{
750+
SET_BINARY_PATH_ERROR_MESSAGE(path, "GetBinaryLocation: GetModuleFileName (WideCharToMultiByte) has failed.");
751+
return;
752+
}
753+
path[str_len] = char(0);
754+
#elif defined(__APPLE__)
755+
uint32_t path_size = size;
756+
char *tmp = nullptr;
757+
int str_len;
758+
if (_NSGetExecutablePath(path, &path_size))
759+
{
760+
SET_BINARY_PATH_ERROR_MESSAGE(path, "GetBinaryLocation: _NSGetExecutablePath has failed.");
761+
return;
762+
}
763+
764+
tmp = (char*)malloc(size);
765+
char *result = realpath(path, tmp);
766+
str_len = strlen(result);
767+
memcpy(path, result, str_len);
768+
free(tmp);
769+
path[str_len] = char(0);
770+
#elif defined(__linux__)
771+
int str_len = readlink("/proc/self/exe", path, size - 1);
772+
if (str_len <= 0)
773+
{
774+
SET_BINARY_PATH_ERROR_MESSAGE(path, "GetBinaryLocation: /proc/self/exe has failed.");
775+
return;
776+
}
777+
path[str_len] = char(0);
778+
#else
779+
#warning "Implement GetBinaryLocation for this platform"
780+
#endif
781+
}
782+
718783
bool WScriptJsrt::Initialize()
719784
{
720785
HRESULT hr = S_OK;
786+
char CH_BINARY_LOCATION[2048];
787+
#ifdef CHAKRA_STATIC_LIBRARY
788+
const char* LINK_TYPE = "static";
789+
#else
790+
const char* LINK_TYPE = "shared";
791+
#endif
792+
721793
JsValueRef wscript;
722794
IfJsrtErrorFail(ChakraRTInterface::JsCreateObject(&wscript), false);
723795

@@ -746,9 +818,29 @@ bool WScriptJsrt::Initialize()
746818
JsPropertyIdRef archProperty;
747819
IfJsrtErrorFail(ChakraRTInterface::JsGetPropertyIdFromNameUtf8("ARCH", &archProperty), false);
748820
JsValueRef archValue;
749-
IfJsrtErrorFail(ChakraRTInterface::JsPointerToStringUtf8(CPU_ARCH_TEXT, strlen(CPU_ARCH_TEXT), &archValue), false);
821+
IfJsrtErrorFail(ChakraRTInterface::JsPointerToStringUtf8(CPU_ARCH_TEXT,strlen(CPU_ARCH_TEXT), &archValue), false);
750822
IfJsrtErrorFail(ChakraRTInterface::JsSetProperty(platformObject, archProperty, archValue, true), false);
751823

824+
// Set Link Type [static / shared]
825+
JsPropertyIdRef linkProperty;
826+
IfJsrtErrorFail(ChakraRTInterface::JsGetPropertyIdFromNameUtf8("LINK_TYPE", &linkProperty), false);
827+
JsValueRef linkValue;
828+
IfJsrtErrorFail(ChakraRTInterface::JsPointerToStringUtf8(LINK_TYPE,strlen(LINK_TYPE), &linkValue), false);
829+
IfJsrtErrorFail(ChakraRTInterface::JsSetProperty(platformObject, linkProperty, linkValue, true), false);
830+
831+
// Set Binary Location
832+
JsValueRef binaryPathValue;
833+
GetBinaryLocation(CH_BINARY_LOCATION, sizeof(CH_BINARY_LOCATION));
834+
835+
JsPropertyIdRef binaryPathProperty;
836+
IfJsrtErrorFail(ChakraRTInterface::JsGetPropertyIdFromNameUtf8("BINARY_PATH",
837+
&binaryPathProperty), false);
838+
839+
IfJsrtErrorFail(ChakraRTInterface::JsPointerToStringUtf8(CH_BINARY_LOCATION,
840+
strlen(CH_BINARY_LOCATION), &binaryPathValue), false);
841+
IfJsrtErrorFail(ChakraRTInterface::JsSetProperty(platformObject, binaryPathProperty,
842+
binaryPathValue, true), false);
843+
752844
// Set destination OS
753845
JsPropertyIdRef osProperty;
754846
IfJsrtErrorFail(ChakraRTInterface::JsGetPropertyIdFromNameUtf8("OS", &osProperty), false);

lib/Jsrt/ChakraCommon.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -84,6 +84,7 @@ typedef uint32_t UINT32;
8484
typedef int64_t INT64;
8585
typedef void* HANDLE;
8686
typedef unsigned char BYTE;
87+
typedef BYTE byte;
8788
typedef UINT32 DWORD;
8889
#endif
8990

Lines changed: 54 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,54 @@
1+
//-------------------------------------------------------------------------------------------------------
2+
// Copyright (C) Microsoft. All rights reserved.
3+
// Licensed under the MIT license. See LICENSE.txt file in the project root for full license information.
4+
//-------------------------------------------------------------------------------------------------------
5+
6+
var isWindows = !WScript.Platform || WScript.Platform.OS == 'win32';
7+
var path_sep = isWindows ? '\\' : '/';
8+
var isStaticBuild = WScript.Platform && WScript.Platform.LINK_TYPE == 'static';
9+
10+
if (!isStaticBuild) {
11+
// test will be ignored
12+
print("# IGNORE_THIS_TEST");
13+
} else {
14+
var platform = WScript.Platform.OS;
15+
var binaryPath = WScript.Platform.BINARY_PATH;
16+
// discard `ch` from path
17+
binaryPath = binaryPath.substr(0, binaryPath.lastIndexOf(path_sep));
18+
var makefile =
19+
"IDIR=" + binaryPath + "/../../lib/Jsrt \n\
20+
\n\
21+
LIBRARY_PATH=" + binaryPath + "/lib\n\
22+
PLATFORM=" + platform + "\n\
23+
LDIR=$(LIBRARY_PATH)/../pal/src/libChakra.Pal.a \
24+
$(LIBRARY_PATH)/Common/Core/libChakra.Common.Core.a \
25+
$(LIBRARY_PATH)/Jsrt/libChakra.Jsrt.a \n\
26+
\n\
27+
ifeq (darwin, ${PLATFORM})\n\
28+
\tICU4C_LIBRARY_PATH ?= /usr/local/opt/icu4c\n\
29+
\tCFLAGS=-lstdc++ -std=c++11 -I$(IDIR)\n\
30+
\tFORCE_STARTS=-Wl,-force_load,\n\
31+
\tFORCE_ENDS=\n\
32+
\tLIBS=-framework CoreFoundation -framework Security -lm -ldl -Wno-c++11-compat-deprecated-writable-strings \
33+
-Wno-deprecated-declarations -Wno-unknown-warning-option -o sample.o\n\
34+
\tLDIR+=$(ICU4C_LIBRARY_PATH)/lib/libicudata.a \
35+
$(ICU4C_LIBRARY_PATH)/lib/libicuuc.a \
36+
$(ICU4C_LIBRARY_PATH)/lib/libicui18n.a\n\
37+
else\n\
38+
\tCFLAGS=-lstdc++ -std=c++0x -I$(IDIR)\n\
39+
\tFORCE_STARTS=-Wl,--whole-archive\n\
40+
\tFORCE_ENDS=-Wl,--no-whole-archive\n\
41+
\tLIBS=-pthread -lm -ldl -licuuc -lunwind-x86_64 -Wno-c++11-compat-deprecated-writable-strings \
42+
-Wno-deprecated-declarations -Wno-unknown-warning-option -o sample.o\n\
43+
endif\n\
44+
\n\
45+
testmake:\n\
46+
\t$(CC) sample.cpp $(CFLAGS) $(FORCE_STARTS) $(LDIR) $(FORCE_ENDS) $(LIBS)\n\
47+
\n\
48+
.PHONY: clean\n\
49+
\n\
50+
clean:\n\
51+
\trm sample.o\n";
52+
53+
print(makefile)
54+
}
Lines changed: 50 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,50 @@
1+
//-------------------------------------------------------------------------------------------------------
2+
// Copyright (C) Microsoft. All rights reserved.
3+
// Licensed under the MIT license. See LICENSE.txt file in the project root for full license information.
4+
//-------------------------------------------------------------------------------------------------------
5+
6+
#include "ChakraCore.h"
7+
#include <string>
8+
#include <iostream>
9+
10+
using namespace std;
11+
12+
int main()
13+
{
14+
JsRuntimeHandle runtime;
15+
JsContextRef context;
16+
JsValueRef result;
17+
unsigned currentSourceContext = 0;
18+
19+
const char* script = "(()=>{return \'SUCCESS\';})()";
20+
21+
// Create a runtime.
22+
JsCreateRuntime(JsRuntimeAttributeNone, nullptr, &runtime);
23+
24+
// Create an execution context.
25+
JsCreateContext(runtime, &context);
26+
27+
// Now set the current execution context.
28+
JsSetCurrentContext(context);
29+
30+
// Run the script.
31+
JsRunScriptUtf8(script, currentSourceContext++, "", &result);
32+
33+
// Convert your script result to String in JavaScript; redundant if your script returns a String
34+
JsValueRef resultJSString;
35+
JsConvertValueToString(result, &resultJSString);
36+
37+
// Project script result back to C++.
38+
char *resultSTR;
39+
size_t stringLength;
40+
JsStringToPointerUtf8Copy(resultJSString, &resultSTR, &stringLength);
41+
42+
printf("Result -> %s \n", resultSTR);
43+
JsStringFree(resultSTR);
44+
45+
// Dispose runtime
46+
JsSetCurrentContext(JS_INVALID_REFERENCE);
47+
JsDisposeRuntime(runtime);
48+
49+
return 0;
50+
}

test/native-tests/test_native.sh

Lines changed: 65 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,65 @@
1+
#-------------------------------------------------------------------------------------------------------
2+
# Copyright (C) Microsoft. All rights reserved.
3+
# Licensed under the MIT license. See LICENSE.txt file in the project root for full license information.
4+
#-------------------------------------------------------------------------------------------------------
5+
6+
CH_DIR=$1
7+
RES=
8+
CC=0
9+
CXX=0
10+
11+
FIND_CLANG() {
12+
for i in 7 8 9
13+
do
14+
if [[ -f "/usr/bin/clang-3.${i}" ]]; then
15+
CC="/usr/bin/clang-3.${i}"
16+
CXX="/usr/bin/clang++-3.${i}"
17+
fi
18+
done
19+
if [[ $CC == 0 ]]; then
20+
echo "Error: Couldn't find Clang"
21+
exit 1
22+
fi
23+
}
24+
25+
SAFE_RUN() {
26+
local SF_RETURN_VALUE=$($1 2>&1)
27+
28+
if [[ $? != 0 ]]; then
29+
>&2 echo $SF_RETURN_VALUE
30+
exit 1
31+
fi
32+
echo $SF_RETURN_VALUE
33+
}
34+
35+
TEST () {
36+
if [[ $RES =~ $1 ]]; then
37+
echo "${TEST_PATH} : PASS"
38+
else
39+
echo "${TEST_PATH} FAILED"
40+
echo -e "$RES"
41+
exit 1
42+
fi
43+
}
44+
45+
RES=$(c++ --version)
46+
if [[ ! $RES =~ "Apple LLVM" ]]; then
47+
FIND_CLANG
48+
else
49+
CC="cc"
50+
CXX="c++"
51+
fi
52+
53+
# test-static-native
54+
TEST_PATH="test-static-native"
55+
SAFE_RUN `cd $TEST_PATH; ${CH_DIR} Platform.js > Makefile`
56+
RES=$(cd $TEST_PATH; cat Makefile)
57+
if [[ $RES =~ "# IGNORE_THIS_TEST" ]]; then
58+
echo "Ignoring $TEST_PATH"
59+
else
60+
SAFE_RUN `cd $TEST_PATH; make CC=${CC} CXX=${CXX}`
61+
RES=$(cd $TEST_PATH; ./sample.o)
62+
TEST "SUCCESS"
63+
SAFE_RUN `rm -rf ./sample.o`
64+
fi
65+
SAFE_RUN `rm -rf Makefile`

0 commit comments

Comments
 (0)