diff --git a/README.md b/README.md
index b008af414..3e668cd8c 100644
--- a/README.md
+++ b/README.md
@@ -82,4 +82,3 @@ speed up the debugging process.
request, or [write a plugin](plugins/README.md#writing-your-own-plugins)!
* The Linux and Windows implementations currently use GLFW. This is not going
to be the final implementation for either platform.
-* Plugins and text input do not yet work on Windows.
diff --git a/example/windows/GLFW Example.vcxproj b/example/windows/GLFW Example.vcxproj
index 1da8b14ed..e15a6eda7 100644
--- a/example/windows/GLFW Example.vcxproj
+++ b/example/windows/GLFW Example.vcxproj
@@ -72,7 +72,7 @@
$(SolutionDir)bin\$(Platform)\$(Configuration)\$(ProjectName)\
$(SolutionDir)bin\intermediates\$(Platform)\$(Configuration)\$(ProjectName)\
- $(ProjectDir)..\..\library\windows\dependencies\GLFW\;$(ProjectDir)..\..\library\windows\;$(IncludePath)
+ $(ProjectDir)..\..\library\windows\dependencies\;$(ProjectDir)..\..\;$(IncludePath);$(ProjectDir)..\..\library\windows\
$(ProjectDir)..\..\library\windows\dependencies\GLFW\;$(SolutionDir)bin\$(Platform)\$(Configuration)\GLFW Library\;$(LibraryPath)
@@ -84,7 +84,7 @@
$(SolutionDir)bin\$(Platform)\$(Configuration)\$(ProjectName)\
$(SolutionDir)bin\intermediates\$(Platform)\$(Configuration)\$(ProjectName)\
- $(ProjectDir)..\..\library\windows\dependencies\GLFW\;$(ProjectDir)..\..\library\windows\;$(IncludePath)
+ $(ProjectDir)..\..\library\windows\dependencies\;$(ProjectDir)..\..\;$(IncludePath);$(ProjectDir)..\..\library\windows\
$(ProjectDir)..\..\library\windows\dependencies\GLFW\;$(SolutionDir)bin\$(Platform)\$(Configuration)\GLFW Library\;$(LibraryPath)
@@ -227,4 +227,4 @@
$(SolutionDir)
-
+
\ No newline at end of file
diff --git a/example/windows/flutter_embedder_example.cpp b/example/windows/flutter_embedder_example.cpp
index d8485e70f..165bbd55e 100644
--- a/example/windows/flutter_embedder_example.cpp
+++ b/example/windows/flutter_embedder_example.cpp
@@ -15,10 +15,10 @@
#include
#include
-#include
+#include "embedder.h"
int main(int argc, char **argv) {
- if (!FlutterInit()) {
+ if (!flutter_desktop_embedding::FlutterInit()) {
std::cout << "Couldn't init GLFW" << std::endl;
}
// Arguments for the Flutter Engine.
@@ -31,15 +31,15 @@ int main(int argc, char **argv) {
#endif
// Start the engine.
// TODO: Make paths relative to the executable so it can be run from anywhere.
- auto window = CreateFlutterWindowInSnapshotMode(
+ auto window = flutter_desktop_embedding::CreateFlutterWindowInSnapshotMode(
640, 480, "..\\..\\example\\flutter_app\\build\\flutter_assets",
"..\\..\\library\\windows\\dependencies\\engine\\icudtl.dat", arguments);
if (window == nullptr) {
- FlutterTerminate();
+ flutter_desktop_embedding::FlutterTerminate();
return EXIT_FAILURE;
}
- FlutterWindowLoop(window);
- FlutterTerminate();
+ flutter_desktop_embedding::FlutterWindowLoop(window);
+ flutter_desktop_embedding::FlutterTerminate();
return EXIT_SUCCESS;
}
diff --git a/library/windows/.gitignore b/library/windows/.gitignore
index f431ddc7c..099c5cb6a 100644
--- a/library/windows/.gitignore
+++ b/library/windows/.gitignore
@@ -1,3 +1,6 @@
+# Ignore third party code fetched as part of build process of the Flutter embedding library
+third_party
+
## Ignore Visual Studio temporary files, build results, and
## files generated by popular Visual Studio add-ons.
##
@@ -327,3 +330,4 @@ ASALocalRun/
# MFractors (Xamarin productivity tool) working folder
.mfractor/
+
diff --git a/library/windows/GLFW Library.vcxproj b/library/windows/GLFW Library.vcxproj
index 2df1af2eb..634ea94d9 100644
--- a/library/windows/GLFW Library.vcxproj
+++ b/library/windows/GLFW Library.vcxproj
@@ -75,8 +75,9 @@
$(SolutionDir)bin\intermediates\$(Platform)\$(Configuration)\$(ProjectName)\
flutter_embedder
.dll
- $(ProjectDir)dependencies\engine\;$(ProjectDir)dependencies\GLFW\;$(IncludePath)
- $(ProjectDir)dependencies\engine\;$(ProjectDir)dependencies\GLFW\;$(LibraryPath)
+ $(ProjectDir)dependencies\engine\;$(ProjectDir)dependencies;$(ProjectDir)third_party\jsoncpp\include;$(ProjectDir)..\..\;$(IncludePath)
+ $(ProjectDir)dependencies\engine\;$(ProjectDir)dependencies\json\x64\debug;$(ProjectDir)dependencies\GLFW\;$(LibraryPath)
+ $(ProjectDir)..\..\library\common\internal;$(SourcePath)
$(SolutionDir)bin\$(Platform)\$(Configuration)\$(ProjectName)\
@@ -91,8 +92,9 @@
$(SolutionDir)bin\intermediates\$(Platform)\$(Configuration)\$(ProjectName)\
flutter_embedder
.dll
- $(ProjectDir)dependencies\engine\;$(ProjectDir)dependencies\GLFW\;$(IncludePath)
- $(ProjectDir)dependencies\engine\;$(ProjectDir)dependencies\GLFW\;$(LibraryPath)
+ $(ProjectDir)dependencies\engine\;$(ProjectDir)dependencies;$(ProjectDir)third_party\jsoncpp\include;$(ProjectDir)..\..\;$(IncludePath)
+ $(ProjectDir)dependencies\engine\;$(ProjectDir)dependencies\json\x64\release;;$(ProjectDir)dependencies\GLFW\;$(LibraryPath)
+ $(ProjectDir)..\..\library\common\internal;$(SourcePath)
$(SolutionDir)bin\$(Platform)\$(Configuration)\$(ProjectName)\
@@ -108,9 +110,10 @@
Disabled
true
true
+ MultiThreadedDebugDLL
- flutter_engine.dll.lib;glfw3.lib;opengl32.lib;%(AdditionalDependencies)
+ flutter_engine.dll.lib;glfw3.lib;opengl32.lib;%(AdditionalDependencies);json_vc71_libmtd.lib
exports.def
@@ -123,7 +126,7 @@
- $(ProjectDir)scripts\update_flutter_engine && $(ProjectDir)scripts\get_engine_artifacts && $(ProjectDir)scripts\get_GLFW
+ $(ProjectDir)scripts\update_flutter_engine && $(ProjectDir)scripts\get_engine_artifacts && $(ProjectDir)scripts\get_GLFW && $(ProjectDir)scripts\build_jsonlib
Get the flutter engine, engine artifacts and GLFW
@@ -186,11 +189,12 @@
true
true
true
+ MultiThreadedDLL
true
true
- flutter_engine.dll.lib;glfw3.lib;opengl32.lib;%(AdditionalDependencies)
+ flutter_engine.dll.lib;glfw3.lib;opengl32.lib;%(AdditionalDependencies);json_vc71_libmt.lib
exports.def
$(OutDir)$(TargetName)$(TargetExt)
$(OutDir)$(TargetName).lib
@@ -201,7 +205,7 @@
- $(ProjectDir)scripts\update_flutter_engine && $(ProjectDir)scripts\get_engine_artifacts && $(ProjectDir)scripts\get_GLFW
+ $(ProjectDir)scripts\update_flutter_engine && $(ProjectDir)scripts\get_engine_artifacts && $(ProjectDir)scripts\get_GLFW && $(ProjectDir)scripts\build_jsonlib
Get the flutter engine, engine artifacts and GLFW
@@ -259,6 +263,19 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
@@ -270,4 +287,4 @@
-
+
\ No newline at end of file
diff --git a/library/windows/GLFW Library.vcxproj.filters b/library/windows/GLFW Library.vcxproj.filters
index 58963352d..02a3922cf 100644
--- a/library/windows/GLFW Library.vcxproj.filters
+++ b/library/windows/GLFW Library.vcxproj.filters
@@ -1,32 +1,35 @@
-
-
-
-
- {4FC737F1-C7A5-4376-A066-2A32D752A2FF}
- cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx
-
-
- {93995380-89BD-4b04-88EB-625FBE52EBFB}
- h;hh;hpp;hxx;hm;inl;inc;ipp;xsd
-
-
- {67DA6AB6-F800-4c08-8B7A-83BB121AAD01}
- rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx;tiff;tif;png;wav;mfcribbon-ms
-
-
-
-
- Source Files
-
-
-
-
- Header Files
-
-
-
-
- Source Files
-
-
-
\ No newline at end of file
+
+
+
+
+ {4FC737F1-C7A5-4376-A066-2A32D752A2FF}
+ cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx
+
+
+ {93995380-89BD-4b04-88EB-625FBE52EBFB}
+ h;hh;hpp;hxx;hm;inl;inc;ipp;xsd
+
+
+ {67DA6AB6-F800-4c08-8B7A-83BB121AAD01}
+ rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx;tiff;tif;png;wav;mfcribbon-ms
+
+
+
+
+ Source Files
+
+
+ Source Files
+
+
+
+
+ Header Files
+
+
+
+
+ Source Files
+
+
+
diff --git a/library/windows/dependencies/.gitignore b/library/windows/dependencies/.gitignore
index 443ccd53a..7f1435b47 100644
--- a/library/windows/dependencies/.gitignore
+++ b/library/windows/dependencies/.gitignore
@@ -3,3 +3,4 @@ flutter_engine.*
.last_engine_version
icudtl.dat
glfw3.*
+json
diff --git a/library/windows/dependencies/json/.gitkeep b/library/windows/dependencies/json/.gitkeep
new file mode 100644
index 000000000..e69de29bb
diff --git a/library/windows/embedder.cpp b/library/windows/embedder.cpp
index a601c9c73..e76f35f9a 100644
--- a/library/windows/embedder.cpp
+++ b/library/windows/embedder.cpp
@@ -21,14 +21,33 @@
#include
+#include "library/common/glfw/keyboard_hook_handler.h"
+#include "library/common/glfw/text_input_plugin.h"
+#include "library/common/internal/plugin_handler.h"
+
static_assert(FLUTTER_ENGINE_VERSION == 1, "");
-static constexpr char kDefaultWindowTitle[] = "Flutter";
+// Struct for storing state within an instance of the GLFW Window.
+struct FlutterEmbedderState {
+ FlutterEngine engine;
+ std::unique_ptr plugin_handler;
-bool FlutterInit() { return glfwInit(); }
+ // plugin_handler owns these pointers. Destruction happens when this struct is
+ // deleted from the heap.
+ std::vector
+ keyboard_hook_handlers;
+};
-void FlutterTerminate() { glfwTerminate(); }
+static constexpr char kDefaultWindowTitle[] = "Flutter";
+
+// Retreaves state bag for the window in question from the GLFWWindow
+static FlutterEmbedderState *GetSavedEmbedderState(GLFWwindow *window) {
+ return reinterpret_cast(
+ glfwGetWindowUserPointer(window));
+}
+// When GLFW calls back to the window with a cursor position move, forward to
+// FlutterEngine as a pointer event with appropriate phase
static void GLFWcursorPositionCallbackAtPhase(GLFWwindow *window,
FlutterPointerPhase phase,
double x, double y) {
@@ -41,11 +60,11 @@ static void GLFWcursorPositionCallbackAtPhase(GLFWwindow *window,
std::chrono::duration_cast(
std::chrono::high_resolution_clock::now().time_since_epoch())
.count();
- FlutterEngineSendPointerEvent(
- reinterpret_cast(glfwGetWindowUserPointer(window)), &event,
- 1);
+ FlutterEngineSendPointerEvent(GetSavedEmbedderState(window)->engine, &event,
+ 1);
}
+// Report cursor move to engine
static void GLFWcursorPositionCallback(GLFWwindow *window, double x, double y) {
GLFWcursorPositionCallbackAtPhase(window, FlutterPointerPhase::kMove, x, y);
}
@@ -65,8 +84,19 @@ static void GLFWmouseButtonCallback(GLFWwindow *window, int key, int action,
}
}
+static void GLFWCharCallback(GLFWwindow *window, unsigned int code_point) {
+ for (flutter_desktop_embedding::KeyboardHookHandler *handler :
+ GetSavedEmbedderState(window)->keyboard_hook_handlers) {
+ handler->CharHook(window, code_point);
+ }
+}
+
static void GLFWKeyCallback(GLFWwindow *window, int key, int scancode,
int action, int mods) {
+ for (flutter_desktop_embedding::KeyboardHookHandler *handler :
+ GetSavedEmbedderState(window)->keyboard_hook_handlers) {
+ handler->KeyboardHook(window, key, scancode, action, mods);
+ }
if (key == GLFW_KEY_ESCAPE && action == GLFW_PRESS) {
glfwSetWindowShouldClose(window, GLFW_TRUE);
}
@@ -79,9 +109,41 @@ static void GLFWwindowSizeCallback(GLFWwindow *window, int width, int height) {
event.height = height;
// TODO: Handle pixel ratio for different DPI monitors.
event.pixel_ratio = 1.0;
- FlutterEngineSendWindowMetricsEvent(
- reinterpret_cast(glfwGetWindowUserPointer(window)),
- &event);
+ FlutterEngineSendWindowMetricsEvent(GetSavedEmbedderState(window)->engine,
+ &event);
+}
+
+// Flushes event queue and then assigns default window callbacks.
+static void GLFWAssignEventCallbacks(GLFWwindow *window) {
+ glfwPollEvents();
+ glfwSetKeyCallback(window, GLFWKeyCallback);
+ glfwSetCharCallback(window, GLFWCharCallback);
+ glfwSetMouseButtonCallback(window, GLFWmouseButtonCallback);
+}
+
+// Clears default window events.
+static void GLFWClearEventCallbacks(GLFWwindow *window) {
+ glfwSetKeyCallback(window, nullptr);
+ glfwSetCharCallback(window, nullptr);
+ glfwSetMouseButtonCallback(window, nullptr);
+}
+
+// The Flutter Engine calls out to this function when new platform messages are
+// available
+static void GLFWOnFlutterPlatformMessage(const FlutterPlatformMessage *message,
+ void *user_data) {
+ if (message->struct_size != sizeof(FlutterPlatformMessage)) {
+ std::cerr << "Invalid message size received. Expected: "
+ << sizeof(FlutterPlatformMessage) << " but received "
+ << message->struct_size << std::endl;
+ return;
+ }
+
+ GLFWwindow *window = reinterpret_cast(user_data);
+ auto state = GetSavedEmbedderState(window);
+ state->plugin_handler->HandleMethodCallMessage(
+ message, [window] { GLFWClearEventCallbacks(window); },
+ [window] { GLFWAssignEventCallbacks(window); });
}
static bool GLFWMakeContextCurrent(void *user_data) {
@@ -152,6 +214,7 @@ static FlutterEngine RunFlutterEngine(
args.icu_data_path = icu_data_path.c_str();
args.command_line_argc = argv.size();
args.command_line_argv = &argv[0];
+ args.platform_message_callback = GLFWOnFlutterPlatformMessage;
FlutterEngine engine = nullptr;
auto result =
FlutterEngineRun(FLUTTER_ENGINE_VERSION, &config, &args, window, &engine);
@@ -161,6 +224,28 @@ static FlutterEngine RunFlutterEngine(
return engine;
}
+namespace flutter_desktop_embedding {
+
+// Initialize glfw
+bool FlutterInit() { return glfwInit(); }
+
+// Tear down glfw
+void FlutterTerminate() { glfwTerminate(); }
+
+// set up embedder state and add the plugin to the plugin_handler
+bool AddPlugin(GLFWwindow *flutter_window, std::unique_ptr plugin) {
+ auto state = GetSavedEmbedderState(flutter_window);
+ return state->plugin_handler->AddPlugin(std::move(plugin));
+}
+
+GLFWwindow *CreateFlutterWindowInSnapshotMode(
+ size_t initial_width, size_t initial_height, const std::string &assets_path,
+ const std::string &icu_data_path,
+ const std::vector &arguments) {
+ return CreateFlutterWindow(initial_width, initial_height, "", assets_path, "",
+ icu_data_path, arguments);
+}
+
GLFWwindow *CreateFlutterWindow(size_t initial_width, size_t initial_height,
const std::string &main_path,
const std::string &assets_path,
@@ -173,35 +258,43 @@ GLFWwindow *CreateFlutterWindow(size_t initial_width, size_t initial_height,
return nullptr;
}
GLFWClearCanvas(window);
- auto flutter_engine_run_result = RunFlutterEngine(
- window, main_path, assets_path, packages_path, icu_data_path, arguments);
- if (flutter_engine_run_result == nullptr) {
+ auto engine = RunFlutterEngine(window, main_path, assets_path, packages_path,
+ icu_data_path, arguments);
+ if (engine == nullptr) {
glfwDestroyWindow(window);
return nullptr;
}
- glfwSetWindowUserPointer(window, flutter_engine_run_result);
+
+ FlutterEmbedderState *state = new FlutterEmbedderState();
+ state->plugin_handler = std::make_unique(engine);
+ state->engine = engine;
+ auto input_plugin = std::make_unique();
+ state->keyboard_hook_handlers.push_back(input_plugin.get());
+
+ glfwSetWindowUserPointer(window, state);
+
+ AddPlugin(window, std::move(input_plugin));
+
int width, height;
glfwGetWindowSize(window, &width, &height);
GLFWwindowSizeCallback(window, width, height);
glfwSetKeyCallback(window, GLFWKeyCallback);
glfwSetWindowSizeCallback(window, GLFWwindowSizeCallback);
glfwSetMouseButtonCallback(window, GLFWmouseButtonCallback);
+ GLFWAssignEventCallbacks(window);
return window;
}
-GLFWwindow *CreateFlutterWindowInSnapshotMode(
- size_t initial_width, size_t initial_height, const std::string &assets_path,
- const std::string &icu_data_path,
- const std::vector &arguments) {
- return CreateFlutterWindow(initial_width, initial_height, "", assets_path, "",
- icu_data_path, arguments);
-}
-
void FlutterWindowLoop(GLFWwindow *flutter_window) {
while (!glfwWindowShouldClose(flutter_window)) {
glfwWaitEvents();
+ // TODO(awdavies): This will be deprecated soon.
+ __FlutterEngineFlushPendingTasksNow();
}
- FlutterEngineShutdown(reinterpret_cast(
- glfwGetWindowUserPointer(flutter_window)));
+ auto state = GetSavedEmbedderState(flutter_window);
+ FlutterEngineShutdown(state->engine);
+ delete state;
glfwDestroyWindow(flutter_window);
}
+
+} // namespace flutter_desktop_embedding
diff --git a/library/windows/embedder.h b/library/windows/embedder.h
index 5d52c1c18..028d418fb 100644
--- a/library/windows/embedder.h
+++ b/library/windows/embedder.h
@@ -18,7 +18,11 @@
#include
#include
-#include
+#include
+
+#include "library/include/flutter_desktop_embedding/plugin.h"
+
+namespace flutter_desktop_embedding {
// Calls glfwInit()
//
@@ -65,6 +69,12 @@ GLFWwindow *CreateFlutterWindowInSnapshotMode(
const std::string &icu_data_path,
const std::vector &arguments);
+// Adds a plugin to the flutter_window.
+//
+// If a plugin already exists for this plugin's channel, returns false.
+// Otherwise returns true.
+bool AddPlugin(GLFWwindow *flutter_window, std::unique_ptr plugin);
+
// Loops on flutter window events until termination.
//
// Must be used instead of glfwWindowShouldClose as it cleans up engine state
@@ -74,4 +84,6 @@ GLFWwindow *CreateFlutterWindowInSnapshotMode(
// cleanup.
void FlutterWindowLoop(GLFWwindow *flutter_window);
+} // namespace flutter_desktop_embedding
+
#endif // WINDOWS_LIBRARY_EMBEDDER_H_
diff --git a/library/windows/scripts/build_jsonlib.bat b/library/windows/scripts/build_jsonlib.bat
new file mode 100644
index 000000000..17f663456
--- /dev/null
+++ b/library/windows/scripts/build_jsonlib.bat
@@ -0,0 +1,105 @@
+:: Copyright 2018 Google LLC
+::
+:: Licensed under the Apache License, Version 2.0 (the "License");
+:: you may not use this file except in compliance with the License.
+:: You may obtain a copy of the License at
+::
+:: http://www.apache.org/licenses/LICENSE-2.0
+::
+:: Unless required by applicable law or agreed to in writing, software
+:: distributed under the License is distributed on an "AS IS" BASIS,
+:: WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+:: See the License for the specific language governing permissions and
+:: limitations under the License.
+@echo off
+
+:: Find where VS lives and start a VC command prompt
+set pre=Microsoft.VisualStudio.Product.
+set ids=%pre%Community %pre%Professional %pre%Enterprise %pre%BuildTools
+
+pushd "C:\Program Files (x86)\Microsoft Visual Studio\Installer\"
+for /f "usebackq tokens=1* delims=: " %%i in (`vswhere -latest -products *`) do (if /i "%%i"=="installationPath" set InstallDir=%%j)
+popd
+
+pushd %InstallDir%\VC\Auxiliary\Build
+call vcvarsall.bat x86_amd64
+popd
+
+set JSONDEBUGLIBEXISTS=true
+if not exist %~dp0..\dependencies\json\x64\debug\json_vc71_libmtd.lib set JSONDEBUGLIBEXISTS=false
+
+set JSONRELEASELIBEXISTS=true
+if not exist %~dp0..\dependencies\json\x64\release\json_vc71_libmt.lib set JSONRELEASELIBEXISTS=false
+
+if %JSONDEBUGLIBEXISTS% == true (
+ if %JSONRELEASELIBEXISTS% == true (
+ echo jsoncpp found.
+ goto DONE
+ )
+)
+
+set THIRDPARTYDIREXISTS=true
+if not exist %~dp0..\third_party set THIRDPARTYDIREXISTS=false
+
+if %THIRDPARTYDIREXISTS% == false (
+ mkdir %~dp0..\third_party
+)
+
+set JSONDIREXISTS=true
+if not exist %~dp0..\third_party\jsoncpp set JSONDIREXISTS=false
+
+if %JSONDIREXISTS% == false (
+ mkdir %~dp0..\third_party\jsoncpp
+)
+
+set JSONEXISTS=true
+if not exist %~dp0..\third_party\jsoncpp\README.md set JSONEXISTS=false
+
+:: Clone source
+if %JSONEXISTS% == false (
+ :: PR opened on json cpp for VS2017 support: https://github.com/open-source-parsers/jsoncpp/pull/853
+ echo Cloning via git clone --branch supportvs2017 https://github.com/clarkezone/jsoncpp.git %~dp0..\third_party\jsoncpp
+ call git clone --branch supportvs2017 https://github.com/clarkezone/jsoncpp.git %~dp0..\third_party\jsoncpp
+
+ pushd %~dp0..\third_party\jsoncpp
+
+ call git checkout 3ae7e8073a425c93329c8577a3c813c206322ca4
+
+ popd
+)
+
+:: Build debug lib
+echo Building debug lib: msbuild %~dp0..\third_party\jsoncpp\makefiles\msvc2017\lib_json.vcxproj
+msbuild %~dp0..\third_party\jsoncpp\makefiles\msvc2017\lib_json.vcxproj
+
+set DEPBINDIREXISTS=true
+if not exist %~dp0..\dependencies\json\x64 set DEPBINDIREXISTS=false
+
+if %DEPBINDIREXISTS% == false (
+ mkdir %~dp0..\dependencies\json\x64
+)
+
+set DEPBINDBGDIREXISTS=true
+if not exist %~dp0..\dependencies\json\x64\debug set DEPBINDBGDIREXISTS=false
+
+if %DEPBINDBGDIREXISTS% == false (
+ mkdir %~dp0..\dependencies\json\x64\debug
+)
+
+copy %~dp0..\third_party\jsoncpp\makefiles\msvc2017\x64\debug\json_vc71_libmtd.lib %~dp0..\dependencies\json\x64\debug\.
+
+:: Build release lib
+echo Building release lib: msbuild %~dp0..\third_party\jsoncpp\makefiles\msvc2017\lib_json.vcxproj /p:Configuration=Release
+msbuild %~dp0..\third_party\jsoncpp\makefiles\msvc2017\lib_json.vcxproj /p:Configuration=Release
+
+set DEPBINRELDIREXISTS=true
+if not exist %~dp0..\dependencies\json\x64\release set DEPBINRELDIREXISTS=false
+
+if %DEPBINRELDIREXISTS% == false (
+ mkdir %~dp0..\dependencies\json\x64\release
+)
+
+copy %~dp0..\third_party\jsoncpp\makefiles\msvc2017\x64\release\json_vc71_libmt.lib %~dp0..\dependencies\json\x64\release\.
+
+:DONE
+echo jsoncpplib complete.
\ No newline at end of file