Compile all
Some checks failed
CI/CD Pipeline / Code Linting (push) Failing after 25s
CI/CD Pipeline / Build and Test (Debug, clang, ubuntu-latest) (push) Failing after 5m4s
CI/CD Pipeline / Build and Test (Debug, gcc, ubuntu-latest) (push) Failing after 6m12s
CI/CD Pipeline / Build and Test (Release, clang, ubuntu-20.04) (push) Failing after 6m15s
CI/CD Pipeline / Build and Test (Release, clang, ubuntu-latest) (push) Failing after 5m14s
CI/CD Pipeline / Build and Test (Release, gcc, ubuntu-20.04) (push) Failing after 6m3s
CI/CD Pipeline / Build and Test (Release, gcc, ubuntu-latest) (push) Failing after 6m2s
CI/CD Pipeline / Docker Build Test (push) Failing after 1m13s
CI/CD Pipeline / Performance Benchmarks (push) Has been skipped
CI/CD Pipeline / Build Documentation (push) Failing after 30s
CI/CD Pipeline / Create Release Package (push) Has been skipped

This commit is contained in:
2025-06-23 16:57:16 +02:00
parent 417844f19b
commit 38b27805ff
3 changed files with 58 additions and 247 deletions

View File

@@ -49,8 +49,21 @@ FetchContent_Declare(
)
FetchContent_MakeAvailable(Catch2)
# Add external libraries
add_subdirectory(external)
# Fetch libsvm
FetchContent_Declare(
libsvm
GIT_REPOSITORY https://github.com/cjlin1/libsvm.git
GIT_TAG v332
)
FetchContent_MakeAvailable(libsvm)
# Fetch liblinear
FetchContent_Declare(
liblinear
GIT_REPOSITORY https://github.com/cjlin1/liblinear.git
GIT_TAG v249
)
FetchContent_MakeAvailable(liblinear)
# Include directories
include_directories(${CMAKE_SOURCE_DIR}/include)
@@ -71,25 +84,47 @@ set(HEADERS
include/svm_classifier/types.hpp
)
# Create library
add_library(svm_classifier STATIC ${SOURCES} ${HEADERS})
# Add external sources directly to our library
set(EXTERNAL_SOURCES)
# Link libraries - Updated to use object libraries and BLAS if available
# target_link_libraries(svm_classifier
# PUBLIC
# ${TORCH_LIBRARIES}
# PRIVATE
# nlohmann_json::nlohmann_json
# $<TARGET_OBJECTS:libsvm_objects>
# $<TARGET_OBJECTS:liblinear_objects>
# $<$<TARGET_EXISTS:blas_functions>:blas_functions>
# )
# Add libsvm sources
if(EXISTS "${libsvm_SOURCE_DIR}/svm.cpp")
list(APPEND EXTERNAL_SOURCES "${libsvm_SOURCE_DIR}/svm.cpp")
endif()
# Add liblinear sources
if(EXISTS "${liblinear_SOURCE_DIR}/linear.cpp")
list(APPEND EXTERNAL_SOURCES "${liblinear_SOURCE_DIR}/linear.cpp")
endif()
if(EXISTS "${liblinear_SOURCE_DIR}/newton.cpp")
list(APPEND EXTERNAL_SOURCES "${liblinear_SOURCE_DIR}/newton.cpp")
elseif(EXISTS "${liblinear_SOURCE_DIR}/tron.cpp")
list(APPEND EXTERNAL_SOURCES "${liblinear_SOURCE_DIR}/tron.cpp")
endif()
# Add BLAS sources
if(EXISTS "${liblinear_SOURCE_DIR}/blas")
file(GLOB BLAS_C_FILES "${liblinear_SOURCE_DIR}/blas/*.c")
list(APPEND EXTERNAL_SOURCES ${BLAS_C_FILES})
endif()
# Create library with all sources
add_library(svm_classifier STATIC ${SOURCES} ${HEADERS} ${EXTERNAL_SOURCES})
# Set language properties for different file types
foreach(source_file ${EXTERNAL_SOURCES})
if(source_file MATCHES "\\.c$")
set_source_files_properties(${source_file} PROPERTIES LANGUAGE C)
endif()
endforeach()
# Link libraries
target_link_libraries(svm_classifier
PUBLIC
${TORCH_LIBRARIES}
PRIVATE
nlohmann_json::nlohmann_json
$<$<TARGET_EXISTS:svm_external_combined>:svm_external_combined>
)
# Set include directories
@@ -99,27 +134,11 @@ target_include_directories(svm_classifier
$<INSTALL_INTERFACE:include>
PRIVATE
${CMAKE_CURRENT_SOURCE_DIR}/src
${libsvm_SOURCE_DIR}
${liblinear_SOURCE_DIR}
${liblinear_SOURCE_DIR}/blas
)
# Add include directories from external libraries using variables set by external/CMakeLists.txt
if(LIBSVM_INCLUDE_DIR)
target_include_directories(svm_classifier
PRIVATE ${LIBSVM_INCLUDE_DIR}
)
endif()
if(LIBLINEAR_INCLUDE_DIR)
target_include_directories(svm_classifier
PRIVATE ${LIBLINEAR_INCLUDE_DIR}
)
endif()
if(LIBLINEAR_BLAS_INCLUDE_DIR)
target_include_directories(svm_classifier
PRIVATE ${LIBLINEAR_BLAS_INCLUDE_DIR}
)
endif()
# Compiler-specific options
target_compile_features(svm_classifier PUBLIC cxx_std_17)
@@ -227,7 +246,7 @@ add_subdirectory(tests)
# Add examples
add_subdirectory(examples)
# Installation - Fixed version
# Installation
install(TARGETS svm_classifier
EXPORT SVMClassifierTargets
LIBRARY DESTINATION ${CMAKE_INSTALL_LIBDIR}

View File

@@ -1,210 +1,2 @@
# External dependencies CMakeLists.txt - Fixed version with proper BLAS handling
include(FetchContent)
# Set policies for FetchContent
if(POLICY CMP0135)
cmake_policy(SET CMP0135 NEW)
endif()
# Fetch libsvm
FetchContent_Declare(
libsvm
GIT_REPOSITORY https://github.com/cjlin1/libsvm.git
GIT_TAG v332
)
FetchContent_MakeAvailable(libsvm)
# Fetch liblinear
FetchContent_Declare(
liblinear
GIT_REPOSITORY https://github.com/cjlin1/liblinear.git
GIT_TAG v249
)
FetchContent_MakeAvailable(liblinear)
# Build libsvm as OBJECT library
if(EXISTS "${libsvm_SOURCE_DIR}/svm.cpp")
set(LIBSVM_SOURCES "${libsvm_SOURCE_DIR}/svm.cpp")
add_library(libsvm_objects OBJECT ${LIBSVM_SOURCES})
# Set properties for the object library
target_include_directories(libsvm_objects
PUBLIC
${libsvm_SOURCE_DIR}
)
# Set C++ standard for libsvm
target_compile_features(libsvm_objects PRIVATE cxx_std_17)
# Make the include directory available to parent scope
set(LIBSVM_INCLUDE_DIR ${libsvm_SOURCE_DIR} PARENT_SCOPE)
message(STATUS "libsvm built successfully as object library")
else()
message(WARNING "libsvm source files not found")
# Create empty object library
add_library(libsvm_objects OBJECT)
set(LIBSVM_INCLUDE_DIR "" PARENT_SCOPE)
endif()
# Build liblinear with BLAS as a static library
set(LIBLINEAR_SOURCES)
set(BLAS_SOURCES)
# Check for main liblinear source files
if(EXISTS "${liblinear_SOURCE_DIR}/linear.cpp")
list(APPEND LIBLINEAR_SOURCES "${liblinear_SOURCE_DIR}/linear.cpp")
endif()
# Check for optimization files (tron.cpp, newton.cpp, etc.)
if(EXISTS "${liblinear_SOURCE_DIR}/tron.cpp")
list(APPEND LIBLINEAR_SOURCES "${liblinear_SOURCE_DIR}/tron.cpp")
elseif(EXISTS "${liblinear_SOURCE_DIR}/newton.cpp")
list(APPEND LIBLINEAR_SOURCES "${liblinear_SOURCE_DIR}/newton.cpp")
endif()
# Check for BLAS files in blas directory
if(EXISTS "${liblinear_SOURCE_DIR}/blas")
# Explicitly add the required BLAS source files
set(BLAS_FILES
"${liblinear_SOURCE_DIR}/blas/daxpy.c"
"${liblinear_SOURCE_DIR}/blas/ddot.c"
"${liblinear_SOURCE_DIR}/blas/dnrm2.c"
"${liblinear_SOURCE_DIR}/blas/dscal.c"
)
# Check which BLAS files actually exist and add them
foreach(blas_file ${BLAS_FILES})
if(EXISTS ${blas_file})
list(APPEND BLAS_SOURCES ${blas_file})
message(STATUS "Adding BLAS file: ${blas_file}")
endif()
endforeach()
else()
message(WARNING "BLAS directory not found in liblinear source")
endif()
# Create liblinear with BLAS
if(LIBLINEAR_SOURCES)
# First create BLAS library if we have BLAS sources
if(BLAS_SOURCES)
add_library(blas_functions STATIC ${BLAS_SOURCES})
target_include_directories(blas_functions
PUBLIC ${liblinear_SOURCE_DIR}/blas
)
# Set C language for BLAS
set_target_properties(blas_functions PROPERTIES
LINKER_LANGUAGE C
POSITION_INDEPENDENT_CODE ON
)
# Ensure symbols are exported
if(CMAKE_C_COMPILER_ID MATCHES "GNU|Clang")
target_compile_options(blas_functions PRIVATE -fvisibility=default)
endif()
endif()
# Create liblinear object library
add_library(liblinear_objects OBJECT ${LIBLINEAR_SOURCES})
# Set properties for the object library
target_include_directories(liblinear_objects
PUBLIC
${liblinear_SOURCE_DIR}
)
# Add blas directory if it exists
if(EXISTS "${liblinear_SOURCE_DIR}/blas")
target_include_directories(liblinear_objects
PUBLIC ${liblinear_SOURCE_DIR}/blas
)
endif()
# Set C++ standard for liblinear
target_compile_features(liblinear_objects PRIVATE cxx_std_17)
# Compiler specific flags
if(CMAKE_CXX_COMPILER_ID MATCHES "GNU|Clang")
target_compile_options(liblinear_objects PRIVATE -w) # Suppress warnings
endif()
# Make the include directories available to parent scope
set(LIBLINEAR_INCLUDE_DIR ${liblinear_SOURCE_DIR} PARENT_SCOPE)
if(EXISTS "${liblinear_SOURCE_DIR}/blas")
set(LIBLINEAR_BLAS_INCLUDE_DIR ${liblinear_SOURCE_DIR}/blas PARENT_SCOPE)
endif()
# Export BLAS library target to parent scope if it exists
if(TARGET blas_functions)
set(LIBLINEAR_BLAS_TARGET blas_functions PARENT_SCOPE)
endif()
message(STATUS "liblinear built with sources: ${LIBLINEAR_SOURCES}")
if(BLAS_SOURCES)
message(STATUS "BLAS functions built as separate static library")
endif()
else()
# Create minimal liblinear implementation as object library
message(WARNING "liblinear source files not found, creating minimal implementation")
# Create a minimal linear.cpp file
set(MINIMAL_LIBLINEAR_DIR "${CMAKE_CURRENT_BINARY_DIR}/minimal_liblinear")
file(MAKE_DIRECTORY ${MINIMAL_LIBLINEAR_DIR})
# Create minimal header
file(WRITE "${MINIMAL_LIBLINEAR_DIR}/linear.h"
"#pragma once\n"
"extern \"C\" {\n"
"struct feature_node { int index; double value; };\n"
"struct problem { int l, n; double *y; struct feature_node **x; double bias; };\n"
"struct parameter { int solver_type; double eps, C; };\n"
"struct model { struct parameter param; int nr_class, nr_feature; double *w; int *label; double bias; };\n"
"struct model* train(const struct problem *prob, const struct parameter *param);\n"
"double predict(const struct model *model_, const struct feature_node *x);\n"
"void free_and_destroy_model(struct model **model_ptr_ptr);\n"
"}\n"
)
# Create minimal implementation
file(WRITE "${MINIMAL_LIBLINEAR_DIR}/linear.cpp"
"#include \"linear.h\"\n"
"#include <cstdlib>\n"
"#include <cstring>\n"
"struct model* train(const struct problem *prob, const struct parameter *param) {\n"
" auto model = (struct model*)malloc(sizeof(struct model));\n"
" memset(model, 0, sizeof(struct model));\n"
" model->nr_feature = prob->n;\n"
" model->nr_class = 2;\n"
" model->w = (double*)calloc(prob->n, sizeof(double));\n"
" return model;\n"
"}\n"
"double predict(const struct model *model_, const struct feature_node *x) {\n"
" return 1.0; // Dummy prediction\n"
"}\n"
"void free_and_destroy_model(struct model **model_ptr_ptr) {\n"
" if (*model_ptr_ptr) {\n"
" free((*model_ptr_ptr)->w);\n"
" free(*model_ptr_ptr);\n"
" *model_ptr_ptr = nullptr;\n"
" }\n"
"}\n"
)
add_library(liblinear_objects OBJECT "${MINIMAL_LIBLINEAR_DIR}/linear.cpp")
target_include_directories(liblinear_objects PUBLIC ${MINIMAL_LIBLINEAR_DIR})
target_compile_features(liblinear_objects PRIVATE cxx_std_17)
set(LIBLINEAR_INCLUDE_DIR ${MINIMAL_LIBLINEAR_DIR} PARENT_SCOPE)
endif()
# Print summary
message(STATUS "External libraries configured:")
message(STATUS " - libsvm: ${libsvm_SOURCE_DIR}")
message(STATUS " - liblinear: ${liblinear_SOURCE_DIR}")
if(TARGET blas_functions)
message(STATUS " - BLAS functions built as separate static library")
endif()
message(STATUS " - Using combination of OBJECT and STATIC libraries")
# External dependencies are now handled directly in the main CMakeLists.txt
# This file is kept for compatibility

View File

@@ -24,7 +24,7 @@ target_link_libraries(svm_classifier_tests
svm_classifier
Catch2::Catch2WithMain
nlohmann_json::nlohmann_json
$<$<TARGET_EXISTS:blas_functions>:blas_functions>
# No need to link external libraries as they're already in svm_classifier
)
# Set include directories - Handle external libraries dynamically