blob: 1d7ece548e64c44b56c5358515024b5e6227b7ce [file] [log] [blame]
// Copyright 2020 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
//
// https://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.
#include <string>
#include <vector>
#include "iree/base/logging.h"
#include "iree/base/main.h"
#include "iree/base/target_platform.h"
#if defined(IREE_PLATFORM_WINDOWS)
#include <combaseapi.h>
#include <shellapi.h>
namespace iree {
namespace {
// Entry point when using /SUBSYSTEM:CONSOLE is the standard main().
extern "C" int main(int argc, char** argv) { return IreeMain(argc, argv); }
// Entry point when using /SUBSYSTEM:WINDOWS.
extern "C" int WINAPI WinMain(HINSTANCE, HINSTANCE, LPSTR, int) {
// Convert command line to an argv-like format.
// NOTE: the command line that comes in with the WinMain arg is garbage.
int argc = 0;
wchar_t** argv_w = ::CommandLineToArgvW(::GetCommandLineW(), &argc);
if (!argc || !argv_w) {
IREE_LOG(FATAL) << "Unable to parse command line";
return 1;
}
// Convert all args to narrow char strings.
std::vector<std::string> allocated_strings(argc);
std::vector<char*> argv_a(argc);
for (int i = 0; i < argc; ++i) {
size_t char_length = wcslen(argv_w[i]);
allocated_strings[i].resize(char_length);
argv_a[i] = const_cast<char*>(allocated_strings[i].data());
std::wcstombs(argv_a[i], argv_w[i], char_length + 1);
}
::LocalFree(argv_w);
// Setup COM on the main thread.
// NOTE: this may fail if COM has already been initialized - that's OK.
::CoInitializeEx(nullptr, COINIT_MULTITHREADED);
// Run standard main function.
int exit_code = IreeMain(argc, argv_a.data());
// Release arg memory.
argv_a.clear();
allocated_strings.clear();
return exit_code;
}
} // namespace
} // namespace iree
#endif // IREE_PLATFORM_WINDOWS