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

cmake changes #1048

Merged
merged 50 commits into from
Nov 17, 2024
Merged

cmake changes #1048

merged 50 commits into from
Nov 17, 2024

Conversation

pca006132
Copy link
Collaborator

I was looking at the changes required to better support including this project as a subdirectory in a cmake project, and went down the rabbit hole of changing stuff...

This PR is very radical, and I do not expect everything to be merged as-is. This is mostly for testing in the CI as well as gather some feedback from the users.

@starseeker @kintel will be nice if you can provide some feedback. I will comment on things that are a bit more interesting than moving things around.

@@ -31,20 +34,6 @@ set(
"${MANIFOLD_VERSION_MAJOR}.${MANIFOLD_VERSION_MINOR}.${MANIFOLD_VERSION_PATCH}"
)

# Correct MANIFOLD_PAR values to on/off (previous NONE/TBB values should still
Copy link
Collaborator Author

Choose a reason for hiding this comment

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

We will be having a new release, so better remove the compatibility code here and start fresh.

CMakeLists.txt Outdated
@@ -111,34 +96,23 @@ if(MANIFOLD_FUZZ)
# enable fuzztest fuzzing mode
set(FUZZTEST_FUZZING_MODE ON)
# address sanitizer required
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -fsanitize=address")
add_compile_options("-fsanitize=address")
Copy link
Collaborator Author

Choose a reason for hiding this comment

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

I think using add_compile_options has the same effect as modifying CMAKE_CXX_FLAGS? And this looks cleaner.

CMakeLists.txt Outdated
endif()

if(EMSCRIPTEN)
message("Building for Emscripten")
add_link_options("-s ALLOW_MEMORY_GROWTH=1")
Copy link
Collaborator Author

Choose a reason for hiding this comment

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

Similarly, add_link_options seems to be cleaner than using CMAKE_EXE_LINKER_FLAGS.

if(CMAKE_SYSTEM_NAME STREQUAL "Windows")
if(CMAKE_CXX_COMPILER_ID STREQUAL "GNU")
list(APPEND WARNING_FLAGS -Wno-format)
endif()
else()
elseif(PROJECT_IS_TOP_LEVEL)
Copy link
Collaborator Author

Choose a reason for hiding this comment

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

We only do -Werror when we are not the top level project.

@@ -7,13 +20,15 @@ include_directories(

add_library(
manifoldc
SHARED
Copy link
Collaborator Author

Choose a reason for hiding this comment

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

I'm thinking maybe rust users will want to build the library statically and link it, so we shouldn't force this as a shared library.

manifoldc.cpp
conv.cpp
box.cpp
cross.cpp
rect.cpp
)
add_library(manifold::manifoldc ALIAS manifoldc)
Copy link
Collaborator Author

Choose a reason for hiding this comment

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

Namespace alias so users can just do manifold::manifold/manifold::manifoldc when they use our library, regardless of whether it is a system install or subdirectory.

)
target_compile_options(manifoldc PRIVATE ${MANIFOLD_FLAGS})
target_compile_features(manifoldc PRIVATE cxx_std_17)
Copy link
Collaborator Author

Choose a reason for hiding this comment

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

Because we have the global CMAKE_CXX_STANDARD, this is now redundant.

include(FetchContent)
logmissingdep("nanobind" , "MANIFOLD_PYBIND")
Copy link
Collaborator Author

Choose a reason for hiding this comment

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

Make sure we will not do download when MANIFOLD_DOWNLOAD is disabled.

Copy link
Collaborator Author

Choose a reason for hiding this comment

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

and I thought of moving this to cmake/manifoldDeps.cmake, but not sure if that is the best thing to do...

set(
MANIFOLD_INCLUDE_DIRS
${PROJECT_SOURCE_DIR}/include
$<$<BOOL:${TBB_INCLUDE_DIRS}>:${TBB_INCLUDE_DIRS}>
Copy link
Collaborator Author

Choose a reason for hiding this comment

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

This now uses generator expressions to reduce the number of lines. Not sure if this is what everyone likes, but I feel this is now somewhat easier to read.

Copy link

codecov bot commented Nov 16, 2024

Codecov Report

All modified and coverable lines are covered by tests ✅

Project coverage is 84.69%. Comparing base (d437097) to head (5979b06).
Report is 156 commits behind head on master.

Additional details and impacted files
@@            Coverage Diff             @@
##           master    #1048      +/-   ##
==========================================
- Coverage   91.84%   84.69%   -7.15%     
==========================================
  Files          37       62      +25     
  Lines        4976     9685    +4709     
  Branches        0     1050    +1050     
==========================================
+ Hits         4570     8203    +3633     
- Misses        406     1482    +1076     

☔ View full report in Codecov by Sentry.
📢 Have feedback on the report? Share it here.

@elalish
Copy link
Owner

elalish commented Nov 16, 2024

This looks like the last PR for v3.0 - agreed? I don't know enough CMake to review this one particularly, but it certainly looks to be going in a good direction. How much feedback do you want to wait for before we merge? And after all the commits, do you still feel this is a preliminary attempt?

@pca006132
Copy link
Collaborator Author

Changes here are mostly internal, except the target alias that is already covered by #1049. I also changed MANIFOLD_CBIND a bit to allow it to build as a static library, which rust users may be interested in. But again this can be moved to a separate PR, and that is not related to system library anyway, so missing a release is fine.

Also, this includes things from #1045, which is probably not that ready for a release. I am fine for merging this after v3.0, and get some feedback from the users, who have more experience working with cmake than I do.

@pca006132
Copy link
Collaborator Author

pca006132 commented Nov 16, 2024

And I feel like merging a 1.5k line refactor a few days before a major version release is a bit too risky for my liking :P

(Though technically the changes are quite trivial.)

Comment on lines +143 to +150
list(
APPEND
WARNING_FLAGS
-Wall
-Wno-unknown-warning-option
-Wno-unused
-Wno-shorten-64-to-32
)
Copy link
Contributor

@kintel kintel Nov 16, 2024

Choose a reason for hiding this comment

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

Are these compiler flags now supported across all supported versions of (gcc and clang) compilers?

Copy link
Collaborator Author

Choose a reason for hiding this comment

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

I think the most important flag is -Wno-unknown-warning-option, it allows us to use some other warning options not supported by the compiler. We should check when gcc and clang supports this...

Copy link
Collaborator Author

Choose a reason for hiding this comment

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

This seems to be a clang only flag, which is supported at least 13 years ago (https://bugzilla.mozilla.org/show_bug.cgi?id=731316).

GCC will not complain about unknown warning options anyway:

When an unrecognized warning option is requested (e.g., -Wunknown-warning), GCC emits a diagnostic stating that the option is not recognized. However, if the -Wno- form is used, the behavior is slightly different: no diagnostic is produced for -Wno-unknown-warning unless other diagnostics are being produced. This allows the use of new -Wno- options with old compilers, but if something goes wrong, the compiler warns that an unrecognized option is present.

These flags should be fine.

@kintel
Copy link
Contributor

kintel commented Nov 16, 2024

One think that I'm uncertain how to deal with:

  1. Build and install manifold using the built-in clipper
  2. Update the version of the built-in clipper
  3. Build and reinstall manifold -> it will pick up the clipper from the previous installation instead of using the built-in one

This can be solved by never using builtins, but it feels wrong the way it's done today. Not sure how easy it is to work around this, either from within manifold or inside the target build environment.

Copy link
Owner

@elalish elalish left a comment

Choose a reason for hiding this comment

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

So, it looks like we want to merge this for v3.0 - but I have a few questions first:

bindings/wasm/bindings.js Outdated Show resolved Hide resolved
cmake/manifoldDeps.cmake Show resolved Hide resolved
src/parallel.h Outdated
Copy link
Owner

Choose a reason for hiding this comment

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

I thought you had put this in include so OpenSCAD could use our parallel functions. Did something change?

Copy link
Collaborator Author

Choose a reason for hiding this comment

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

Yes this was the plan, but later I found that I can just use tbb functions directly there. Having this as a public header will require us to make tbb a public dependency, which is problematic when we build the fetched dependency as a static library...

Copy link
Owner

Choose a reason for hiding this comment

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

Okay, sounds good to me - the less in our public includes the better, as far as I'm concerned.

Copy link
Contributor

Choose a reason for hiding this comment

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

I wasn't plugged in this weekend, so it's too late for 3.0, but IIRC iters.h was only public in the headers for parallel.h so as long as that's still true we can make that header private too for the next round.

@pca006132
Copy link
Collaborator Author

I cannot speak for other platforms, but the nice thing to do when building for macOS is to set LC_ID_DYLIB to @rpath/libmanifold.2.dylib, which seems to be the case for manifold (I assume that's what modern CMake does). This will make the library resolve to whatever rpath the application sets up, which in the case of macOS is typically either a package manager like Homebrew, or bundled libraries (which OpenSCAD does).

Would be great if someone with mac can check if our build already does that. @elalish @kintel

@elalish
Copy link
Owner

elalish commented Nov 17, 2024

I have a mac, but I'm not sure what to check. Also, I'm going to bed.

@pca006132
Copy link
Collaborator Author

@hzeller I moved the version.h.in into cmake directory (not sure if it is the right place for this kind of things), as well as modified the build interface include path of manifold target to include ${PROJECT_BINARY_DIR}/include, so the generated version.h can be referenced regardless of whether the library is used from a subdirectory or as an installed library.

@pca006132
Copy link
Collaborator Author

@elalish I guess we can wait for kintel to test that :)

@hzeller
Copy link
Contributor

hzeller commented Nov 17, 2024

@hzeller I moved the version.h.in into cmake directory (not sure if it is the right place for this kind of things), as well as modified the build interface include path of manifold target to include ${PROJECT_BINARY_DIR}/include, so the generated version.h can be referenced regardless of whether the library is used from a subdirectory or as an installed library.

SGTM, thanks!

Copy link
Owner

@elalish elalish left a comment

Choose a reason for hiding this comment

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

LGTM, though I'm no CMake expert. I'll go update our required tests so merging isn't blocked.

# library conflict.
# When the system package is unavailable, the option will be automatically set
# to true.
option(MANIFOLD_USE_BUILTIN_TBB "Use builtin tbb" OFF)
Copy link
Collaborator Author

Choose a reason for hiding this comment

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

Users can choose not to use the system version of the dependencies. I saw this in the openscad wishlist, so I added it.

@pca006132
Copy link
Collaborator Author

Exported library and binary files are now placed under lib/Release and bin/Release respectively under msvc, i.e. manifold.lib, manifoldc.lib, manifold_test.exe and various executables under extras.

Configuration info is now logging the full set of compile and link options for manifold for better debugging...

@kintel
Copy link
Contributor

kintel commented Nov 17, 2024

Would be great if someone with mac can check if our build already does that. @elalish @kintel

Look good from here,
I have TBB installed on the system but not Clipper:

$  cmake -DCMAKE_INSTALL_PREFIX=install -DCMAKE_OSX_DEPLOYMENT_TARGET=10.15 -DCMAKE_OSX_ARCHITECTURES="x86_64 arm64" -DMANIFOLD_CBIND=OFF -DMANIFOLD_TEST=OFF -DMANIFOLD_PAR=ON ..
$  make install
otool -L install/lib/libmanifold.dylib
install/lib/libmanifold.dylib (architecture x86_64):
	@rpath/libmanifold.2.dylib (compatibility version 2.0.0, current version 2.5.1)
	@rpath/libtbb.12.dylib (compatibility version 12.0.0, current version 12.12.0)
	/usr/lib/libSystem.B.dylib (compatibility version 1.0.0, current version 1336.61.1)
	/usr/lib/libc++.1.dylib (compatibility version 1.0.0, current version 1600.157.0)
install/lib/libmanifold.dylib (architecture arm64):
	@rpath/libmanifold.2.dylib (compatibility version 2.0.0, current version 2.5.1)
	@rpath/libtbb.12.dylib (compatibility version 12.0.0, current version 12.12.0)
	/usr/lib/libSystem.B.dylib (compatibility version 1.0.0, current version 1336.61.1)
	/usr/lib/libc++.1.dylib (compatibility version 1.0.0, current version 1600.157.0)

@pca006132
Copy link
Collaborator Author

I think this should be ready to merge?


#define MANIFOLD_VERSION_MAJOR @MANIFOLD_VERSION_MAJOR@
#define MANIFOLD_VERSION_MINOR @MANIFOLD_VERSION_MINOR@
#define MANIFOLD_VERSION_PATH @MANIFOLD_VERSION_PATCH@
Copy link
Contributor

Choose a reason for hiding this comment

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

Typo: PATH -> PATCH

Copy link
Contributor

Choose a reason for hiding this comment

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

Ups, I take full responsibility for that typo...

@kintel
Copy link
Contributor

kintel commented Nov 17, 2024

Re. compile time version. It could be nice with a single integer version number in addition. I can find examples from other libs if needed for inspiration

@hzeller
Copy link
Contributor

hzeller commented Nov 17, 2024

I think this should be merged soon, as it is getting big and allows folks to easier play with it, and final polish-ups can be done in a follow-up.

@kintel
Copy link
Contributor

kintel commented Nov 17, 2024

Re. compile time version. It could be nice with a single integer version number in addition. I can find examples from other libs if needed for inspiration

Examples (all taken from the OpenSCAD codebase):

#if CGAL_VERSION_NR < CGAL_VERSION_NUMBER(5, 4, 0)

#if QT_VERSION < QT_VERSION_CHECK(6, 0, 0)

#if QSCINTILLA_VERSION >= 0x020b00

#if MPFR_VERSION < MPFR_VERSION_NUM(3, 0, 0)

#if SYS_GMP_VER < GMPMAJOR * 10000 + GMPMINOR * 100 + GMPPATCH * 1

#if CAIRO_VERSION >= CAIRO_VERSION_ENCODE(1, 16, 0)

#if EIGEN_VERSION_AT_LEAST(3,4,0)

@elalish
Copy link
Owner

elalish commented Nov 17, 2024

Okay, I fixed the typo, so I'm going to go ahead and merge this. I'm not quite sure how you want a single version number int exposed, so I'll wait for a PR from @kintel or @hzeller for that. When it sounds like things have settled, I'll cut v3.0. Please let me know - I'd like to avoid an immediate 3.0.1 if possible.

@elalish elalish merged commit 7f298aa into elalish:master Nov 17, 2024
23 checks passed
@hzeller
Copy link
Contributor

hzeller commented Nov 17, 2024

I have put the comparable version number suggestion in #1054

@pca006132 pca006132 deleted the cmake-refactor branch November 18, 2024 03:22
if(MANIFOLD_EXPORT)
list(APPEND MANIFOLD_PUBLIC_HDRS include/manifold/meshIO.h)
endif()
list(TRANSFORM MANIFOLD_PUBLIC_HDRS PREPEND include/manifold/)
Copy link
Contributor

Choose a reason for hiding this comment

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

Slick! That's a new one for me.

${PROJECT_SOURCE_DIR}/src/sort.cpp
${PROJECT_SOURCE_DIR}/src/cross_section/cross_section.cpp
${PROJECT_SOURCE_DIR}/src/polygon.cpp
${PROJECT_SOURCE_DIR}/include/manifold/common.h
Copy link
Contributor

Choose a reason for hiding this comment

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

Ah, good catch. Using CMAKE_SOURCE_DIR is a habit I have left from the old days, looks like PROJECT_SOURCE_DIR is probably what one would want most of the time.

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