@@ -12,7 +12,7 @@ set(CMAKE_EXPORT_COMPILE_COMMANDS ON)
1212# Build options
1313option (ENABLE_PRECOMPILED_HEADERS "Enable precompiled headers" ON )
1414option (FAST_COMPILE "Optimize for faster compilation (-O0) vs execution (-O3)" OFF )
15- option (USE_OPENMP "Enable OpenMP support for parallel processing" ON )
15+ option (USE_OPENMP "Enable OpenMP support for parallel processing" OFF )
1616
1717# Apply optimization flags
1818if (FAST_COMPILE)
@@ -24,50 +24,93 @@ endif()
2424# ==============================================================================
2525# Dependencies
2626# ==============================================================================
27+ include (ExternalProject)
2728
29+ # Define source directories for external dependencies
30+ set (EXTERNAL_DIR "${CMAKE_CURRENT_SOURCE_DIR} /external" )
31+ set (EIGEN_INCLUDE_DIR "${EXTERNAL_DIR} /eigen" )
32+
33+ # Create a custom target for all external dependencies
34+ add_custom_target (external_downloads ALL )
35+
36+ # ========================================================================
2837# Setup Eigen
29- set (EIGEN_INCLUDE_DIR ${CMAKE_CURRENT_SOURCE_DIR} /external/eigen)
30- find_package (Eigen3 QUIET )
31- if (NOT Eigen3_FOUND)
32- # Download Eigen if not found
33- if (NOT EXISTS ${EIGEN_INCLUDE_DIR} )
34- message (STATUS "Downloading Eigen..." )
35- file (MAKE_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR} /external)
36- file (DOWNLOAD
37- https://gitlab.com/libeigen/eigen/-/archive/3.4.0/eigen-3.4.0.zip
38- ${CMAKE_CURRENT_SOURCE_DIR} /eigen.zip
39- SHOW_PROGRESS
40- )
41- execute_process (
42- COMMAND ${CMAKE_COMMAND} -E tar xf ${CMAKE_CURRENT_SOURCE_DIR} /eigen.zip
43- WORKING_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR} /external
44- )
45- execute_process (
46- COMMAND ${CMAKE_COMMAND} -E rename
47- ${CMAKE_CURRENT_SOURCE_DIR} /external/eigen-3.4.0
48- ${EIGEN_INCLUDE_DIR}
49- )
50- file (REMOVE ${CMAKE_CURRENT_SOURCE_DIR} /eigen.zip)
51- endif ()
52- set (EIGEN3_INCLUDE_DIRS ${EIGEN_INCLUDE_DIR} )
38+ # ========================================================================
39+ if (NOT EXISTS "${EIGEN_INCLUDE_DIR} " )
40+ message (STATUS "Downloading Eigen..." )
41+ ExternalProject_Add(
42+ eigen_download
43+ URL https://gitlab.com/libeigen/eigen/-/archive/3.4.0/eigen-3.4.0.zip
44+ SOURCE_DIR "${EIGEN_INCLUDE_DIR} "
45+ CONFIGURE_COMMAND ""
46+ BUILD_COMMAND ""
47+ INSTALL_COMMAND ""
48+ LOG_DOWNLOAD ON
49+ UPDATE_COMMAND ""
50+ PATCH_COMMAND ""
51+ TLS_VERIFY ON
52+ )
53+ add_dependencies (external_downloads eigen_download)
5354endif ()
55+ set (EIGEN3_INCLUDE_DIRS "${EIGEN_INCLUDE_DIR} " )
56+
57+ # Print include directories for verification
58+ message (STATUS "============= Dependencies =============" )
59+ message (STATUS "EIGEN INCLUDE DIRECTORY: ${EIGEN_INCLUDE_DIR} " )
60+ message (STATUS "=========================================" )
5461
5562# Find Python and nanobind
5663find_package (Python 3.8 REQUIRED COMPONENTS Interpreter Development.Module)
5764find_package (nanobind CONFIG REQUIRED)
5865find_package (Threads REQUIRED)
5966
60- # Setup OpenMP
67+ # Setup OpenMP - Properly handle macOS and make it optional
6168if (USE_OPENMP)
62- find_package (OpenMP QUIET )
63- if (OpenMP_CXX_FOUND)
64- message (STATUS "OpenMP found - enabling parallel processing" )
65- add_definitions (-DSHAPEOP_OPENMP)
69+ # Check what platform we're on
70+ if (APPLE )
71+ # On macOS, OpenMP might not be available with the default Clang
72+ # Check if we have Homebrew's LLVM/Clang with OpenMP support
73+ find_program (BREW NAMES brew)
74+ if (BREW)
75+ execute_process (
76+ COMMAND ${BREW} --prefix llvm
77+ OUTPUT_VARIABLE LLVM_DIR
78+ OUTPUT_STRIP_TRAILING_WHITESPACE
79+ )
80+ if (LLVM_DIR)
81+ # Use Homebrew's LLVM for OpenMP support
82+ set (OpenMP_CXX_FLAGS "-fopenmp" )
83+ set (OpenMP_CXX_LIB_NAMES "omp" )
84+ set (OpenMP_omp_LIBRARY "${LLVM_DIR} /lib/libomp.dylib" )
85+ message (STATUS "Using Homebrew LLVM for OpenMP support: ${LLVM_DIR} " )
86+ add_definitions (-DSHAPEOP_OPENMP)
87+ else ()
88+ message (STATUS "Homebrew LLVM not found. OpenMP support disabled on macOS." )
89+ set (USE_OPENMP OFF )
90+ endif ()
91+ else ()
92+ message (STATUS "Homebrew not found. OpenMP support disabled on macOS." )
93+ set (USE_OPENMP OFF )
94+ endif ()
6695 else ()
67- message (STATUS "OpenMP not found - parallel processing disabled" )
96+ # For non-macOS platforms, use standard FindOpenMP
97+ find_package (OpenMP QUIET )
98+ if (OpenMP_CXX_FOUND)
99+ message (STATUS "OpenMP found - enabling parallel processing" )
100+ add_definitions (-DSHAPEOP_OPENMP)
101+ else ()
102+ message (STATUS "OpenMP not found - parallel processing disabled" )
103+ set (USE_OPENMP OFF )
104+ endif ()
68105 endif ()
69106endif ()
70107
108+ # Add include directories
109+ include_directories (
110+ ${CMAKE_CURRENT_SOURCE_DIR} /src
111+ ${EIGEN3_INCLUDE_DIRS}
112+ )
113+
71114# ==============================================================================
72115# ShapeOp library
73116# ==============================================================================
@@ -87,16 +130,23 @@ add_library(shapeop STATIC
87130 ${SHAPEOP_SRC_DIR} /custom_constraints/NormalForce.cpp
88131)
89132
90- target_include_directories (shapeop PUBLIC
91- ${CMAKE_CURRENT_SOURCE_DIR} /src
92- ${EIGEN3_INCLUDE_DIRS}
93- )
133+ # Make shapeop depend on the external downloads
134+ add_dependencies (shapeop external_downloads)
94135
95136target_compile_options (shapeop PRIVATE -fPIC)
96137target_compile_definitions (shapeop PUBLIC SHAPEOP_EXPORT)
97- if (OpenMP_CXX_FOUND)
98- target_compile_options (shapeop PUBLIC ${OpenMP_CXX_FLAGS} )
99- target_link_libraries (shapeop PUBLIC ${OpenMP_CXX_LIBRARIES} )
138+
139+ # Apply OpenMP flags only if enabled and available
140+ if (USE_OPENMP)
141+ if (DEFINED OpenMP_CXX_FLAGS)
142+ target_compile_options (shapeop PUBLIC ${OpenMP_CXX_FLAGS} )
143+ if (DEFINED OpenMP_CXX_LIBRARIES)
144+ target_link_libraries (shapeop PUBLIC ${OpenMP_CXX_LIBRARIES} )
145+ endif ()
146+ if (APPLE AND DEFINED OpenMP_omp_LIBRARY)
147+ target_link_libraries (shapeop PUBLIC ${OpenMP_omp_LIBRARY} )
148+ endif ()
149+ endif ()
100150endif ()
101151
102152# ==============================================================================
@@ -117,26 +167,47 @@ endif()
117167# Python module
118168# ==============================================================================
119169
120- # Add the Solver Python module
121- nanobind_add_module(
122- _shapeop
123- STABLE_ABI
124- NB_STATIC
125- src/shapeop.cpp
126- )
170+ # Function to add a nanobind module with include directories
171+ function (add_nanobind_module module_name source_file)
172+ nanobind_add_module(
173+ ${module_name}
174+ STABLE_ABI
175+ NB_STATIC
176+ ${source_file}
177+ )
127178
128- target_include_directories (_shapeop PRIVATE
129- ${CMAKE_CURRENT_SOURCE_DIR} /src
130- ${EIGEN3_INCLUDE_DIRS}
131- ${nanobind_INCLUDE_DIRS}
132- )
179+ target_include_directories (${module_name} PRIVATE
180+ ${CMAKE_CURRENT_SOURCE_DIR} /src
181+ ${EIGEN3_INCLUDE_DIRS}
182+ ${nanobind_INCLUDE_DIRS}
183+ )
133184
134- target_link_libraries (_shapeop PRIVATE shapeop)
135- if (ENABLE_PRECOMPILED_HEADERS)
136- target_link_libraries (_shapeop PRIVATE compas_pch)
137- endif ()
185+ # Make module depend on the external downloads
186+ add_dependencies (${module_name} external_downloads)
187+
188+ # Apply OpenMP flags only if enabled and available
189+ if (USE_OPENMP)
190+ if (DEFINED OpenMP_CXX_FLAGS)
191+ target_compile_options (${module_name} PRIVATE ${OpenMP_CXX_FLAGS} )
192+ if (DEFINED OpenMP_CXX_LIBRARIES)
193+ target_link_libraries (${module_name} PRIVATE ${OpenMP_CXX_LIBRARIES} )
194+ endif ()
195+ if (APPLE AND DEFINED OpenMP_omp_LIBRARY)
196+ target_link_libraries (${module_name} PRIVATE ${OpenMP_omp_LIBRARY} )
197+ endif ()
198+ endif ()
199+ endif ()
138200
139- install (TARGETS _shapeop LIBRARY DESTINATION compas_shapeop)
201+ if (ENABLE_PRECOMPILED_HEADERS)
202+ target_link_libraries (${module_name} PRIVATE compas_pch)
203+ endif ()
204+
205+ install (TARGETS ${module_name} LIBRARY DESTINATION compas_shapeop)
206+ endfunction ()
207+
208+ # Add ShapeOp module
209+ add_nanobind_module(_shapeop src/shapeop.cpp)
210+ target_link_libraries (_shapeop PRIVATE shapeop)
140211
141212# ==============================================================================
142213# Summary
@@ -147,4 +218,7 @@ message(STATUS "Build Type: ${CMAKE_BUILD_TYPE}")
147218message (STATUS "C++ Standard: C++${CMAKE_CXX_STANDARD} " )
148219message (STATUS "Optimization: ${FAST_COMPILE} (O0 if ON, O3 if OFF)" )
149220message (STATUS "Precompiled Headers: ${ENABLE_PRECOMPILED_HEADERS} " )
150- message (STATUS "=============================================" )
221+ message (STATUS "OpenMP Support: ${USE_OPENMP} " )
222+ message (STATUS "Eigen Include Dir: ${EIGEN3_INCLUDE_DIRS} " )
223+ message (STATUS "External Dir: ${EXTERNAL_DIR} " )
224+ message (STATUS "===============================================" )
0 commit comments