@@ -32,14 +32,21 @@ file jemalloc_vendor_lib do
3232 # Copy jemalloc files to vendor directory
3333 jemalloc_lib_dir = File . expand_path ( 'jemalloc/lib' , __dir__ )
3434
35- # Copy the actual library file (libjemalloc.so.2)
36- actual_lib = File . join ( jemalloc_lib_dir , "libjemalloc.#{ jemalloc_shared_lib_ext } .2" )
35+ # Find jemalloc library file (macOS/Linux)
36+ actual_lib = if jemalloc_shared_lib_ext == 'dylib'
37+ Dir [ File . join ( jemalloc_lib_dir , 'libjemalloc.2.dylib' ) ] . first ||
38+ File . join ( jemalloc_lib_dir , 'libjemalloc.dylib.2' )
39+ else
40+ File . join ( jemalloc_lib_dir , 'libjemalloc.so.2' )
41+ end
3742 vendor_actual_lib = File . join ( VENDOR_LIB_DIR , "libjemalloc.#{ jemalloc_shared_lib_ext } .2" )
3843 FileUtils . cp ( actual_lib , vendor_actual_lib )
3944
4045 # Create symlinks in vendor directory
4146 Dir . chdir ( VENDOR_LIB_DIR ) do
4247 FileUtils . ln_sf ( "libjemalloc.#{ jemalloc_shared_lib_ext } .2" , "libjemalloc.#{ jemalloc_shared_lib_ext } " )
48+ # Also create libjemalloc.2.dylib symlink on macOS for compatibility
49+ FileUtils . ln_sf ( 'libjemalloc.dylib.2' , 'libjemalloc.2.dylib' ) if jemalloc_shared_lib_ext == 'dylib'
4350 end
4451
4552 puts "Moved jemalloc library to vendor: #{ jemalloc_vendor_lib } "
@@ -95,15 +102,15 @@ def patch_cmake_jemalloc
95102 return if File . exist? ( jemalloc_backup )
96103
97104 content = File . read ( cmake_file )
98-
105+
99106 # Remove or comment out the JEMALLOC_LINK_LIBRARIES setting
100107 patched = content . gsub ( /^(\s *set\s *\( \s *JEMALLOC_LINK_LIBRARIES\s +"jemalloc"\s *\) )/ , '# \1 # Patched by Rakefile' )
101-
102- if content != patched
103- File . write ( jemalloc_backup , content )
104- File . write ( cmake_file , patched )
105- puts "Patched jemalloc linking in: #{ cmake_file } "
106- end
108+
109+ return unless content != patched
110+
111+ File . write ( jemalloc_backup , content )
112+ File . write ( cmake_file , patched )
113+ puts "Patched jemalloc linking in: #{ cmake_file } "
107114end
108115
109116def restore_cmake_jemalloc
119126def patch_sdsl_lite
120127 # Patch louds_tree.hpp after sdsl-lite build
121128 louds_tree_files = Dir . glob ( 'odgi/build/sdsl-lite-prefix/src/sdsl-lite*/include/sdsl/louds_tree.hpp' )
122-
123129 louds_tree_files . each do |file |
124130 next unless File . exist? ( file )
125131
@@ -130,17 +136,59 @@ def patch_sdsl_lite
130136 # Fix the specific lines in swap function
131137 patched = content . gsub ( /util::swap_support\( m_bv_select1, tree\. m_select1,/ , 'util::swap_support(m_bv_select1, tree.m_bv_select1,' )
132138 . gsub ( /util::swap_support\( m_bv_select0, tree\. m_select0,/ , 'util::swap_support(m_bv_select0, tree.m_bv_select0,' )
133-
134139 next unless content != patched
135140
136141 File . write ( orig , content ) # Backup original
137142 File . write ( file , patched )
138143 puts "Patched sdsl-lite: #{ file } "
139144 end
145+
146+ # Patch util.hpp to guard process.h include for non-Windows
147+ util_hpp_files = Dir . glob ( 'odgi/build/sdsl-lite-prefix/src/sdsl-lite*/include/sdsl/util.hpp' )
148+ util_hpp_files . each do |file |
149+ next unless File . exist? ( file )
150+
151+ orig = "#{ file } .orig"
152+ next if File . exist? ( orig ) # Already patched
153+
154+ content = File . read ( file )
155+ # Guard #include <process.h> with #ifdef _WIN32 ... #endif
156+ patched = content . gsub ( /^(\s *)#include\s *<process\. h>\s *$/ ) do |_match |
157+ indent = Regexp . last_match ( 1 ) || ''
158+ "#{ indent } #ifdef _WIN32\n #{ indent } #include <process.h>\n #{ indent } #endif"
159+ end
160+ next unless content != patched
161+
162+ File . write ( orig , content ) # Backup original
163+ File . write ( file , patched )
164+ puts "Patched process.h include in: #{ file } "
165+ end
166+ end
167+
168+ def patch_atomic_queue
169+ # Patch atomic_queue.h to fix template argument list issues
170+ atomic_queue_file = 'odgi/deps/atomic_queue/include/atomic_queue/atomic_queue.h'
171+ return unless File . exist? ( atomic_queue_file )
172+
173+ orig = "#{ atomic_queue_file } .orig"
174+ return if File . exist? ( orig ) # Already patched
175+
176+ content = File . read ( atomic_queue_file )
177+
178+ # Fix template argument list issues for Clang 20+
179+ patched = content . gsub ( /Base::template do_pop_any\( / , 'Base::template do_pop_any<>(' )
180+ . gsub ( /Base::template do_push_any\( / , 'Base::template do_push_any<>(' )
181+
182+ return unless content != patched
183+
184+ File . write ( orig , content ) # Backup original
185+ File . write ( atomic_queue_file , patched )
186+ puts "Patched atomic_queue: #{ atomic_queue_file } "
140187end
141188
142189def restore_sdsl_lite
143190 louds_tree_files = Dir . glob ( 'odgi/build/sdsl-lite-prefix/src/sdsl-lite*/include/sdsl/louds_tree.hpp' )
191+ util_hpp_files = Dir . glob ( 'odgi/build/sdsl-lite-prefix/src/sdsl-lite*/include/sdsl/util.hpp' )
144192
145193 louds_tree_files . each do |file |
146194 orig = "#{ file } .orig"
@@ -150,6 +198,25 @@ def restore_sdsl_lite
150198 File . delete ( orig )
151199 puts "Restored sdsl-lite: #{ file } "
152200 end
201+
202+ util_hpp_files . each do |file |
203+ orig = "#{ file } .orig"
204+ next unless File . exist? ( orig )
205+
206+ File . write ( file , File . read ( orig ) )
207+ File . delete ( orig )
208+ puts "Restored sdsl-lite util.hpp: #{ file } "
209+ end
210+ end
211+
212+ def restore_atomic_queue
213+ atomic_queue_file = 'odgi/deps/atomic_queue/include/atomic_queue/atomic_queue.h'
214+ orig = "#{ atomic_queue_file } .orig"
215+ return unless File . exist? ( orig )
216+
217+ File . write ( atomic_queue_file , File . read ( orig ) )
218+ File . delete ( orig )
219+ puts "Restored atomic_queue: #{ atomic_queue_file } "
153220end
154221
155222# Define odgi shared library paths
@@ -167,9 +234,15 @@ file odgi_vendor_lib => [jemalloc_vendor_lib] do
167234 jemalloc_lib_file = jemalloc_vendor_lib
168235
169236 Dir . chdir ( 'odgi' ) do
237+ # Apply atomic_queue patch before build
238+ patch_atomic_queue
239+
170240 # Set rpath to use $ORIGIN for relative path resolution and override JEMALLOC_LINK_LIBRARIES
171241 rpath_setting = "'$ORIGIN'"
172- sh "cmake -H. -Bbuild -DJEMALLOC_LIBRARY=#{ jemalloc_lib_file } -DJEMALLOC_INCLUDE_DIR=#{ jemalloc_include_dir } -DJEMALLOC_LINK_LIBRARIES=#{ jemalloc_lib_file } -DCMAKE_BUILD_WITH_INSTALL_RPATH=ON -DCMAKE_INSTALL_RPATH=#{ rpath_setting } -DCMAKE_BUILD_RPATH=#{ rpath_setting } "
242+ openmp_include = ENV [ 'HOMEBREW_PREFIX' ] ? "#{ ENV [ 'HOMEBREW_PREFIX' ] } /opt/libomp/include" : '/opt/homebrew/opt/libomp/include'
243+ cmake_cxx_flags = "-I#{ openmp_include } -Wno-error=missing-template-arg-list-after-template-kw"
244+ cmake_c_flags = "-I#{ openmp_include } "
245+ sh "cmake -H. -Bbuild -DJEMALLOC_LIBRARY=#{ jemalloc_lib_file } -DJEMALLOC_INCLUDE_DIR=#{ jemalloc_include_dir } -DJEMALLOC_LINK_LIBRARIES=#{ jemalloc_lib_file } -DCMAKE_BUILD_WITH_INSTALL_RPATH=ON -DCMAKE_INSTALL_RPATH=#{ rpath_setting } -DCMAKE_BUILD_RPATH=#{ rpath_setting } -DCMAKE_CXX_FLAGS='#{ cmake_cxx_flags } ' -DCMAKE_C_FLAGS='#{ cmake_c_flags } '"
173246
174247 # Apply sdsl-lite patch before build
175248 patch_sdsl_lite
@@ -219,7 +292,8 @@ namespace :vendor do
219292 restore_cmake_versions
220293 restore_cmake_jemalloc
221294 restore_sdsl_lite
222-
295+ restore_atomic_queue
296+
223297 if Dir . exist? ( VENDOR_DIR )
224298 FileUtils . rm_rf ( VENDOR_DIR )
225299 puts "Cleaned vendor directory: #{ VENDOR_DIR } "
0 commit comments