https://github.com/cvxgrp/scs
Tip revision: f0c23340da03bcd663072dc4a90cf1aab8968c61 authored by Brendan O'Donoghue on 05 April 2023, 08:18:05 UTC
bump version to 3.2.3 (#248)
bump version to 3.2.3 (#248)
Tip revision: f0c2334
CMakeLists.txt
# CMakeLists.txt file for scs. This software may be modified and distributed
# under the terms of the MIT License
cmake_minimum_required(VERSION 3.5)
project(
scs
LANGUAGES C
VERSION 3.2.3)
# Defines the CMAKE_INSTALL_LIBDIR, CMAKE_INSTALL_BINDIR and many other useful
# macros. See https://cmake.org/cmake/help/latest/module/GNUInstallDirs.html
include(GNUInstallDirs)
# Control where libraries and executables are placed during the build. With the
# following settings executables are placed in <the top level of the build
# tree>/bin and libraries/archives in <top level of the build tree>/lib. This is
# particularly useful to run ctests on libraries built on Windows machines:
# tests, which are executables, are placed in the same folders of dlls, which
# are treated as executables as well, so that they can properly find the
# libraries to run. This is a because of missing RPATH on Windows.
set(CMAKE_RUNTIME_OUTPUT_DIRECTORY
"${CMAKE_BINARY_DIR}/${CMAKE_INSTALL_BINDIR}")
set(CMAKE_LIBRARY_OUTPUT_DIRECTORY
"${CMAKE_BINARY_DIR}/${CMAKE_INSTALL_LIBDIR}")
set(CMAKE_ARCHIVE_OUTPUT_DIRECTORY
"${CMAKE_BINARY_DIR}/${CMAKE_INSTALL_LIBDIR}")
# To build shared libraries in Windows, we set CMAKE_WINDOWS_EXPORT_ALL_SYMBOLS
# to TRUE. See
# https://cmake.org/cmake/help/v3.4/variable/CMAKE_WINDOWS_EXPORT_ALL_SYMBOLS.html
# See
# https://blog.kitware.com/create-dlls-on-windows-without-declspec-using-new-cmake-export-all-feature/
set(CMAKE_WINDOWS_EXPORT_ALL_SYMBOLS ON)
# Under MSVC, we set CMAKE_DEBUG_POSTFIX to "d" to add a trailing "d" to library
# built in debug mode. In this Windows user can compile, build and install the
# library in both Release and Debug configuration avoiding naming clashes in the
# installation directories.
if(MSVC)
set(CMAKE_DEBUG_POSTFIX "d")
endif()
# Build position independent code. Position Independent Code (PIC) is commonly
# used for shared libraries so that the same shared library code can be loaded
# in each program address space in a location where it will not overlap with any
# other uses of such memory. In particular, this option avoids problems
# occurring when a process wants to load more than one shared library at the
# same virtual address. Since shared libraries cannot predict where other shared
# libraries could be loaded, this is an unavoidable problem with the traditional
# shared library concept. Generating position-independent code is often the
# default behavior for most modern compilers. Moreover linking a static library
# that is not built with PIC from a shared library will fail on some
# compiler/architecture combinations. Further details on PIC can be found here:
# https://eli.thegreenplace.net/2011/11/03/position-independent-code-pic-in-shared-libraries/
set(CMAKE_POSITION_INDEPENDENT_CODE ON)
# Disable C and C++ compiler extensions. C/CXX_EXTENSIONS are ON by default to
# allow the compilers to use extended variants of the C/CXX language. However,
# this could expose cross-platform bugs in user code or in the headers of
# third-party dependencies and thus it is strongly suggested to turn extensions
# off.
set(CMAKE_C_EXTENSIONS OFF)
set(CMAKE_CXX_EXTENSIONS OFF)
list(APPEND CMAKE_MODULE_PATH ${CMAKE_CURRENT_SOURCE_DIR}/cmake)
# Options Shared/Dynamic or Static library?
option(BUILD_SHARED_LIBS "Build libraries as shared as opposed to static" ON)
# Enable RPATH support for installed binaries and libraries
include(AddInstallRPATHSupport)
add_install_rpath_support(
BIN_DIRS
"${CMAKE_INSTALL_FULL_BINDIR}"
LIB_DIRS
"${CMAKE_INSTALL_FULL_LIBDIR}"
INSTALL_NAME_DIR
"${CMAKE_INSTALL_FULL_LIBDIR}"
USE_LINK_PATH)
# Encourage user to specify a build type (e.g. Release, Debug, etc.), otherwise
# set it to Release.
if(NOT CMAKE_CONFIGURATION_TYPES)
if(NOT CMAKE_BUILD_TYPE)
message(STATUS "Setting build type to 'Release' as none was specified.")
set_property(CACHE CMAKE_BUILD_TYPE PROPERTY VALUE "Release")
endif()
endif()
# Build test related commands?
option(BUILD_TESTING "Create tests using CMake" OFF)
if(BUILD_TESTING)
enable_testing()
endif()
# Add uninstall target After 'make install' can run 'make uninstall' to remove.
include(AddUninstallTarget)
# Some variables useful for sampling the building process. Note that the GPU
# profile is not compiled.
set(LINSYS linsys)
set(DIRSRC ${LINSYS}/cpu/direct)
set(INDIRSRC ${LINSYS}/cpu/indirect)
set(EXTERNAL ${LINSYS}/external)
# Options
# ----------------------------------------------
# Use floats instead of doubles
option(SFLOAT "Use single precision floats rather than doubles" OFF)
message(STATUS "Single precision floats (32bit) are ${SFLOAT}")
# Use long integers for indexing
option(DLONG "Use long integers (64bit) for indexing" OFF)
message(STATUS "Long integers (64bit) are ${DLONG}")
# Disable all printing
option(NO_PRINTING "Disables all printing" OFF)
message(STATUS "Printing is NOT ${NO_PRINTING}")
# Disable all read/write functionality
option(NO_READ_WRITE "Disables all read/write functionality" OFF)
message(STATUS "Read/write functionality is NOT ${NO_READ_WRITE}")
set(COMPILER_OPTS "-DUSE_LAPACK -DCTRLC")
# Primitive types
if(SFLOAT)
set(SCS_FLOAT_TYPE "float")
set(COMPILER_OPTS "-DSFLOAT ${COMPILER_OPTS}")
else()
set(SCS_FLOAT_TYPE "double")
endif()
if(DLONG)
set(SCS_INT_TYPE "long long")
set(COMPILER_OPTS "-DDLONG ${COMPILER_OPTS}")
else()
set(SCS_INT_TYPE "int")
endif()
if(NO_PRINTING)
set(COMPILER_OPTS "-DNO_PRINTING=1 ${COMPILER_OPTS}")
endif()
if(NO_READ_WRITE)
set(COMPILER_OPTS "-DNO_READ_WRITE=1 ${COMPILER_OPTS}")
endif()
message(STATUS "COMPILER_OPTS = ${COMPILER_OPTS}")
# TODO this is a hack that overwrites the scs_types.h file, we should find a way
# to do this that doesn't pollute the master directory.
configure_file(${CMAKE_CURRENT_SOURCE_DIR}/cmake/scs_types.h.in
${CMAKE_CURRENT_SOURCE_DIR}/include/scs_types.h NEWLINE_STYLE LF)
# Public headers
set(${PROJECT_NAME}_PUBLIC_HDR include/scs_types.h include/scs.h)
# Common source files
set(${PROJECT_NAME}_SRC
src/aa.c
src/cones.c
src/ctrlc.c
src/exp_cone.c
src/linalg.c
src/normalize.c
src/rw.c
src/scs.c
src/scs_version.c
src/util.c
${LINSYS}/csparse.c
${LINSYS}/scs_matrix.c)
# Common header files
set(${PROJECT_NAME}_HDR
include/aa.h
include/cones.h
include/ctrlc.h
include/glbopts.h
include/linalg.h
include/linsys.h
include/normalize.h
include/rw.h
include/scs.h
include/scs_blas.h
include/scs_types.h
include/scs_work.h
include/util.h
${LINSYS}/csparse.h
${LINSYS}/scs_matrix.h)
# get all the c file in amd/external
file(GLOB ${PROJECT_NAME}_AMD_EXTERNAL_SRC ${EXTERNAL}/amd/*.c)
# get all the h file in amd/external
file(GLOB ${PROJECT_NAME}_AMD_EXTERNAL_HDR ${EXTERNAL}/amd/*.h)
# get all the c file in amd/external
file(GLOB ${PROJECT_NAME}_LDL_EXTERNAL_HDR ${EXTERNAL}/qdldl/*.h)
# ##############################################################################
# Direct method. Here we compile the direct method library.
set(${PROJECT_NAME}_DIRECT ${PROJECT_NAME}dir)
add_library(
${${PROJECT_NAME}_DIRECT}
${${PROJECT_NAME}_HDR}
${${PROJECT_NAME}_SRC}
${DIRSRC}/private.c
${DIRSRC}/private.h
${EXTERNAL}/qdldl/qdldl.c
${${PROJECT_NAME}_AMD_EXTERNAL_SRC}
${${PROJECT_NAME}_AMD_EXTERNAL_HDR}
${${PROJECT_NAME}_LDL_EXTERNAL_HDR})
target_include_directories(
${${PROJECT_NAME}_DIRECT}
PRIVATE
"$<BUILD_INTERFACE:${CMAKE_CURRENT_SOURCE_DIR}/${EXTERNAL}/amd;${CMAKE_CURRENT_SOURCE_DIR}/${EXTERNAL}/qdldl;${CMAKE_CURRENT_SOURCE_DIR}/${DIRSRC};${CMAKE_CURRENT_SOURCE_DIR}/${LINSYS}>"
)
target_include_directories(
${${PROJECT_NAME}_DIRECT}
PUBLIC "$<BUILD_INTERFACE:${CMAKE_CURRENT_SOURCE_DIR}/include>"
"$<INSTALL_INTERFACE:${CMAKE_INSTALL_INCLUDEDIR}/scs>")
# Compiled with blas and lapack, can solve LPs, SOCPs, SDPs, ECPs, and PCPs
target_compile_definitions(${${PROJECT_NAME}_DIRECT} PRIVATE ${COMPILER_OPTS})
# The library depends on math (m) blas and lapack
target_link_libraries(${${PROJECT_NAME}_DIRECT} PRIVATE m blas lapack)
# Set some properties
set_target_properties(
${${PROJECT_NAME}_DIRECT}
PROPERTIES VERSION ${scs_VERSION} PUBLIC_HEADER
"${${PROJECT_NAME}_PUBLIC_HDR}")
add_library(scs::${${PROJECT_NAME}_DIRECT} ALIAS ${${PROJECT_NAME}_DIRECT})
# Install the library
install(
TARGETS ${${PROJECT_NAME}_DIRECT}
EXPORT ${PROJECT_NAME}
COMPONENT runtime
LIBRARY DESTINATION "${CMAKE_INSTALL_LIBDIR}" COMPONENT shlib
ARCHIVE DESTINATION "${CMAKE_INSTALL_LIBDIR}" COMPONENT lib
RUNTIME DESTINATION "${CMAKE_INSTALL_BINDIR}" COMPONENT bin
PUBLIC_HEADER DESTINATION "${CMAKE_INSTALL_INCLUDEDIR}/scs")
# Add the direct method to the set of the compiled targets
set_property(GLOBAL APPEND PROPERTY SCS_TARGETS ${${PROJECT_NAME}_DIRECT})
# ##############################################################################
# Indirect method. Here we compile the indirect method library.
set(${PROJECT_NAME}_INDIRECT ${PROJECT_NAME}indir)
add_library(
${${PROJECT_NAME}_INDIRECT}
${${PROJECT_NAME}_HDR} ${${PROJECT_NAME}_SRC} ${INDIRSRC}/private.c
${INDIRSRC}/private.h ${${${PROJECT_NAME}_INDIRECT}_HDR})
target_include_directories(
${${PROJECT_NAME}_INDIRECT}
PRIVATE
"$<BUILD_INTERFACE:${CMAKE_CURRENT_SOURCE_DIR}/${INDIRSRC};${CMAKE_CURRENT_SOURCE_DIR}/${LINSYS}>"
)
target_include_directories(
${${PROJECT_NAME}_INDIRECT}
PUBLIC "$<BUILD_INTERFACE:${CMAKE_CURRENT_SOURCE_DIR}/include>"
"$<INSTALL_INTERFACE:${CMAKE_INSTALL_INCLUDEDIR}/scs>")
# Compiled with blas and lapack, can solve LPs, SOCPs, SDPs, ECPs, and PCPs
target_compile_definitions(${${PROJECT_NAME}_INDIRECT} PRIVATE ${COMPILER_OPTS}
-DINDIRECT)
# The library depends on math (m) blas and lapack
target_link_libraries(${${PROJECT_NAME}_INDIRECT} PUBLIC m blas lapack)
# Set some properties
set_target_properties(
${${PROJECT_NAME}_INDIRECT}
PROPERTIES VERSION ${scs_VERSION} PUBLIC_HEADER
"${${PROJECT_NAME}_PUBLIC_HDR}")
add_library(scs::${${PROJECT_NAME}_INDIRECT} ALIAS ${${PROJECT_NAME}_INDIRECT})
# Install the library
install(
TARGETS ${${PROJECT_NAME}_INDIRECT}
EXPORT ${PROJECT_NAME}
COMPONENT runtime
LIBRARY DESTINATION "${CMAKE_INSTALL_LIBDIR}" COMPONENT shlib
ARCHIVE DESTINATION "${CMAKE_INSTALL_LIBDIR}" COMPONENT lib
RUNTIME DESTINATION "${CMAKE_INSTALL_BINDIR}" COMPONENT bin
PUBLIC_HEADER DESTINATION "${CMAKE_INSTALL_INCLUDEDIR}/scs")
# Add the indirect method to the set of the compiled targets
set_property(GLOBAL APPEND PROPERTY SCS_TARGETS ${${PROJECT_NAME}_INDIRECT})
# ##############################################################################
# If MKLROOT is defined, then we install the MKL version.
if(DEFINED ENV{MKLROOT})
message(STATUS "MKLROOT set to $ENV{MKLROOT}")
message(STATUS "Will install SCS-MKL (libscsmkl).")
set(MKLSRC ${LINSYS}/mkl/direct)
# Here we compile the direct MKL pardiso library
set(${PROJECT_NAME}_MKL ${PROJECT_NAME}mkl)
add_library(
${${PROJECT_NAME}_MKL}
${${PROJECT_NAME}_HDR} ${${PROJECT_NAME}_SRC} ${MKLSRC}/private.c
${MKLSRC}/private.h ${${${PROJECT_NAME}_MKL}_HDR})
target_include_directories(
${${PROJECT_NAME}_MKL}
PRIVATE
"$<BUILD_INTERFACE:${CMAKE_CURRENT_SOURCE_DIR}/${MKLSRC};${CMAKE_CURRENT_SOURCE_DIR}/${LINSYS}>"
)
target_include_directories(
${${PROJECT_NAME}_MKL}
PUBLIC "$<BUILD_INTERFACE:${CMAKE_CURRENT_SOURCE_DIR}/include>"
"$<INSTALL_INTERFACE:${CMAKE_INSTALL_INCLUDEDIR}/scs>")
target_compile_definitions(${${PROJECT_NAME}_MKL} PRIVATE ${COMPILER_OPTS})
# See:
# https://www.intel.com/content/www/us/en/developer/tools/oneapi/onemkl-link-line-advisor.html
# This is probably not correct for other systems. TODO: make SCS-MKL
# work for all combinations of platform / compiler / threading options.
target_link_options(${${PROJECT_NAME}_MKL} PRIVATE "LINKER:--no-as-needed")
target_link_directories(${${PROJECT_NAME}_MKL} PRIVATE $ENV{MKLROOT}/lib)
target_link_libraries(
${${PROJECT_NAME}_MKL}
PRIVATE m
mkl_rt
mkl_gnu_thread
mkl_core
gomp
pthread
dl)
# Set some properties
set_target_properties(
${${PROJECT_NAME}_MKL}
PROPERTIES VERSION ${scs_VERSION} PUBLIC_HEADER
"${${PROJECT_NAME}_PUBLIC_HDR}")
add_library(scs::${${PROJECT_NAME}_MKL} ALIAS ${${PROJECT_NAME}_MKL})
# Install the library
install(
TARGETS ${${PROJECT_NAME}_MKL}
EXPORT ${PROJECT_NAME}
COMPONENT runtime
LIBRARY DESTINATION "${CMAKE_INSTALL_LIBDIR}" COMPONENT shlib
ARCHIVE DESTINATION "${CMAKE_INSTALL_LIBDIR}" COMPONENT lib
RUNTIME DESTINATION "${CMAKE_INSTALL_BINDIR}" COMPONENT bin
PUBLIC_HEADER DESTINATION "${CMAKE_INSTALL_INCLUDEDIR}/scs")
# Add the mkl method to the set of the compiled targets
set_property(GLOBAL APPEND PROPERTY SCS_TARGETS ${${PROJECT_NAME}_MKL})
else()
message(
STATUS "MKLROOT environment variable is undefined, skipping SCS-MKL install"
)
endif()
# ##############################################################################
# Install the .cmake file. It is possible to link scs o consumer libraries.
include(InstallBasicPackageFiles)
install_basic_package_files(
${PROJECT_NAME}
NAMESPACE
scs::
VERSION
${${PROJECT_NAME}_VERSION}
TARGETS_PROPERTY
SCS_TARGETS
COMPATIBILITY
SameMajorVersion
VARS_PREFIX
${PROJECT_NAME}
NO_CHECK_REQUIRED_COMPONENTS_MACRO)
# Add the tests
if(BUILD_TESTING)
add_executable(run_tests_direct test/run_tests.c)
target_compile_definitions(run_tests_direct PRIVATE ${COMPILER_OPTS})
target_link_libraries(run_tests_direct PRIVATE scs::scsdir)
target_include_directories(
run_tests_direct
PRIVATE
"$<BUILD_INTERFACE:${CMAKE_CURRENT_SOURCE_DIR}/test;${CMAKE_CURRENT_SOURCE_DIR}/include;${CMAKE_CURRENT_SOURCE_DIR}/${LINSYS}>"
)
add_test(
NAME run_tests_direct
COMMAND run_tests_direct
WORKING_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR})
add_executable(run_tests_indirect test/run_tests.c)
target_compile_definitions(run_tests_indirect PRIVATE ${COMPILER_OPTS})
target_link_libraries(run_tests_indirect PRIVATE scs::scsindir)
target_include_directories(
run_tests_indirect
PRIVATE
"$<BUILD_INTERFACE:${CMAKE_CURRENT_SOURCE_DIR}/test;${CMAKE_CURRENT_SOURCE_DIR}/include;${CMAKE_CURRENT_SOURCE_DIR}/${LINSYS}>"
)
add_test(
NAME run_tests_indirect
COMMAND run_tests_indirect
WORKING_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR})
if(DEFINED ENV{MKLROOT})
add_executable(run_tests_mkl test/run_tests.c)
target_compile_definitions(run_tests_mkl PRIVATE ${COMPILER_OPTS})
target_link_libraries(run_tests_mkl PRIVATE scs::scsmkl)
target_include_directories(
run_tests_mkl
PRIVATE
"$<BUILD_INTERFACE:${CMAKE_CURRENT_SOURCE_DIR}/test;${CMAKE_CURRENT_SOURCE_DIR}/include;${CMAKE_CURRENT_SOURCE_DIR}/${LINSYS}>"
)
add_test(
NAME run_tests_mkl
COMMAND run_tests_mkl
WORKING_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR})
endif()
endif()