From a3d0a30c86327e05b92d9593de93683b76f965ea Mon Sep 17 00:00:00 2001 From: Corentin Le Molgat Date: Tue, 2 Apr 2019 15:07:59 +0200 Subject: [PATCH] Add CMake based build support - Fix super build (e.g. FetchContent) integration - cmake: option() honors normal variables (CMP0077) - add some Osi test to cmake adapt test to ignore when mps file are not present --- .gitignore | 23 +-- CMakeLists.txt | 139 ++++++++++++++++ Osi/CMakeLists.txt | 116 ++++++++++++++ Osi/config.h.cmake.in | 112 +++++++++++++ Osi/config_osi.h.cmake.in | 13 ++ Osi/src/OsiCommonTest/OsiColCutTest.cpp | 108 +++++++------ Osi/src/OsiCommonTest/OsiRowCutTest.cpp | 36 +++-- .../OsiCommonTest/OsiSolverInterfaceTest.cpp | 54 ++++--- Osi/test/CMakeLists.txt | 30 ++++ cmake/CheckEnv.cmake | 151 ++++++++++++++++++ cmake/Config.cmake.in | 19 +++ cmake/ParseAc.cmake | 28 ++++ 12 files changed, 721 insertions(+), 108 deletions(-) create mode 100644 CMakeLists.txt create mode 100644 Osi/CMakeLists.txt create mode 100644 Osi/config.h.cmake.in create mode 100644 Osi/config_osi.h.cmake.in create mode 100644 Osi/test/CMakeLists.txt create mode 100644 cmake/CheckEnv.cmake create mode 100644 cmake/Config.cmake.in create mode 100644 cmake/ParseAc.cmake diff --git a/.gitignore b/.gitignore index f28ec2dcb..0b76a74bb 100644 --- a/.gitignore +++ b/.gitignore @@ -1,19 +1,4 @@ -# Ignore VS files -*.suo -*.db -*.bak -*.user -**/.vs/ -**/MSVisualStudio/**/Release/ -**/MSVisualStudio/**/ReleaseParallel/ -**/MSVisualStudio/**/Debug/ - -# Ignore files created during unit tests -**/MSVisualStudio/**/*.mps -**/MSVisualStudio/**/*.lp -**/MSVisualStudio/**/*.out - -# Ignore autotools cache files -aclocal.m4* -acinclude.m4 -autom4te* +*.swp +.vs/ +build/ +cache/ diff --git a/CMakeLists.txt b/CMakeLists.txt new file mode 100644 index 000000000..bc22fbda1 --- /dev/null +++ b/CMakeLists.txt @@ -0,0 +1,139 @@ +cmake_minimum_required(VERSION 3.16) +list(APPEND CMAKE_MODULE_PATH "${CMAKE_CURRENT_SOURCE_DIR}/cmake") + +include(ParseAc) +parse_ac(VERSION MAJOR MINOR PATCH) + +project(Osi VERSION ${VERSION} LANGUAGES CXX C) +set(PROJECT_NAMESPACE coin) +message(STATUS "${PROJECT_NAME} version: ${PROJECT_VERSION}") +#message(STATUS "major: ${PROJECT_VERSION_MAJOR}") +#message(STATUS "minor: ${PROJECT_VERSION_MINOR}") +#message(STATUS "patch: ${PROJECT_VERSION_PATCH}") + +# Default Build Type to be Release +get_property(isMultiConfig GLOBAL PROPERTY GENERATOR_IS_MULTI_CONFIG) +if(isMultiConfig) + if(NOT CMAKE_CONFIGURATION_TYPES) + set(CMAKE_CONFIGURATION_TYPES "Release;Debug" CACHE STRING + "Choose the type of builds, options are: Debug Release RelWithDebInfo MinSizeRel. (default: Release;Debug)" + FORCE) + endif() + message(STATUS "Configuration types: ${CMAKE_CONFIGURATION_TYPES}") +else() + if(NOT CMAKE_BUILD_TYPE) + set(CMAKE_BUILD_TYPE "Release" CACHE STRING + "Choose the type of build, options are: Debug Release RelWithDebInfo MinSizeRel. (default: Release)" + FORCE) + endif() + message(STATUS "Build type: ${CMAKE_BUILD_TYPE}") +endif() + +# Layout build dir like install dir +include(GNUInstallDirs) +set(CMAKE_BUILD_WITH_INSTALL_RPATH TRUE) +set(CMAKE_BUILD_RPATH_USE_ORIGIN ON) +set(CMAKE_INSTALL_RPATH_USE_LINK_PATH ON) +if(UNIX) + option(BUILD_SHARED_LIBS "Build shared libraries (.so or .dylib)." ON) + set(CMAKE_LIBRARY_OUTPUT_DIRECTORY ${CMAKE_BINARY_DIR}/${CMAKE_INSTALL_LIBDIR}) + set(CMAKE_ARCHIVE_OUTPUT_DIRECTORY ${CMAKE_BINARY_DIR}/${CMAKE_INSTALL_LIBDIR}) + set(CMAKE_RUNTIME_OUTPUT_DIRECTORY ${CMAKE_BINARY_DIR}/${CMAKE_INSTALL_BINDIR}) + # for multi-config build system (e.g. Xcode, Ninja Multi-Config) + foreach(OutputConfig IN LISTS CMAKE_CONFIGURATION_TYPES) + string(TOUPPER ${OutputConfig} OUTPUTCONFIG) + set(CMAKE_LIBRARY_OUTPUT_DIRECTORY_${OUTPUTCONFIG} ${CMAKE_BINARY_DIR}/${OutputConfig}/${CMAKE_INSTALL_LIBDIR}) + set(CMAKE_ARCHIVE_OUTPUT_DIRECTORY_${OUTPUTCONFIG} ${CMAKE_BINARY_DIR}/${OutputConfig}/${CMAKE_INSTALL_LIBDIR}) + set(CMAKE_RUNTIME_OUTPUT_DIRECTORY_${OUTPUTCONFIG} ${CMAKE_BINARY_DIR}/${OutputConfig}/${CMAKE_INSTALL_BINDIR}) + endforeach() +else() + # Currently Only support static build for windows + option(BUILD_SHARED_LIBS "Build shared libraries (.dll)." OFF) + set(CMAKE_LIBRARY_OUTPUT_DIRECTORY ${CMAKE_BINARY_DIR}/${CMAKE_INSTALL_BINDIR}) + set(CMAKE_ARCHIVE_OUTPUT_DIRECTORY ${CMAKE_BINARY_DIR}/${CMAKE_INSTALL_BINDIR}) + set(CMAKE_RUNTIME_OUTPUT_DIRECTORY ${CMAKE_BINARY_DIR}/${CMAKE_INSTALL_BINDIR}) + # for multi-config builds (e.g. msvc) + foreach(OutputConfig IN LISTS CMAKE_CONFIGURATION_TYPES) + string(TOUPPER ${OutputConfig} OUTPUTCONFIG) + set(CMAKE_LIBRARY_OUTPUT_DIRECTORY_${OUTPUTCONFIG} ${CMAKE_BINARY_DIR}/${OutputConfig}/${CMAKE_INSTALL_BINDIR}) + set(CMAKE_ARCHIVE_OUTPUT_DIRECTORY_${OUTPUTCONFIG} ${CMAKE_BINARY_DIR}/${OutputConfig}/${CMAKE_INSTALL_BINDIR}) + set(CMAKE_RUNTIME_OUTPUT_DIRECTORY_${OUTPUTCONFIG} ${CMAKE_BINARY_DIR}/${OutputConfig}/${CMAKE_INSTALL_BINDIR}) + endforeach() +endif() + +if(MSVC AND BUILD_SHARED_LIBS) + set(CMAKE_WINDOWS_EXPORT_ALL_SYMBOLS ON) +endif() + +# config options +if(MSVC) + # Build with multiple processes + add_definitions(/MP) + add_definitions(/D_CRT_SECURE_NO_WARNINGS /D_CRT_SECURE_NO_DEPRECATE) + # MSVC warning suppressions + add_definitions( + /wd4018 # 'expression' : signed/unsigned mismatch + /wd4065 # switch statement contains 'default' but no 'case' labels + /wd4101 # 'identifier' : unreferenced local variable + /wd4102 # 'label' : unreferenced label + /wd4244 # 'conversion' conversion from 'type1' to 'type2', possible loss of data + /wd4267 # 'var' : conversion from 'size_t' to 'type', possible loss of data + /wd4309 # 'conversion' : truncation of constant value + /wd4805 # 'operation' : unsafe mix of type 'type1' and type 'type2' in operation. + /wd4996 # The compiler encountered a deprecated declaration. + ) +endif() +if(APPLE) + set( + CMAKE_CXX_FLAGS + "${CMAKE_CXX_FLAGS} -Wno-inconsistent-missing-override -Wno-unused-command-line-argument -Wno-unused-result -Wno-exceptions" + ) + set(CMAKE_OSX_DEPLOYMENT_TARGET "10.15" CACHE STRING "Minimum OS X deployment version") +endif() + +# ZLIB +if(NOT TARGET ZLIB::ZLIB) + find_package(ZLIB) +endif() +if(ZLIB_FOUND OR TARGET ZLIB::ZLIB) + message(STATUS "Use zlib") + set(HAVE_ZLIB_H "1" CACHE INTERNAL "Use zlib") + set(COIN_HAS_ZLIB "1" CACHE INTERNAL "Use zlib") +endif() + +# PThread +set(THREADS_PREFER_PTHREAD_FLAG ON) +find_package(Threads) +if(CMAKE_USE_PTHREADS_INIT) + set(PTHREADS_FOUND TRUE) +else() + set(PTHREADS_FOUND FALSE) +endif() + +# CoinUtils +if(NOT TARGET Coin::CoinUtils) + find_package(CoinUtils REQUIRED CONFIG) +endif() + +include(CheckEnv) +include(CTest) + +add_subdirectory(Osi) + +include(GNUInstallDirs) +install(EXPORT ${PROJECT_NAME}Targets + NAMESPACE Coin:: + DESTINATION "${CMAKE_INSTALL_LIBDIR}/cmake/${PROJECT_NAME}") +include(CMakePackageConfigHelpers) +configure_package_config_file(cmake/Config.cmake.in + "${PROJECT_BINARY_DIR}/${PROJECT_NAME}Config.cmake" + INSTALL_DESTINATION "${CMAKE_INSTALL_LIBDIR}/cmake/${PROJECT_NAME}") +write_basic_package_version_file( + "${PROJECT_BINARY_DIR}/${PROJECT_NAME}ConfigVersion.cmake" + COMPATIBILITY SameMajorVersion) +install( + FILES + "${PROJECT_BINARY_DIR}/${PROJECT_NAME}Config.cmake" + "${PROJECT_BINARY_DIR}/${PROJECT_NAME}ConfigVersion.cmake" + DESTINATION "${CMAKE_INSTALL_LIBDIR}/cmake/${PROJECT_NAME}" + COMPONENT Devel) diff --git a/Osi/CMakeLists.txt b/Osi/CMakeLists.txt new file mode 100644 index 000000000..7503f3933 --- /dev/null +++ b/Osi/CMakeLists.txt @@ -0,0 +1,116 @@ +set(NAME "OSI") + +# PTHREAD +if(PTHREADS_FOUND) + set(${NAME}_PTHREADS "1" CACHE INTERNAL "Use pthread") +endif() + +set(COIN_${NAME}_CHECKLEVEL "0" CACHE INTERNAL + "${NAME} check level") +set(COIN_${NAME}_VERBOSITY "0" CACHE INTERNAL + "${NAME} verbosity level") +configure_file(config.h.cmake.in config.h) +configure_file(config_osi.h.cmake.in config_osi.h) + +set(_SRCS + src/Osi/OsiAuxInfo.cpp + src/Osi/OsiBranchingObject.cpp + src/Osi/OsiChooseVariable.cpp + src/Osi/OsiColCut.cpp + src/Osi/OsiCut.cpp + src/Osi/OsiCuts.cpp + src/Osi/OsiNames.cpp + src/Osi/OsiPresolve.cpp + src/Osi/OsiRowCut.cpp + src/Osi/OsiRowCutDebugger.cpp + src/Osi/OsiSolverBranch.cpp + src/Osi/OsiSolverInterface.cpp) + +set(_HDRS + src/Osi/OsiConfig.h + src/Osi/OsiAuxInfo.hpp + src/Osi/OsiBranchingObject.hpp + src/Osi/OsiChooseVariable.hpp + src/Osi/OsiColCut.hpp + src/Osi/OsiCollections.hpp + src/Osi/OsiCut.hpp + src/Osi/OsiCuts.hpp + src/Osi/OsiPresolve.hpp + src/Osi/OsiRowCut.hpp + src/Osi/OsiRowCutDebugger.hpp + src/Osi/OsiSolverBranch.hpp + src/Osi/OsiSolverInterface.hpp + src/Osi/OsiSolverParameters.hpp) + +include(GNUInstallDirs) + +add_library(Osi ${_SRCS} ${_HDRS}) +target_include_directories(Osi PUBLIC + $ + $ + $ + $) +target_compile_definitions(Osi + PUBLIC HAVE_CONFIG_H + PRIVATE OSI_BUILD) +if(CMAKE_VERSION VERSION_LESS "3.8.2") + set_property(TARGET Osi PROPERTY CXX_STANDARD 11) + set_property(TARGET Osi PROPERTY CXX_STANDARD_REQUIRED ON) +else() + target_compile_features(Osi PUBLIC cxx_std_11) +endif() +if(APPLE) + set_target_properties(Osi PROPERTIES INSTALL_RPATH "@loader_path") +elseif(UNIX) + set_target_properties(Osi PROPERTIES INSTALL_RPATH "$ORIGIN") +endif() +target_link_libraries(Osi PUBLIC Coin::CoinUtils) +set_target_properties(Osi PROPERTIES + PUBLIC_HEADER "${_HDRS};${CMAKE_CURRENT_BINARY_DIR}/config_osi.h" + VERSION ${PROJECT_VERSION} + SOVERSION ${PROJECT_VERSION_MAJOR}) +add_library(Coin::Osi ALIAS Osi) + +# Install +install(TARGETS Osi + EXPORT ${PROJECT_NAME}Targets + PUBLIC_HEADER DESTINATION ${CMAKE_INSTALL_INCLUDEDIR}/coin + ARCHIVE DESTINATION ${CMAKE_INSTALL_LIBDIR} + LIBRARY DESTINATION ${CMAKE_INSTALL_LIBDIR} + ) + +if(BUILD_TESTING) +add_library(OsiCommonTest "") +target_sources(OsiCommonTest PRIVATE + src/OsiCommonTest/OsiColCutTest.cpp + src/OsiCommonTest/OsiCutsTest.cpp + src/OsiCommonTest/OsiNetlibTest.cpp + src/OsiCommonTest/OsiRowCutDebuggerTest.cpp + src/OsiCommonTest/OsiRowCutTest.cpp + src/OsiCommonTest/OsiSimplexAPITest.cpp + src/OsiCommonTest/OsiSolverInterfaceTest.cpp + src/OsiCommonTest/OsiUnitTests.hpp + src/OsiCommonTest/OsiUnitTestUtils.cpp) +target_include_directories(OsiCommonTest PUBLIC + $ + $ + $ + $) +target_compile_definitions(OsiCommonTest + PUBLIC HAVE_CONFIG_H + PRIVATE OSI_BUILD) +target_compile_features(OsiCommonTest PUBLIC cxx_std_11) +if(APPLE) + set_target_properties(OsiCommonTest PROPERTIES INSTALL_RPATH "@loader_path") +elseif(UNIX) + set_target_properties(OsiCommonTest PROPERTIES INSTALL_RPATH "$ORIGIN") +endif() +target_link_libraries(OsiCommonTest PUBLIC Coin::Osi) +set_target_properties(OsiCommonTest PROPERTIES + PUBLIC_HEADER "src/OsiCommonTest/OsiUnitTests.hpp" + VERSION ${PROJECT_VERSION} + SOVERSION ${PROJECT_VERSION_MAJOR}) +add_library(Coin::OsiCommonTest ALIAS OsiCommonTest) + + add_subdirectory(test) +endif() diff --git a/Osi/config.h.cmake.in b/Osi/config.h.cmake.in new file mode 100644 index 000000000..f544df840 --- /dev/null +++ b/Osi/config.h.cmake.in @@ -0,0 +1,112 @@ +/*config.h. Generated by configure_file.*/ + +#define COIN_HAS_COINUTILS 1 + +/* VERSION */ +#define VERSION "${VERSION}" +/* ${NAME}_VERSION */ +#define ${NAME}_VERSION "${VERSION}" +/* ${NAME}_VERSION_MAJOR */ +#define ${NAME}_VERSION_MAJOR ${MAJOR} +/* ${NAME}_VERSION_MINOR */ +#define ${NAME}_VERSION_MINOR ${MINOR} +/* ${NAME}_VERSION_RELEASE */ +#define ${NAME}_VERSION_RELEASE ${PATCH} + +/* HAVE_MATH_H */ +#cmakedefine HAVE_MATH_H ${HAVE_MATH_H} +/* HAVE_CTYPE_H */ +#cmakedefine HAVE_CTYPE_H ${HAVE_CTYPE_H} +/* HAVE_INTTYPES_H */ +#cmakedefine HAVE_INTTYPES_H ${HAVE_INTTYPES_H} +/* HAVE_FLOAT_H */ +#cmakedefine HAVE_FLOAT_H ${HAVE_FLOAT_H} +/* HAVE_IEEEFP_H */ +#cmakedefine HAVE_IEEEFP_H ${HAVE_IEEEFP_H} +/* HAVE_STDARG_H */ +#cmakedefine HAVE_STDARG_H ${HAVE_STDARG_H} +/* HAVE_STDDEF_H */ +#cmakedefine HAVE_STDDEF_H ${HAVE_STDDEF_H} +/* HAVE_STDINT_H */ +#cmakedefine HAVE_STDINT_H ${HAVE_STDINT_H} +/* HAVE_STDIO_H */ +#cmakedefine HAVE_STDIO_H ${HAVE_STDIO_H} +/* HAVE_STDLIB_H */ +#cmakedefine HAVE_STDLIB_H ${HAVE_STDLIB_H} +/* HAVE_ASSERT_H */ +#cmakedefine HAVE_ASSERT_H ${HAVE_ASSERT_H} +/* HAVE_DLFCN_H */ +#cmakedefine HAVE_DLFCN_H ${HAVE_DLFCN_H} +/* HAVE_ENDIAN_H */ +#cmakedefine HAVE_ENDIAN_H ${HAVE_ENDIAN_H} +/* HAVE_MEMORY_H */ +#cmakedefine HAVE_MEMORY_H ${HAVE_MEMORY_H} +/* HAVE_STRINGS_H */ +#cmakedefine HAVE_STRINGS_H ${HAVE_STRINGS_H} +/* HAVE_STRING_H */ +#cmakedefine HAVE_STRING_H ${HAVE_STRING_H} +/* HAVE_TIME_H */ +#cmakedefine HAVE_TIME_H ${HAVE_TIME_H} +/* HAVE_UNISTD_H */ +#cmakedefine HAVE_UNISTD_H ${HAVE_UNISTD_H} +/* HAVE_SYS_STAT_H */ +#cmakedefine HAVE_SYS_STAT_H ${HAVE_SYS_STAT_H} +/* HAVE_SYS_TYPES_H */ +#cmakedefine HAVE_SYS_TYPES_H ${HAVE_SYS_TYPES_H} + +/* HAVE_CMATH */ +#cmakedefine HAVE_CMATH ${HAVE_CMATH} +/* HAVE_CCTYPE */ +#cmakedefine HAVE_CCTYPE ${HAVE_CCTYPE} +/* HAVE_CINTTYPES */ +#cmakedefine HAVE_CINTTYPES ${HAVE_CINTTYPES} +/* HAVE_CFLOAT */ +#cmakedefine HAVE_CFLOAT ${HAVE_CFLOAT} +/* HAVE_CIEEEFP */ +#cmakedefine HAVE_CIEEEFP ${HAVE_CIEEEFP} +/* HAVE_CSTDARG */ +#cmakedefine HAVE_CSTDARG ${HAVE_CSTDARG} +/* HAVE_CSTDDEF */ +#cmakedefine HAVE_CSTDDEF ${HAVE_CSTDDEF} +/* HAVE_CSTDINT */ +#cmakedefine HAVE_CSTDINT ${HAVE_CSTDINT} +/* HAVE_CSTDIO */ +#cmakedefine HAVE_CSTDIO ${HAVE_CSTDIO} +/* HAVE_CSTDLIB */ +#cmakedefine HAVE_CSTDLIB ${HAVE_CSTDLIB} +/* HAVE_CASSERT */ +#cmakedefine HAVE_CASSERT ${HAVE_CASSERT} +/* HAVE_CSTRING */ +#cmakedefine HAVE_CSTRING ${HAVE_CSTRING} +/* HAVE_CTIME */ +#cmakedefine HAVE_CTIME ${HAVE_CTIME} + +/* COIN_C_FINITE */ +#cmakedefine COIN_C_FINITE ${COIN_C_FINITE} +/* COIN_C_ISNAN */ +#cmakedefine COIN_C_ISNAN ${COIN_C_ISNAN} +/* COIN_INT64_T */ +#cmakedefine COIN_INT64_T ${COIN_INT64_T} +/* COIN_UINT64_T */ +#cmakedefine COIN_UINT64_T ${COIN_UINT64_T} +/* COIN_INTPTR_T */ +#cmakedefine COIN_INTPTR_T ${COIN_INTPTR_T} + +/* COIN_${NAME}_CHECKLEVEL */ +#define COIN_${NAME}_CHECKLEVEL ${COIN_${NAME}_CHECKLEVEL} +/* COIN_${NAME}_VERBOSITY */ +#define COIN_${NAME}_VERBOSITY ${COIN_${NAME}_VERBOSITY} + +/* PACKAGE */ +#cmakedefine PACKAGE +/* PACKAGE_NAME */ +#cmakedefine PACKAGE_NAME +/* PACKAGE_VERSION */ +#cmakedefine PACKAGE_VERSION +/* PACKAGE_STRING */ +#cmakedefine PACKAGE_STRING +/* PACKAGE_TARNAME */ +#cmakedefine PACKAGE_TARNAME +/* PACKAGE_BUGREPORT */ +#cmakedefine PACKAGE_BUGREPORT + diff --git a/Osi/config_osi.h.cmake.in b/Osi/config_osi.h.cmake.in new file mode 100644 index 000000000..8dc44bf97 --- /dev/null +++ b/Osi/config_osi.h.cmake.in @@ -0,0 +1,13 @@ +#ifndef __CONFIG_${NAME}_H__ +#define __CONFIG_${NAME}_H__ + +/* ${NAME}_VERSION */ +#define ${NAME}_VERSION "${VERSION}" +/* ${NAME}_VERSION_MAJOR */ +#define ${NAME}_VERSION_MAJOR ${MAJOR} +/* ${NAME}_VERSION_MINOR */ +#define ${NAME}_VERSION_MINOR ${MINOR} +/* ${NAME}_VERSION_RELEASE */ +#define ${NAME}_VERSION_RELEASE ${PATCH} + +#endif diff --git a/Osi/src/OsiCommonTest/OsiColCutTest.cpp b/Osi/src/OsiCommonTest/OsiColCutTest.cpp index 256e1d0a0..d5068177e 100644 --- a/Osi/src/OsiCommonTest/OsiColCutTest.cpp +++ b/Osi/src/OsiCommonTest/OsiColCutTest.cpp @@ -187,8 +187,10 @@ void OsiColCutUnitTest(const OsiSolverInterface *baseSiP, const std::string &mps OsiSolverInterface *imP = baseSiP->clone(); assert(imP != NULL); std::string fn = mpsDir + "exmip1"; - imP->readMps(fn.c_str(), "mps"); - OSIUNITTEST_ASSERT_ERROR(!r.consistent(*imP), {}, "osicolcut", "consistent"); + const int error = imP->readMps(fn.c_str(), "mps"); + if (!error) { + OSIUNITTEST_ASSERT_ERROR(!r.consistent(*imP), {}, "osicolcut", "consistent"); + } delete imP; } { @@ -208,38 +210,39 @@ void OsiColCutUnitTest(const OsiSolverInterface *baseSiP, const std::string &mps OsiSolverInterface *imP = baseSiP->clone(); assert(imP != NULL); std::string fn = mpsDir + "exmip1"; - imP->readMps(fn.c_str(), "mps"); - - OsiColCut cut; - const int ne = 1; - int inx[ne] = { 20 }; - double el[ne] = { 0.25 }; - cut.setLbs(ne, inx, el); - OSIUNITTEST_ASSERT_ERROR(!cut.consistent(*imP), {}, "osicolcut", "consistent(IntegerModel)"); - - cut.setLbs(0, NULL, NULL); - cut.setUbs(ne, inx, el); - OSIUNITTEST_ASSERT_ERROR(!cut.consistent(*imP), {}, "osicolcut", "consistent(IntegerModel)"); - - inx[0] = 4; - cut.setLbs(ne, inx, el); - cut.setUbs(0, NULL, NULL); - OSIUNITTEST_ASSERT_ERROR(cut.consistent(*imP), {}, "osicolcut", "consistent(IntegerModel)"); - - el[0] = 4.5; - cut.setLbs(0, NULL, NULL); - cut.setUbs(ne, inx, el); - OSIUNITTEST_ASSERT_ERROR(cut.consistent(*imP), {}, "osicolcut", "consistent(IntegerModel)"); - - cut.setLbs(ne, inx, el); - cut.setUbs(0, NULL, NULL); - OSIUNITTEST_ASSERT_ERROR(cut.consistent(*imP), {}, "osicolcut", "consistent(IntegerModel)"); - OSIUNITTEST_ASSERT_ERROR(cut.infeasible(*imP), {}, "osicolcut", "infeasible(IntegerModel)"); - - el[0] = 3.0; - cut.setLbs(ne, inx, el); - cut.setUbs(ne, inx, el); - OSIUNITTEST_ASSERT_ERROR(cut.consistent(*imP), {}, "osicolcut", "consistent(IntegerModel)"); + const int error = imP->readMps(fn.c_str(), "mps"); + if (!error) { + OsiColCut cut; + const int ne = 1; + int inx[ne] = { 20 }; + double el[ne] = { 0.25 }; + cut.setLbs(ne, inx, el); + OSIUNITTEST_ASSERT_ERROR(!cut.consistent(*imP), {}, "osicolcut", "consistent(IntegerModel)"); + + cut.setLbs(0, NULL, NULL); + cut.setUbs(ne, inx, el); + OSIUNITTEST_ASSERT_ERROR(!cut.consistent(*imP), {}, "osicolcut", "consistent(IntegerModel)"); + + inx[0] = 4; + cut.setLbs(ne, inx, el); + cut.setUbs(0, NULL, NULL); + OSIUNITTEST_ASSERT_ERROR(cut.consistent(*imP), {}, "osicolcut", "consistent(IntegerModel)"); + + el[0] = 4.5; + cut.setLbs(0, NULL, NULL); + cut.setUbs(ne, inx, el); + OSIUNITTEST_ASSERT_ERROR(cut.consistent(*imP), {}, "osicolcut", "consistent(IntegerModel)"); + + cut.setLbs(ne, inx, el); + cut.setUbs(0, NULL, NULL); + OSIUNITTEST_ASSERT_ERROR(cut.consistent(*imP), {}, "osicolcut", "consistent(IntegerModel)"); + OSIUNITTEST_ASSERT_ERROR(cut.infeasible(*imP), {}, "osicolcut", "infeasible(IntegerModel)"); + + el[0] = 3.0; + cut.setLbs(ne, inx, el); + cut.setUbs(ne, inx, el); + OSIUNITTEST_ASSERT_ERROR(cut.consistent(*imP), {}, "osicolcut", "consistent(IntegerModel)"); + } delete imP; } { @@ -248,24 +251,25 @@ void OsiColCutUnitTest(const OsiSolverInterface *baseSiP, const std::string &mps OsiSolverInterface *imP = baseSiP->clone(); assert(imP != NULL); std::string fn = mpsDir + "exmip1"; - imP->readMps(fn.c_str(), "mps"); - - OsiColCut cut; - const int ne = 1; - int inx[ne] = { 4 }; - double el[ne] = { 4.5 }; - cut.setLbs(ne, inx, el); - OSIUNITTEST_ASSERT_ERROR(cut.infeasible(*imP), {}, "osicolcut", "infeasible(IntegerModel)"); - - el[0] = 0.25; - cut.setLbs(0, NULL, NULL); - cut.setUbs(ne, inx, el); - OSIUNITTEST_ASSERT_ERROR(cut.infeasible(*imP), {}, "osicolcut", "infeasible(IntegerModel)"); - - el[0] = 3.0; - cut.setLbs(ne, inx, el); - cut.setUbs(ne, inx, el); - OSIUNITTEST_ASSERT_ERROR(!cut.infeasible(*imP), {}, "osicolcut", "infeasible(IntegerModel)"); + const int error = imP->readMps(fn.c_str(), "mps"); + if (!error) { + OsiColCut cut; + const int ne = 1; + int inx[ne] = { 4 }; + double el[ne] = { 4.5 }; + cut.setLbs(ne, inx, el); + OSIUNITTEST_ASSERT_ERROR(cut.infeasible(*imP), {}, "osicolcut", "infeasible(IntegerModel)"); + + el[0] = 0.25; + cut.setLbs(0, NULL, NULL); + cut.setUbs(ne, inx, el); + OSIUNITTEST_ASSERT_ERROR(cut.infeasible(*imP), {}, "osicolcut", "infeasible(IntegerModel)"); + + el[0] = 3.0; + cut.setLbs(ne, inx, el); + cut.setUbs(ne, inx, el); + OSIUNITTEST_ASSERT_ERROR(!cut.infeasible(*imP), {}, "osicolcut", "infeasible(IntegerModel)"); + } delete imP; } diff --git a/Osi/src/OsiCommonTest/OsiRowCutTest.cpp b/Osi/src/OsiCommonTest/OsiRowCutTest.cpp index 95f51c2b5..10f0835a4 100644 --- a/Osi/src/OsiCommonTest/OsiRowCutTest.cpp +++ b/Osi/src/OsiCommonTest/OsiRowCutTest.cpp @@ -252,8 +252,7 @@ void OsiRowCutUnitTest(const OsiSolverInterface *baseSiP, OsiSolverInterface *imP = baseSiP->clone(); assert(imP != NULL); std::string fn = mpsDir + "exmip1"; - OSIUNITTEST_ASSERT_ERROR(imP->readMps(fn.c_str(), "mps") == 0, {}, "osirowcut", "read MPS"); - + const int error = imP->readMps(fn.c_str(), "mps"); OsiRowCut c; const int ne = 3; int inx[ne] = { -1, 5, 4 }; @@ -285,7 +284,9 @@ void OsiRowCutUnitTest(const OsiSolverInterface *baseSiP, c.setLb(5.5); OSIUNITTEST_ASSERT_ERROR(c.consistent(), {}, "osirowcut", "consistent"); - OSIUNITTEST_ASSERT_ERROR(c.infeasible(*imP), {}, "osirowcut", "infeasible"); + if (!error) { + OSIUNITTEST_ASSERT_ERROR(c.infeasible(*imP), {}, "osirowcut", "infeasible"); + } delete imP; } #endif @@ -294,8 +295,7 @@ void OsiRowCutUnitTest(const OsiSolverInterface *baseSiP, OsiSolverInterface *imP = baseSiP->clone(); assert(imP != NULL); std::string fn = mpsDir + "exmip1"; - OSIUNITTEST_ASSERT_ERROR(imP->readMps(fn.c_str(), "mps") == 0, {}, "osirowcut", "read MPS"); - + const int error = imP->readMps(fn.c_str(), "mps"); OsiRowCut cut; const int ne = 3; int inx[ne] = { 3, 5, 4 }; @@ -305,12 +305,14 @@ void OsiRowCutUnitTest(const OsiSolverInterface *baseSiP, inx[0] = 7; cut.setRow(ne, inx, el); - OSIUNITTEST_ASSERT_ERROR(cut.consistent(*imP), {}, "osirowcut", "consistent(IntegerModel)"); + if (!error) { + OSIUNITTEST_ASSERT_ERROR(cut.consistent(*imP), {}, "osirowcut", "consistent(IntegerModel)"); - inx[0] = 8; - cut.setRow(ne, inx, el); - OSIUNITTEST_ASSERT_ERROR(cut.consistent(), {}, "osirowcut", "consistent(IntegerModel)"); - OSIUNITTEST_ASSERT_ERROR(!cut.consistent(*imP), {}, "osirowcut", "consistent(IntegerModel)"); + inx[0] = 8; + cut.setRow(ne, inx, el); + OSIUNITTEST_ASSERT_ERROR(cut.consistent(), {}, "osirowcut", "consistent(IntegerModel)"); + OSIUNITTEST_ASSERT_ERROR(!cut.consistent(*imP), {}, "osirowcut", "consistent(IntegerModel)"); + } delete imP; } { @@ -318,19 +320,21 @@ void OsiRowCutUnitTest(const OsiSolverInterface *baseSiP, OsiSolverInterface *imP = baseSiP->clone(); assert(imP != NULL); std::string fn = mpsDir + "exmip1"; - OSIUNITTEST_ASSERT_ERROR(imP->readMps(fn.c_str(), "mps") == 0, {}, "osirowcut", "read MPS"); + const int error = imP->readMps(fn.c_str(), "mps"); OsiRowCut cut; const int ne = 3; int inx[ne] = { 3, 5, 4 }; double el[ne] = { 1., 1., 1. }; cut.setRow(ne, inx, el); - OSIUNITTEST_ASSERT_ERROR(!cut.infeasible(*imP), {}, "osirowcut", "infeasible(IntegerModel)"); + if (!error) { + OSIUNITTEST_ASSERT_ERROR(!cut.infeasible(*imP), {}, "osirowcut", "infeasible(IntegerModel)"); - OsiRowCut c1; - OSIUNITTEST_ASSERT_ERROR(!c1.infeasible(*imP), {}, "osirowcut", "infeasible(IntegerModel)"); - OSIUNITTEST_ASSERT_ERROR(c1.consistent(), {}, "osirowcut", "consistent"); - OSIUNITTEST_ASSERT_ERROR(c1.consistent(*imP), {}, "osirowcut", "consistent(IntegerModel)"); + OsiRowCut c1; + OSIUNITTEST_ASSERT_ERROR(!c1.infeasible(*imP), {}, "osirowcut", "infeasible(IntegerModel)"); + OSIUNITTEST_ASSERT_ERROR(c1.consistent(), {}, "osirowcut", "consistent"); + OSIUNITTEST_ASSERT_ERROR(c1.consistent(*imP), {}, "osirowcut", "consistent(IntegerModel)"); + } delete imP; } { diff --git a/Osi/src/OsiCommonTest/OsiSolverInterfaceTest.cpp b/Osi/src/OsiCommonTest/OsiSolverInterfaceTest.cpp index 3874dd00c..0acc1d4c0 100644 --- a/Osi/src/OsiCommonTest/OsiSolverInterfaceTest.cpp +++ b/Osi/src/OsiCommonTest/OsiSolverInterfaceTest.cpp @@ -36,12 +36,12 @@ If you work on this code, please keep these conventions in mind: * This unit test is meant as a certification that OsiXXX correctly implements the OSI API specification. Don't step around it! - + If OsiXXX is not capable of meeting a particular requirement and you edit the unit test code to avoid the test, don't just sweep it under the rug! Print a failure message saying the test has been skipped, or something else informative. - + OsiVol is the worst offender for this (the underlying algorithm is not simplex and imposes serious limitations on the type of lp that vol can handle). Any simplex-oriented solver should *NOT* be exempted from any @@ -1462,7 +1462,11 @@ void testNames(const OsiSolverInterface *emptySi, std::string fn) // std::cout << "Testing lazy names from MPS input file." << std::endl ; OSIUNITTEST_ASSERT_SEVERITY_EXPECTED(si->setIntParam(OsiNameDiscipline, 1) == true, recognisesOsiNames = false, solverName, "testNames: switch to lazy names", TestOutcome::NOTE, false); - OSIUNITTEST_ASSERT_ERROR(si->readMps(fn.c_str(), "mps") == 0, delete si; return, solverName, "testNames: read MPS"); + const int error = si->readMps(fn.c_str(), "mps"); + if (error) { + delete si; + return; + } OsiSolverInterface::OsiNameVec rowNames; int rowNameCnt; @@ -2219,7 +2223,7 @@ void testObjFunctions(const OsiSolverInterface *emptySi, c1 lower basic c2 upper basic c3 basic lower - + */ void testArtifStatus(const OsiSolverInterface *emptySi) @@ -2464,7 +2468,7 @@ void testReducedCosts(const OsiSolverInterface *emptySi, /* Test the writeMps and writeMpsNative functions by loading a problem, writing it out to a file, reloading it, and solving. - + Implicitly assumes readMps has already been tested. fn should be the path to exmip1. @@ -2492,7 +2496,7 @@ void testWriteMps(const OsiSolverInterface *emptySi, std::string fn) /* Write a test output file with writeMpsNative, then read and solve. See if we get the right answer. - + FIXME: Really, this test should verify values --- Vol could participate in that (lh, 070726). */ @@ -3430,7 +3434,7 @@ void testAddToEmptySystem(const OsiSolverInterface *emptySi, under test. OsiPresolve simply calls the underlying OsiXXX when it needs to solve a model. All the work involved with presolve and postsolve transforms is handled in OsiPresolve. - + The problems are a selection of problems from Data/Sample. In particular, e226 is in the list by virtue of having a constant offset (7.113) defined for the objective, and p0201 is in the list because presolve (as of 071015) @@ -3902,7 +3906,7 @@ void OsiSolverInterfaceCommonUnitTest(const OsiSolverInterface *emptySi, std::string fn = mpsDir + "exmip1"; OsiSolverInterface *exmip1Si = emptySi->clone(); assert(exmip1Si != NULL); - OSIUNITTEST_ASSERT_ERROR(exmip1Si->readMps(fn.c_str(), "mps") == 0, return, *exmip1Si, "read MPS file"); + const int error = exmip1Si->readMps(fn.c_str(), "mps"); /* Test that the solver correctly handles row and column names. */ @@ -3921,7 +3925,7 @@ void OsiSolverInterfaceCommonUnitTest(const OsiSolverInterface *emptySi, // Test that problem was loaded correctly - { + if (!error) { int nc = exmip1Si->getNumCols(); int nr = exmip1Si->getNumRows(); OSIUNITTEST_ASSERT_ERROR(nc == 8, return, *exmip1Si, "problem read correctly: number of columns"); @@ -4007,7 +4011,7 @@ void OsiSolverInterfaceCommonUnitTest(const OsiSolverInterface *emptySi, } // Test matrixByCol method - { + if (!error) { const CoinPackedMatrix *goldmtx = BuildExmip1Mtx(); OsiSolverInterface &si = *exmip1Si->clone(); CoinPackedMatrix sm = *si.getMatrixByCol(); @@ -4027,7 +4031,7 @@ void OsiSolverInterfaceCommonUnitTest(const OsiSolverInterface *emptySi, } // Test clone - { + if (!error) { OsiSolverInterface *si2; int ad = 13579; { @@ -4129,7 +4133,7 @@ void OsiSolverInterfaceCommonUnitTest(const OsiSolverInterface *emptySi, // end of clone testing // Test apply cuts method - { + if (!error) { OsiSolverInterface &im = *(exmip1Si->clone()); OsiCuts cuts; @@ -4288,7 +4292,9 @@ void OsiSolverInterfaceCommonUnitTest(const OsiSolverInterface *emptySi, yet properly counting errors. -- lh, 100826 -- */ - testSettingSolutions(*exmip1Si); + if (!error) { + testSettingSolutions(*exmip1Si); + } // Test column type methods // skip for vol since it does not support this function @@ -4377,17 +4383,23 @@ void OsiSolverInterfaceCommonUnitTest(const OsiSolverInterface *emptySi, problem loaded. This routine also puts some stress on cloning --- it creates nine simultaneous clones of the OSI under test. */ - testLoadAndAssignProblem(emptySi, exmip1Si); - testAddToEmptySystem(emptySi, volSolverInterface); + if (!error) { + testLoadAndAssignProblem(emptySi, exmip1Si); + testAddToEmptySystem(emptySi, volSolverInterface); + } /* Test write methods. */ - testWriteMps(emptySi, fn); - testWriteLp(emptySi, fn); + if (!error) { + testWriteMps(emptySi, fn); + testWriteLp(emptySi, fn); + } /* Test the simplex portion of the OSI interface. */ - testSimplexAPI(emptySi, mpsDir); + if (!error) { + testSimplexAPI(emptySi, mpsDir); + } // Add a Laci suggested test case // Load in a problem as column ordered matrix, @@ -4396,7 +4408,7 @@ void OsiSolverInterfaceCommonUnitTest(const OsiSolverInterface *emptySi, // extract the row ordered copy again and test whether it's ok. // (the same can be done with reversing the role // of row and column ordered.) - { + if (!error) { OsiSolverInterface *si = emptySi->clone(); si->loadProblem( @@ -4441,7 +4453,7 @@ void OsiSolverInterfaceCommonUnitTest(const OsiSolverInterface *emptySi, delete si; } - { + if (!error) { OsiSolverInterface *si = emptySi->clone(); si->loadProblem( @@ -4501,7 +4513,7 @@ void OsiSolverInterfaceCommonUnitTest(const OsiSolverInterface *emptySi, delete exmip1Si; - { + if (!error) { // Testing parameter settings OsiSolverInterface *si = emptySi->clone(); int i; diff --git a/Osi/test/CMakeLists.txt b/Osi/test/CMakeLists.txt new file mode 100644 index 000000000..743f310b4 --- /dev/null +++ b/Osi/test/CMakeLists.txt @@ -0,0 +1,30 @@ +add_executable(OsiTest) +target_sources(OsiTest PRIVATE + OsiTestSolver.cpp + OsiTestSolverInterface.cpp + OsiTestSolverInterfaceIO.cpp + OsiTestSolverInterfaceTest.cpp + unitTest.cpp) +target_include_directories(OsiTest PUBLIC + $ + $) +target_compile_definitions(OsiTest + PUBLIC HAVE_CONFIG_H + PRIVATE OSI_BUILD) +target_compile_features(OsiTest PUBLIC cxx_std_11) +if(APPLE) + set_target_properties(OsiTest PROPERTIES + INSTALL_RPATH "@loader_path;@loader_path/../${CMAKE_INSTALL_LIBDIR}") +elseif(UNIX) + set_target_properties(OsiTest PROPERTIES + INSTALL_RPATH "$ORIGIN:$ORIGIN/../${CMAKE_INSTALL_LIBDIR}") +endif() +target_link_libraries(OsiTest PRIVATE + Coin::Osi + Coin::OsiCommonTest +) +set_target_properties(OsiTest PROPERTIES + VERSION ${PROJECT_VERSION} + SOVERSION ${PROJECT_VERSION_MAJOR}) +add_executable(Coin::OsiTest ALIAS OsiTest) +add_test(NAME OsiTest COMMAND OsiTest) diff --git a/cmake/CheckEnv.cmake b/cmake/CheckEnv.cmake new file mode 100644 index 000000000..b24770250 --- /dev/null +++ b/cmake/CheckEnv.cmake @@ -0,0 +1,151 @@ +# Flags +include (CheckIncludeFile) +check_include_file(math.h HAVE_MATH_H) +check_include_file(ctype.h HAVE_CTYPE_H) +check_include_file(inttypes.h HAVE_INTTYPES_H) +check_include_file(float.h HAVE_FLOAT_H) +check_include_file(ieeefp.h HAVE_IEEEFP_H) +check_include_file(stdarg.h HAVE_STDARG_H) +check_include_file(stddef.h HAVE_STDDEF_H) +check_include_file(stdint.h HAVE_STDINT_H) +check_include_file(stdio.h HAVE_STDIO_H) +check_include_file(stdlib.h HAVE_STDLIB_H) +check_include_file(assert.h HAVE_ASSERT_H) +check_include_file(dlfcn.h HAVE_DLFCN_H) +check_include_file(endian.h HAVE_ENDIAN_H) +check_include_file(memory.h HAVE_MEMORY_H) +check_include_file(strings.h HAVE_STRINGS_H) +check_include_file(string.h HAVE_STRING_H) +check_include_file(time.h HAVE_TIME_H) +check_include_file(unistd.h HAVE_UNISTD_H) +check_include_file(sys/stat.h HAVE_SYS_STAT_H) +check_include_file(sys/types.h HAVE_SYS_TYPES_H) + +include (CheckIncludeFileCXX) +check_include_file_cxx(cmath HAVE_CMATH) +check_include_file_cxx(cctype HAVE_CCTYPE) +check_include_file_cxx(cinttypes HAVE_CINTTYPES) +check_include_file_cxx(cfloat HAVE_CFLOAT) +check_include_file_cxx(cieeefp HAVE_CIEEEFP) +check_include_file_cxx(cstdarg HAVE_CSTDARG) +check_include_file_cxx(cstddef HAVE_CSTDDEF) +check_include_file_cxx(cstdint HAVE_CSTDINT) +check_include_file_cxx(cstdio HAVE_CSTDIO) +check_include_file_cxx(cstdlib HAVE_CSTDLIB) +check_include_file_cxx(cassert HAVE_CASSERT) +check_include_file_cxx(cstring HAVE_CSTRING) +check_include_file_cxx(ctime HAVE_CTIME) + +set(STDC_HEADERS 1 CACHE INTERNAL "System has ANSI C header files") + +set(TEST_INCLUDES "") +if(HAVE_CMATH) + list(APPEND TEST_INCLUDES "cmath") +endif() +if(HAVE_CFLOAT) + list(APPEND TEST_INCLUDES "cfloat") +endif() +if(HAVE_CIEEEFP) + list(APPEND TEST_INCLUDES "cieeefp") +endif() +if(HAVE_MATH_H) + list(APPEND TEST_INCLUDES "math.h") +endif() +if(HAVE_FLOAT_H) + list(APPEND TEST_INCLUDES "float.h") +endif() +if(HAVE_IEEEFP_H) + list(APPEND TEST_INCLUDES "ieeefp.h") +endif() + +# ISFINITE +include(CheckCXXSourceCompiles) +check_cxx_source_compiles( + "#include \nint main(){return std::isfinite(0);}" + HAVE_STD_ISFINITE) +include(CheckFunctionExists) +include(CheckCXXSymbolExists) +check_cxx_symbol_exists(isfinite "${TEST_INCLUDES}" HAVE_ISFINITE) +check_cxx_symbol_exists(finite "${TEST_INCLUDES}" HAVE_FINITE) +check_cxx_symbol_exists(_finite "${TEST_INCLUDES}" HAVE__FINITE) +check_cxx_symbol_exists(__finite "${TEST_INCLUDES}" HAVE___FINITE) +if(HAVE_STD_ISFINITE) + set(COIN_C_FINITE "std::isfinite") +elseif(HAVE_ISFINITE) + set(COIN_C_FINITE "isfinite") +elseif(HAVE_FINITE) + set(COIN_C_FINITE "finite") +elseif(HAVE__FINITE) + set(COIN_C_FINITE "_finite") +elseif(HAVE___FINITE) + set(COIN_C_FINITE "__finite") +else() + message(FATAL_ERROR "Can't find isfinite()") +endif() +message(STATUS "Found isfinite: ${COIN_C_FINITE}") + +# ISNAN +include(CheckCXXSourceCompiles) +check_cxx_source_compiles( + "#include \nint main(){return std::isnan(0);}" + HAVE_STD_ISNAN) +include(CheckFunctionExists) +include(CheckCXXSymbolExists) +check_cxx_symbol_exists(isnan "${TEST_INCLUDES}" HAVE_ISNAN) +check_cxx_symbol_exists(_isnan "${TEST_INCLUDES}" HAVE__ISNAN) +check_cxx_symbol_exists(__isnan "${TEST_INCLUDES}" HAVE___ISNAN) +if(HAVE_STD_ISNAN) + set(COIN_C_ISNAN "std::isnan") +elseif(HAVE_ISNAN) + set(COIN_C_ISNAN "isnan") +elseif(HAVE__ISNAN) + set(COIN_C_ISNAN "_isnan") +elseif(HAVE___ISNAN) + set(COIN_C_ISNAN "__isnan") +else() + message(FATAL_ERROR "Can't find isnan()") +endif() +message(STATUS "Found isnan: ${COIN_C_ISNAN}") + +# Basic type +include(CheckTypeSize) +check_type_size("int64_t" SIZEOF_INT64_T) +check_type_size("long long" SIZEOF_LONG_LONG) +check_type_size("long" SIZEOF_LONG) +check_type_size("uint64_t" SIZEOF_UINT64_T) +check_type_size("unsigned long long" SIZEOF_ULONG_LONG) +check_type_size("unsigned long" SIZEOF_ULONG) +check_type_size("intptr_t" SIZEOF_INTPTR_T) +check_type_size("int *" SIZEOF_INT_P) + +if(SIZEOF_INT64_T EQUAL "8") + set(COIN_INT64_T "int64_t") +elseif(SIZEOF_LONG EQUAL "8") + set(COIN_INT64_T "long") +elseif(SIZEOF_LONG_LONG EQUAL "8") + set(COIN_INT64_T "long long") +else() + message(FATAL_ERROR "Can't find suitable int64_t") +endif() +message(STATUS "Found int64_t: ${COIN_INT64_T}") + +if(SIZEOF_UINT64_T EQUAL "8") + set(COIN_UINT64_T "uint64_t") +elseif(SIZEOF_ULONG EQUAL "8") + set(COIN_INT64_T "unsigned long") +elseif(SIZEOF_ULONG_LONG EQUAL "8") + set(COIN_INT64_T "unsigned long long") +else() + message(FATAL_ERROR "Can't find suitable uint64_t") +endif() +message(STATUS "Found uint64_t: ${COIN_UINT64_T}") + +if(SIZEOF_INTPTR_T) + set(COIN_INTPTR_T "intptr_t") +elseif(SIZEOF_INT_P) + set(COIN_INTPTR_T "int *") +else() + message(FATAL_ERROR "Can't find suitable intptr_t") +endif() +message(STATUS "Found intptr_t: ${COIN_INTPTR_T}") + diff --git a/cmake/Config.cmake.in b/cmake/Config.cmake.in new file mode 100644 index 000000000..94f7abe8d --- /dev/null +++ b/cmake/Config.cmake.in @@ -0,0 +1,19 @@ +@PACKAGE_INIT@ + +include(CMakeFindDependencyMacro) + +if(@ZLIB_FOUND@) + find_dependency(ZLIB REQUIRED) +endif() + +if(@PTHREADS_FOUND@) + find_dependency(Threads REQUIRED) +endif() + +if(${CMAKE_VERSION} VERSION_LESS "3.9.6") + find_dependency(CoinUtils REQUIRED) +else() + find_dependency(CoinUtils REQUIRED CONFIG) +endif() + +include("${CMAKE_CURRENT_LIST_DIR}/@PROJECT_NAME@Targets.cmake") diff --git a/cmake/ParseAc.cmake b/cmake/ParseAc.cmake new file mode 100644 index 000000000..4b307024a --- /dev/null +++ b/cmake/ParseAc.cmake @@ -0,0 +1,28 @@ +function(parse_ac VERSION_STRING VERSION_MAJOR VERSION_MINOR VERSION_PATCH) + file(READ "configure.ac" IN) + if(IN MATCHES "AC_INIT\\(.*trunk.*\\)") + message(WARNING "using trunk...") + set(MAJOR 999) + set(MINOR 0) + set(PATCH 0) + else() + # AC_INIT([Osi],[major.minor.patch or trunk],[url or email]) + string(REGEX MATCH + "AC_INIT\\([^,]+,\\[([0-9]+)\\.([0-9]+)(\\.([0-9]+))?\\],[^\\)]+\\)" AC_INIT ${IN}) + message(STATUS "AC_INIT: ${AC_INIT}") + set(MAJOR ${CMAKE_MATCH_1}) + set(MINOR ${CMAKE_MATCH_2}) + if(CMAKE_MATCH_3) + set(PATCH ${CMAKE_MATCH_4}) + else() + set(PATCH 0) + endif() + endif() + set(VERSION "${MAJOR}.${MINOR}.${PATCH}") + + set(${VERSION_MAJOR} ${MAJOR} PARENT_SCOPE) + set(${VERSION_MINOR} ${MINOR} PARENT_SCOPE) + set(${VERSION_PATCH} ${PATCH} PARENT_SCOPE) + set(${VERSION_STRING} ${VERSION} PARENT_SCOPE) + message(STATUS "version: ${VERSION}") +endfunction()