Skip to content

Bazel build/test on Windows#85

Closed
dgoffredo wants to merge 20 commits intomainfrom
david.goffredo/windows
Closed

Bazel build/test on Windows#85
dgoffredo wants to merge 20 commits intomainfrom
david.goffredo/windows

Conversation

@dgoffredo
Copy link
Contributor

@dgoffredo dgoffredo commented Jan 8, 2024

This is my attempt to address #84.

Bazel can build and test this code using Visual Studio 2022 Community Edition on Windows 10.

I have yet to check whether Envoy can build this code on Windows, because I can't get Envoy to build on Windows in any case. Something about a missing header in quiche.

See the commit messages for lists of the changes. We'll want to go through the changes in person to discuss alternatives.

Finally, we'll want to add a Windows bazel build/test to CircleCI. Otherwise it'll break immediately. It looks like it's possible with CircleCI's Windows "orb," but I have yet to try it. Ideally, Visual Studio is already installed; then we can install "chocolatey," then choco install bazelisk, and then go to town in powershell. None of that is here.

Edit: CI is working :D

- `T(T&) = default;` is not a thing.
  - That's neither a copy constructor nor a move constructor.
  - In order to fix this, it was best to remove the template
    flavors of `Expected` member functions. Instead, I manually
    define the relevant overloads.
- `#include <windows.h>` before including other Windows-related headers.
- Use `.bazelrc` for platform-specific compiler options.
    - But now how will Envoy know to `-DDD_USE_ABSEIL_FOR_ENVOY`?
- Setting an environment variable to an empty string instead removes the
  environment variable. This affected some tests.
- ::gethostname requires special setup.
- timegm(...) has a different name.
- The compiler wouldn't automatically capture a local `const std::time_t`.
- Since bazel builds don't include libcurl, tests had to be updated to
  use a mock `HTTPClient` instance, otherwise configuration fails.
- bazel builds use `absl::string_view`, so some appearances of
  `operator=` had to be changed to `assign`.
- Deleting a file using the facilities in `std::filesystem` does not
  delete the file.
- `::gethostname` requires winsock linkage.
- `Expected` now does not contain any member function templates. I don't
  want to think about how to explain why.
@dgoffredo dgoffredo requested a review from dmehala January 8, 2024 04:26
Copy link
Collaborator

@dmehala dmehala left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Using _putenv instead of GetEnvironmentVariable in GuardEnv should be enough.

I was quite surprised that you didn't have to update all occurrences of range. Most errors I had 2 weeks ago were related to range accepting const char* while most usage provides an iterator. So, I booted my Windows machine and tried to compile your branch.
Unfortunately, it is not compiling, I use Visual Studio 17.7 - 193732822. Could you provide your version of Visual Studio and the C++ compiler?


Anyway, this morning I cleaned a bit my branch and opened a draft PR, there is a lot more going on. Have a look, try to compile it and if needed take what you need.

dd-trace-cpp on Windows (taken yesterday):
ddtracecpp-win

Things our branches do not handle:

  • Ninja generator complaining on targets name.
  • Update README build section with cmake --build <BUILD_DIR> -j instead of make && make install.
  • Symbol visibility
// export
#define DD_TRACE_SHARED __declspec(dllexport)
// import
#define DD_TRACE_SHARED __declspec(dllimport)

// for linux
#define DD_TRACE_SHARED __attribute__((visibility("default")))

Good job and good luck with CircleCI.

#ifdef _MSC_VER
// maximum size of an environment variable value on Windows
char buffer[32767];
const DWORD rc = GetEnvironmentVariable(name, buffer, sizeof buffer);
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

No need to write a windows specific version. There is two way to set/get environment variables on Windows:

  • _putenv/getenv
  • GetEnvironmentVariable/SetEnvironmentVariable

MSVC implementation of the STL uses getenv, so, to set an environment use _putenv instead.

const char* get_value() {
#ifdef _MSC_VER
const DWORD rc =
GetEnvironmentVariable(name_.c_str(), buffer_, sizeof buffer_);
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

ditto

@dgoffredo
Copy link
Contributor Author

I booted up my Windows machine again this morning.

bazelisk build --subcommands dd_trace_cpp printed a lot of information. For example, here's one compiler invocation:

# Configuration: 308244673dcfff942bac53deb0add1f990177841812fbc4375ad833de86fdd78
# Execution platform: @@local_config_platform//:host
SUBCOMMAND: # //:dd_trace_cpp [action 'Compiling src/datadog/tags.cpp', configuration: 308244673dcfff942bac53deb0add1f990177841812fbc4375ad833de86fdd78, execution platform: @@local_config_platform//:host, mnemonic: CppCompile]
cd /d C:/users/mathm/_bazel_mathm/gfzrazm3/execroot/_main
  SET INCLUDE=C:\Program Files\Microsoft Visual Studio\2022\Community\VC\Tools\MSVC\14.38.33130\include;C:\Program Files\Microsoft Visual Studio\2022\Community\VC\Tools\MSVC\14.38.33130\ATLMFC\include;C:\Program Files\Microsoft Visual Studio\2022\Community\VC\Auxiliary\VS\include;C:\Program Files (x86)\Windows Kits\10\include\10.0.22621.0\ucrt;C:\Program Files (x86)\Windows Kits\10\\include\10.0.22621.0\\um;C:\Program Files (x86)\Windows Kits\10\\include\10.0.22621.0\\shared;C:\Program Files (x86)\Windows Kits\10\\include\10.0.22621.0\\winrt;C:\Program Files (x86)\Windows Kits\10\\include\10.0.22621.0\\cppwinrt
    SET PATH=C:\Program Files\Microsoft Visual Studio\2022\Community\VC\Tools\MSVC\14.38.33130\bin\HostX64\x64;C:\Program Files\Microsoft Visual Studio\2022\Community\Common7\IDE\VC\VCPackages;C:\Program Files\Microsoft Visual Studio\2022\Community\Common7\IDE\CommonExtensions\Microsoft\TestWindow;C:\Program Files\Microsoft Visual Studio\2022\Community\Common7\IDE\CommonExtensions\Microsoft\TeamFoundation\Team Explorer;C:\Program Files\Microsoft Visual Studio\2022\Community\MSBuild\Current\bin\Roslyn;C:\Program Files\Microsoft Visual Studio\2022\Community\Team Tools\Performance Tools\x64;C:\Program Files\Microsoft Visual Studio\2022\Community\Team Tools\Performance Tools;C:\Program Files\Microsoft Visual Studio\2022\Community\Team Tools\DiagnosticsHub\Collector;C:\Program Files (x86)\Windows Kits\10\bin\10.0.22621.0\\x64;C:\Program Files (x86)\Windows Kits\10\bin\\x64;C:\Program Files\Microsoft Visual Studio\2022\Community\\MSBuild\Current\Bin\amd64;C:\Windows\Microsoft.NET\Framework64\v4.0.30319;C:\Program Files\Microsoft Visual Studio\2022\Community\Common7\IDE\;C:\Program Files\Microsoft Visual Studio\2022\Community\Common7\Tools\;;C:\Windows\system32;C:\Program Files\Microsoft Visual Studio\2022\Community\Common7\IDE\CommonExtensions\Microsoft\CMake\CMake\bin;C:\Program Files\Microsoft Visual Studio\2022\Community\Common7\IDE\CommonExtensions\Microsoft\CMake\Ninja;C:\Program Files\Microsoft Visual Studio\2022\Community\Common7\IDE\VC\Linux\bin\ConnectionManagerExe;C:\Program Files\Microsoft Visual Studio\2022\Community\VC\vcpkg
    SET PWD=/proc/self/cwd
    SET RUNFILES_MANIFEST_ONLY=1
    SET TEMP=C:\Users\MathM\AppData\Local\Temp
    SET TMP=C:\Users\MathM\AppData\Local\Temp
    SET VSLANG=1033
  C:\Program Files\Microsoft Visual Studio\2022\Community\VC\Tools\MSVC\14.38.33130\bin\HostX64\x64\cl.exe @bazel-out/x64_windows-fastbuild/bin/_objs/dd_trace_cpp/tags.obj.params``

Looking at the last line, that's my local cl.exe given arguments (parameters) from a file bazel-out/x64_windows-fastbuild/bin/_objs/dd_trace_cpp/tags.obj.params.

Here's getting the content of the file:

PS C:\users\mathm\src\dd-trace-cpp> cat bazel-out/x64_windows-fastbuild/bin/_objs/dd_trace_cpp/tags.obj.params
/nologo
/DCOMPILER_MSVC
/DNOMINMAX
/D_WIN32_WINNT=0x0601
/D_CRT_SECURE_NO_DEPRECATE
/D_CRT_SECURE_NO_WARNINGS
/bigobj
/Zm500
/EHsc
/wd4351
/wd4291
/wd4250
/wd4996
/I.
/Ibazel-out/x64_windows-fastbuild/bin
/Iexternal/com_google_absl
/Ibazel-out/x64_windows-fastbuild/bin/external/com_google_absl
/Ibazel-out/x64_windows-fastbuild/bin/_virtual_includes/dd_trace_cpp
/D__CLANG_SUPPORT_DYN_ANNOTATION__
/showIncludes
/MD
/Od
/Z7
/wd4117
-D__DATE__=\"redacted\"
-D__TIMESTAMP__=\"redacted\"
-D__TIME__=\"redacted\"
/std:c++17
/DDD_USE_ABSEIL_FOR_ENVOY
/Fobazel-out/x64_windows-fastbuild/bin/_objs/dd_trace_cpp/tags.obj
/c
src/datadog/tags.cpp

Maybe it's those /wd...x flags. They suppress warnings. Ah, but your compiler was emitting errors, so still a mystery. That first warning (4351) is missing from Microsoft's documentation, so maybe those are more about bugged warnings than about diagnostic preferences. Just a guess.

If I run the compiler without arguments, it prints its version:

PS C:\users\mathm\src\dd-trace-cpp> C:\'Program Files'\'Microsoft Visual Studio'\2022\Community\VC\Tools\MSVC\14.38.33130\bin\HostX64\x64\cl.exe
Microsoft (R) C/C++ Optimizing Compiler Version 19.38.33133 for x64
Copyright (C) Microsoft Corporation.  All rights reserved.

usage: cl [ option... ] filename... [ /link linkoption... ]

There are no other versions installed:

PS C:\users\mathm\src\dd-trace-cpp> ls C:\'Program Files'\'Microsoft Visual Studio'\2022\Community\VC\Tools\MSVC\


    Directory: C:\Program Files\Microsoft Visual Studio\2022\Community\VC\Tools\MSVC


Mode                 LastWriteTime         Length Name
----                 -------------         ------ ----
d-----          1/6/2024   1:21 PM                14.38.33130


PS C:\users\mathm\src\dd-trace-cpp>

Windows info:

Edition	Windows 10 Home
Version	22H2
Installed on	‎9/‎8/‎2020
OS build	19045.3803
Experience	Windows Feature Experience Pack 1000.19053.1000.0

System info:

Device name	DESKTOP-K678O5O
Processor	Intel(R) Core(TM) i7-9700K CPU @ 3.60GHz   3.60 GHz
Installed RAM	16.0 GB
Device ID	B3AB65F5-79E3-4627-A8D7-998FF68433CB
Product ID	00325-81869-51316-AAOEM
System type	64-bit operating system, x64-based processor
Pen and touch	No pen or touch input is available for this display

Bazel info:

PS C:\users\mathm\src\dd-trace-cpp> bazelisk version
Bazelisk version: v1.19.0
Build label: 7.0.0
Build target: @@//src/main/java/com/google/devtools/build/lib/bazel:BazelServer
Build time: Mon Dec 11 16:54:12 2023 (1702313652)
Build timestamp: 1702313652
Build timestamp as int: 1702313652
PS C:\users\mathm\src\dd-trace-cpp>

Visual Studio info:
vs

@dmehala
Copy link
Collaborator

dmehala commented Jan 9, 2024

Just for the record, we already talk about it on Slack. We have a similar Windows setup (that's new we did not talk about it yet). The difference is that bazel build uses abseil and abseil string_view iterator is a const char* while MSVC STL Iterator is not an alias to const char*

@pr-commenter
Copy link

pr-commenter bot commented Jan 13, 2024

Benchmarks

Benchmark execution time: 2024-03-15 20:59:43

Comparing candidate commit 11d3170 in PR branch david.goffredo/windows with baseline commit 80bd66e in branch main.

Found 0 performance improvements and 0 performance regressions! Performance is the same for 1 metrics, 0 unstable metrics.

@dgoffredo
Copy link
Contributor Author

Et voila!

Still remaining:

  • Use std::getenv and _putenv on Windows, instead of {Get,Set}EnvironmentVariable.
  • Figure out how to convey -DDD_USE_ABSEIL_FOR_ENVOY to Envoy when Envoy builds this library with Bazel.
    • We could put it as part of copts in BUILD.bazel, but then I don't know how to disable it for other kinds of builds. Right now I'm using two different .bazelrc files.
  • Figure out how to build Envoy on Windows, so that we can test enabling the Datadog tracer in Envoy.

@dgoffredo dgoffredo force-pushed the david.goffredo/windows branch from df69e33 to fd07f86 Compare March 15, 2024 19:25
@dmehala
Copy link
Collaborator

dmehala commented Apr 22, 2024

Soon™️

@dmehala dmehala closed this Apr 22, 2024
@dgoffredo
Copy link
Contributor Author

Consider integrating the trace_sampler_config.cpp bug fix into main.

@dmehala dmehala mentioned this pull request May 6, 2024
@dmehala dmehala deleted the david.goffredo/windows branch September 14, 2025 16:38
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants