Skip to content

Commit

Permalink
Add support for building with MinGW (microsoft#9137)
Browse files Browse the repository at this point in the history
* Add support for building with MinGW

Tested with MSYS2 MinGW 8.3.0, gcc-mcf.lhmouse MinGW 9.2.1,
and StephanTLavavej/mingw-distro!

* Add MinGW toolchain

From your MinGW configured shell you could just use vcpkg to
configure packages.

An x64-mingw triplet would look like:
```
set(VCPKG_TARGET_ARCHITECTURE x64)
set(VCPKG_CRT_LINKAGE dynamic)
set(VCPKG_LIBRARY_LINKAGE static)
set(VCPKG_ENV_PASSTHROUGH PATH)

set(VCPKG_CMAKE_SYSTEM_NAME MinGW)
```

* Add MinGW community tripplets

x64 tested with https://github.com/StephanTLavavej/mingw-distro
x86, arm64, arm tested with https://github.com/mstorsjo/llvm-mingw
  • Loading branch information
cristianadam authored and vicroms committed Jan 17, 2020
1 parent f56645c commit 38b9590
Show file tree
Hide file tree
Showing 15 changed files with 148 additions and 21 deletions.
4 changes: 4 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -294,8 +294,12 @@ __pycache__/
#ignore custom triplets
/triplets/*
#add vcpkg-designed triplets back in
!triplets/community/arm64-mingw.cmake
!triplets/community/arm64-uwp.cmake
!triplets/community/arm-mingw.cmake
!triplets/community/arm-windows.cmake
!triplets/community/x64-mingw.cmake
!triplets/community/x86-mingw.cmake
!triplets/community/x86-uwp.cmake
!triplets/community/x86-windows-static.cmake
!triplets/arm-uwp.cmake
Expand Down
19 changes: 13 additions & 6 deletions scripts/cmake/vcpkg_common_definitions.cmake
Original file line number Diff line number Diff line change
Expand Up @@ -37,9 +37,12 @@ elseif(VCPKG_CMAKE_SYSTEM_NAME STREQUAL "Android")
set(VCPKG_TARGET_IS_ANDROID 1)
elseif(VCPKG_CMAKE_SYSTEM_NAME STREQUAL "FreeBSD")
set(VCPKG_TARGET_IS_FREEBSD 1)
elseif(VCPKG_CMAKE_SYSTEM_NAME STREQUAL "MinGW")
set(VCPKG_TARGET_IS_WINDOWS 1)
set(VCPKG_TARGET_IS_MINGW 1)
endif()

#Helper variable to identify the host path separator.
#Helper variable to identify the host path separator.
if(CMAKE_HOST_WIN32)
set(VCPKG_HOST_PATH_SEPARATOR ";")
elseif(CMAKE_HOST_UNIX)
Expand Down Expand Up @@ -71,11 +74,15 @@ if(VCPKG_TARGET_IS_WINDOWS)
set(VCPKG_TARGET_IMPORT_LIBRARY_PREFIX "")
set(VCPKG_FIND_LIBRARY_SUFFIXES ".lib" ".dll") #This is a slight modification to CMakes value which does not include ".dll".
set(VCPKG_FIND_LIBRARY_PREFIXES "" "lib") #This is a slight modification to CMakes value which does not include "lib".
## For CYGWIN and Windows GNU, maybe VCPKG will support that in the future?
#set(VCPKG_TARGET_IMPORT_LIBRARY_SUFFIX ".dll.a")
#set(VCPKG_TARGET_IMPORT_LIBRARY_PREFIX "lib")
#set(VCPKG_FIND_LIBRARY_SUFFIXES ".dll" ".dll.a" ".a" ".lib")
#set(VCPKG_FIND_LIBRARY_PREFIXES "lib" "")
elseif(VCPKG_TARGET_IS_MINGW)
set(VCPKG_TARGET_STATIC_LIBRARY_SUFFIX ".a")
set(VCPKG_TARGET_IMPORT_LIBRARY_SUFFIX ".dll.a")
set(VCPKG_TARGET_SHARED_LIBRARY_SUFFIX ".dll")
set(VCPKG_TARGET_STATIC_LIBRARY_PREFIX "lib")
set(VCPKG_TARGET_SHARED_LIBRARY_PREFIX "lib")
set(VCPKG_TARGET_IMPORT_LIBRARY_PREFIX "lib")
set(VCPKG_FIND_LIBRARY_SUFFIXES ".dll" ".dll.a" ".a" ".lib")
set(VCPKG_FIND_LIBRARY_PREFIXES "lib" "")
elseif(VCPKG_TARGET_IS_OSX)
set(VCPKG_TARGET_STATIC_LIBRARY_SUFFIX ".a")
set(VCPKG_TARGET_IMPORT_LIBRARY_SUFFIX "")
Expand Down
8 changes: 5 additions & 3 deletions scripts/cmake/vcpkg_configure_cmake.cmake
Original file line number Diff line number Diff line change
Expand Up @@ -59,7 +59,7 @@
## * [poco](https://github.com/Microsoft/vcpkg/blob/master/ports/poco/portfile.cmake)
## * [opencv](https://github.com/Microsoft/vcpkg/blob/master/ports/opencv/portfile.cmake)
function(vcpkg_configure_cmake)
cmake_parse_arguments(_csc
cmake_parse_arguments(_csc
"PREFER_NINJA;DISABLE_PARALLEL_CONFIGURE;NO_CHARSET_FLAG"
"SOURCE_PATH;GENERATOR"
"OPTIONS;OPTIONS_DEBUG;OPTIONS_RELEASE"
Expand Down Expand Up @@ -177,13 +177,13 @@ function(vcpkg_configure_cmake)
"Invalid setting for VCPKG_LIBRARY_LINKAGE: \"${VCPKG_LIBRARY_LINKAGE}\". "
"It must be \"static\" or \"dynamic\"")
endif()

macro(check_both_vars_are_set var1 var2)
if((NOT DEFINED ${var1} OR NOT DEFINED ${var2}) AND (DEFINED ${var1} OR DEFINED ${var2}))
message(FATAL_ERROR "Both ${var1} and ${var2} must be set.")
endif()
endmacro()

check_both_vars_are_set(VCPKG_CXX_FLAGS_DEBUG VCPKG_C_FLAGS_DEBUG)
check_both_vars_are_set(VCPKG_CXX_FLAGS_RELEASE VCPKG_C_FLAGS_RELEASE)
check_both_vars_are_set(VCPKG_CXX_FLAGS VCPKG_C_FLAGS)
Expand All @@ -204,6 +204,8 @@ function(vcpkg_configure_cmake)
set(VCPKG_CHAINLOAD_TOOLCHAIN_FILE "${SCRIPTS}/toolchains/osx.cmake")
elseif(VCPKG_CMAKE_SYSTEM_NAME STREQUAL "FreeBSD")
set(VCPKG_CHAINLOAD_TOOLCHAIN_FILE "${SCRIPTS}/toolchains/freebsd.cmake")
elseif(VCPKG_CMAKE_SYSTEM_NAME STREQUAL "MinGW")
set(VCPKG_CHAINLOAD_TOOLCHAIN_FILE "${SCRIPTS}/toolchains/mingw.cmake")
endif()
endif()

Expand Down
7 changes: 4 additions & 3 deletions scripts/templates/portfile.in.cmake
Original file line number Diff line number Diff line change
Expand Up @@ -22,11 +22,12 @@
# VCPKG_TARGET_IS_OSX
# VCPKG_TARGET_IS_FREEBSD
# VCPKG_TARGET_IS_ANDROID
# VCPKG_TARGET_IS_MINGW
# VCPKG_TARGET_EXECUTABLE_SUFFIX
# VCPKG_TARGET_STATIC_LIBRARY_SUFFIX
# VCPKG_TARGET_SHARED_LIBRARY_SUFFIX
#
# See additional helpful variables in /docs/maintainers/vcpkg_common_definitions.md
# See additional helpful variables in /docs/maintainers/vcpkg_common_definitions.md

# # Specifies if the port install should fail immediately given a condition
# vcpkg_fail_port_install(MESSAGE "@PORT@ currently only supports Linux and Mac platforms" ON_TARGET "Windows")
Expand All @@ -39,10 +40,10 @@ vcpkg_download_distfile(ARCHIVE

vcpkg_extract_source_archive_ex(
OUT_SOURCE_PATH SOURCE_PATH
ARCHIVE ${ARCHIVE}
ARCHIVE ${ARCHIVE}
# (Optional) A friendly name to use instead of the filename of the archive (e.g.: a version number or tag).
# REF 1.0.0
# (Optional) Read the docs for how to generate patches at:
# (Optional) Read the docs for how to generate patches at:
# https://github.com/Microsoft/vcpkg/blob/master/docs/examples/patching.md
# PATCHES
# 001_port_fixes.patch
Expand Down
40 changes: 40 additions & 0 deletions scripts/toolchains/mingw.cmake
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
if(NOT _VCPKG_MINGW_TOOLCHAIN)
set(_VCPKG_MINGW_TOOLCHAIN 1)
if(CMAKE_HOST_SYSTEM_NAME STREQUAL "Windows")
set(CMAKE_CROSSCOMPILING OFF CACHE BOOL "")
endif()

# Need to override MinGW from VCPKG_CMAKE_SYSTEM_NAME
set(CMAKE_SYSTEM_NAME Windows CACHE STRING "" FORCE)

if(VCPKG_TARGET_ARCHITECTURE STREQUAL "x86")
set(CMAKE_SYSTEM_PROCESSOR i686 CACHE STRING "")
elseif(VCPKG_TARGET_ARCHITECTURE STREQUAL "x64")
set(CMAKE_SYSTEM_PROCESSOR x86_64 CACHE STRING "")
elseif(VCPKG_TARGET_ARCHITECTURE STREQUAL "arm")
set(CMAKE_SYSTEM_PROCESSOR armv7 CACHE STRING "")
elseif(VCPKG_TARGET_ARCHITECTURE STREQUAL "arm64")
set(CMAKE_SYSTEM_PROCESSOR aarch64 CACHE STRING "")
endif()

foreach(lang C CXX)
set(CMAKE_${lang}_COMPILER_TARGET "${CMAKE_SYSTEM_PROCESSOR}-windows-gnu" CACHE STRING "")
endforeach()

get_property( _CMAKE_IN_TRY_COMPILE GLOBAL PROPERTY IN_TRY_COMPILE )
if(NOT _CMAKE_IN_TRY_COMPILE)
string(APPEND CMAKE_C_FLAGS_INIT " ${VCPKG_C_FLAGS} ")
string(APPEND CMAKE_CXX_FLAGS_INIT " ${VCPKG_CXX_FLAGS} ")
string(APPEND CMAKE_C_FLAGS_DEBUG_INIT " ${VCPKG_C_FLAGS_DEBUG} ")
string(APPEND CMAKE_CXX_FLAGS_DEBUG_INIT " ${VCPKG_CXX_FLAGS_DEBUG} ")
string(APPEND CMAKE_C_FLAGS_RELEASE_INIT " ${VCPKG_C_FLAGS_RELEASE} ")
string(APPEND CMAKE_CXX_FLAGS_RELEASE_INIT " ${VCPKG_CXX_FLAGS_RELEASE} ")

string(APPEND CMAKE_SHARED_LINKER_FLAGS_INIT " ${VCPKG_LINKER_FLAGS} ")
string(APPEND CMAKE_EXE_LINKER_FLAGS_INIT " ${VCPKG_LINKER_FLAGS} ")
if(VCPKG_CRT_LINKAGE STREQUAL "static")
string(APPEND CMAKE_SHARED_LINKER_FLAGS_INIT "-static ")
string(APPEND CMAKE_EXE_LINKER_FLAGS_INIT "-static ")
endif()
endif()
endif()
30 changes: 28 additions & 2 deletions toolsrc/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -65,7 +65,14 @@ if(CLANG AND NOT MSVC)
endif()

if(GCC OR (CLANG AND USES_LIBSTDCXX))
link_libraries(stdc++fs)
include(CheckCXXSourceCompiles)
set(CMAKE_REQUIRED_LIBRARIES stdc++fs)
check_cxx_source_compiles("#include <experimental/filesystem>
int main() { return 0; }" LINKS_TO_STDCXX_FS)
unset(CMAKE_REQUIRED_LIBRARIES)
if (LINKS_TO_STDCXX_FS)
link_libraries(stdc++fs)
endif()
elseif(CLANG AND NOT MSVC AND NOT NO_LIBCXXFS)
link_libraries(c++fs)
endif()
Expand Down Expand Up @@ -94,7 +101,7 @@ elseif(GCC OR CLANG)
add_compile_options(-std=c++1z)

if(VCPKG_DEVELOPMENT_WARNINGS)
add_compile_options(-Wall -Wextra -Wpedantic -Wno-unknown-pragmas -Wno-missing-field-initializers -Werror)
add_compile_options(-Wall -Wextra -Wpedantic -Wno-unknown-pragmas -Wno-missing-field-initializers -Wno-redundant-move -Werror)

# GCC and clang have different names for the same warning
if (GCC)
Expand Down Expand Up @@ -143,3 +150,22 @@ if(MSVC)
target_sources(vcpkg PRIVATE src/pch.cpp)
target_compile_options(vcpkg PRIVATE /Yupch.h /FIpch.h /Zm200)
endif()

if (MINGW)
include(CheckCXXSourceCompiles)
check_cxx_source_compiles("#include <experimental/filesystem>
int main() { return 0; }" USES_EXPERIMENTAL_FS)

if (NOT USES_EXPERIMENTAL_FS)
add_compile_definitions(USE_STD_FILESYSTEM)
endif()

add_compile_definitions(
UNICODE
_WIN32_WINNT=0x0601
WINHTTP_ACCESS_TYPE_AUTOMATIC_PROXY=4
__fastfail=exit)
foreach(tgt vcpkg vcpkg-test)
target_link_libraries(${tgt} PRIVATE winhttp bcrypt version ole32 uuid)
endforeach()
endif()
4 changes: 4 additions & 0 deletions toolsrc/include/pch.h
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,11 @@
#include <cstdint>
#define _SILENCE_EXPERIMENTAL_FILESYSTEM_DEPRECATION_WARNING
#include <cstring>
#if USE_STD_FILESYSTEM
#include <filesystem>
#else
#include <experimental/filesystem>
#endif
#include <fstream>
#include <functional>
#include <iomanip>
Expand Down
8 changes: 8 additions & 0 deletions toolsrc/include/vcpkg/base/files.h
Original file line number Diff line number Diff line change
Expand Up @@ -2,12 +2,20 @@

#include <vcpkg/base/expected.h>

#if USE_STD_FILESYSTEM
#include <filesystem>
#else
#define _SILENCE_EXPERIMENTAL_FILESYSTEM_DEPRECATION_WARNING
#include <experimental/filesystem>
#endif

namespace fs
{
#if USE_STD_FILESYSTEM
namespace stdfs = std::filesystem;
#else
namespace stdfs = std::experimental::filesystem;
#endif

using stdfs::copy_options;
using stdfs::path;
Expand Down
13 changes: 12 additions & 1 deletion toolsrc/src/vcpkg.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -263,7 +263,18 @@ static void load_config()

#if defined(_WIN32)
// note: this prevents a false positive for -Wmissing-prototypes on clang-cl
int wmain(int, const wchar_t* const*);
int wmain(int, const wchar_t* const* const);

#if !defined(_MSC_VER)
#include <shellapi.h>
int main(int argc, const char* const* const /*argv*/)
{
wchar_t **wargv;
wargv = CommandLineToArgvW(GetCommandLineW(), &argc);
return wmain(argc, wargv);
}
#endif

int wmain(const int argc, const wchar_t* const* const argv)
#else
int main(const int argc, const char* const* const argv)
Expand Down
8 changes: 4 additions & 4 deletions toolsrc/src/vcpkg/base/hash.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -123,9 +123,9 @@ namespace vcpkg::Hash
void top_bits(T) = delete;

static constexpr uchar top_bits(uchar x) noexcept { return x; }
static constexpr uchar top_bits(std::uint32_t x) noexcept { return (x >> 24) & 0xFF; }
static constexpr uchar top_bits(std::uint64_t x) noexcept { return (x >> 56) & 0xFF; }
static constexpr uchar top_bits(UInt128 x) noexcept { return top_bits(x.top); }
[[maybe_unused]] static constexpr uchar top_bits(std::uint32_t x) noexcept { return (x >> 24) & 0xFF; }
[[maybe_unused]] static constexpr uchar top_bits(std::uint64_t x) noexcept { return (x >> 56) & 0xFF; }
[[maybe_unused]] static constexpr uchar top_bits(UInt128 x) noexcept { return top_bits(x.top); }

// treats UIntTy as big endian for the purpose of this mapping
template<class UIntTy>
Expand All @@ -145,7 +145,7 @@ namespace vcpkg::Hash
for (uchar& ch : buff)
{
ch = top_bits(tmp);
tmp <<= 8;
tmp = UIntTy(tmp << 8);
}

for (const auto byte : buff)
Expand Down
4 changes: 2 additions & 2 deletions toolsrc/src/vcpkg/base/system.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -378,7 +378,7 @@ namespace vcpkg

g_ctrl_c_state.transition_to_spawn_process();
auto clean_env = compute_clean_environment(extra_env, prepend_to_path);
windows_create_process(cmd_line, clean_env.data(), process_info, NULL);
windows_create_process(cmd_line, clean_env.data(), process_info, 0);

CloseHandle(process_info.hThread);

Expand Down Expand Up @@ -542,7 +542,7 @@ namespace vcpkg
{
HKEY k = nullptr;
const LSTATUS ec =
RegOpenKeyExW(reinterpret_cast<HKEY>(base_hkey), Strings::to_utf16(sub_key).c_str(), NULL, KEY_READ, &k);
RegOpenKeyExW(reinterpret_cast<HKEY>(base_hkey), Strings::to_utf16(sub_key).c_str(), 0, KEY_READ, &k);
if (ec != ERROR_SUCCESS) return nullopt;

auto w_valuename = Strings::to_utf16(valuename);
Expand Down
6 changes: 6 additions & 0 deletions triplets/community/arm-mingw.cmake
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
set(VCPKG_TARGET_ARCHITECTURE arm)
set(VCPKG_CRT_LINKAGE dynamic)
set(VCPKG_LIBRARY_LINKAGE static)
set(VCPKG_ENV_PASSTHROUGH PATH)

set(VCPKG_CMAKE_SYSTEM_NAME MinGW)
6 changes: 6 additions & 0 deletions triplets/community/arm64-mingw.cmake
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
set(VCPKG_TARGET_ARCHITECTURE arm64)
set(VCPKG_CRT_LINKAGE dynamic)
set(VCPKG_LIBRARY_LINKAGE static)
set(VCPKG_ENV_PASSTHROUGH PATH)

set(VCPKG_CMAKE_SYSTEM_NAME MinGW)
6 changes: 6 additions & 0 deletions triplets/community/x64-mingw.cmake
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
set(VCPKG_TARGET_ARCHITECTURE x64)
set(VCPKG_CRT_LINKAGE dynamic)
set(VCPKG_LIBRARY_LINKAGE static)
set(VCPKG_ENV_PASSTHROUGH PATH)

set(VCPKG_CMAKE_SYSTEM_NAME MinGW)
6 changes: 6 additions & 0 deletions triplets/community/x86-mingw.cmake
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
set(VCPKG_TARGET_ARCHITECTURE x86)
set(VCPKG_CRT_LINKAGE dynamic)
set(VCPKG_LIBRARY_LINKAGE static)
set(VCPKG_ENV_PASSTHROUGH PATH)

set(VCPKG_CMAKE_SYSTEM_NAME MinGW)

0 comments on commit 38b9590

Please sign in to comment.