未验证 提交 74a2d905 编写于 作者: B Ben Konyi 提交者: GitHub

Changes to assets/ build/ flow/ runtime/ and shell/ to allow for compilation on Windows (#4407)

Made changes to assets/ build/ flow/ runtime/ and shell/ to allow for
compilation on Windows.
上级 da43e7c6
......@@ -3,9 +3,13 @@
// found in the LICENSE file.
#include "flutter/assets/directory_asset_bundle.h"
#include "lib/fxl/build_config.h"
#include <fcntl.h>
#if !defined(OS_WIN)
#include <unistd.h>
#endif
#include <utility>
......
......@@ -3,9 +3,13 @@
// found in the LICENSE file.
#include "flutter/assets/zip_asset_store.h"
#include "lib/fxl/build_config.h"
#include <fcntl.h>
#if !defined(OS_WIN)
#include <unistd.h>
#endif
#include <string>
#include <utility>
......
......@@ -119,6 +119,8 @@ def list_files(from_root, filter_func=None):
def remove_broken_symlink(path):
if not USE_LINKS:
return
try:
link_path = os.readlink(path)
except OSError as e:
......@@ -131,6 +133,8 @@ def remove_broken_symlink(path):
def remove_broken_symlinks(root_dir):
if not USE_LINKS:
return
for current_dir, _, child_files in os.walk(root_dir):
for filename in child_files:
path = os.path.join(current_dir, filename)
......@@ -268,7 +272,7 @@ def main():
# Symlink packages/
package_path = os.path.join(args.package_root, args.package_name)
link(lib_path, package_path)
copy_or_link(lib_path, package_path)
# Link dart-pkg/$package/packages to dart-pkg/packages
link_if_possible(args.package_root, target_packages_dir)
......
......@@ -2,6 +2,13 @@
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#include "lib/fxl/build_config.h"
#if defined(OS_WIN)
#define _USE_MATH_DEFINES
#endif
#include <cmath>
#include "flutter/flow/matrix_decomposition.h"
#include "third_party/gtest/include/gtest/gtest.h"
......
......@@ -3,6 +3,12 @@
// found in the LICENSE file.
#include "flutter/runtime/dart_controller.h"
#include "lib/fxl/build_config.h"
#if defined(OS_WIN)
#include <windows.h>
#undef GetCurrentDirectory
#endif
#include <utility>
......@@ -33,6 +39,37 @@ using tonic::ToDart;
namespace blink {
namespace {
#if defined(OS_WIN)
std::string FindAndReplace(const std::string& str,
const std::string& findStr,
const std::string& replaceStr) {
std::string rStr = str;
size_t pos = 0;
while ((pos = rStr.find(findStr, pos)) != std::string::npos) {
rStr.replace(pos, findStr.length(), replaceStr);
pos += replaceStr.length();
}
return rStr;
}
std::string SanitizePath(const std::string& path) {
return FindAndReplace(path, "\\\\", "/");
}
std::string ResolvePath(std::string path) {
std::string sanitized = SanitizePath(path);
if ((sanitized.length() > 2) && (sanitized[1] == ':')) {
return sanitized;
}
return files::SimplifyPath(files::GetCurrentDirectory() + "/" + sanitized);
}
#else // defined(OS_WIN)
std::string SanitizePath(const std::string& path) {
return path;
}
// TODO(abarth): Consider adding this to //garnet/public/lib/fxl.
std::string ResolvePath(std::string path) {
......@@ -41,6 +78,8 @@ std::string ResolvePath(std::string path) {
return files::SimplifyPath(files::GetCurrentDirectory() + "/" + path);
}
#endif
} // namespace
DartController::DartController() : ui_dart_state_(nullptr) {}
......@@ -169,7 +208,7 @@ tonic::DartErrorHandleType DartController::RunFromSource(
tonic::FileLoader& loader = dart_state()->file_loader();
if (!packages.empty() && !loader.LoadPackagesMap(ResolvePath(packages)))
FXL_LOG(WARNING) << "Failed to load package map: " << packages;
Dart_Handle result = loader.LoadScript(main);
Dart_Handle result = loader.LoadScript(SanitizePath(main));
LogIfError(result);
error = tonic::GetErrorHandleType(result);
}
......
......@@ -3,11 +3,18 @@
// found in the LICENSE file.
#include "flutter/runtime/dart_init.h"
#include "flutter/sky/engine/wtf/OperatingSystem.h"
#include <string.h>
#include <sys/stat.h>
#include <sys/types.h>
#if defined(OS_WIN)
#include <windows.h>
#undef ERROR
#else
#include <unistd.h>
#endif
#include <memory>
#include <string>
......
......@@ -4,11 +4,28 @@
#include "flutter/shell/common/engine.h"
#if OS(WIN)
#include <io.h>
#include <windows.h>
#define access _access
#define R_OK 0x4
#ifndef S_ISDIR
#define S_ISDIR(mode) (((mode)&S_IFMT) == S_IFDIR)
#endif
#ifndef S_ISREG
#define S_ISREG(mode) (((mode)&S_IFMT) == S_IFREG)
#endif
#else
#include <dlfcn.h>
#include <fcntl.h>
#include <sys/mman.h>
#include <sys/stat.h>
#include <unistd.h>
#endif // OS(WIN)
#include <fcntl.h>
#include <sys/stat.h>
#include <memory>
#include <utility>
......@@ -46,6 +63,30 @@ constexpr char kNavigationChannel[] = "flutter/navigation";
constexpr char kLocalizationChannel[] = "flutter/localization";
constexpr char kSettingsChannel[] = "flutter/settings";
void FindAndReplaceInPlace(std::string& str,
const std::string& findStr,
const std::string& replaceStr) {
size_t pos = 0;
while ((pos = str.find(findStr, pos)) != std::string::npos) {
str.replace(pos, findStr.length(), replaceStr);
pos += replaceStr.length();
}
}
std::string SanitizePath(const std::string& path) {
#if OS(WIN)
std::string sanitized = path;
FindAndReplaceInPlace(sanitized, "\\\\", "/");
if ((sanitized.length() > 2) && (sanitized[1] == ':')) {
// Path begins with a drive letter.
sanitized = '/' + sanitized;
}
return sanitized;
#else
return path;
#endif
}
bool PathExists(const std::string& path) {
return access(path.c_str(), R_OK) == 0;
}
......@@ -63,7 +104,7 @@ std::string FindPackagesPath(const std::string& main_dart) {
}
std::string GetScriptUriFromPath(const std::string& path) {
return "file://" + path;
return "file://" + SanitizePath(path);
}
} // namespace
......@@ -93,6 +134,7 @@ fml::WeakPtr<Engine> Engine::GetWeakPtr() {
#if !FLUTTER_AOT
#elif OS(IOS)
#elif OS(ANDROID)
// TODO(bkonyi): do we even get here for Windows?
static const uint8_t* MemMapSnapshot(const std::string& aot_snapshot_path,
const std::string& default_file_name,
const std::string& settings_file_name,
......@@ -104,6 +146,49 @@ static const uint8_t* MemMapSnapshot(const std::string& aot_snapshot_path,
asset_path = aot_snapshot_path + "/" + settings_file_name;
}
#if OS(WIN)
HANDLE file_handle_ =
CreateFileA(reinterpret_cast<LPCSTR>(path.c_str()), GENERIC_READ,
FILE_SHARE_READ, nullptr, OPEN_EXISTING,
FILE_ATTRIBUTE_NORMAL | FILE_FLAG_RANDOM_ACCESS, nullptr);
if (file_handle_ == INVALID_HANDLE_VALUE) {
return;
}
size_ = GetFileSize(file_handle_, nullptr);
if (size_ == INVALID_FILE_SIZE) {
size_ = 0;
return;
}
int mapping_flags = executable ? PAGE_EXECUTE_READ : PAGE_READONLY;
mapping_handle_ = CreateFileMapping(file_handle_, nullptr, mapping_flags, 0,
size_, nullptr);
CloseHandle(file_handle_);
if (mapping_handle_ == INVALID_HANDLE_VALUE) {
return;
}
int access_flags = FILE_MAP_READ;
if (executable) {
access_flags |= FILE_MAP_EXECUTE;
}
auto mapping = MapViewOfFile(mapping_handle_, access_flags, 0, 0, size_);
if (mapping == INVALID_HANDLE_VALUE) {
CloseHandle(mapping_handle_);
mapping_handle_ = INVALID_HANDLE_VALUE;
return;
}
void* symbol = static_cast<void*>(mapping);
if (symbol == NULL) {
return nullptr;
}
#else
struct stat info;
if (stat(asset_path.c_str(), &info) < 0) {
return nullptr;
......@@ -123,6 +208,7 @@ static const uint8_t* MemMapSnapshot(const std::string& aot_snapshot_path,
if (symbol == MAP_FAILED) {
return nullptr;
}
#endif
return reinterpret_cast<const uint8_t*>(symbol);
}
#endif
......@@ -161,7 +247,7 @@ void Engine::Init(const std::string& bundle_path) {
dlsym(library_handle, "kDartIsolateSnapshotData"));
default_isolate_snapshot_instr = reinterpret_cast<const uint8_t*>(
dlsym(library_handle, "kDartIsolateSnapshotInstructions"));
#elif OS(ANDROID)
#elif OS(ANDROID) || OS(WIN)
const blink::Settings& settings = blink::Settings::Get();
const std::string& aot_shared_library_path = settings.aot_shared_library_path;
const std::string& aot_snapshot_path = settings.aot_snapshot_path;
......
......@@ -2,6 +2,7 @@
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#include <algorithm>
#include <iomanip>
#include <iostream>
#include <sstream>
......@@ -27,7 +28,7 @@ struct SwitchDesc {
// clang-format off
#define DEF_SWITCHES_START static const struct SwitchDesc gSwitchDescs[] = {
#define DEF_SWITCH(p_swtch, p_flag, p_help) \
{ .sw = shell::Switch:: p_swtch, .flag = p_flag, .help = p_help },
{ shell::Switch:: p_swtch, p_flag, p_help },
#define DEF_SWITCHES_END };
// clang-format on
......
......@@ -17,7 +17,9 @@ group("platform") {
"embedder",
]
} else if (is_win) {
print("Shell currently not supported on Windows.")
deps = [
"win"
]
} else {
assert(false, "Unknown/Unsupported platform.")
}
......
# Copyright 2016 The Chromium Authors. All rights reserved.
# Use of this source code is governed by a BSD-style license that can be
# found in the LICENSE file.
executable("win") {
output_name = "flutter_tester"
sources = [
"main_win.cc",
]
deps = [
"//flutter/common",
"//flutter/flow",
"//flutter/fml",
"//flutter/shell/common",
"//flutter/shell/testing",
"//flutter/sky/engine/wtf",
"//garnet/public/lib/fxl",
"//third_party/dart/runtime/bin:embedded_dart_io",
"//third_party/dart/runtime:libdart_jit",
"//third_party/skia",
"//topaz/lib/tonic",
]
libs = [
"iphlpapi.lib",
"Rpcrt4.lib"
]
}
// Copyright 2015 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#include <windows.h>
#include "flutter/common/threads.h"
#include "flutter/fml/message_loop.h"
#include "flutter/shell/common/platform_view.h"
#include "flutter/shell/common/shell.h"
#include "flutter/shell/common/switches.h"
#include "flutter/shell/testing/test_runner.h"
#include "flutter/shell/testing/testing.h"
#include "lib/fxl/command_line.h"
#include "lib/tonic/dart_microtask_queue.h"
#include "third_party/dart/runtime/bin/embedded_dart_io.h"
namespace {
// Exit codes used by the Dart command line tool.
const int kApiErrorExitCode = 253;
const int kCompilationErrorExitCode = 254;
const int kErrorExitCode = 255;
// Checks whether the engine's main Dart isolate has no pending work. If so,
// then exit the given message loop.
class ScriptCompletionTaskObserver : public fml::TaskObserver {
public:
ScriptCompletionTaskObserver(fxl::RefPtr<fxl::TaskRunner> task_runner)
: main_task_runner_(std::move(task_runner)),
prev_live_(false),
last_error_(tonic::kNoError) {}
void DidProcessTask() override {
shell::TestRunner& test_runner = shell::TestRunner::Shared();
shell::Engine& engine = test_runner.platform_view().engine();
if (engine.GetLoadScriptError() != tonic::kNoError) {
last_error_ = engine.GetLoadScriptError();
main_task_runner_->PostTask(
[]() { fml::MessageLoop::GetCurrent().Terminate(); });
return;
}
bool live = engine.UIIsolateHasLivePorts();
if (prev_live_ && !live) {
last_error_ = engine.GetUIIsolateLastError();
main_task_runner_->PostTask(
[]() { fml::MessageLoop::GetCurrent().Terminate(); });
}
prev_live_ = live;
}
tonic::DartErrorHandleType last_error() { return last_error_; }
private:
fxl::RefPtr<fxl::TaskRunner> main_task_runner_;
bool prev_live_;
tonic::DartErrorHandleType last_error_;
};
int ConvertErrorTypeToExitCode(tonic::DartErrorHandleType error) {
switch (error) {
case tonic::kCompilationErrorType:
return kCompilationErrorExitCode;
case tonic::kApiErrorType:
return kApiErrorExitCode;
case tonic::kUnknownErrorType:
return kErrorExitCode;
default:
return 0;
}
}
void RunNonInteractive(fxl::CommandLine initial_command_line,
bool run_forever) {
// This is a platform thread (i.e not one created by fml::Thread), so perform
// one time initialization.
fml::MessageLoop::EnsureInitializedForCurrentThread();
shell::Shell::InitStandalone(initial_command_line);
// Note that this task observer must be added after the observer that drains
// the microtask queue.
ScriptCompletionTaskObserver task_observer(
fml::MessageLoop::GetCurrent().GetTaskRunner());
if (!run_forever) {
blink::Threads::UI()->PostTask([&task_observer] {
fml::MessageLoop::GetCurrent().AddTaskObserver(&task_observer);
});
}
if (!shell::InitForTesting(initial_command_line)) {
shell::PrintUsage("flutter_tester");
::ExitProcess(EXIT_FAILURE);
return;
}
fml::MessageLoop::GetCurrent().Run();
shell::TestRunner& test_runner = shell::TestRunner::Shared();
tonic::DartErrorHandleType error =
test_runner.platform_view().engine().GetLoadScriptError();
if (error == tonic::kNoError)
error = task_observer.last_error();
if (error == tonic::kNoError) {
fxl::AutoResetWaitableEvent latch;
blink::Threads::UI()->PostTask([&error, &latch] {
error = tonic::DartMicrotaskQueue::GetForCurrentThread()->GetLastError();
latch.Signal();
});
latch.Wait();
}
// The script has completed and the engine may not be in a clean state,
// so just stop the process.
::ExitProcess(ConvertErrorTypeToExitCode(error));
}
} // namespace
int main(int argc, char* argv[]) {
dart::bin::SetExecutableName(argv[0]);
dart::bin::SetExecutableArguments(argc - 1, argv);
auto command_line = fxl::CommandLineFromArgcArgv(argc, argv);
if (command_line.HasOption(shell::FlagForSwitch(shell::Switch::Help))) {
shell::PrintUsage("flutter_tester");
return EXIT_SUCCESS;
}
bool run_forever =
command_line.HasOption(shell::FlagForSwitch(shell::Switch::RunForever));
RunNonInteractive(std::move(command_line), run_forever);
return EXIT_SUCCESS;
}
......@@ -9600,6 +9600,7 @@ FILE: ../../../flutter/shell/platform/darwin/ios/framework/Source/FlutterAppDele
FILE: ../../../flutter/shell/platform/darwin/ios/framework/Source/vsync_waiter_ios.h
FILE: ../../../flutter/shell/platform/darwin/ios/framework/Source/vsync_waiter_ios.mm
FILE: ../../../flutter/shell/platform/linux/main_linux.cc
FILE: ../../../flutter/shell/platform/win/main_win.cc
FILE: ../../../flutter/sky/engine/wtf/Allocator.h
FILE: ../../../flutter/sky/engine/wtf/MakeUnique.h
----------------------------------------------------------------------------------------------------
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册