Skip to content

Commit

Permalink
Enable Windows CI //source/exe:envoy-static build (#10293)
Browse files Browse the repository at this point in the history
Description:
 - Build and CI tooling to get windows compiling
 - (Reintroduces an experimental ci/windows_build_steps.ps1)
 - Source changes required for Windows compilation on msvc
 - Pick up a flavor of nameser.h for Windows only from c-ares dependency
 - Excludes all source fixes unrelated to compilation passing on Windows

Risk Level: Low
Testing: local on linux/gcc windows/msvc
Docs Changes: n/a
Release Notes: n/a

Signed-off-by: Sunjay Bhatia <sbhatia@pivotal.io>
Signed-off-by: William A Rowe Jr <wrowe@pivotal.io>
  • Loading branch information
wrowe authored Mar 14, 2020
1 parent 82e4b26 commit e7fc5fc
Show file tree
Hide file tree
Showing 21 changed files with 245 additions and 85 deletions.
4 changes: 4 additions & 0 deletions .azure-pipelines/windows.yml
Original file line number Diff line number Diff line change
Expand Up @@ -19,3 +19,7 @@ jobs:
- bash: ci/windows_ci_steps.sh
displayName: "Run Windows CI"
env:
TMPDIR: $(Agent.TempDirectory)
BAZEL_VC: "C:\\Program Files (x86)\\Microsoft Visual Studio\\2019\\Enterprise\\VC"
BAZEL_SH: "C:\\Program Files\\Git\\bin\\bash.exe"
1 change: 1 addition & 0 deletions bazel/envoy_binary.bzl
Original file line number Diff line number Diff line change
Expand Up @@ -78,6 +78,7 @@ def _envoy_linkopts():

def _envoy_stamped_deps():
return select({
"@envoy//bazel:windows_x86_64": [],
"@envoy//bazel:apple": [
"@envoy//bazel:raw_build_id.ldscript",
],
Expand Down
13 changes: 7 additions & 6 deletions bazel/envoy_internal.bzl
Original file line number Diff line number Diff line change
Expand Up @@ -18,21 +18,22 @@ def envoy_copts(repository, test = False):
]

# Windows options for cleanest service compilation;
# General MSVC C++ options
# Streamline windows.h behavior for Win8+ API (for ntohll, see;
# https://msdn.microsoft.com/en-us/library/windows/desktop/aa383745(v=vs.85).aspx )
# Minimize Win32 API, dropping GUI-oriented features
# General MSVC C++ options for Envoy current expectations.
# Target windows.h for all Windows 10 (0x0A) API prototypes (ntohll etc)
# (See https://msdn.microsoft.com/en-us/library/windows/desktop/aa383745(v=vs.85).aspx )
# Optimize Windows headers by dropping GUI-oriented features from compilation
msvc_options = [
"-WX",
"-Zc:__cplusplus",
"-std:c++14",
"-DWIN32",
"-D_WIN32_WINNT=0x0602",
"-DNTDDI_VERSION=0x06020000",
"-D_WIN32_WINNT=0x0A00", # _WIN32_WINNT_WIN10
"-DNTDDI_VERSION=0x0A000000", # NTDDI_WIN10
"-DWIN32_LEAN_AND_MEAN",
"-DNOUSER",
"-DNOMCX",
"-DNOIME",
"-DNOCRYPT",
]

return select({
Expand Down
3 changes: 3 additions & 0 deletions bazel/external/BUILD
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,9 @@ cc_library(
name = "all_external",
srcs = [":empty.cc"],
defines = ["OPENTRACING_STATIC"],
# TODO: external/io_opentracing_cpp/BUILD.bazel:19:1: Executing genrule
# @io_opentracing_cpp//:generate_version_h failed - needs porting
tags = ["skip_on_windows"],
deps = [
"@com_github_datadog_dd_opentracing_cpp//:dd_opentracing_cpp",
"@com_google_googletest//:gtest",
Expand Down
8 changes: 8 additions & 0 deletions bazel/foreign_cc/BUILD
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,8 @@ load("@rules_foreign_cc//tools/build_defs:configure.bzl", "configure_make")

envoy_package()

# autotools packages are unusable on Windows as-is
# TODO: Consider our own gperftools.BUILD file as we do with many other packages
configure_make(
name = "gperftools_build",
configure_options = [
Expand All @@ -22,16 +24,20 @@ configure_make(
"//bazel:debug_tcmalloc": ["libtcmalloc_debug.a"],
"//conditions:default": ["libtcmalloc_and_profiler.a"],
}),
tags = ["skip_on_windows"],
)

# Workaround for https://github.com/bazelbuild/rules_foreign_cc/issues/227
cc_library(
name = "gperftools",
tags = ["skip_on_windows"],
deps = [
"gperftools_build",
],
)

# autotools packages are unusable on Windows as-is
# TODO: Consider our own luajit.BUILD file as we do with many other packages
configure_make(
name = "luajit",
configure_command = "build.py",
Expand All @@ -48,6 +54,7 @@ configure_make(
static_libraries = [
"libluajit-5.1.a",
],
tags = ["skip_on_windows"],
)

configure_make(
Expand All @@ -66,6 +73,7 @@ configure_make(
static_libraries = [
"libluajit-5.1.a",
],
tags = ["skip_on_windows"],
)

envoy_cmake_external(
Expand Down
12 changes: 12 additions & 0 deletions bazel/foreign_cc/cares-win32-nameser.patch
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
--- CMakeLists.txt.orig 2020-02-19 14:42:47.978299400 -0500
+++ CMakeLists.txt 2020-02-19 14:45:18.925903400 -0500
@@ -652,6 +652,9 @@
# Headers installation target
IF (CARES_INSTALL)
SET (CARES_HEADERS ares.h ares_version.h ares_dns.h "${PROJECT_BINARY_DIR}/ares_build.h" ares_rules.h)
+ IF (WIN32)
+ SET (CARES_HEADERS ${CARES_HEADERS} nameser.h)
+ ENDIF()
INSTALL (FILES ${CARES_HEADERS} DESTINATION ${CMAKE_INSTALL_INCLUDEDIR})
ENDIF ()

1 change: 1 addition & 0 deletions bazel/repositories.bzl
Original file line number Diff line number Diff line change
Expand Up @@ -207,6 +207,7 @@ def _com_github_c_ares_c_ares():
location = REPOSITORY_LOCATIONS["com_github_c_ares_c_ares"]
http_archive(
name = "com_github_c_ares_c_ares",
patches = ["@envoy//bazel/foreign_cc:cares-win32-nameser.patch"],
build_file_content = BUILD_ALL_CONTENT,
**location
)
Expand Down
2 changes: 1 addition & 1 deletion ci/build_setup.ps1
Original file line number Diff line number Diff line change
Expand Up @@ -18,4 +18,4 @@ echo "ENVOY_BAZEL_ROOT: $env:ENVOY_BAZEL_ROOT"
echo "ENVOY_SRCDIR: $env:ENVOY_SRCDIR"

$env:BAZEL_BASE_OPTIONS="--noworkspace_rc --output_base=$env:ENVOY_BAZEL_ROOT --bazelrc=$env:ENVOY_SRCDIR\windows\.bazelrc"
$env:BAZEL_BUILD_OPTIONS="--features=compiler_param_file --strategy=Genrule=standalone --spawn_strategy=standalone --verbose_failures --jobs=$env:NUM_CPUS --show_task_finish --test_output=all $env:BAZEL_BUILD_EXTRA_OPTIONS $env:BAZEL_EXTRA_TEST_OPTIONS"
$env:BAZEL_BUILD_OPTIONS="--config=msvc-cl --features=compiler_param_file --strategy=Genrule=standalone --spawn_strategy=standalone --verbose_failures --jobs=$env:NUM_CPUS --show_task_finish --test_output=all $env:BAZEL_BUILD_EXTRA_OPTIONS $env:BAZEL_EXTRA_TEST_OPTIONS"
30 changes: 21 additions & 9 deletions ci/do_ci.ps1
Original file line number Diff line number Diff line change
Expand Up @@ -14,41 +14,53 @@ function bazel_binary_build($type) {
}

function bazel_test($type, $test) {
if ($test -ne "") {
bazel $env:BAZEL_BASE_OPTIONS.Split(" ") test $env:BAZEL_BUILD_OPTIONS.Split(" ") -c $type $test
if ($test) {
echo "running windows tests $test"
bazel $env:BAZEL_BASE_OPTIONS.Split(" ") test $env:BAZEL_BUILD_OPTIONS.Split(" ") -c $type --build_tests_only $test
} else {
echo "running windows tests"
bazel $env:BAZEL_BASE_OPTIONS.Split(" ") test $env:BAZEL_BUILD_OPTIONS.Split(" ") -c $type "//test/..."
echo "running all windows tests"
bazel $env:BAZEL_BASE_OPTIONS.Split(" ") test $env:BAZEL_BUILD_OPTIONS.Split(" ") -c $type "//test/..." --test_tag_filters=-skip_on_windows --build_tests_only --test_summary=terse --test_output=errors
}
exit $LASTEXITCODE
}

$action = $args[0]
$test = $args[1]
$action, $test = $args

switch ($action) {
"bazel.release" {
echo "bazel release build with tests..."
bazel_binary_build "opt"
bazel_test "opt" "$test"
bazel_test "opt" $test
}
"bazel.release.server_only" {
echo "bazel release build..."
bazel_binary_build "opt"
}
"bazel.release.test_only" {
echo "bazel release build with tests..."
bazel_test "opt" $test
}
"bazel.debug" {
echo "bazel debug build with tests..."
bazel_binary_build "dbg"
bazel_test "dbg" "$test"
bazel_test "dbg" $test
}
"bazel.debug.server_only" {
echo "bazel debug build..."
bazel_binary_build "dbg"
}
"bazel.debug.test_only" {
echo "bazel debug build with tests..."
bazel_test "dbg" $test
}
"bazel.dev" {
echo "bazel fastbuild build with tests..."
bazel_binary_build "fastbuild"
bazel_test "fastbuild" "$test"
bazel_test "fastbuild" $test
}
"bazel.dev.test_only" {
echo "bazel fastbuild build with tests..."
bazel_test "fastbuild" $test
}
default {
echo "unknown action: $action"
Expand Down
2 changes: 1 addition & 1 deletion ci/windows_ci_setup.ps1
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
# This file only installs dependencies needed in additio to Azure pipelines hosted image.
# The list of installed software can be found at:
# https://github.com/Microsoft/azure-pipelines-image-generation/blob/master/images/win/Vs2019-Server2019-Readme.md
# https://github.com/actions/virtual-environments/blob/master/images/win/Windows2019-Readme.md

Add-Type -AssemblyName System.IO.Compression.FileSystem
function Unzip
Expand Down
24 changes: 16 additions & 8 deletions ci/windows_ci_steps.sh
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
# No hashbang here because this script is intended for Windows
#!/usr/bin/bash.exe

set -e

Expand All @@ -13,13 +13,21 @@ df -h

. "$(dirname "$0")"/setup_cache.sh

# TODO(dio): Put in windows/.bazelrc.
export PATH="/c/Program Files (x86)/Windows Kits/10/bin/10.0.17763.0/x64":$PATH

BAZEL_STARTUP_OPTIONS="--bazelrc=windows/.bazelrc"
BAZEL_BUILD_OPTIONS="--show_task_finish --verbose_failures \
# Set up TMPDIR so bash and non-bash can access
# e.g. TMPDIR=/d/tmp, make a link from /d/d to /d so both bash and Windows programs resolve the
# same path
# This is due to this issue: https://github.com/bazelbuild/rules_foreign_cc/issues/334
# rules_foreign_cc does not currently use bazel output/temp directories by default, it uses mktemp
# which respects the value of the TMPDIR environment variable
drive="$(readlink -f $TMPDIR | cut -d '/' -f2)"
/c/windows/system32/cmd.exe "/c mklink /d $drive:\\$drive $drive:\\"

BAZEL_STARTUP_OPTIONS="--noworkspace_rc --bazelrc=windows/.bazelrc --output_base=c:/_eb"
BAZEL_BUILD_OPTIONS="-c opt --config=msvc-cl --show_task_finish --verbose_failures \
--test_output=all ${BAZEL_BUILD_EXTRA_OPTIONS} ${BAZEL_EXTRA_TEST_OPTIONS}"

bazel ${BAZEL_STARTUP_OPTIONS} build ${BAZEL_BUILD_OPTIONS} //bazel/foreign_cc:nghttp2 //bazel/foreign_cc:event //bazel/foreign_cc:yaml
bazel ${BAZEL_STARTUP_OPTIONS} build ${BAZEL_BUILD_OPTIONS} //bazel/... --build_tag_filters=-skip_on_windows

bazel ${BAZEL_STARTUP_OPTIONS} build ${BAZEL_BUILD_OPTIONS} //source/exe:envoy-static

bazel ${BAZEL_STARTUP_OPTIONS} test ${BAZEL_BUILD_OPTIONS} @envoy_api_canonical//test/build/...
# bazel ${BAZEL_STARTUP_OPTIONS} test ${BAZEL_BUILD_OPTIONS} //test/... --test_tag_filters=-skip_on_windows --build_tests_only --test_summary=terse --test_output=errors
5 changes: 5 additions & 0 deletions include/envoy/common/platform.h
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,11 @@
#include <mswsock.h>
#include <ws2tcpip.h>

// This is introduced in Windows SDK 10.0.17063.0 which is required
// to build Envoy on Windows (we will reevaluate whether earlier builds
// of Windows can be detected and PipeInstance marked unsupported at runtime.)
#include <afunix.h>

// <windows.h> defines some frequently used symbols, so we need to undef these
// interfering symbols.
#undef DELETE
Expand Down
4 changes: 2 additions & 2 deletions source/common/network/address_impl.cc
Original file line number Diff line number Diff line change
Expand Up @@ -163,7 +163,7 @@ InstanceConstSharedPtr peerAddressFromFd(os_fd_t fd) {
}

IoHandlePtr InstanceBase::socketFromSocketType(SocketType socket_type) const {
#if defined(__APPLE__)
#if defined(__APPLE__) || defined(WIN32)
int flags = 0;
#else
int flags = SOCK_NONBLOCK;
Expand Down Expand Up @@ -195,7 +195,7 @@ IoHandlePtr InstanceBase::socketFromSocketType(SocketType socket_type) const {
fmt::format("socket(2) failed, got error: {}", strerror(result.errno_)));
IoHandlePtr io_handle = std::make_unique<IoSocketHandleImpl>(result.rc_);

#ifdef __APPLE__
#if defined(__APPLE__) || defined(WIN32)
// Cannot set SOCK_NONBLOCK as a ::socket flag.
const int rc = os_sys_calls.setsocketblocking(io_handle->fd(), false).rc_;
RELEASE_ASSERT(!SOCKET_FAILURE(rc), "");
Expand Down
2 changes: 1 addition & 1 deletion source/common/network/listen_socket_impl.cc
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@ namespace Network {

void ListenSocketImpl::doBind() {
const Api::SysCallIntResult result = local_address_->bind(io_handle_->fd());
if (result.rc_ == -1) {
if (SOCKET_FAILURE(result.rc_)) {
close();
throw SocketBindException(
fmt::format("cannot bind '{}': {}", local_address_->asString(), strerror(result.errno_)),
Expand Down
2 changes: 1 addition & 1 deletion source/common/network/listen_socket_impl.h
Original file line number Diff line number Diff line change
Expand Up @@ -83,7 +83,7 @@ template <typename T> class NetworkListenSocket : public ListenSocketImpl {
NetworkListenSocket(const Address::InstanceConstSharedPtr& address,
const Network::Socket::OptionsSharedPtr& options, bool bind_to_port)
: ListenSocketImpl(address->socket(T::type), address) {
RELEASE_ASSERT(io_handle_->fd() != -1, "");
RELEASE_ASSERT(SOCKET_VALID(io_handle_->fd()), "");

setPrebindSocketOptions();

Expand Down
4 changes: 3 additions & 1 deletion source/common/network/utility.cc
Original file line number Diff line number Diff line change
Expand Up @@ -193,9 +193,10 @@ void Utility::throwWithMalformedIp(absl::string_view ip_address) {
// the default is to return a loopback address of type version. This function may
// need to be updated in the future. Discussion can be found at Github issue #939.
Address::InstanceConstSharedPtr Utility::getLocalAddress(const Address::IpVersion version) {
Address::InstanceConstSharedPtr ret;
#ifndef WIN32
struct ifaddrs* ifaddr;
struct ifaddrs* ifa;
Address::InstanceConstSharedPtr ret;

const int rc = getifaddrs(&ifaddr);
RELEASE_ASSERT(!rc, "");
Expand All @@ -221,6 +222,7 @@ Address::InstanceConstSharedPtr Utility::getLocalAddress(const Address::IpVersio
if (ifaddr) {
freeifaddrs(ifaddr);
}
#endif

// If the local address is not found above, then return the loopback address by default.
if (ret == nullptr) {
Expand Down
Loading

0 comments on commit e7fc5fc

Please sign in to comment.