cmake_minimum_required(VERSION 3.14) project(jsonl_parser) # Set C++ standard set(CMAKE_CXX_STANDARD 17) set(CMAKE_CXX_STANDARD_REQUIRED ON) # Explicitly prioritize system libraries over Anaconda # This addresses the libgomp.so.1 conflict set(CMAKE_SKIP_BUILD_RPATH FALSE) set(CMAKE_BUILD_WITH_INSTALL_RPATH FALSE) set(CMAKE_INSTALL_RPATH "/usr/lib/x86_64-linux-gnu:/usr/lib/gcc/x86_64-linux-gnu/11") set(CMAKE_INSTALL_RPATH_USE_LINK_PATH TRUE) # Explicitly set the path to find libgomp to avoid Anaconda conflicts if(NOT APPLE) find_library(GOMP_LIBRARY gomp PATHS /usr/lib/gcc/x86_64-linux-gnu/11 NO_DEFAULT_PATH) if(GOMP_LIBRARY) message(STATUS "Found libgomp: ${GOMP_LIBRARY}") else() message(WARNING "Could not find system libgomp.so.1 - this might cause conflicts with Anaconda") endif() endif() # Find Arrow package find_package(Arrow REQUIRED) find_package(ArrowDataset REQUIRED) # For dataset functionality find_package(Parquet REQUIRED) # Often useful with Arrow # Find OpenMP for parallel processing if(APPLE) # For macOS, we need special handling for OpenMP option(USE_OPENMP "Use OpenMP for parallel processing" ON) if(USE_OPENMP) # Try to find OpenMP the standard way first find_package(OpenMP QUIET) if(NOT OpenMP_FOUND) # Check if libomp is installed via Homebrew execute_process( COMMAND brew --prefix libomp RESULT_VARIABLE BREW_LIBOMP OUTPUT_VARIABLE BREW_LIBOMP_PREFIX OUTPUT_STRIP_TRAILING_WHITESPACE ) if(BREW_LIBOMP EQUAL 0) # Found libomp from Homebrew set(OpenMP_C_FLAGS "-Xpreprocessor -fopenmp -I${BREW_LIBOMP_PREFIX}/include") set(OpenMP_CXX_FLAGS "-Xpreprocessor -fopenmp -I${BREW_LIBOMP_PREFIX}/include") set(OpenMP_C_LIB_NAMES "omp") set(OpenMP_CXX_LIB_NAMES "omp") set(OpenMP_omp_LIBRARY "${BREW_LIBOMP_PREFIX}/lib/libomp.dylib") # Manually define the target add_library(OpenMP_TARGET INTERFACE) target_compile_options(OpenMP_TARGET INTERFACE ${OpenMP_CXX_FLAGS}) target_link_libraries(OpenMP_TARGET INTERFACE ${OpenMP_omp_LIBRARY}) add_library(OpenMP::OpenMP_CXX ALIAS OpenMP_TARGET) set(OpenMP_FOUND TRUE) else() message(STATUS "OpenMP not available on this Mac. Install with: brew install libomp") set(USE_OPENMP OFF) endif() endif() endif() else() # Enhanced OpenMP handling for Linux to avoid Anaconda conflicts find_package(OpenMP) if(OpenMP_FOUND) set(USE_OPENMP ON) # Check if we found OpenMP in an Anaconda directory string(FIND "${OpenMP_CXX_LIBRARIES}" "anaconda" ANACONDA_OPENMP) if(ANACONDA_OPENMP GREATER -1) message(WARNING "Found OpenMP in Anaconda environment. This might cause performance issues.") # Try to find the system OpenMP instead find_library(SYS_OMP_LIBRARY gomp PATHS /usr/lib/gcc/x86_64-linux-gnu/11 NO_DEFAULT_PATH) if(SYS_OMP_LIBRARY) message(STATUS "Will use system OpenMP instead: ${SYS_OMP_LIBRARY}") # Create a custom OpenMP target with system library add_library(SystemOpenMP_CXX INTERFACE) target_compile_options(SystemOpenMP_CXX INTERFACE ${OpenMP_CXX_FLAGS}) target_link_libraries(SystemOpenMP_CXX INTERFACE ${SYS_OMP_LIBRARY}) # Replace the standard target add_library(OpenMP::OpenMP_CXX ALIAS SystemOpenMP_CXX) endif() endif() else() set(USE_OPENMP OFF) endif() endif() # Add simdjson as source files directly set(SIMDJSON_SOURCES simdjson.cpp # Make sure this path is correct ) # Add your executable with all source files add_executable(parser main.cpp ${SIMDJSON_SOURCES} ) # Link against Arrow libraries and OpenMP target_link_libraries(parser PRIVATE Arrow::arrow_shared Parquet::parquet_shared ) # Conditionally add OpenMP and explicitly use system libgomp if found if(USE_OPENMP AND OpenMP_FOUND) target_link_libraries(parser PRIVATE OpenMP::OpenMP_CXX) target_compile_definitions(parser PRIVATE HAVE_OPENMP) message(STATUS "Building with OpenMP support") # If we found the system libgomp directly, use that if(GOMP_LIBRARY AND NOT APPLE) target_link_libraries(parser PRIVATE ${GOMP_LIBRARY}) message(STATUS "Explicitly linking with system libgomp") endif() else() message(STATUS "Building without OpenMP support") endif() # Add include directories if needed target_include_directories(parser PRIVATE ${CMAKE_CURRENT_SOURCE_DIR} ) # Function to check and add compiler flags if supported include(CheckCXXCompilerFlag) function(add_compiler_flag_if_supported flag flag_name) check_cxx_compiler_flag("${flag}" COMPILER_SUPPORTS_${flag_name}) if(COMPILER_SUPPORTS_${flag_name}) target_compile_options(parser PRIVATE "${flag}") target_compile_definitions(parser PRIVATE "HAVE_${flag_name}") endif() # Set a parent scope variable so we can use it later set(COMPILER_SUPPORTS_${flag_name} ${COMPILER_SUPPORTS_${flag_name}} PARENT_SCOPE) endfunction() # Detect and enable SIMD instructions based on architecture if(CMAKE_SYSTEM_PROCESSOR MATCHES "x86_64|amd64|AMD64") # Check for x86 SIMD support add_compiler_flag_if_supported("-mavx2" AVX2) add_compiler_flag_if_supported("-mpopcnt" POPCNT) add_compiler_flag_if_supported("-msse4.2" SSE42) add_compiler_flag_if_supported("-msse4.1" SSE41) add_compiler_flag_if_supported("-mssse3" SSSE3) add_compiler_flag_if_supported("-msse3" SSE3) add_compiler_flag_if_supported("-msse2" SSE2) elseif(CMAKE_SYSTEM_PROCESSOR MATCHES "arm|ARM|aarch64") # ARM NEON SIMD support add_compiler_flag_if_supported("-mneon" NEON) endif() # Add SIMD feature detection macros if(COMPILER_SUPPORTS_AVX2) target_compile_definitions(parser PRIVATE USE_AVX2) endif() if(COMPILER_SUPPORTS_SSE42) target_compile_definitions(parser PRIVATE USE_SSE4_2) endif() if(COMPILER_SUPPORTS_SSE41) target_compile_definitions(parser PRIVATE USE_SSE4_1) endif() if(COMPILER_SUPPORTS_SSSE3) target_compile_definitions(parser PRIVATE USE_SSSE3) endif() if(COMPILER_SUPPORTS_SSE3) target_compile_definitions(parser PRIVATE USE_SSE3) endif() if(COMPILER_SUPPORTS_SSE2) target_compile_definitions(parser PRIVATE USE_SSE2) endif() if(COMPILER_SUPPORTS_NEON) target_compile_definitions(parser PRIVATE USE_NEON) endif() if(COMPILER_SUPPORTS_POPCNT) target_compile_definitions(parser PRIVATE USE_POPCNT) endif() # Enable more aggressive optimizations in Release mode target_compile_options(parser PRIVATE $<$:-O3 -march=native -mtune=native -ffast-math> ) # Add debugging symbols in Debug mode while keeping optimizations target_compile_options(parser PRIVATE $<$:-O2 -g> ) # Ensure the runtime path is properly set to find system libraries first set_target_properties(parser PROPERTIES BUILD_WITH_INSTALL_RPATH TRUE INSTALL_RPATH "/usr/lib/x86_64-linux-gnu:/usr/lib/gcc/x86_64-linux-gnu/11" )