123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439 |
- # Minimum version required
- cmake_minimum_required (VERSION 3.2)
- # Project name
- project (osqp)
- # Export compile commands
- set(CMAKE_EXPORT_COMPILE_COMMANDS ON)
- # Set the output folder where your program will be created
- set(EXECUTABLE_OUTPUT_PATH ${PROJECT_BINARY_DIR}/out)
- set(LIBRARY_OUTPUT_PATH ${PROJECT_BINARY_DIR}/out)
- # Some non-standard CMake modules
- LIST(APPEND CMAKE_MODULE_PATH ${PROJECT_SOURCE_DIR}/configure/cmake)
- INCLUDE(FindPythonModule)
- INCLUDE(Utils)
- # include(FindMKL) # Find MKL module
- # Detect operating system
- # ----------------------------------------------
- message(STATUS "We are on a ${CMAKE_SYSTEM_NAME} system")
- if(${CMAKE_SYSTEM_NAME} STREQUAL "Linux")
- set(IS_LINUX ON)
- elseif(${CMAKE_SYSTEM_NAME} STREQUAL "Darwin")
- set(IS_MAC ON)
- elseif(${CMAKE_SYSTEM_NAME} STREQUAL "Windows")
- set(IS_WINDOWS ON)
- endif()
- # Set options
- # ----------------------------------------------
- # Are unittests generated?
- option (UNITTESTS "Enable unittests generation" OFF)
- # Is the code generated for embedded platforms?
- # 1 : Yes. Matrix update not allowed.
- # 2 : Yes. Matrix update allowed.
- if (NOT DEFINED EMBEDDED)
- message(STATUS "Embedded is OFF")
- else()
- message(STATUS "Embedded is ${EMBEDDED}")
- endif()
- # Is printing enabled?
- option (PRINTING "Enable solver printing" OFF)
- if (DEFINED EMBEDDED)
- message(STATUS "Disabling printing for embedded")
- set(PRINTING OFF)
- endif()
- set(PRINTING OFF)
- message(STATUS "Printing is ${PRINTING}")
- # Is profiling enabled?
- option (PROFILING "Enable solver profiling (timing)" ON)
- if (DEFINED EMBEDDED)
- message(STATUS "Disabling profiling for embedded")
- set(PROFILING OFF)
- endif()
- message(STATUS "Profiling is ${PROFILING}")
- # Is user interrupt enabled?
- option (CTRLC "Enable user interrupt (Ctrl-C)" ON)
- if (DEFINED EMBEDDED)
- message(STATUS "Disabling user interrupt for embedded")
- set(CTRLC OFF)
- endif()
- message(STATUS "User interrupt is ${CTRLC}")
- # Use floats instead of integers
- option (DFLOAT "Use float numbers instead of doubles" OFF)
- message(STATUS "Floats are ${DFLOAT}")
- # Use long integers for indexing
- option (DLONG "Use long integers (64bit) for indexing" OFF)
- if (NOT (CMAKE_SIZEOF_VOID_P EQUAL 8))
- message(STATUS "Disabling long integers (64bit) on 32bit machine")
- set(DLONG OFF)
- endif()
- message(STATUS "Long integers (64bit) are ${DLONG}")
- option (DEBUG "Debug mode" OFF)
- if (CMAKE_BUILD_TYPE STREQUAL "Debug")
- set (DEBUG ON)
- message(STATUS "Debug mode is ${DEBUG}")
- endif()
- # Add code coverage
- option (COVERAGE "Perform code coverage" OFF)
- message(STATUS "Code coverage is ${COVERAGE}")
- # Memory allocators
- # ----------------------------------------------
- #Report on custom user header options. This is intended to allow
- #users to provide definitions of their own memory functions
- # The header should define the functions as follows
- #
- # define c_malloc mymalloc
- # define c_calloc mycalloc
- # define c_realloc myrealloc
- # define c_free myfree
- if(OSQP_CUSTOM_MEMORY)
- message(STATUS "User custom memory management header: ${OSQP_CUSTOM_MEMORY}")
- endif()
- # Linear solvers dependencies
- # ---------------------------------------------
- option (ENABLE_MKL_PARDISO "Enable MKL Pardiso solver" ON)
- if (DFLOAT)
- message(STATUS "Disabling MKL Pardiso Solver with floats")
- set(ENABLE_MKL_PARDISO OFF)
- elseif(DEFINED EMBEDDED)
- message(STATUS "Disabling MKL Pardiso Solver for embedded")
- set(ENABLE_MKL_PARDISO OFF)
- endif()
- message(STATUS "MKL Pardiso: ${ENABLE_MKL_PARDISO}")
- # Generate header file with the global options
- # ---------------------------------------------
- configure_file(${CMAKE_CURRENT_SOURCE_DIR}/configure/osqp_configure.h.in
- ${CMAKE_CURRENT_SOURCE_DIR}/include/osqp_configure.h
- NEWLINE_STYLE LF)
- # Set Compiler flags
- # ----------------------------------------------
- set(CMAKE_POSITION_INDEPENDENT_CODE ON) # -fPIC
- if (NOT MSVC)
- if (COVERAGE)
- set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} --coverage")
- if(FORTRAN)
- set(CMAKE_FORTRAN_FLAGS "${CMAKE_FORTRAN_FLAGS} --coverage")
- endif(FORTRAN)
- endif()
- if (DEBUG)
- set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -O0 -g")
- else()
- set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -O3")
- endif()
- set(CMAKE_C_STANDARD_LIBRARIES "${CMAKE_C_STANDARD_LIBRARIES} -lm") # Include math
- # Include real time library in linux
- if(${CMAKE_SYSTEM_NAME} STREQUAL "Linux")
- set(CMAKE_C_STANDARD_LIBRARIES "${CMAKE_C_STANDARD_LIBRARIES} -lrt -ldl")
- endif()
- endif (NOT MSVC)
- # Set sources and includes
- # ----------------------------------------------
- add_subdirectory (src)
- add_subdirectory (include)
- # if we are building the Python interface, let's look for Python
- # and set some options
- # -----------------------------------------------------------------
- if (PYTHON)
- # Python include directories need to be passed by the python compilation process
- if (NOT PYTHON_INCLUDE_DIRS)
- message( FATAL_ERROR "You need Python include directories to build the Python interface" )
- endif (NOT PYTHON_INCLUDE_DIRS)
- # Include directories for Python headers
- include_directories(${PYTHON_INCLUDE_DIRS})
- # Pass PYTHON flag to C compiler
- add_definitions(-DPYTHON)
- if (UNITTESTS)
- # Disable unittests
- message(STATUS "Disabling UNITTESTS because we are building Python interface")
- set(UNITTESTS OFF)
- endif (UNITTESTS)
- endif (PYTHON)
- # if we are building the Matlab interface, let's look for Matlab
- # and set some options
- # -----------------------------------------------------------------
- if (MATLAB)
- find_package(Matlab)
- if (NOT Matlab_FOUND)
- message( FATAL_ERROR "You need Matlab libraries to build the Matlab interface" )
- endif (NOT Matlab_FOUND)
- # Include directories for Matlab headers
- include_directories(${Matlab_INCLUDE_DIRS})
- message(STATUS "Matlab root is " ${Matlab_ROOT_DIR})
- # Pass MATLAB flag to C compiler
- add_definitions(-DMATLAB)
- # Insist on the pre 2018 complex data API
- # so that mxGetPr will work correctly
- add_definitions(-DMATLAB_MEXSRC_RELEASE=R2017b)
- message(STATUS "Using Matlab pre-2018a API for mxGetPr compatibility")
- if (UNITTESTS)
- # Disable unittests
- message(STATUS "Disabling UNITTESTS because we are building Matlab interface")
- set(UNITTESTS OFF)
- endif (UNITTESTS)
- endif (MATLAB)
- # if we are building the R interface, let's look for R
- # and set some options
- # -----------------------------------------------------------------
- if (R_LANG)
- message(STATUS "We are building the R interface")
- # Look for R libraries
- find_package(R)
- if (NOT R_FOUND)
- message( FATAL_ERROR "You need R libraries to build the R interface" )
- endif (NOT R_FOUND)
- message(STATUS "R exec is: " ${R_EXEC})
- message(STATUS "R root dir is: " ${R_ROOT_DIR})
- message(STATUS "R includes are in: " ${R_INCLUDE_DIRS})
- # Include directories for R headers
- include_directories(${R_INCLUDE_DIRS})
- # Pass R_LANG flag to C compiler
- add_definitions(-DR_LANG)
- if (UNITTESTS)
- # Disable unittests
- message(STATUS "Disabling UNITTESTS because we are building the R interface")
- set(UNITTESTS OFF)
- endif (UNITTESTS)
- endif (R_LANG)
- # Create Static Library
- # ----------------------------------------------
- # Add linear system solvers cumulative library
- add_subdirectory(lin_sys)
- # Static library
- add_library (osqpstatic STATIC ${osqp_src} ${osqp_headers} ${linsys_solvers})
- # Give same name to static library output
- set_target_properties(osqpstatic PROPERTIES OUTPUT_NAME osqp)
- # Include directories for linear system solvers
- target_include_directories(osqpstatic PRIVATE ${linsys_solvers_includes})
- # Declare include directories for the cmake exported target
- target_include_directories(osqpstatic
- PUBLIC "$<BUILD_INTERFACE:${CMAKE_CURRENT_SOURCE_DIR}/include>"
- "$<INSTALL_INTERFACE:$<INSTALL_PREFIX>/${CMAKE_INSTALL_INCLUDEDIR}/osqp>")
- # Install Static Library
- # ----------------------------------------------
- include(GNUInstallDirs)
- install(TARGETS osqpstatic
- EXPORT ${PROJECT_NAME}
- ARCHIVE DESTINATION "${CMAKE_INSTALL_LIBDIR}"
- LIBRARY DESTINATION "${CMAKE_INSTALL_LIBDIR}"
- RUNTIME DESTINATION "${CMAKE_INSTALL_BINDIR}")
- # Install Headers
- # ----------------------------------------------
- install(FILES ${osqp_headers} DESTINATION "${CMAKE_INSTALL_INCLUDEDIR}/osqp")
- if (MATLAB)
- target_link_libraries (osqpstatic ${Matlab_LIBRARIES})
- endif (MATLAB)
- # If we are building Python/Matlab/R interface:
- # - do not build shared library
- # - do not build demo
- if (NOT PYTHON AND NOT MATLAB AND NOT R_LANG AND NOT EMBEDDED)
- # Create osqp shared library
- # NB: Add all the linear system solvers here
- add_library (osqp SHARED ${osqp_src} ${osqp_headers} ${linsys_solvers})
- # Include directories for linear system solvers
- target_include_directories(osqp PRIVATE ${linsys_solvers_includes})
- # Declare include directories for the cmake exported target
- target_include_directories(osqp
- PUBLIC "$<BUILD_INTERFACE:${CMAKE_CURRENT_SOURCE_DIR}/include>"
- "$<INSTALL_INTERFACE:$<INSTALL_PREFIX>/${CMAKE_INSTALL_INCLUDEDIR}/osqp>")
- # Install osqp shared library
- install(TARGETS osqp
- EXPORT ${PROJECT_NAME}
- LIBRARY DESTINATION "${CMAKE_INSTALL_LIBDIR}"
- ARCHIVE DESTINATION "${CMAKE_INSTALL_LIBDIR}"
- RUNTIME DESTINATION "${CMAKE_INSTALL_BINDIR}")
- # Create demo executable (linked to static library)
- add_executable (osqp_demo ${PROJECT_SOURCE_DIR}/examples/osqp_demo.c)
- target_link_libraries (osqp_demo osqpstatic)
- endif (NOT PYTHON AND NOT MATLAB AND NOT R_LANG AND NOT EMBEDDED)
- # Create CMake packages for the build directory
- # ----------------------------------------------
- include(CMakePackageConfigHelpers)
- export(EXPORT ${PROJECT_NAME}
- FILE "${CMAKE_CURRENT_BINARY_DIR}/osqp-targets.cmake"
- NAMESPACE osqp::)
- if(NOT EXISTS ${CMAKE_CURRENT_BINARY_DIR}/osqp-config.cmake)
- file(WRITE ${CMAKE_CURRENT_BINARY_DIR}/osqp-config.cmake "include(\"\${CMAKE_CURRENT_LIST_DIR}/osqp-targets.cmake\")\n")
- endif()
- # Create CMake packages for the install directory
- # ----------------------------------------------
- set(ConfigPackageLocation lib/cmake/osqp)
- install(EXPORT ${PROJECT_NAME}
- FILE osqp-targets.cmake
- NAMESPACE osqp::
- DESTINATION ${ConfigPackageLocation})
- install(FILES ${CMAKE_CURRENT_BINARY_DIR}/osqp-config.cmake
- DESTINATION ${ConfigPackageLocation})
- # Add uninstall command
- # ----------------------------------------------
- if(NOT TARGET uninstall)
- configure_file(
- "${CMAKE_CURRENT_SOURCE_DIR}/configure/cmake/cmake_uninstall.cmake.in"
- "${CMAKE_CURRENT_BINARY_DIR}/cmake_uninstall.cmake"
- IMMEDIATE @ONLY)
- add_custom_target(uninstall
- COMMAND ${CMAKE_COMMAND} -P ${CMAKE_CURRENT_BINARY_DIR}/cmake_uninstall.cmake)
- endif()
- # Add testing
- # ----------------------------------------------
- # Add custom command to generate tests
- if (UNITTESTS)
- find_package(PythonInterp)
- if(NOT PYTHONINTERP_FOUND)
- message( FATAL_ERROR "You need python installed to generate unittests. If you do not want to compile the unittests pass -DUNITTESTS=OFF to cmake." )
- endif()
- INCLUDE(FindPythonModule)
- find_python_module(numpy)
- IF(NOT NUMPY_FOUND)
- message( FATAL_ERROR "You need numpy python module installed to generate unittests. If you do not want to compile the unittests pass -DUNITTESTS=OFF to cmake." )
- ENDIF()
- find_python_module(scipy)
- # Check scipy version for sparse.random functionalities
- IF((NOT SCIPY_FOUND) OR (SCIPY_VERSION VERSION_LESS 0.17.0))
- message( FATAL_ERROR "You need scipy python module installed to generate unittests. If you do not want to compile the unittests pass -DUNITTESTS=OFF to cmake." )
- ENDIF()
- find_python_module(__future__)
- IF(NOT __FUTURE___FOUND)
- message( FATAL_ERROR "You need future python module installed to generate unittests. If you do not want to compile the unittests pass -DUNITTESTS=OFF to cmake." )
- ENDIF()
- # Add test_headers and codegen_test_headers
- add_subdirectory(tests)
- # Generating tests.stamp so that the test data are not always generated
- # set(data_timestamp ${PROJECT_SOURCE_DIR}/tests/tests_data.stamp)
- add_custom_command(
- WORKING_DIRECTORY ${PROJECT_SOURCE_DIR}/tests
- COMMAND ${PYTHON_EXECUTABLE} generate_tests_data.py
- DEPENDS ${PROJECT_SOURCE_DIR}/tests/generate_tests_data.py
- OUTPUT ${codegen_test_headers}
- COMMENT "Generating unittests data files using Python"
- )
- # Direct linear solver testing
- include_directories(tests)
- add_executable(osqp_tester
- ${PROJECT_SOURCE_DIR}/tests/osqp_tester.c
- ${PROJECT_SOURCE_DIR}/tests/osqp_tester.h
- ${PROJECT_SOURCE_DIR}/tests/minunit.h
- ${test_headers}
- ${codegen_test_headers})
- target_link_libraries (osqp_tester osqpstatic)
- # Add custom memory target
- add_executable(osqp_tester_custom_memory
- EXCLUDE_FROM_ALL
- ${PROJECT_SOURCE_DIR}/tests/osqp_tester.c
- ${PROJECT_SOURCE_DIR}/tests/osqp_tester.h
- ${PROJECT_SOURCE_DIR}/tests/minunit.h
- ${test_headers}
- ${codegen_test_headers}
- ${PROJECT_SOURCE_DIR}/tests/custom_memory/custom_memory.c
- ${PROJECT_SOURCE_DIR}/tests/custom_memory/custom_memory.h
- )
- target_link_libraries (osqp_tester_custom_memory osqpstatic)
- # Add testing
- include(CTest)
- enable_testing()
- add_test(NAME tester COMMAND $<TARGET_FILE:osqp_tester>)
- endif()
|