Skip to content
This repository has been archived by the owner on Jan 26, 2024. It is now read-only.

Support build on Windows with MSVC 15.7 (#85) #93

Merged
merged 6 commits into from
Jun 14, 2018
Merged

Support build on Windows with MSVC 15.7 (#85) #93

merged 6 commits into from
Jun 14, 2018

Conversation

mdouaihy
Copy link
Contributor

  • Export Symbols
  • Add Runtime targets to the install steps. On windows, static libraries are very tricky. shared library is needed.
  • Add some MSVC compile options (_SCL_SECURE_NO_WARNINGS). This warning warns about unsafe methods or usage of the stl.
  • Add appveyor build file. Credits for @hypnoce
  • Add output directory and ignore build folder in git

* Export Symbols
* Add Runtime targets to the install steps
* Fix failing unit test under Windows
* Add some MSVC compile options
* Add appveyor build file
* add output directory and ignore build folder in git
@rnburn
Copy link
Contributor

rnburn commented Jun 11, 2018

Thanks @mdouaihy. I'll get to reviewing this soon.

OPEN_TRACING_EXPORT int OPEN_TRACING_ATT
OpenTracingMakeTracerFactory(
const char* opentracing_version, const void** error_category,
void** tracer_factory);
Copy link
Contributor

Choose a reason for hiding this comment

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

OPEN_TRACING_ATT doesn't expand to anything on windows, right?

Suppose I have two tracing libraries libTracerA, libTracerB, and then I link them both into my app with the intention of switching between them based on a config -- would that give a multiple definition error on windows because both would define OpenTracingMakeTracerFactory ?

The weak attribute was there to support that scenario. Could we maybe use __declspec(selectany) for this?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Indeed, OPEN_TRACING_ATT does not expand to anything on Windows.

if we take your example, why would I link directly with the two tracers? I'd rather use the dynamic loading mechanism to load the implementation, no?

Copy link
Contributor

Choose a reason for hiding this comment

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

I would prefer people use the dynamic loading interface for that as well. But there are a few reasons why they might want to link directly, and it should be a scenario that we support if possible:

  1. You might want all your dependencies linked into the same file so that it's easier to deploy.
  2. You may want to use tracer-specific options that aren't available through the JSON configuration. For example, customized logging or transports where you need to pass in a callback in the options.

Envoy, for example, is an application that links in multiple tracers like this and uses some customizations that wouldn't be available through a JSON configuration interface.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

ok I understand now your point.

Unfortunately, weak symbols are not exposed by MSVC compiler. selectany works only on data items and not on methods.
https://docs.microsoft.com/en-us/cpp/cpp/selectany

However, we can use the /FORCE:MULTIPLE link flag to force the link of the binary even if multiple definitions of a symbol exists
https://docs.microsoft.com/en-us/cpp/build/reference/force-force-file-output

Also, on windows, using dynamic linking, having the same symbols is not a problem.
This last point is important. If we take again the example, linking TracerA and TracerB statically with OT will cause duplication of the symbols of OT, among them the Global Tracer, which is not what we really want.

What do you think?

Copy link
Contributor

Choose a reason for hiding this comment

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

Could you use selectany with a data variable that's a function pointer?

If we take again the example, linking TracerA and TracerB statically with OT will cause duplication of the symbols of OT, among them the Global Tracer, which is not what we really want.

Static libraries are usually built as thin archives (i.e. without the dependent libraries linked in), so there wouldn't be duplication of the OT symbols since OT would be linked in by the app along with the tracing libraries.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

done.


#ifdef _MSC_VER

#define OPEN_TRACING_EXPORT __declspec(dllexport)
Copy link
Contributor

Choose a reason for hiding this comment

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

Could we s/OPEN_TRACING/OPENTRACING/ to keep the naming convention consistent?

reinterpret_cast<decltype(OpenTracingMakeTracerFactory)*>(
GetProcAddress(handle, "OpenTracingMakeTracerFactory"));
if (make_tracer_factory == nullptr) {
error_message = "An error occurred whike looking up for OpenTracingMakeTracerFactory : " + GetLastError();
Copy link
Contributor

Choose a reason for hiding this comment

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

An error occurred whike

typo

@mdouaihy
Copy link
Contributor Author

@rnburn, changes done as per our discussion.

#endif // OPENTRACING_EXPORTS
#endif // OPENTRACING_STATIC

#define OPENTRACING_ATT
Copy link
Contributor

Choose a reason for hiding this comment

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

The OPENTRACING_ATT macro isn't used anywhere now, right? Can we remove?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

yes. removed in the latest commit.

dlsym(handle, "OpenTracingMakeTracerFactory"));
if (make_tracer_factory == nullptr) {
if (make_tracer_factory == nullptr || *make_tracer_factory == nullptr) {
error_message = dlerror();
Copy link
Contributor

Choose a reason for hiding this comment

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

If *make_tracer_factory == nullptr, won't this need a different error message since dlerror wouldn't return anything?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

indeed. you're totally right.

GetProcAddress(handle, "OpenTracingMakeTracerFactory"));

if (make_tracer_factory == nullptr) {
error_message = "An error occurred while looking up for OpenTracingMakeTracerFactory : " + GetLastError();
Copy link
Contributor

Choose a reason for hiding this comment

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

This StackOverflow question says that we need to use FormatMessage along with GetLastError to get a useful message.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Good idea. Change done. an example

Failed to load tracer library. An error occurred: The specified module could not be found.

@rnburn
Copy link
Contributor

rnburn commented Jun 14, 2018

Could we add some brief instructions to README.md for how to install on windows? The current instructions, I think, are unix/linux-specific.

@mdouaihy
Copy link
Contributor Author

sure. Very good idea.

@mdouaihy mdouaihy closed this Jun 14, 2018
@rnburn
Copy link
Contributor

rnburn commented Jun 14, 2018

@mdouaihy - Why'd you close?

@mdouaihy mdouaihy reopened this Jun 14, 2018
@mdouaihy
Copy link
Contributor Author

I didnt do that on purpose. I might have pressed on the wrong button

@mdouaihy
Copy link
Contributor Author

Instructions to generate the Visual Studio solution, to run the build and the tests are added now. Both Release and Debug target are covered.

\
int __attribute((weak)) \
X(const char* opentracing_version, const void** error_category, \
void** tracer_factory); \
Copy link
Contributor

Choose a reason for hiding this comment

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

I don't think we need these declarations:

+__declspec(dllexport) int X(const char* opentracing_version,                \
+                            const void** error_category,                    \
+                            void** tracer_factory);
+  int __attribute((weak))                                                   \
+      X(const char* opentracing_version, const void** error_category,       \
+        void** tracer_factory); 

All that needs to be exposed is the variable OpenTracingMakeTracerFactory. X can be a static function in the translation unit.

Copy link
Contributor Author

@mdouaihy mdouaihy Jun 14, 2018

Choose a reason for hiding this comment

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

This declaration is useful so that

OPENTRACING_DECLARE_IMPL_FACTORY(OpenTracingMakeTracerFactoryFct);

can be declared anywhere in the translation unit.

change done.

@@ -4,7 +4,7 @@
#include <cstring>
#include <exception>

int OpenTracingMakeTracerFactory(const char* opentracing_version,
int OpenTracingMakeTracerFactoryFct(const char* opentracing_version,
Copy link
Contributor

Choose a reason for hiding this comment

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

Can we make OpenTracingMakeTracerFactoryFct static?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Sure.

@rnburn
Copy link
Contributor

rnburn commented Jun 14, 2018

@mdouaihy - This looks good. Was there anything else you wanted to add or should I go ahead and merge in?

@mdouaihy
Copy link
Contributor Author

mdouaihy commented Jun 14, 2018

@rnburn, nothing to add from my side for the moment. Once you merge, please create a version that we update on Hunter to finalize the Jaeger windows build.

Thank you for your time.

@rnburn rnburn merged commit e677ceb into opentracing:master Jun 14, 2018
@rnburn
Copy link
Contributor

rnburn commented Jun 14, 2018

@mdouaihy - I have another PR (#91) that also makes some changes to the dynamic loading API. I'll update it with the changes here, but I'd like to merge that before making the next release.

Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants