Skip to content
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

Fix Shared library export and don't install GTEST #245

Conversation

damiandixon
Copy link
Contributor

@damiandixon damiandixon commented Sep 30, 2022

The shared library export fix is detailed in #244 for non Windows only.

This adds the CLIPPER2_DLL to all classes and methods that are in the headers that have a cpp implementation.

The CMakeLists.txt is updated to ensure that the exports are exported.

The libraries are built so that symbols are hidden unless exported.

Additional updates in CMakeLists.txt:

  • Added a default CMAKE_BUILD_TYPE of release and set the build type options to make it easier to select.
  • Turned off the install of GTEST as it makes no sense to install it.

This leaves the Windows build as a static library.

The default on Linux is a Shared library.

This is a work in progress.

Damian Dixon added 3 commits September 30, 2022 09:41
Build libraries as shared.
Hide classes and methods not exported or fully defined in headers
Set default build to Release
@damiandixon damiandixon mentioned this pull request Sep 30, 2022
@lederernc
Copy link
Contributor

lederernc commented Sep 30, 2022

To get around the issue with the current build you will need to either disable the C4251 warning or prohibit the windows build from building a shared library.

To disable the C4251 warning you will need to sprinkle code like this throughout the code base inside class/struct declarations:

#pragma warning(push)
#pragma warning(disable : 4251)  // dllexport warning
...
#pragma warning(pop)

Here is a diff that fixes it:

git diff --staged
diff --git a/CPP/Clipper2Lib/clipper.engine.h b/CPP/Clipper2Lib/clipper.engine.h
index 5d28baa..5d3d647 100644
--- a/CPP/Clipper2Lib/clipper.engine.h
+++ b/CPP/Clipper2Lib/clipper.engine.h
@@ -20,6 +20,8 @@
 #include <functional>
 #include "clipper.core.h"

+#pragma warning(push)
+#pragma warning(disable : 4251)  // dllexport warning
 namespace Clipper2Lib {

        struct Scanline;
@@ -498,5 +500,6 @@ namespace Clipper2Lib {
        };

 }  // namespace
+#pragma warning(pop)

 #endif  // clipper_engine_h
diff --git a/CPP/Clipper2Lib/clipper.offset.h b/CPP/Clipper2Lib/clipper.offset.h
index d5399b4..1f91081 100644
--- a/CPP/Clipper2Lib/clipper.offset.h
+++ b/CPP/Clipper2Lib/clipper.offset.h
@@ -13,6 +13,8 @@

 #include "clipper.core.h"

+#pragma warning(push)
+#pragma warning(disable : 4251)  // dllexport warning
 namespace Clipper2Lib {

 enum class JoinType { Square, Round, Miter };
@@ -105,4 +107,6 @@ public:
 };

 }
+#pragma warning(pop)
+
 #endif /* CLIPPER_OFFSET_H_ */

@@ -11,12 +11,27 @@ option(CLIPPER2_UTILS "Build utilities" ON)
option(CLIPPER2_EXAMPLES "Build examples" ON)
option(CLIPPER2_TESTS "Build tests" ON)

set(CMAKE_CONFIGURATION_TYPES "Debug;Release;RelWithDebInfo" CACHE STRING "Configs" FORCE)
Copy link

Choose a reason for hiding this comment

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

Please don't force the value of this variable, as this can disrupt projects including Clipper2 as a subproject.

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

@@ -11,12 +11,27 @@ option(CLIPPER2_UTILS "Build utilities" ON)
option(CLIPPER2_EXAMPLES "Build examples" ON)
option(CLIPPER2_TESTS "Build tests" ON)

set(CMAKE_CONFIGURATION_TYPES "Debug;Release;RelWithDebInfo" CACHE STRING "Configs" FORCE)
if(DEFINED CMAKE_BUILD_TYPE)
SET_PROPERTY(CACHE CMAKE_BUILD_TYPE PROPERTY STRINGS ${CMAKE_CONFIGURATION_TYPES})
Copy link

Choose a reason for hiding this comment

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

Use lowercase.

@@ -25,17 +40,27 @@ set(CLIPPER2_SRC
)

# 2d version of Clipper2
add_library(Clipper2 STATIC ${CLIPPER2_INC} ${CLIPPER2_SRC})

add_library(Clipper2 SHARED ${CLIPPER2_INC} ${CLIPPER2_SRC})
Copy link

Choose a reason for hiding this comment

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

It is preferable to omit SHARED or STATIC altogether and let CMake generate a static/shared library based on the value of the BUILD_SHARED option (set by the user).

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

* License : http://www.boost.org/LICENSE_1_0.txt *
*******************************************************************************/

#ifndef CLIPPER2_DLL
Copy link

Choose a reason for hiding this comment

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

Consider using https://cmake.org/cmake/help/latest/module/GenerateExportHeader.html rather than defining this by hand (provides flexibility for both static/shared libs with the same CMake target).

Copy link
Contributor Author

Choose a reason for hiding this comment

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

I was not aware of this. Tx.

@AngusJohnson
Copy link
Owner

This adds the CLIPPER2_DLL to all classes and methods that are in the headers that have a cpp implementation.

I'm wondering if exporting classes is the best approach for DLLs?
Would it not be better/safer to add additional (admittedly more complex) functions that encapsulate these classes; functions that provide the full feature set of these classes?

@damiandixon
Copy link
Contributor Author

This adds the CLIPPER2_DLL to all classes and methods that are in the headers that have a cpp implementation.

I'm wondering if exporting classes is the best approach for DLLs? Would it not be better/safer to add additional (admittedly more complex) functions that encapsulate these classes; functions that provide the full feature set of these classes?

Personally, I would prefer to keep the classes. All shared libraries in C++ bump into this in one form or another.

@AngusJohnson
Copy link
Owner

Personally, I would prefer to keep the classes. All shared libraries in C++ bump into this in one form or another.

I appreciate that exporting C++ classes may be very useful in Linux, but ISTM that it's discouraged in Windows.
And is this approach really better than providing a small set of exported functions that will do everything that's done by these classes?

# define CLIPPER2_DLL
# else
# if __GNUC__ >= 4
# define CLIPPER2_DLL __attribute__((visibility("default")))
Copy link

@SpaceIm SpaceIm Oct 17, 2022

Choose a reason for hiding this comment

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

CLIPPER2_DLL is a misleading name, since it's designed to be cross-platform. Usually it's called <LIB>_API or <LIB>_EXPORT

Copy link
Owner

@AngusJohnson AngusJohnson Oct 17, 2022

Choose a reason for hiding this comment

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

I'd be happy to rename it CLIPPER2_EXPORT if there's concensus with that.
Edit: And presumably the file would be clipper.export.h .

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.

5 participants