if(NOT BUILD_CXX) return() endif() # Check dependencies set(CMAKE_THREAD_PREFER_PTHREAD TRUE) set(THREAD_PREFER_PTHREAD_FLAG TRUE) find_package(Threads REQUIRED) # Tell find_package() to try “Config” mode before “Module” mode if no mode was specified. # This should avoid find_package() to first find our FindXXX.cmake modules if # distro package already provide a CMake config file... set(CMAKE_FIND_PACKAGE_PREFER_CONFIG TRUE) # libprotobuf force us to depends on ZLIB::ZLIB target if(BUILD_ZLIB) find_package(ZLIB REQUIRED CONFIG) else() find_package(ZLIB REQUIRED) endif() if(BUILD_absl) find_package(absl REQUIRED CONFIG) else() find_package(absl REQUIRED) endif() set(ABSL_DEPS absl::base absl::cord absl::random_random absl::raw_hash_set absl::hash absl::memory absl::meta absl::status absl::str_format absl::strings absl::synchronization absl::any ) set(GFLAGS_USE_TARGET_NAMESPACE TRUE) if(BUILD_gflags) find_package(gflags REQUIRED CONFIG) set(GFLAGS_DEP gflags::gflags_static) else() find_package(gflags REQUIRED) set(GFLAGS_DEP gflags::gflags) endif() if(BUILD_glog) find_package(glog REQUIRED CONFIG) else() find_package(glog REQUIRED) endif() if(BUILD_Protobuf) find_package(Protobuf REQUIRED CONFIG) else() find_package(Protobuf REQUIRED) endif() if(USE_COINOR) if(BUILD_CoinUtils) find_package(CoinUtils REQUIRED CONFIG) else() find_package(CoinUtils REQUIRED) endif() if(BUILD_Osi) find_package(Osi REQUIRED CONFIG) else() find_package(Osi REQUIRED) endif() if(BUILD_Clp) find_package(Clp REQUIRED CONFIG) else() find_package(Clp REQUIRED) endif() if(BUILD_Cgl) find_package(Cgl REQUIRED CONFIG) else() find_package(Cgl REQUIRED) endif() if(BUILD_Cbc) find_package(Cbc REQUIRED CONFIG) else() find_package(Cbc REQUIRED) endif() set(COINOR_DEPS Coin::CbcSolver Coin::OsiCbc Coin::ClpSolver Coin::OsiClp) endif() # Check optional Dependencies if(USE_CPLEX) find_package(CPLEX REQUIRED) set(CPLEX_DEP CPLEX::CPLEX) endif() if(USE_SCIP) find_package(SCIP REQUIRED) set(SCIP_DEP SCIP::SCIP) endif() if(USE_XPRESS) find_package(XPRESS REQUIRED) set(XPRESS_DEP XPRESS::XPRESS) endif() # Main Target add_library(${PROJECT_NAME} "") # Xcode fails to build if library doesn't contains at least one source file. if(XCODE) file(GENERATE OUTPUT ${PROJECT_BINARY_DIR}/${PROJECT_NAME}/version.cpp CONTENT "namespace {char* version = \"${PROJECT_VERSION}\";}") target_sources(${PROJECT_NAME} PRIVATE ${PROJECT_BINARY_DIR}/${PROJECT_NAME}/version.cpp) endif() list(APPEND OR_TOOLS_COMPILE_DEFINITIONS "USE_BOP" # enable BOP support "USE_GLOP" # enable GLOP support ) if(USE_COINOR) list(APPEND OR_TOOLS_COMPILE_DEFINITIONS "USE_CBC" # enable COIN-OR CBC support "USE_CLP" # enable COIN-OR CLP support ) endif() if(USE_CPLEX) list(APPEND OR_TOOLS_COMPILE_DEFINITIONS "USE_CPLEX") endif() if(USE_SCIP) list(APPEND OR_TOOLS_COMPILE_DEFINITIONS "USE_SCIP") endif() if(USE_XPRESS) list(APPEND OR_TOOLS_COMPILE_DEFINITIONS "USE_XPRESS") endif() if(WIN32) list(APPEND OR_TOOLS_COMPILE_DEFINITIONS "__WIN32__") endif() if(MSVC) list(APPEND OR_TOOLS_COMPILE_OPTIONS "/bigobj" # Allow big object "/DNOMINMAX" "/DWIN32_LEAN_AND_MEAN=1" "/D_CRT_SECURE_NO_WARNINGS" "/D_CRT_SECURE_NO_DEPRECATE" "/MP" # Build with multiple processes ) # Prefer /MD over /MT and add NDEBUG in Release if(CMAKE_BUILD_TYPE STREQUAL "Debug") list(APPEND OR_TOOLS_COMPILE_OPTIONS "/MDd") else() list(APPEND OR_TOOLS_COMPILE_OPTIONS "/MD" "/DNDEBUG") endif() # MSVC warning suppressions list(APPEND OR_TOOLS_COMPILE_OPTIONS "/wd4005" # 'macro-redefinition' "/wd4018" # 'expression' : signed/unsigned mismatch "/wd4065" # switch statement contains 'default' but no 'case' labels "/wd4068" # 'unknown pragma' "/wd4101" # 'identifier' : unreferenced local variable "/wd4146" # unary minus operator applied to unsigned type, result still unsigned "/wd4200" # nonstandard extension used : zero-sized array in struct/union "/wd4244" # 'conversion' conversion from 'type1' to 'type2', possible loss of data "/wd4251" # 'identifier' : class 'type' needs to have dll-interface to be used by clients of class 'type2' "/wd4267" # 'var' : conversion from 'size_t' to 'type', possible loss of data "/wd4305" # 'identifier' : truncation from 'type1' to 'type2' "/wd4307" # 'operator' : integral constant overflow "/wd4309" # 'conversion' : truncation of constant value "/wd4334" # 'operator' : result of 32-bit shift implicitly converted to 64 bits (was 64-bit shift intended?) "/wd4355" # 'this' : used in base member initializer list "/wd4477" # 'fwprintf' : format string '%s' requires an argument of type 'wchar_t *' "/wd4506" # no definition for inline function 'function' "/wd4715" # function' : not all control paths return a value "/wd4800" # 'type' : forcing value to bool 'true' or 'false' (performance warning) "/wd4996" # The compiler encountered a deprecated declaration. ) else() list(APPEND OR_TOOLS_COMPILE_OPTIONS "-fwrapv") endif() # Includes target_include_directories(${PROJECT_NAME} INTERFACE $ $ $ ) # Compile options set_target_properties(${PROJECT_NAME} PROPERTIES CXX_STANDARD 11 CXX_STANDARD_REQUIRED ON CXX_EXTENSIONS OFF ) target_compile_features(${PROJECT_NAME} PUBLIC cxx_std_11) target_compile_definitions(${PROJECT_NAME} PUBLIC ${OR_TOOLS_COMPILE_DEFINITIONS}) target_compile_options(${PROJECT_NAME} PUBLIC ${OR_TOOLS_COMPILE_OPTIONS}) # Properties if(NOT APPLE) set_target_properties(${PROJECT_NAME} PROPERTIES VERSION ${PROJECT_VERSION}) else() # Clang don't support version x.y.z with z > 255 set_target_properties(${PROJECT_NAME} PROPERTIES INSTALL_RPATH "@loader_path" VERSION ${PROJECT_VERSION_MAJOR}.${PROJECT_VERSION_MINOR}) endif() set_target_properties(${PROJECT_NAME} PROPERTIES SOVERSION ${PROJECT_VERSION_MAJOR} POSITION_INDEPENDENT_CODE ON INTERFACE_POSITION_INDEPENDENT_CODE ON ) set_target_properties(${PROJECT_NAME} PROPERTIES INTERFACE_${PROJECT_NAME}_MAJOR_VERSION ${PROJECT_VERSION_MAJOR}) set_target_properties(${PROJECT_NAME} PROPERTIES COMPATIBLE_INTERFACE_STRING ${PROJECT_NAME}_MAJOR_VERSION) # Dependencies target_link_libraries(${PROJECT_NAME} PUBLIC ZLIB::ZLIB ${ABSL_DEPS} ${GFLAGS_DEP} glog::glog protobuf::libprotobuf ${COINOR_DEPS} ${CPLEX_DEP} ${SCIP_DEP} ${XPRESS_DEP} Threads::Threads) if(WIN32) target_link_libraries(${PROJECT_NAME} PUBLIC psapi.lib ws2_32.lib) endif() # ALIAS add_library(${PROJECT_NAME}::${PROJECT_NAME} ALIAS ${PROJECT_NAME}) # Generate Protobuf cpp sources set(PROTO_HDRS) set(PROTO_SRCS) file(GLOB_RECURSE proto_files RELATIVE ${PROJECT_SOURCE_DIR} "ortools/bop/*.proto" "ortools/constraint_solver/*.proto" "ortools/data/*.proto" "ortools/glop/*.proto" "ortools/graph/*.proto" "ortools/linear_solver/*.proto" "ortools/sat/*.proto" "ortools/util/*.proto" "ortools/linear_solver/*.proto" ) # Get Protobuf include dir get_target_property(protobuf_dirs protobuf::libprotobuf INTERFACE_INCLUDE_DIRECTORIES) foreach(dir IN LISTS protobuf_dirs) if ("${dir}" MATCHES "BUILD_INTERFACE") list(APPEND PROTO_DIRS "\"--proto_path=${dir}\"") endif() endforeach() foreach(PROTO_FILE IN LISTS proto_files) #message(STATUS "protoc proto(cc): ${PROTO_FILE}") get_filename_component(PROTO_DIR ${PROTO_FILE} DIRECTORY) get_filename_component(PROTO_NAME ${PROTO_FILE} NAME_WE) set(PROTO_HDR ${PROJECT_BINARY_DIR}/${PROTO_DIR}/${PROTO_NAME}.pb.h) set(PROTO_SRC ${PROJECT_BINARY_DIR}/${PROTO_DIR}/${PROTO_NAME}.pb.cc) #message(STATUS "protoc hdr: ${PROTO_HDR}") #message(STATUS "protoc src: ${PROTO_SRC}") add_custom_command( OUTPUT ${PROTO_SRC} ${PROTO_HDR} COMMAND protobuf::protoc "--proto_path=${PROJECT_SOURCE_DIR}" ${PROTO_DIRS} "--cpp_out=${PROJECT_BINARY_DIR}" ${PROTO_FILE} DEPENDS ${PROTO_FILE} protobuf::protoc COMMENT "Generate C++ protocol buffer for ${PROTO_FILE}" VERBATIM) list(APPEND PROTO_HDRS ${PROTO_HDR}) list(APPEND PROTO_SRCS ${PROTO_SRC}) endforeach() #add_library(${PROJECT_NAME}_proto STATIC ${PROTO_SRCS} ${PROTO_HDRS}) add_library(${PROJECT_NAME}_proto OBJECT ${PROTO_SRCS} ${PROTO_HDRS}) set_target_properties(${PROJECT_NAME}_proto PROPERTIES POSITION_INDEPENDENT_CODE ON) set_target_properties(${PROJECT_NAME}_proto PROPERTIES CXX_STANDARD 11) set_target_properties(${PROJECT_NAME}_proto PROPERTIES CXX_STANDARD_REQUIRED ON) set_target_properties(${PROJECT_NAME}_proto PROPERTIES CXX_EXTENSIONS OFF) target_include_directories(${PROJECT_NAME}_proto PRIVATE ${PROJECT_SOURCE_DIR} ${PROJECT_BINARY_DIR} $ ) target_compile_definitions(${PROJECT_NAME}_proto PUBLIC ${OR_TOOLS_COMPILE_DEFINITIONS}) target_compile_options(${PROJECT_NAME}_proto PUBLIC ${OR_TOOLS_COMPILE_OPTIONS}) #target_link_libraries(${PROJECT_NAME}_proto PRIVATE protobuf::libprotobuf) add_dependencies(${PROJECT_NAME}_proto protobuf::libprotobuf) add_library(${PROJECT_NAME}::proto ALIAS ${PROJECT_NAME}_proto) # Add ortools::proto to libortools #target_link_libraries(${PROJECT_NAME} PRIVATE ${PROJECT_NAME}::proto) target_sources(${PROJECT_NAME} PRIVATE $) add_dependencies(${PROJECT_NAME} ${PROJECT_NAME}::proto) foreach(SUBPROJECT IN ITEMS algorithms base bop constraint_solver data glop graph linear_solver lp_data port sat util) add_subdirectory(ortools/${SUBPROJECT}) #target_link_libraries(${PROJECT_NAME} PRIVATE ${PROJECT_NAME}::${SUBPROJECT}) target_sources(${PROJECT_NAME} PRIVATE $) add_dependencies(${PROJECT_NAME} ${PROJECT_NAME}::${SUBPROJECT}) endforeach() if(BUILD_TESTING) add_subdirectory(examples/cpp) endif() # Install rules include(GNUInstallDirs) # Install builded dependencies if(INSTALL_BUILD_DEPS) if( BUILD_ZLIB OR BUILD_absl OR BUILD_gflags OR BUILD_glog OR BUILD_Protobuf OR BUILD_CoinUtils OR BUILD_Osi OR BUILD_Clp OR BUILD_Cgl OR BUILD_Cbc ) install( DIRECTORY ${CMAKE_BINARY_DIR}/dependencies/install/ DESTINATION ${CMAKE_INSTALL_PREFIX} ) endif() endif() include(GenerateExportHeader) GENERATE_EXPORT_HEADER(${PROJECT_NAME}) install(FILES ${PROJECT_BINARY_DIR}/${PROJECT_NAME}_export.h DESTINATION ${CMAKE_INSTALL_INCLUDEDIR}) install(TARGETS ${PROJECT_NAME} EXPORT ${PROJECT_NAME}Targets INCLUDES DESTINATION ${CMAKE_INSTALL_INCLUDEDIR} ARCHIVE DESTINATION ${CMAKE_INSTALL_LIBDIR} LIBRARY DESTINATION ${CMAKE_INSTALL_LIBDIR} RUNTIME DESTINATION ${CMAKE_INSTALL_BINDIR} ) install(EXPORT ${PROJECT_NAME}Targets NAMESPACE ${PROJECT_NAME}:: DESTINATION ${CMAKE_INSTALL_LIBDIR}/cmake/${PROJECT_NAME}) install(DIRECTORY ortools DESTINATION ${CMAKE_INSTALL_INCLUDEDIR} COMPONENT Devel FILES_MATCHING PATTERN "*.h") install(DIRECTORY ${PROJECT_BINARY_DIR}/ortools DESTINATION ${CMAKE_INSTALL_INCLUDEDIR} COMPONENT Devel FILES_MATCHING PATTERN "*.pb.h" PATTERN CMakeFiles EXCLUDE) include(CMakePackageConfigHelpers) string (TOUPPER "${PROJECT_NAME}" PACKAGE_PREFIX) configure_package_config_file(cmake/${PROJECT_NAME}Config.cmake.in "${PROJECT_BINARY_DIR}/${PROJECT_NAME}Config.cmake" INSTALL_DESTINATION "${CMAKE_INSTALL_LIBDIR}/cmake/${PROJECT_NAME}" NO_CHECK_REQUIRED_COMPONENTS_MACRO) 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)