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

Shared library #243

Merged
merged 4 commits into from
Sep 30, 2022
Merged

Shared library #243

merged 4 commits into from
Sep 30, 2022

Conversation

sergey-239
Copy link
Contributor

Angus,

please review the last change of the last commit in this PR: I hope I got the original intent properly

Thank you,
Sergey

@AngusJohnson
Copy link
Owner

AngusJohnson commented Sep 29, 2022

Thanks Sergey. I'm not doubting your changes but since I'm not competent to critique them, I'm hoping someone who's already contributed to Clipper2's makefile (@lederernc, @reunanen & @damiandixon) will have a quick look before I commit. Cheers.

@sergey-239
Copy link
Contributor Author

Thanks Sergey. I'm not doubting your changes but since I'm not competent to critique them, I'm hoping someone who's already contributed to Clipper2's makefile (@lederernc, @reunanen & @damiandixon) to have a quick look before I commit. Cheers.

this is fine with me.

Regards,
Sergey

@sergey-239
Copy link
Contributor Author

The Fedora package build result could be seen here:
https://copr.fedorainfracloud.org/coprs/snmende/libClipper2/build/4878266/

@@ -25,21 +28,19 @@ set(CLIPPER2_SRC
)

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

Choose a reason for hiding this comment

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

Removing the STATIC is a good idea, but for some IDE (like Visual Studio), it's nice to add the include files to the library sources (the PUBLIC_HEADER property is only relevant for installing targets on macOS).

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Does VS use cmake files nowadays?
No, not a problem for me to bring the header lists back to add_libray's, I'm just curious

Copy link

@jdumas jdumas Sep 29, 2022

Choose a reason for hiding this comment

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

Yes you can, but I generally let CMake generate the Visual Studio project for me. When header files are properly listed in the target sources they show us along with other .cpp. Otherwise they get mixed up with system headers and such.

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 see now.

Copy link
Contributor

@lederernc lederernc Sep 29, 2022

Choose a reason for hiding this comment

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

Clipper2 will not compile as a DLL with all the appropriate warning flags as errors in Visual Studio. This is because the library needs to export classes that contain std::vector which is "not a good idea" on Windows.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

@lederernc, then we could make this conditionally disabled for WIN32 builds.

DESTINATION include
FILES_MATCHING PATTERN "*.h"
install(TARGETS Clipper2 Clipper2Z
PUBLIC_HEADER DESTINATION ${CMAKE_INSTALL_INCLUDEDIR}/clipper2
Copy link

Choose a reason for hiding this comment

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

This change will solve #232 when an installed version of clipper2 is used, but it will not do anything when clipper2 is used as a subproject (e.g. via FetchContent + add_subdirectory()).

@@ -64,7 +64,7 @@ class BMH_Search
{
while (current < end)
{
uint8_t i = shift[*current]; //compare last byte first
uint8_t i = shift[(unsigned)*current]; //compare last byte first
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 more C++-y typecasting, e.g. static_cast<unsigned>(*current).

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 also prefer more modern typecasting

@AngusJohnson
Copy link
Owner

Thanks everyone for all the helpful feedback.
Sergey, would you be happy to revise this PR to accommodate this feedback or create a new PR? Cheers.

@sergey-239
Copy link
Contributor Author

sergey-239 commented Sep 30, 2022

Angus, yes, I could do this. We just need to define the new directory structure as @jdumas pointed scenarios where it is important. How about this:

CPP/Clipper2Lib
├── include
│   └── clipper2
└── src

These three new are subdirs of Clipper2Lib

@AngusJohnson
Copy link
Owner

CPP/Clipper2Lib
            ├── include
            │       └── clipper2
            └── src

I'm presuming that we're just talking about the files that are currently in Clipper2Lib.
I'm also presuming that the .h files go in include and the .cpp files into src.
But I don't understand why you need a subdirectory under include?

@sergey-239
Copy link
Contributor Author

sergey-239 commented Sep 30, 2022

Angus,
it is because you would put the <clipper2/clipper.h>, for example, into #include directive. To let the compiler treat this properly you should use the path to a directory that contains the clipper2 directory as argument of the -I compiler option: e.g.:
gcc mytest,cpp -I ./Clipper2Lib/include
So, when the headers installed into the system include directory the same source file compiles with just default compiler includes search path.
Probably, we could leave the source files in the Clipper2Lib, create one subdirectory clipper2 under it and move headers into it. But then, the Clipper2Lib would be searchable for include files during build of library itself, tools and tests.
I see the latter solution as a possible source of compilation problems, but it might be that my approach is an overkill.
Any way, it is completely up to you to decide.

Thank you
Sergey

@AngusJohnson
Copy link
Owner

AngusJohnson commented Sep 30, 2022

it is because you would put the <clipper2/clipper.h>, for example, into #include directive.

OK, I think I get what you're suggesting now.

CPP/Clipper2Lib
            ├── include
            │       │ 
            │       └── clipper2
            │               clipper.h
            │               clipper.core.h
            │               clipper.engine.h
            │               clipper.offset.h
            │               clipper.minkowski.h
            └── src
                  clipper.engine.cpp
                  clipper.offset.cpp

I don't really follow why/how this structure helps, but I'm very happy to go with it and trust you and others who have a much better understanding of C++.

@sergey-239
Copy link
Contributor Author

Yes, exactly.
I'll give a time to others to comment.
Thanks you

@AngusJohnson
Copy link
Owner

Yes, exactly.
I'll give a time to others to comment.

Great. Thanks.
And just for my education ... why is the clipper2 subdirectory of include helpful?
Is it simply that a raw #include "clipper.h" (ie without a preceding directory) would imply a core library?

@sergey-239
Copy link
Contributor Author

sergey-239 commented Sep 30, 2022

It's useful because you might have a few projects under development, part of which depends on Clipper1 and the other part on Clipper2 library.
For example,

rpm -ql polyclipping-devel-6.4.2-14.fc36.x86_64
/usr/include/polyclipping
/usr/include/polyclipping/agg_conv_clipper.h
/usr/include/polyclipping/clipper.hpp
/usr/lib64/libpolyclipping.so

your original clipper library packaged for Fedora with this directory layout as there were no established one.

Now you may define that Clipper2 include files are in clipper2 subfolder of the standard include path, so when your new library would spread over different unix flavours, it will be common to use #include <clipper2/clipper.h> or whatever include file you would provide in the course of lib development. Of course, you could encode the lib "generation" number into file names but this is usually less convenient.

By the way I have one project I would like to package for Fedora, that uses some strange version of clipper that I can't identify:

ClipperBase.cpp
ClipperBase.h
Clipper.cpp
Clipper.h
Enum.h
Exception.h
Int128.cpp
Int128.h
IntersectNode.cpp
IntersectNode.h
IntPoint.cpp
IntPoint.h
OffsetBuilder.cpp
OffsetBuilder.h
OutPt.cpp
OutPt.h
OutRec.cpp
OutRec.h
Polygon.cpp
Polygon.h
Polygons.cpp
Polygons.h
PolyNode.cpp
PolyNode.h
PolyTree.cpp
PolyTree.h
TEdge.cpp
TEdge.h
Util.h

All these files copyrighted by you and have version 5.1.6
Curious?

@AngusJohnson
Copy link
Owner

It's useful because you might have a few projects under development, part of which depends on Clipper1 and the other part on Clipper2 library.

OK. That does make sense.

By the way I have one project I would like to package for Fedora, that uses some strange version of clipper that I can't identify:

It looks like someone (not me) split my very large clipper.hpp and clipper.cpp files into lots of smaller ones.
I see advantages and disadvantages to this but lots of little files seems more common in C++.

@@ -10,6 +10,7 @@ set_property(GLOBAL PROPERTY USE_FOLDERS ON)
option(CLIPPER2_UTILS "Build utilities" ON)
option(CLIPPER2_EXAMPLES "Build examples" ON)
option(CLIPPER2_TESTS "Build tests" ON)
option(BUILD_SHARED_LIBS "Build shared libs" OFF)
Copy link
Contributor

@damiandixon damiandixon Sep 30, 2022

Choose a reason for hiding this comment

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

I would suggest shared library is on by default.

The original cmake was to build a shared library but was changed in #169 to static.

Copy link
Contributor

Choose a reason for hiding this comment

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

The DLL export on Windows requires the classes and methods to be exported using:

#ifndef CLIPPER2_DLL
#  if defined(_WIN32)
#    ifdef CLIPPER2_DLL_EXPORT
#      define CLIPPER2_DLL __declspec(dllexport)
#    else
#      define CLIPPER2_DLL __declspec(dllimport)
#    endif
#  else
#    if __GNUC__ >= 4
#      define CLIPPER2_DLL __attribute__((visibility("default")))
#    else
#      define CLIPPER2_DLL
#    endif
#  endif
#endif

With classes defined:

class CLIPPER2_DLL Clipper2Class ....

When building the Define CLIPPER2_DLL_EXPORT is declared.

Probably should be a separate issue.

Copy link
Contributor

Choose a reason for hiding this comment

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

Raised #244 for exporting symbols in a shared library.

Copy link
Contributor

@damiandixon damiandixon Sep 30, 2022

Choose a reason for hiding this comment

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

I've done a pull request #245 dealing with shared libraries

@AngusJohnson
Copy link
Owner

OK, I really do appreciate all the advice that flowing in re C++ packaging. Unfortunately however, I'm not experienced enough in C++ to sensibly navigate all the proposed changes. Sergey or Damian, would either of you be happy to coordinate this current flurry of activity re C++ packaging? If so, that'd be a very big help.

@damiandixon
Copy link
Contributor

damiandixon commented Sep 30, 2022

OK, I really do appreciate all the advice that flowing in re C++ packaging. Unfortunately however, I'm not experienced enough in C++ to sensibly navigate all the proposed changes. Sergey or Damian, would either of you be happy to coordinate this current flurry of activity re C++ packaging? If so, that'd be a very big help.

I don't have an issue with the changes here as they move things in the right direction. TBH I'm no expert on cmake either, as I'm stumped as to how to deal with #243 (comment) as I normally use submodules with git.

There are issues around shared libraries and Windows builds that I'm looking at on pull request #245, though I suspect #243 (comment) may mean a shared library on Windows is difficult or a non-starter. I would suggest using the simplest approach to shared libraries for Linux and stick to static on Windows for this update.

@sergey-239
Copy link
Contributor Author

OK, I really do appreciate all the advice that flowing in re C++ packaging. Unfortunately however, I'm not experienced enough in C++ to sensibly navigate all the proposed changes. Sergey or Damian, would either of you be happy to coordinate this current flurry of activity re C++ packaging? If so, that'd be a very big help.

I don't have an issue with the changes here as they move things in the right direction. TBH I'm no expert on cmake either, as I'm stumped as to how to deal with #243 (comment) as I normally use submodules with git.

There are issues around shared libraries and Windows builds that I'm looking at on pull request #245, though I suspect #243 (comment) may mean a shared library on Windows is difficult or a non-starter. I would suggest using the simplest approach to shared libraries for Linux and stick to static on Windows for this update.

Ok, then I can redo the patch taking to account discussion above. I don't see an issue with default static build configuration for all platforms: if one need the shared lib then it will be just one option to cmake to get shared versions. Just like me: it's Fedora preference to package separately as much as possible as shared libraries to minimise licensing issues.

@AngusJohnson
Copy link
Owner

Thanks Sergey.

@AngusJohnson AngusJohnson merged commit c9de2eb into AngusJohnson:main Sep 30, 2022
@sergey-239 sergey-239 deleted the shared_library branch October 1, 2022 03:58
@sergey-239 sergey-239 restored the shared_library branch October 1, 2022 04:08
@sergey-239
Copy link
Contributor Author

sergey-239 commented Oct 1, 2022

Angus,

did you merge this pr intentionally?
I meant that I will remake all changes from the point where I branched from main trunk.
Please, clarify

Thank you
Sergey.

@AngusJohnson
Copy link
Owner

AngusJohnson commented Oct 1, 2022

did you merge this pr intentionally?

Sorry, it was late at night and I "jumped the gun" 😱.
Nevertheless, I think it's OK as it is (at least until you're ready to complete).
But if you'd prefer I can revert.

@sergey-239
Copy link
Contributor Author

sergey-239 commented Oct 1, 2022

I am not sure: I actually don't know if github allows to do reset --hard on last commit. If it would do an actual revert, i.e. it will produce a new commit, then no, this would only pollute the commit history even more.
So if it can't do reset --hard HEAD~1 then I manage myself.

@AngusJohnson
Copy link
Owner

Sergey, as you can see, I've just given you temporary collaborator access so feel free to manage this as you think best 😁.

@sergey-239
Copy link
Contributor Author

Found this:

Can you make a positive commit to fix the problem and what is the fix class?

Rewriting public history is a bad idea. It requires everyone else to do special things and you must publicly announce your failure. Ideally you will create either a commit to just fix the problem, or a new git revert commit to create a new commit which undoes what the commit target of the revert did.

So, I will manage myself. No action required.

sergey-239 added a commit to sergey-239/Clipper2 that referenced this pull request Oct 1, 2022
sergey-239 added a commit to sergey-239/Clipper2 that referenced this pull request Oct 1, 2022
damiandixon pushed a commit to damiandixon/Clipper2 that referenced this pull request Oct 1, 2022
* Allow building as a shared lib

* Disable annoying `unused func/var` warnings in utils & tests

* Fix headers installation destination & cleanup of CMakeLists.txt

* BugFix: unsigned char promotes to int by C and C++ standards
BugFix: evaluation order of `*c = case_table[*c++];` expression is undefined
AngusJohnson pushed a commit that referenced this pull request Oct 1, 2022
* Fixes for #243 as per discussion

* Move files as per #243 discussion

* Fix include paths in Examples

* * Replace relative include paths in examples
* Disable unused-(function|result) warning for gcc targets
* Fix some indentation in CMakeLists.txt

* - Add pkgconfig
- Fix test in CMakeLists.txt for actual gcc use
@sergey-239 sergey-239 deleted the shared_library branch October 2, 2022 01:43
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.

6 participants