-
Notifications
You must be signed in to change notification settings - Fork 513
[WIP] Ability to use Standard Library as a substitute for nostd:: classes #275
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Conversation
- add stdtypes.h umbrella header - move all "optional" headers to nostd/stl - add optional dependency on GSL for gsl::span - add build option to build API with/without Standard Library - improvements to EventSender example - Visual Studio project for EventSender
… string literals.
- ETW (EventWriteString in XML format) - OutputDebugStringA (UTF-8) - File - plain k-v pairs - File - JSON Plus generic framework for adding new stream types and converters.
…as a build-time option
Codecov Report
@@ Coverage Diff @@
## master #275 +/- ##
==========================================
+ Coverage 94.59% 94.64% +0.04%
==========================================
Files 146 148 +2
Lines 6629 6754 +125
==========================================
+ Hits 6271 6392 +121
- Misses 358 362 +4
|
- add HAVE_SPAN_BYTE for future byte array support
- add Visual Studio 2015 support - add absl::variant as alternative to nostd::variant
jsuereth
left a comment
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
A bunch of general thoughts and questions.
I appreciate how much work went into this! High level comments:
- can we make it explicit in tests/builds what build flags are being used?
- Can we document a matrix of build flags we're going to support as well as what the "DEFAULT" release is, where we expect vendors to support ABI.
- Is ABSEIL missing from the testing matrix for non MSVC++ compilers? Is it not needed?
Pardon me if I'm asking silly questions, still not 100% ramped up on code structure.
| double, | ||
| nostd::string_view, | ||
| const char *, | ||
| #ifdef HAVE_SPAN_BYTE |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Is this part of this PR or noise?
If so, are there any concerns around this #ifidef causing compatibility issues with dynamic linking SDKs, or are we ONLY using this in a static-linked manner?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@jsuereth - apologies, I'm gonna send another PR from a separate branch to minimize the 'noise'. My master branch contained changes that I needed for some other flows, e.g. byte array support is needed for my internal customer needs, which is logged as an open issue in OT spec (but not implemented yet).
I'll try to answer your questions in the new PR.
| [submodule "third_party/ms-gsl"] | ||
| path = "third_party/ms-gsl" | ||
| url = https://github.com/microsoft/GSL | ||
| branch = master |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
should this be picking a specific version of ms-GSL for those who opt-in to it?
it wasn't clear from the repo how folks understand what version they're using and pull in bug fixes.
additionally, if we want to guarantee any kind of ABI/API compat we probably need to know exactly which version is getting linked in when the flag is used.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Right now it's pulling the latest. But since we use submodules - for CMake build we pin-point to specific commit ID. Technically the MS-GSL is only needed for older compilers without C++20 support, i.e. latest-latest Mac and latest gcc-9+ (as well as vs2019 with c++_latest flag) no longer require MS-GSL. As an alternative - I also want to add an option to build with ABSEIL instead of MS-GSL....
Re. pinning in Bazel - I am not sure how to do it. I wonder if we add Abseil, then test the combo of Bazel+Abseil, and CMake+GSL, that'd be covering the most needed build configurations for those who want to build statically. I can add CMake+Abseil build flavor.
| option(WITH_STL "Whether to use Standard Library for C++latest features" OFF) | ||
|
|
||
| option(WITH_ABSEIL "Whether to use Abseil for C++latest features" OFF) | ||
|
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Nit: if both option are usable or not usable together, should we call that out?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@jsuereth - This is complicated, but I'll try to elaborate :)
-
technically Abseil would be best for vs2015 support, because there is no alternate good variant working with vs2015. Only
absl::variantworks. The one we borrowed from MPark -nostd::variant- does not compile for vs2015, to be more exact - it has problems with complex aggregate variant types. -
now Abseil actually requires statically linked library of itself, which I 'hacked' - if we only use Abseil for variant and nothing else. Whereas GSL itself is header-only. In certain environments I'd prefer the full set of everything to be built with Standard Library and, preferably, header-only --- not needing Abseil (e.g. if I compile the OpenTelemetry SDK for inclusion in some Azure cloud Service).
So - it's problematic on all accounts everywhere:
nostd::variant- the one we have today, is not compiling on vs2015. The only one compiling isabsl::variantabsl::variant- if used without any hacks, requires Abseil STATIC lib (messy)- whereas GSL only has
gsl::spanand does not havegsl::variant:(
So -- to answer your question, in my setup I would prefer:
- just a portion of Abseil for
absl::variant(but not the entire Abseil) + MS-GSL forspan... whereas - Google projects would probably prefer Abseil for everything ... whereas
- dynamic libs prefer
nostd::classes... except this won't work for vs2015. We may need to borrow just thevariantfrom Abseil, tweak it so that it doesn't require static linking of the core Abseil, and replace MPark (nostd::variant) with Abseil... Which I wanted to do in a separate PR.
| add_subdirectory(test) | ||
| endif() | ||
|
|
||
| if(WITH_STL) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Nit: can we include ABSEIL here too?
| static bool Detach(Token &token) noexcept { return ContextHandler()->InternalDetach(token); } | ||
|
|
||
| static RuntimeContext *context_handler_; | ||
| static inline IRuntimeContext *ContextHandler(IRuntimeContext *context_handler = nullptr) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
is this new, and/or part of this PR (or just merge conflict overreporting?)
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I'll clean it. Sorry, this is messy - I was showing an alternate implementation of context. I'll resend the PR from a clean branch.
| @@ -0,0 +1,63 @@ | |||
| # Usage example for nostd classes | |||
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
nice writeup!
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I'll send this in a separate PR.
| "@com_google_googletest//:gtest_main", | ||
| ], | ||
| ) | ||
| # cc_test( |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
why is this disabled?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I'll reenable it.
| const opentelemetry::common::AttributeValue &value) | ||
| { | ||
|
|
||
| #if 0 // FIXME |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Is this because of the HAVE_COLLECTIONS flag?
| set "CMAKE_GEN=Visual Studio 14 2015 Win64" | ||
| cd %~dp0 | ||
| call setup-buildtools.cmd | ||
| call build.cmd -DWITH_ABSEIL:BOOL=ON |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I wasn't sure what you meant originally around having multiple builds.
I thought you were implying we'd have a matrix of builds
Compiler x ABSEIL_FLAG x STD_FLAG
It looks like, instead, each version of VisualStudio gets a configuration. Do we need to make a visual matrix of that for users? While I definitely want the ability to statically link against STD we should make sure it's obvious which configurations support which and what you get out of the box.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Basically if we want to produce a static lib linkable with anything vs2015|vs2017|vs2019, then it MUST be built using vs2015. This is quite silly linker limitation. For example, if we statically produce a lib with vs2019, then it just won't link with older compilers!!! That's because the latest vs2019 has a bit different exception handling semantics.
I do want to have a matrix doc created.
| make | ||
| } | ||
|
|
||
| build_configuration nostd '-DWITH_STL:BOOL=OFF' |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
do we also need ABSEIL ON/OFF permutations here?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I'll elaborate in the new PR.
chore(deps): update ubuntu:24.04 docker digest to 6015f66
This is a summary of changes needed to swap the
nostdclasses withstd::analogs available in C++14/C++17/C++20.Motivation
In certain scenarios it may be of benefit to compile the OpenTelemetry SDK from source using standard library container classes (
std::map,std::string_view,std::span,std::variant) instead of OpenTelemetrynostd::analogs (which were backported to C++11 and designed as ABI-stable). This PR also can be used as a foundation for alternate approach - to also allow bindings to abseil classes. That is in environments that would rather preferAbseilclasses over the standard lib ornostd.The approach is to provide totally opaque (from SDK code / SDK developer perspective) mapping / aliasing from
nostd::classes back to theirstd::counterparts, and that is only done in environments where this is possible. We continue fully supporting both models and run CI for both.Pros and Cons:
using standard library implementation classes in customer code and on API surface: certain environments would prefer to have standard instead of non-standard due to security / performance / stability / debug'ability considerations.
smaller binary size: no need to marshal types from standard to
nostd, then back to standard library. We use standard classes used elsewhere in the app.better performance: no need to transform from 'native' standard library types, e.g.
std::mapviaKeyValueIterable- we can bypass that transformation process when we know that ABI compat is not a requirement. ETA at least 1.5% to 3% better perf since a transform / memcpy is avoided.Standard Library build flavor works best for statically linking the SDK in a process (environment where ABI compat is not a requirement), or for "header-only" implementation of SDK. We cannot employ this approach for shared libraries in environments where ABI compatibility is required:
Thus, this approach works best for statically linking / header only, and may not work for providing 'prebuilt' SDK binary.
What's included in this proposed PR:
set of changes to build both flavors of SDK:
nostd(OpenTelemetry backport of classes for C++11) vsstl(standard library), plus set of tests to validate both side-by-side.set of changes to validate that all OpenTelemetry functionality is functional irrespective of what library you prefer.
aliasing from
nostd::tostd::namespace for compilers C++17 and above.consistent handling of
std::variantacross various versions of Mac OS X. Backport of a view missing variant features, e.g.std::getandstd::visitfor older version of Mac OS X. Patches that enable proper handling ofstd::visitandstd::variantirrespective of OS version to resolve this quirk.ability to optionally borrow implementation of C++20
gsl::spanfrom Microsoft Guidelines Support Library. This will no longer necessary for compilers that already natively support C++20.set of tools to locally build the SDK with both options across various OS and compilers, including vs2017, vs2019, ubuntu-18.xx (C++17), ubuntu-20.xx (C++20), Mac OS X - in C++17 mode.
a few minor 'logistics` clean-up changes, e.g. a few compiler warning fixes.