Allow Hermes to be built as a DLL on Windows

Summary:
On windows it is required to explicitly specify what symbols need to be exported from a DLL to make them accessible (using `__declspec(dllexport)`). I have added and expanded on existing macros to do this and added exports that were previously missing.

Changelog:
[Internal][Changed] - Allow Hermes to be compiled to a single DLL on windows

Reviewed By: mhorowitz

Differential Revision: D23084343

fbshipit-source-id: 832cb17b9e637e4c04dad479aae6c1fc190f968e
This commit is contained in:
Martin Sherburn 2020-08-24 06:05:15 -07:00 committed by Facebook GitHub Bot
parent 464293f64e
commit 549563e8ab
9 changed files with 74 additions and 28 deletions

2
.gitignore vendored
View File

@ -35,6 +35,8 @@ project.xcworkspace
# Buck
.buckd
buck-out
/.lsp.buckd
/.lsp-buck-out
/ReactAndroid/src/main/jni/prebuilt/lib/
/ReactAndroid/src/main/gen

View File

@ -5,7 +5,10 @@
* LICENSE file in the root directory of this source tree.
*/
#pragma once
// using include guards instead of #pragma once due to compile issues
// with MSVC and BUCK
#ifndef HERMES_INSPECTOR_EXCEPTIONS_H
#define HERMES_INSPECTOR_EXCEPTIONS_H
#include <stdexcept>
@ -47,3 +50,5 @@ class MultipleCommandsPendingException : public std::runtime_error {
} // namespace inspector
} // namespace hermes
} // namespace facebook
#endif // HERMES_INSPECTOR_EXCEPTIONS_H

View File

@ -5,7 +5,10 @@
* LICENSE file in the root directory of this source tree.
*/
#pragma once
// using include guards instead of #pragma once due to compile issues
// with MSVC and BUCK
#ifndef HERMES_INSPECTOR_INSPECTOR_H
#define HERMES_INSPECTOR_INSPECTOR_H
#include <memory>
#include <queue>
@ -362,3 +365,5 @@ class Inspector : public facebook::hermes::debugger::EventObserver,
} // namespace inspector
} // namespace hermes
} // namespace facebook
#endif // HERMES_INSPECTOR_INSPECTOR_H

View File

@ -5,7 +5,10 @@
* LICENSE file in the root directory of this source tree.
*/
#pragma once
// using include guards instead of #pragma once due to compile issues
// with MSVC and BUCK
#ifndef HERMES_INSPECTOR_INSPECTOR_STATE_H
#define HERMES_INSPECTOR_INSPECTOR_STATE_H
#include <condition_variable>
#include <iostream>
@ -405,3 +408,5 @@ class InspectorState::Paused : public InspectorState {
} // namespace inspector
} // namespace hermes
} // namespace facebook
#endif // HERMES_INSPECTOR_INSPECTOR_STATE_H

View File

@ -11,6 +11,18 @@
#include <hermes/hermes.h>
#ifndef INSPECTOR_EXPORT
#ifdef _MSC_VER
#ifdef CREATE_SHARED_LIBRARY
#define INSPECTOR_EXPORT __declspec(dllexport)
#else
#define INSPECTOR_EXPORT
#endif // CREATE_SHARED_LIBRARY
#else // _MSC_VER
#define INSPECTOR_EXPORT __attribute__((visibility("default")))
#endif // _MSC_VER
#endif // !defined(INSPECTOR_EXPORT)
namespace facebook {
namespace hermes {
namespace inspector {
@ -20,7 +32,7 @@ namespace inspector {
* runtime object should stay alive for at least as long as the RuntimeAdapter
* is alive.
*/
class RuntimeAdapter {
class INSPECTOR_EXPORT RuntimeAdapter {
public:
virtual ~RuntimeAdapter() = 0;
@ -49,7 +61,7 @@ class RuntimeAdapter {
* uses shared_ptr to hold on to the runtime. It's generally only used in tests,
* since it does not implement tickleJs.
*/
class SharedRuntimeAdapter : public RuntimeAdapter {
class INSPECTOR_EXPORT SharedRuntimeAdapter : public RuntimeAdapter {
public:
SharedRuntimeAdapter(
std::shared_ptr<jsi::Runtime> runtime,

View File

@ -5,7 +5,10 @@
* LICENSE file in the root directory of this source tree.
*/
#pragma once
// using include guards instead of #pragma once due to compile issues
// with MSVC and BUCK
#ifndef HERMES_INSPECTOR_CONNECTION_H
#define HERMES_INSPECTOR_CONNECTION_H
#include <functional>
#include <memory>
@ -21,7 +24,7 @@ namespace inspector {
namespace chrome {
/// Connection is a duplex connection between the client and the debugger.
class Connection {
class INSPECTOR_EXPORT Connection {
public:
/// Connection constructor enables the debugger on the provided runtime. This
/// should generally called before you start running any JS in the runtime.
@ -60,3 +63,5 @@ class Connection {
} // namespace inspector
} // namespace hermes
} // namespace facebook
#endif // HERMES_INSPECTOR_CONNECTION_H

View File

@ -21,7 +21,7 @@ namespace jsi {
/// controls the instrumentation of.
/// None of these functions should return newly created jsi values, nor should
/// it modify the values of any jsi values in the heap (although GCs are fine).
class Instrumentation {
class JSI_EXPORT Instrumentation {
public:
virtual ~Instrumentation() = default;

View File

@ -17,11 +17,11 @@
#ifndef JSI_EXPORT
#ifdef _MSC_VER
#ifdef JSI_CREATE_SHARED_LIBRARY
#ifdef CREATE_SHARED_LIBRARY
#define JSI_EXPORT __declspec(dllexport)
#else
#define JSI_EXPORT
#endif // JSI_CREATE_SHARED_LIBRARY
#endif // CREATE_SHARED_LIBRARY
#else // _MSC_VER
#define JSI_EXPORT __attribute__((visibility("default")))
#endif // _MSC_VER
@ -31,14 +31,14 @@ class FBJSRuntime;
namespace facebook {
namespace jsi {
class Buffer {
class JSI_EXPORT Buffer {
public:
virtual ~Buffer();
virtual size_t size() const = 0;
virtual const uint8_t* data() const = 0;
};
class StringBuffer : public Buffer {
class JSI_EXPORT StringBuffer : public Buffer {
public:
StringBuffer(std::string s) : s_(std::move(s)) {}
size_t size() const override {
@ -56,7 +56,7 @@ class StringBuffer : public Buffer {
/// form optimized for execution, in a runtime-specific way. Construct one via
/// jsi::Runtime::prepareJavaScript().
/// ** This is an experimental API that is subject to change. **
class PreparedJavaScript {
class JSI_EXPORT PreparedJavaScript {
protected:
PreparedJavaScript() = default;
@ -145,7 +145,7 @@ class JSI_EXPORT HostObject {
/// in a non-Runtime-managed object, and not clean it up before the Runtime
/// is shut down. If your lifecycle is such that avoiding this is hard,
/// you will probably need to do use your own locks.
class Runtime {
class JSI_EXPORT Runtime {
public:
virtual ~Runtime();
@ -326,7 +326,7 @@ class Runtime {
};
// Base class for pointer-storing types.
class Pointer {
class JSI_EXPORT Pointer {
protected:
explicit Pointer(Pointer&& other) : ptr_(other.ptr_) {
other.ptr_ = nullptr;
@ -349,7 +349,7 @@ class Pointer {
};
/// Represents something that can be a JS property key. Movable, not copyable.
class PropNameID : public Pointer {
class JSI_EXPORT PropNameID : public Pointer {
public:
using Pointer::Pointer;
@ -423,7 +423,7 @@ class PropNameID : public Pointer {
/// the debugger not to crash when a Symbol is a property in an Object
/// or element in an array. Complete support for creating will come
/// later.
class Symbol : public Pointer {
class JSI_EXPORT Symbol : public Pointer {
public:
using Pointer::Pointer;
@ -446,7 +446,7 @@ class Symbol : public Pointer {
};
/// Represents a JS String. Movable, not copyable.
class String : public Pointer {
class JSI_EXPORT String : public Pointer {
public:
using Pointer::Pointer;
@ -504,7 +504,7 @@ class Array;
class Function;
/// Represents a JS Object. Movable, not copyable.
class Object : public Pointer {
class JSI_EXPORT Object : public Pointer {
public:
using Pointer::Pointer;
@ -692,7 +692,7 @@ class Object : public Pointer {
/// Represents a weak reference to a JS Object. If the only reference
/// to an Object are these, the object is eligible for GC. Method
/// names are inspired by C++ weak_ptr. Movable, not copyable.
class WeakObject : public Pointer {
class JSI_EXPORT WeakObject : public Pointer {
public:
using Pointer::Pointer;
@ -714,7 +714,7 @@ class WeakObject : public Pointer {
/// Represents a JS Object which can be efficiently used as an array
/// with integral indices.
class Array : public Object {
class JSI_EXPORT Array : public Object {
public:
Array(Array&&) = default;
/// Creates a new Array instance, with \c length undefined elements.
@ -769,7 +769,7 @@ class Array : public Object {
};
/// Represents a JSArrayBuffer
class ArrayBuffer : public Object {
class JSI_EXPORT ArrayBuffer : public Object {
public:
ArrayBuffer(ArrayBuffer&&) = default;
ArrayBuffer& operator=(ArrayBuffer&&) = default;
@ -796,7 +796,7 @@ class ArrayBuffer : public Object {
};
/// Represents a JS Object which is guaranteed to be Callable.
class Function : public Object {
class JSI_EXPORT Function : public Object {
public:
Function(Function&&) = default;
Function& operator=(Function&&) = default;
@ -906,7 +906,7 @@ class Function : public Object {
/// Represents any JS Value (undefined, null, boolean, number, symbol,
/// string, or object). Movable, or explicitly copyable (has no copy
/// ctor).
class Value {
class JSI_EXPORT Value {
public:
/// Default ctor creates an \c undefined JS value.
Value() : Value(UndefinedKind) {}
@ -1178,7 +1178,7 @@ class Value {
/// Instances of this class are intended to be created as automatic stack
/// variables in which case destructor calls don't require any additional
/// locking, provided that the lock (if any) is managed with RAII helpers.
class Scope {
class JSI_EXPORT Scope {
public:
explicit Scope(Runtime& rt) : rt_(rt), prv_(rt.pushScope()) {}
~Scope() {

View File

@ -12,6 +12,18 @@
#include <string>
#include <vector>
#ifndef JSINSPECTOR_EXPORT
#ifdef _MSC_VER
#ifdef CREATE_SHARED_LIBRARY
#define JSINSPECTOR_EXPORT __declspec(dllexport)
#else
#define JSINSPECTOR_EXPORT
#endif // CREATE_SHARED_LIBRARY
#else // _MSC_VER
#define JSINSPECTOR_EXPORT __attribute__((visibility("default")))
#endif // _MSC_VER
#endif // !defined(JSINSPECTOR_EXPORT)
namespace facebook {
namespace react {
@ -27,7 +39,7 @@ struct InspectorPage {
};
/// IRemoteConnection allows the VM to send debugger messages to the client.
class IRemoteConnection : public IDestructible {
class JSINSPECTOR_EXPORT IRemoteConnection : public IDestructible {
public:
virtual ~IRemoteConnection() = 0;
virtual void onMessage(std::string message) = 0;
@ -35,7 +47,7 @@ class IRemoteConnection : public IDestructible {
};
/// ILocalConnection allows the client to send debugger messages to the VM.
class ILocalConnection : public IDestructible {
class JSINSPECTOR_EXPORT ILocalConnection : public IDestructible {
public:
virtual ~ILocalConnection() = 0;
virtual void sendMessage(std::string message) = 0;
@ -43,7 +55,7 @@ class ILocalConnection : public IDestructible {
};
/// IInspector tracks debuggable JavaScript targets (pages).
class IInspector : public IDestructible {
class JSINSPECTOR_EXPORT IInspector : public IDestructible {
public:
using ConnectFunc = std::function<std::unique_ptr<ILocalConnection>(
std::unique_ptr<IRemoteConnection>)>;