diff --git a/CMakeLists.txt b/CMakeLists.txt index 92d613433e..bf3e5dbb23 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -176,6 +176,10 @@ CMAKE_DEPENDENT_OPTION(BUILD_ZLIB "Build the ZLIB dependency Library" OFF "NOT BUILD_DEPS" ON) message(STATUS "Build ZLIB: ${BUILD_ZLIB}") +CMAKE_DEPENDENT_OPTION(BUILD_BZip2 "Build the BZip2 dependency Library" OFF + "NOT BUILD_DEPS" ON) +message(STATUS "Build BZip2: ${BUILD_BZip2}") + CMAKE_DEPENDENT_OPTION(BUILD_absl "Build the abseil-cpp dependency Library" OFF "NOT BUILD_DEPS" ON) message(STATUS "Build abseil-cpp: ${BUILD_absl}") diff --git a/cmake/README.md b/cmake/README.md index c3f207ec67..d8ac411f36 100644 --- a/cmake/README.md +++ b/cmake/README.md @@ -114,6 +114,7 @@ the option `-DBUILD_DEPS=ON` (`OFF` by default) or compile some of them using the options below (see [CMake Options](#cmake-options) below). * zlib (`BUILD_ZLIB`), +* bzip2 (`BUILD_BZip2`), * Google Abseil-cpp (`BUILD_absl`), * Google Protobuf (`BUILD_Protobuf`), * COIN-OR solvers: @@ -196,6 +197,7 @@ cmake -S. -Bbuild -LH | | | | | `BUILD_DEPS` | OFF* | Default to ON if `BUILD_JAVA=ON` or `BUILD_PYTHON=ON` or `BUILD_DOTNET=ON` | | `BUILD_ZLIB` | OFF* | Build the zlib dynamic library
**Forced** to ON if `BUILD_DEPS=ON` | +| `BUILD_BZip2` | OFF* | Build the bzip2 dynamic library
**Forced** to ON if `BUILD_DEPS=ON` | | `BUILD_absl` | OFF* | Build the abseil-cpp dynamic libraries
**Forced** to ON if `BUILD_DEPS=ON` | | `BUILD_Protobuf` | OFF* | Build the protobuf dynamic libraries
**Forced** to ON if `BUILD_DEPS=ON` | | `BUILD_re2` | OFF* | Build the re2 dynamic libraries
**Forced** to ON if `BUILD_DEPS=ON` | diff --git a/cmake/check_deps.cmake b/cmake/check_deps.cmake index 4e6cc73058..b7d5b2c018 100644 --- a/cmake/check_deps.cmake +++ b/cmake/check_deps.cmake @@ -16,6 +16,10 @@ if(NOT TARGET ZLIB::ZLIB) message(FATAL_ERROR "Target ZLIB::ZLIB not available.") endif() +if(NOT TARGET BZip2::BZip2) + message(FATAL_ERROR "Target BZip2::BZip2 not available.") +endif() + if(NOT TARGET absl::base) message(FATAL_ERROR "Target absl::base not available.") endif() diff --git a/cmake/cpp.cmake b/cmake/cpp.cmake index 7035615140..9acfea8745 100644 --- a/cmake/cpp.cmake +++ b/cmake/cpp.cmake @@ -578,6 +578,7 @@ endif() target_link_libraries(${PROJECT_NAME} PUBLIC ${CMAKE_DL_LIBS} ZLIB::ZLIB + BZip2::BZip2 ${ABSL_DEPS} protobuf::libprotobuf ${RE2_DEPS} diff --git a/cmake/dependencies/CMakeLists.txt b/cmake/dependencies/CMakeLists.txt index 5983b1cb14..04a6cc5f60 100644 --- a/cmake/dependencies/CMakeLists.txt +++ b/cmake/dependencies/CMakeLists.txt @@ -73,6 +73,27 @@ if(BUILD_ZLIB) message(CHECK_PASS "fetched") endif() +# ############################################################################## +# BZip2 +# ############################################################################## +if(BUILD_BZip2) + message(CHECK_START "Fetching BZip2") + list(APPEND CMAKE_MESSAGE_INDENT " ") + set(ENABLE_LIB_ONLY ON) + FetchContent_Declare( + BZip2 + GIT_REPOSITORY "https://gitlab.com/bzip2/bzip2.git" + GIT_TAG "master" + # GIT_TAG "bzip2-1.0.8" # CMake support not available + GIT_SHALLOW TRUE + PATCH_COMMAND git apply --ignore-whitespace + "${CMAKE_CURRENT_LIST_DIR}/../../patches/bzip2.patch" + ) + FetchContent_MakeAvailable(BZip2) + list(POP_BACK CMAKE_MESSAGE_INDENT) + message(CHECK_PASS "fetched") +endif() + # ############################################################################## # ABSEIL-CPP # ############################################################################## diff --git a/cmake/docs/cmake.dot b/cmake/docs/cmake.dot index f16a364e8c..30a7947e2a 100644 --- a/cmake/docs/cmake.dot +++ b/cmake/docs/cmake.dot @@ -34,6 +34,13 @@ digraph CMake { label = "madler/zlib.git + cmake patch"; } + subgraph clusterBZIP2 { + BZip2 [label="BZip2::BZip2", color=royalblue]; + + color=royalblue; + label = "bzip2/bzip2.git + cmake patch"; + } + subgraph clusterAbsl { Absl [label="absl::absl_*", color=royalblue]; @@ -195,6 +202,7 @@ digraph CMake { PKG_CPP -> EX_CPP; ZLIB -> OR_SRC; + BZip2 -> OR_SRC; Absl -> OR_SRC; Protobuf -> OR_SRC; Re2 -> OR_SRC; diff --git a/cmake/docs/cmake.svg b/cmake/docs/cmake.svg index ae7a62782c..9d3cbb5d26 100644 --- a/cmake/docs/cmake.svg +++ b/cmake/docs/cmake.svg @@ -4,11 +4,11 @@ - + CMake - + clusterPrerequisite @@ -16,170 +16,175 @@ clusterOR - -OR-Tools (CMake) + +OR-Tools (CMake) clusterDeps - -Dependencies -(-DBUILD_DEPS=ON) + +Dependencies +(-DBUILD_DEPS=ON) clusterZLIB - -madler/zlib.git + cmake patch + +madler/zlib.git + cmake patch -clusterAbsl - -abseil/abseil-cpp.git +clusterBZIP2 + +bzip2/bzip2.git + cmake patch -clusterRe2 - -google/re2.git +clusterAbsl + +abseil/abseil-cpp.git -clusterProtobuf - -protocolbuffers/protobuf.git +clusterRe2 + +google/re2.git +clusterProtobuf + +protocolbuffers/protobuf.git + + clusterCoinOR Coin-OR Solver (-DUSE_COINOR=ON) - -clusterCoinUtils - -Mizux/CoinUtils.git - -clusterOsi - -Mizux/Osi.git +clusterCoinUtils + +Mizux/CoinUtils.git +clusterOsi + +Mizux/Osi.git + + clusterClp Mizux/Clp.git - -clusterCgl - -Mizux/Cgl.git - -clusterCbc - -Mizux/Cbc.git +clusterCgl + +Mizux/Cgl.git -clusterGLPKSolver - -GLPK Solver -(-DUSE_GLPK=ON) +clusterCbc + +Mizux/Cbc.git -clusterGLPK - -Mizux/GLPK.git +clusterGLPKSolver + +GLPK Solver +(-DUSE_GLPK=ON) +clusterGLPK + +Mizux/GLPK.git + + clusterHIGHSSolver HIGHS Solver (-DUSE_HIGHS=ON) - + clusterHIGHS ERGO-Code/HIGHS.git - -clusterSCIPSolver - -SCIP Solver -(-DUSE_SCIP=ON) - -clusterSoplex - -scipopt/soplex.git +clusterSCIPSolver + +SCIP Solver +(-DUSE_SCIP=ON) -clusterSCIP - -scipopt/scip.git +clusterSoplex + +scipopt/soplex.git -clusterCXX - -C++ -(-DBUILD_CXX=ON) +clusterSCIP + +scipopt/scip.git -clusterCXXTest - -Examples -(-DBUILD_TESTING=ON) +clusterCXX + +C++ +(-DBUILD_CXX=ON) -clusterPython - -Python -(-DBUILD_PYTHON=ON) +clusterCXXTest + +Examples +(-DBUILD_TESTING=ON) -clusterPythonTest - -Examples -(-DBUILD_TESTING=ON) +clusterPython + +Python +(-DBUILD_PYTHON=ON) -clusterJava - -Java -(-DBUILD_JAVA=ON) +clusterPythonTest + +Examples +(-DBUILD_TESTING=ON) -clusterJavaTest - -Examples -(-DBUILD_TESTING=ON) +clusterJava + +Java +(-DBUILD_JAVA=ON) -clusterNet - -.Net -(-DBUILD_DOTNET=ON) +clusterJavaTest + +Examples +(-DBUILD_TESTING=ON) +clusterNet + +.Net +(-DBUILD_DOTNET=ON) + + clusterNetTest - -Examples -(-DBUILD_TESTING=ON) + +Examples +(-DBUILD_TESTING=ON) CM - - - - -CMake + + + + +CMake SWIG - - - - -Swig -(Unix) + + + + +Swig +(Unix) @@ -188,12 +193,12 @@ PY - - - - -Python -(3.6+) + + + + +Python +(3.6+) @@ -202,12 +207,12 @@ JV - - - - -Java -(openJDK 8+) + + + + +Java +(openJDK 8+) @@ -216,12 +221,12 @@ DN - - - - -.Net Core SDK -(3.1) + + + + +.Net Core SDK +(3.1) @@ -230,11 +235,11 @@ FS - - - - -.Net F# + + + + +.Net F# @@ -243,126 +248,138 @@ ZLIB - -ZLIB::ZLIB + +ZLIB::ZLIB - + Protobuf - -protobuf::libprotobuf + +protobuf::libprotobuf ZLIB->Protobuf - - + + - + SPX - -libsoplex-pic + +libsoplex-pic ZLIB->SPX - - + + - + SCIP - -SCIP::libscip + +SCIP::libscip ZLIB->SCIP - - + + - + OR_SRC - -OR-Tools src -ortools/... + +OR-Tools src +ortools/... ZLIB->OR_SRC - - + + + + + +BZip2 + +BZip2::BZip2 + + + +BZip2->OR_SRC + + - + Absl - -absl::absl_* + +absl::absl_* - + Re2 - -re2::re2 + +re2::re2 Absl->Re2 - - + + Absl->Protobuf - - + + - + Absl->OR_SRC - - + + Re2->Protobuf - - + + - + Re2->OR_SRC - - + + - + Protobuf->OR_SRC - - + + - + CoinUtils - -Coin::CoinUtils + +Coin::CoinUtils - + Osi - -Coin::Osi + +Coin::Osi CoinUtils->Osi - - + + - + Clp Coin::Clp @@ -370,11 +387,11 @@ CoinUtils->Clp - - + + - + OsiClp Coin::OsiClp @@ -382,74 +399,74 @@ CoinUtils->OsiClp - - + + - + Cgl - -Coin::Cgl + +Coin::Cgl CoinUtils->Cgl - - + + - + Cbc - -Coin::Cbc + +Coin::Cbc CoinUtils->Cbc - - + + - + OsiCbc - -Coin::OsiCbc + +Coin::OsiCbc CoinUtils->OsiCbc - - + + Osi->Clp - - + + Osi->OsiClp - - + + Osi->Cgl - - + + Osi->Cbc - - + + Osi->OsiCbc - - + + @@ -458,7 +475,7 @@ - + ClpSolver Coin::ClpSolver @@ -472,65 +489,65 @@ Clp->Cbc - - + + OsiClp->Cgl - - + + - + ClpSolver->OR_SRC - - + + Cgl->Cbc - - + + Cbc->OsiCbc - - + + - + CbcSolver - -Coin::CbcSolver + +Coin::CbcSolver Cbc->CbcSolver - - + + - + CbcSolver->OR_SRC - - + + - + GLPK - -glpk::glpk + +glpk::glpk - + GLPK->OR_SRC - - + + - + HIGHS highs::highs @@ -538,277 +555,277 @@ SPX->SCIP - - + + - + SCIP->OR_SRC - - + + - + SWIG_WIN swigwin (Windows) - + OR_CPP - -ortools::ortools + +ortools::ortools - + OR_SRC->OR_CPP - - + + - + OR_WPY - - - -C++ Python wrappers + + + +C++ Python wrappers - + OR_SRC->OR_WPY - - -swig + + +swig - + OR_PY - - - -Python files + + + +Python files - + OR_SRC->OR_PY - - -swig + + +swig - + OR_WJAVA - - - -C++ Java wrappers + + + +C++ Java wrappers - + OR_SRC->OR_WJAVA - - -swig + + +swig - + OR_JAVA - - - -Java files + + + +Java files - + OR_SRC->OR_JAVA - - -swig + + +swig - + OR_WNET - - - -C++ .Net wrappers + + + +C++ .Net wrappers - + OR_SRC->OR_WNET - - -swig + + +swig - + OR_NET - - - -.Net files + + + +.Net files - + OR_SRC->OR_NET - - -swig + + +swig - + PKG_CPP - - - - -CMake Package + + + + +CMake Package - + OR_CPP->PKG_CPP - - -install + + +install - + EX_CPP - -C++ samples + +C++ samples PKG_CPP->EX_CPP - - + + - + OR_WPY->OR_PY - - + + - + PKG_PY - - - - -Wheel package + + + + +Wheel package - + OR_PY->PKG_PY - - -python setup.py + + +python setup.py - + EX_PY - -Python samples + +Python samples - + PKG_PY->EX_PY - - + + - + OR_WJAVA->OR_JAVA - - + + - + PKG_JAVA - - - - -Maven package + + + + +Maven package - + OR_JAVA->PKG_JAVA - - -maven + + +maven - + EX_JAVA - -Java samples + +Java samples - + PKG_JAVA->EX_JAVA - - + + - + OR_WNET->OR_NET - - + + - + PKG_NET_RT - - - - -Nuget runtime package -Google.OrTools.runtime.rid.nupkg + + + + +Nuget runtime package +Google.OrTools.runtime.rid.nupkg - + OR_WNET->PKG_NET_RT - - -dotnet package + + +dotnet package - + PKG_NET - - - - -Nuget package -Google.OrTools.nupkg + + + + +Nuget package +Google.OrTools.nupkg - + OR_NET->PKG_NET - - -dotnet package + + +dotnet package - + PKG_NET_RT->PKG_NET - - + + - + EX_NET - -.Net samples + +.Net samples - + PKG_NET->EX_NET - - + + diff --git a/cmake/docs/deps.dot b/cmake/docs/deps.dot index 0ddff8381b..3cf09233dd 100644 --- a/cmake/docs/deps.dot +++ b/cmake/docs/deps.dot @@ -11,6 +11,13 @@ digraph CMakeDeps { label = "madler/zlib.git + cmake patch"; } + subgraph clusterBZip2 { + BZip2 [label="BZip2::BZip2"]; + + color=royalblue; + label = "bzip2/bzip2.git + cmake patch"; + } + subgraph clusterAbsl { Absl [label="absl::absl_*"]; diff --git a/cmake/docs/deps.svg b/cmake/docs/deps.svg index 29d05286f2..700f57e207 100644 --- a/cmake/docs/deps.svg +++ b/cmake/docs/deps.svg @@ -4,137 +4,142 @@ - + CMakeDeps - + clusterZLIB madler/zlib.git + cmake patch +clusterBZip2 + +bzip2/bzip2.git + cmake patch + + clusterAbsl abseil/abseil-cpp.git - + clusterProtobuf protocolbuffers/protobuf.git - + clusterRe2 google/re2.git - -clusterEigen3 - -libeigen/eigen.git - +clusterEigen3 + +libeigen/eigen.git + + clusterCoinOR -DUSE_COINOR=ON AND -DBUILD_DEPS=ON - + clusterCoinUtils Mizux/CoinUtils.git - + clusterOsi Mizux/Osi.git - + clusterClp Mizux/Clp.git - + clusterCgl Mizux/Cgl.git - + clusterCbc Mizux/Cbc.git - -clusterGLPKSolver - --DUSE_GLPK=ON AND -DBUILD_GLPK=ON - -clusterGLPK - -Mizux/GLPK.git +clusterGLPKSolver + +-DUSE_GLPK=ON AND -DBUILD_GLPK=ON -clusterHIGHSSolver - --DUSE_HIGHS=ON AND -DBUILD_HIGHS=ON +clusterGLPK + +Mizux/GLPK.git -clusterHIGHS - -ERGO-Code/HIGHS.git +clusterHIGHSSolver + +-DUSE_HIGHS=ON AND -DBUILD_HIGHS=ON +clusterHIGHS + +ERGO-Code/HIGHS.git + + clusterSCIPSolver -DUSE_SCIP=ON AND -DBUILD_SCIP=ON - + clusterSoplex scipopt/soplex.git - + clusterSCIP scipopt/scip.git - + clusterTesting -DBUILD_TESTING=ON - + clusterGTest google/googletest.git - + clusterBenchmark google/benchmark.git - + clusterFuzzTest google/fuzztest.git - + clusterPython -DBUILD_PYTHON=ON - + clusterPybind11 pybind/pybind11.git - + clusterPybind11Absl pybind/pybind11_abseil.git - + clusterPybind11Protobuf pybind/pybind11_protobuf.git @@ -145,14 +150,20 @@ ZLIB::ZLIB - + +BZip2 + +BZip2::BZip2 + + + Absl absl::absl_* - + Protobuf protobuf::libprotobuf @@ -170,7 +181,7 @@ - + Re2 re2::re2 @@ -182,7 +193,7 @@ - + Protoc @@ -196,19 +207,19 @@ - + Eigen3 - -Eigen3::eigen + +Eigen3::eigen - + CoinUtils Coin::CoinUtils - + Osi Coin::Osi @@ -220,7 +231,7 @@ - + Clp Coin::Clp @@ -238,7 +249,7 @@ - + OsiClp Coin::OsiClp @@ -262,7 +273,7 @@ - + ClpSolver Coin::ClpSolver @@ -274,7 +285,7 @@ - + Cgl Coin::Cgl @@ -298,7 +309,7 @@ - + Cbc Coin::Cbc @@ -334,7 +345,7 @@ - + OsiCbc Coin::OsiCbc @@ -358,7 +369,7 @@ - + CbcSolver Coin::CbcSolver @@ -370,19 +381,19 @@ - + GLPK - -glpk::glpk + +glpk::glpk - + HIGHS - -highs::highs + +highs::highs - + SPX libsoplex @@ -394,7 +405,7 @@ - + SCIP SCIP::libscip @@ -412,7 +423,7 @@ - + gtest GTest::gtest @@ -430,7 +441,7 @@ - + bench benchmark::benchmark @@ -442,7 +453,7 @@ - + fuzz fuzztest::fuzztest @@ -472,13 +483,13 @@ - + Pybind11 pybind11::pybind11 - + Pybind11Absl pybind11::pybind11_abseil @@ -496,7 +507,7 @@ - + Pybind11Protobuf pybind11::pybind11_protobuf diff --git a/cmake/ortoolsConfig.cmake.in b/cmake/ortoolsConfig.cmake.in index 9ee8e216c9..b658904e7d 100644 --- a/cmake/ortoolsConfig.cmake.in +++ b/cmake/ortoolsConfig.cmake.in @@ -11,6 +11,10 @@ if(NOT TARGET ZLIB::ZLIB) find_dependency(ZLIB REQUIRED) endif() +if(NOT TARGET BZip2::BZip2) + find_dependency(BZip2 REQUIRED) +endif() + if(${CMAKE_VERSION} VERSION_GREATER_EQUAL "3.9.6") set(CONFIG_FLAG CONFIG) endif() diff --git a/cmake/system_deps.cmake b/cmake/system_deps.cmake index db2d2567cc..8fcc19cdc7 100644 --- a/cmake/system_deps.cmake +++ b/cmake/system_deps.cmake @@ -26,6 +26,10 @@ if(NOT BUILD_ZLIB AND NOT TARGET ZLIB::ZLIB) find_package(ZLIB REQUIRED) endif() +if(NOT BUILD_BZip2 AND NOT TARGET BZip2::BZip2) + find_package(BZip2 REQUIRED) +endif() + if(NOT BUILD_absl AND NOT TARGET absl::base) find_package(absl REQUIRED) endif() diff --git a/ortools/base/BUILD.bazel b/ortools/base/BUILD.bazel index 03d38e7500..97cb61d29d 100644 --- a/ortools/base/BUILD.bazel +++ b/ortools/base/BUILD.bazel @@ -246,7 +246,6 @@ cc_library( "helpers.h", "options.h", ], - defines = ["USE_BZIP2"], deps = [ ":status_macros", "@abseil-cpp//absl/log", diff --git a/ortools/base/CMakeLists.txt b/ortools/base/CMakeLists.txt index c05028a50e..ffddb85b86 100644 --- a/ortools/base/CMakeLists.txt +++ b/ortools/base/CMakeLists.txt @@ -35,6 +35,7 @@ target_include_directories(${NAME} PRIVATE ${PROJECT_BINARY_DIR}) target_link_libraries(${NAME} PRIVATE ZLIB::ZLIB + BZip2::BZip2 absl::base absl::strings absl::str_format diff --git a/ortools/base/file.cc b/ortools/base/file.cc index 4af9554709..2759af2524 100644 --- a/ortools/base/file.cc +++ b/ortools/base/file.cc @@ -16,12 +16,9 @@ #include #include -#if defined(USE_BZIP2) -#include -#endif -#include - +#include #include + #if defined(_MSC_VER) #include #define access _access @@ -33,7 +30,6 @@ #include #include #include -#include // NOLINT #include #include @@ -42,16 +38,14 @@ #include "absl/status/status.h" #include "absl/strings/str_cat.h" #include "absl/strings/string_view.h" +#include "bzlib.h" #include "google/protobuf/io/tokenizer.h" #include "google/protobuf/message.h" #include "google/protobuf/text_format.h" +#include "zlib.h" namespace { -enum class Format { - NORMAL_FILE, - GZIP_FILE, - BZIP2_FILE -}; +enum class Format { NORMAL_FILE, GZIP_FILE, BZIP2_FILE }; static Format GetFormatFromName(absl::string_view name) { const int size = name.size(); @@ -67,7 +61,7 @@ static Format GetFormatFromName(absl::string_view name) { class CFile : public File { public: CFile(FILE* c_file, absl::string_view name) : File(name), f_(c_file) {} - virtual ~CFile() = default; + ~CFile() override = default; // Reads "size" bytes to buf from file, buf should be pre-allocated. size_t Read(void* buf, size_t size) override { @@ -80,7 +74,7 @@ class CFile : public File { } // Closes the file and delete the underlying FILE* descriptor. - absl::Status Close(int flags) override { + absl::Status Close(int /*flags*/) override { absl::Status status; if (f_ == nullptr) { return status; @@ -113,50 +107,48 @@ class CFile : public File { }; class GzFile : public File { - public: + public: GzFile(gzFile gz_file, absl::string_view name) : File(name), f_(gz_file) {} - virtual ~GzFile() = default; + ~GzFile() override = default; - // Reads "size" bytes to buf from file, buf should be pre-allocated. - size_t Read(void* buf, size_t size) override { - return gzread(f_, buf, size); - } + // Reads "size" bytes to buf from file, buf should be pre-allocated. + size_t Read(void* buf, size_t size) override { return gzread(f_, buf, size); } - // Writes "size" bytes of buf to file, buf should be pre-allocated. - size_t Write(const void* buf, size_t size) override { - return gzwrite(f_, buf, size); - } + // Writes "size" bytes of buf to file, buf should be pre-allocated. + size_t Write(const void* buf, size_t size) override { + return gzwrite(f_, buf, size); + } - // Closes the file and delete the underlying FILE* descriptor. - absl::Status Close(int flags) override { - absl::Status status; - if (f_ == nullptr) { - return status; - } - if (gzclose(f_) == 0) { - f_ = nullptr; - } else { - status.Update( - absl::Status(absl::StatusCode::kInvalidArgument, - absl::StrCat("Could not close file '", name_, "'"))); - } - delete this; - return status; - } - - // Flushes buffer. - bool Flush() override { return gzflush(f_, Z_FINISH) == Z_OK; } - - // Returns file size. - size_t Size() override { + // Closes the file and delete the underlying FILE* descriptor. + absl::Status Close(int /*flags*/) override { + absl::Status status; + if (f_ == nullptr) { + return status; + } + if (gzclose(f_) == 0) { + f_ = nullptr; + } else { + status.Update( + absl::Status(absl::StatusCode::kInvalidArgument, + absl::StrCat("Could not close file '", name_, "'"))); + } + delete this; + return status; + } + + // Flushes buffer. + bool Flush() override { return gzflush(f_, Z_FINISH) == Z_OK; } + + // Returns file size. + size_t Size() override { gzFile file; std::string null_terminated_name = std::string(name_); - #if defined(_MSC_VER) - file = gzopen (null_terminated_name.c_str(), "rb"); - #else - file = gzopen (null_terminated_name.c_str(), "r"); - #endif - if (! file) { +#if defined(_MSC_VER) + file = gzopen(null_terminated_name.c_str(), "rb"); +#else + file = gzopen(null_terminated_name.c_str(), "r"); +#endif + if (!file) { LOG(FATAL) << "Cannot get the size of '" << name_ << "': " << strerror(errno); } @@ -164,7 +156,7 @@ class GzFile : public File { const int kLength = 5 * 1024; unsigned char buffer[kLength]; size_t uncompressed_size = 0; - while (1) { + while (true) { int err; int bytes_read; bytes_read = gzread(file, buffer, kLength - 1); @@ -183,54 +175,53 @@ class GzFile : public File { } gzclose(file); return uncompressed_size; - } + } - bool Open() const override { return f_ != nullptr; } - - private: - gzFile f_; - }; + bool Open() const override { return f_ != nullptr; } - #if defined(USE_BZIP2) - class Bz2File : public File { - public: + private: + gzFile f_; +}; + +class Bz2File : public File { + public: Bz2File(BZFILE* bz_file, absl::string_view name) : File(name), f_(bz_file) {} - virtual ~Bz2File() = default; - - // Reads "size" bytes to buf from file, buf should be pre-allocated. - size_t Read(void* buf, size_t size) override { - return BZ2_bzread(f_, buf, size); - } - - // Writes "size" bytes of buf to file, buf should be pre-allocated. - size_t Write(const void* buf, size_t size) override { - return BZ2_bzwrite(f_, const_cast(buf), size); - } - - // Closes the file and delete the underlying FILE* descriptor. - absl::Status Close(int flags) override { - absl::Status status; - if (f_ == nullptr) { - return absl::OkStatus(); - } - BZ2_bzclose(f_); - f_ = nullptr; - delete this; - return absl::OkStatus(); - } - - // Flushes buffer. - bool Flush() override { return BZ2_bzflush(f_) == 0; } - - // Returns file size. - size_t Size() override { + ~Bz2File() override = default; + + // Reads "size" bytes to buf from file, buf should be pre-allocated. + size_t Read(void* buf, size_t size) override { + return BZ2_bzread(f_, buf, size); + } + + // Writes "size" bytes of buf to file, buf should be pre-allocated. + size_t Write(const void* buf, size_t size) override { + return BZ2_bzwrite(f_, const_cast(buf), size); + } + + // Closes the file and delete the underlying FILE* descriptor. + absl::Status Close(int /*flags*/) override { + absl::Status status; + if (f_ == nullptr) { + return absl::OkStatus(); + } + BZ2_bzclose(f_); + f_ = nullptr; + delete this; + return absl::OkStatus(); + } + + // Flushes buffer. + bool Flush() override { return BZ2_bzflush(f_) == 0; } + + // Returns file size. + size_t Size() override { BZFILE* file; std::string null_terminated_name = std::string(name_); - #if defined(_MSC_VER) - file = BZ2_bzopen (null_terminated_name.c_str(), "rb"); - #else - file = BZ2_bzopen (null_terminated_name.c_str(), "r"); - #endif +#if defined(_MSC_VER) + file = BZ2_bzopen(null_terminated_name.c_str(), "rb"); +#else + file = BZ2_bzopen(null_terminated_name.c_str(), "r"); +#endif if (!file) { LOG(FATAL) << "Cannot get the size of '" << name_ << "': " << strerror(errno); @@ -239,8 +230,7 @@ class GzFile : public File { const int kLength = 5 * 1024; unsigned char buffer[kLength]; size_t uncompressed_size = 0; - while (1) { - int err; + while (true) { int bytes_read; bytes_read = BZ2_bzread(file, buffer, kLength - 1); uncompressed_size += bytes_read; @@ -248,15 +238,14 @@ class GzFile : public File { } BZ2_bzclose(file); return uncompressed_size; - } - - bool Open() const override { return f_ != nullptr; } - - private: - BZFILE* f_; - }; - #endif // USE_BZIP2 - + } + + bool Open() const override { return f_ != nullptr; } + + private: + BZFILE* f_; +}; + } // namespace File::File(absl::string_view name) : name_(name) {} @@ -292,17 +281,14 @@ File* File::Open(absl::string_view file_name, absl::string_view mode) { return new GzFile(gz_file, file_name); } case Format::BZIP2_FILE: { -#if defined(USE_BZIP2) - BZFILE* bz_file = - BZ2_bzopen(null_terminated_name.c_str(), null_terminated_mode.c_str()); + BZFILE* bz_file = BZ2_bzopen(null_terminated_name.c_str(), + null_terminated_mode.c_str()); if (!bz_file) return nullptr; return new Bz2File(bz_file, file_name); -#else - LOG(ERROR) << "Using bzip2 files is not supported"; - return nullptr; -#endif } } + // never reach + return nullptr; } int64_t File::ReadToString(std::string* line, uint64_t max_length) { @@ -399,8 +385,8 @@ absl::Status WriteString(File* file, absl::string_view contents, absl::StrCat("Could not write ", contents.size(), " bytes")); } -absl::Status SetContents(absl::string_view file_name, absl::string_view contents, - Options options) { +absl::Status SetContents(absl::string_view file_name, + absl::string_view contents, Options options) { File* file; // For windows, the "b" is added in file::Open. auto status = file::Open(file_name, "w", &file, options); @@ -430,12 +416,12 @@ absl::Status GetTextProto(absl::string_view file_name, absl::StrCat("Could not read proto from '", file_name, "'.")); } - // Attempt to decode ASCII before deciding binary. Do it in this order because - // it is much harder for a binary encoding to happen to be a valid ASCII - // encoding than the other way around. For instance "index: 1\n" is a valid - // (but nonsensical) binary encoding. We want to avoid printing errors for - // valid binary encodings if the ASCII parsing fails, and so specify a no-op - // error collector. + // Attempt to decode ASCII before deciding binary. Do it in this order + // because it is much harder for a binary encoding to happen to be a valid + // ASCII encoding than the other way around. For instance "index: 1\n" is a + // valid (but nonsensical) binary encoding. We want to avoid printing errors + // for valid binary encodings if the ASCII parsing fails, and so specify a + // no-op error collector. NoOpErrorCollector error_collector; google::protobuf::TextFormat::Parser parser; parser.RecordErrorsTo(&error_collector); diff --git a/ortools/base/file.h b/ortools/base/file.h index f3231e2fab..c53ae28458 100644 --- a/ortools/base/file.h +++ b/ortools/base/file.h @@ -14,6 +14,7 @@ #ifndef OR_TOOLS_BASE_FILE_H_ #define OR_TOOLS_BASE_FILE_H_ +#include #include #include @@ -39,7 +40,7 @@ class File { static File* OpenOrDie(absl::string_view file_name, absl::string_view mode); #endif // SWIG - File(absl::string_view name); + explicit File(absl::string_view name); virtual ~File() = default; // Reads "size" bytes to buf from file, buff should be pre-allocated. @@ -57,7 +58,7 @@ class File { // Returns file size. virtual size_t Size() = 0; - // Returns wether the file is currently open. + // Returns whether the file is currently open. virtual bool Open() const = 0; // Reads the whole file to a string, with a maximum length of 'max_length'. @@ -106,8 +107,8 @@ absl::StatusOr GetContents(absl::string_view path, absl::Status GetContents(absl::string_view file_name, std::string* output, Options options); -absl::Status SetContents(absl::string_view file_name, absl::string_view contents, - Options options); +absl::Status SetContents(absl::string_view file_name, + absl::string_view contents, Options options); absl::Status WriteString(File* file, absl::string_view contents, Options options); diff --git a/ortools/base/strong_int.h b/ortools/base/strong_int.h index 5481289f8a..0ab60afc73 100644 --- a/ortools/base/strong_int.h +++ b/ortools/base/strong_int.h @@ -516,8 +516,6 @@ bool AbslParseFlag(absl::string_view text, value = static_cast(larger_value); } - // TODO(user): We shouldn't crash in flag parsing. - // Validator should be re-tooled to return meaningful values. *out = StrongInt(value); return true; } @@ -693,6 +691,7 @@ StrongIntRange MakeStrongIntRange(IntType begin, IntType end) { // Numeric_limits override for strong int. namespace std { // Allow StrongInt to be used as a key to hashable containers. +// NOLINTNEXTLINE(google3-runtime-std-hash-specialization) template struct hash> : ::util_intops::StrongInt::Hasher {}; diff --git a/ortools/base/strong_int_test.cc b/ortools/base/strong_int_test.cc index 9c2735dc6f..4fca118b38 100644 --- a/ortools/base/strong_int_test.cc +++ b/ortools/base/strong_int_test.cc @@ -181,7 +181,7 @@ TYPED_TEST(StrongIntTest, TestCtors) { EXPECT_EQ(V(93), x.value()); // It is undefined to init an unsigned int from a negative float. - if (std::numeric_limits::is_signed) { + if constexpr (std::numeric_limits::is_signed) { float j = -76.1; T y(j); EXPECT_EQ(V(-76.1), y.value()); @@ -194,7 +194,7 @@ TYPED_TEST(StrongIntTest, TestCtors) { EXPECT_EQ(V(93), x.value()); // It is undefined to init an unsigned int from a negative double. - if (std::numeric_limits::is_signed) { + if constexpr (std::numeric_limits::is_signed) { double j = -76.1; T y(j); EXPECT_EQ(V(-76.1), y.value()); @@ -207,7 +207,7 @@ TYPED_TEST(StrongIntTest, TestCtors) { EXPECT_EQ(V(93), x.value()); // It is undefined to init an unsigned int from a negative long double. - if (std::numeric_limits::is_signed) { + if constexpr (std::numeric_limits::is_signed) { long double j = -76.1; T y(j); EXPECT_EQ(V(-76.1), y.value()); @@ -312,7 +312,7 @@ TYPED_TEST(StrongIntTest, TestAbslParseFlagInvalid) { T t; std::string error; - if (std::numeric_limits::is_signed) { + if constexpr (std::numeric_limits::is_signed) { EXPECT_DEATH(absl::ParseFlag("-123", &t, &error), "PositiveValidator"); } else { EXPECT_FALSE(absl::ParseFlag("-123", &t, &error)); @@ -323,7 +323,7 @@ TYPED_TEST(StrongIntTest, TestAbslParseFlagInvalid) { TYPED_TEST(StrongIntTest, TestCtorDeath) { using V = typename TestFixture::V; - if (std::numeric_limits::is_signed) { + if constexpr (std::numeric_limits::is_signed) { struct CustomTag {}; using T = StrongInt; EXPECT_DEATH(T(static_cast(-123)), "PositiveValidator"); @@ -509,7 +509,7 @@ TYPED_TEST(StrongIntTest, TestMultiplyOperators) { // Test positive vs. positive multiplication. TEST_T_OP_NUM(9, *, V, 3); TEST_NUM_OP_T(V, 9, *, 3); - if (std::is_signed::value) { + if constexpr (std::is_signed::value) { // Test negative vs. positive multiplication. TEST_T_OP_NUM(-9, *, V, 3); TEST_NUM_OP_T(V, -9, *, 3); @@ -526,7 +526,7 @@ TYPED_TEST(StrongIntTest, TestMultiplyOperators) { // Test multiplication by zero. TEST_T_OP_NUM(93, *, V, 0); TEST_NUM_OP_T(V, 93, *, 0); - if (std::is_signed::value) { + if constexpr (std::is_signed::value) { // Test multiplication by a negative. TEST_T_OP_NUM(93, *, V, -1); TEST_NUM_OP_T(V, 93, *, -1); @@ -574,16 +574,20 @@ TYPED_TEST(StrongIntTest, TestDivideOperators) { // Test positive vs. positive division. TEST_T_OP_NUM(9, /, V, 3); - // Test negative vs. positive division. - TEST_T_OP_NUM(-9, /, V, 3); - // Test positive vs. negative division. - TEST_T_OP_NUM(9, /, V, -3); - // Test negative vs. negative division. - TEST_T_OP_NUM(-9, /, V, -3); + if constexpr (std::is_signed::value) { + // Test negative vs. positive division. + TEST_T_OP_NUM(-9, /, V, 3); + // Test positive vs. negative division. + TEST_T_OP_NUM(9, /, V, -3); + // Test negative vs. negative division. + TEST_T_OP_NUM(-9, /, V, -3); + } // Test division by one. TEST_T_OP_NUM(93, /, V, 1); - // Test division by a negative. - TEST_T_OP_NUM(93, /, V, -1); + if constexpr (std::is_signed::value) { + // Test division by a negative. + TEST_T_OP_NUM(93, /, V, -1); + } // Test division by int8_t. TEST_T_OP_NUM(93, /, int8_t, 2); // Test division by uint8_t. diff --git a/patches/bzip2.patch b/patches/bzip2.patch new file mode 100644 index 0000000000..ba1dc7f09a --- /dev/null +++ b/patches/bzip2.patch @@ -0,0 +1,161 @@ +diff --git a/CMakeLists.txt b/CMakeLists.txt +index c4b0b6e..bd3aca3 100644 +--- a/CMakeLists.txt ++++ b/CMakeLists.txt +@@ -1,5 +1,10 @@ + cmake_minimum_required(VERSION 3.12) + ++# option() honors normal variables. ++if (POLICY CMP0077) ++ cmake_policy(SET CMP0077 NEW) ++endif() ++ + project(bzip2 + VERSION 1.1.0 + DESCRIPTION "This Bzip2/libbz2 a program and library for lossless block-sorting data compression." +@@ -283,8 +288,8 @@ set(BZ2_SOURCES + add_library(bz2_ObjLib OBJECT) + target_sources(bz2_ObjLib + PRIVATE ${BZ2_SOURCES} +- PUBLIC ${CMAKE_CURRENT_SOURCE_DIR}/bzlib_private.h +- INTERFACE ${CMAKE_CURRENT_SOURCE_DIR}/bzlib.h) ++ bzlib_private.h ++ bzlib.h) + + # Windows resource file + set(BZ2_RES "") +@@ -301,10 +306,14 @@ if(ENABLE_SHARED_LIB) + # The libbz2 shared library. + add_library(bz2 SHARED ${BZ2_RES}) + target_sources(bz2 +- PRIVATE ${BZ2_SOURCES} +- ${CMAKE_CURRENT_SOURCE_DIR}/libbz2.def +- PUBLIC ${CMAKE_CURRENT_SOURCE_DIR}/bzlib_private.h +- INTERFACE ${CMAKE_CURRENT_SOURCE_DIR}/bzlib.h) ++ PRIVATE ${BZ2_SOURCES} ++ libbz2.def ++ bzlib_private.h ++ bzlib.h) ++ target_include_directories(bz2 PUBLIC ++ $ ++ $ ++ ) + + # Always use '-fPIC'/'-fPIE' option for shared libraries. + set_property(TARGET bz2 PROPERTY POSITION_INDEPENDENT_CODE ON) +@@ -312,8 +321,11 @@ if(ENABLE_SHARED_LIB) + set_target_properties(bz2 PROPERTIES + COMPILE_FLAGS "${WARNCFLAGS}" + VERSION ${LT_VERSION} SOVERSION ${LT_SOVERSION}) +- install(TARGETS bz2 DESTINATION ${CMAKE_INSTALL_LIBDIR}) ++ install(TARGETS bz2 ++ EXPORT ${PROJECT_NAME}Targets ++ DESTINATION ${CMAKE_INSTALL_LIBDIR}) + install(FILES bzlib.h DESTINATION ${CMAKE_INSTALL_INCLUDEDIR}) ++ add_library(BZip2::BZip2 ALIAS bz2) + + if(USE_OLD_SONAME) + # Hack to support the old libbz2.so.1.0 version by including an extra copy. +@@ -323,16 +335,22 @@ if(ENABLE_SHARED_LIB) + add_library(bz2_old_soname SHARED ${BZ2_RES}) + target_sources(bz2_old_soname + PRIVATE ${BZ2_SOURCES} +- ${CMAKE_CURRENT_SOURCE_DIR}/libbz2.def +- PUBLIC ${CMAKE_CURRENT_SOURCE_DIR}/bzlib_private.h +- INTERFACE ${CMAKE_CURRENT_SOURCE_DIR}/bzlib.h ++ libbz2.def ++ bzlib_private.h ++ bzlib.h ++ ) ++ target_include_directories(bz2_old_soname PUBLIC ++ $ ++ $ + ) + set_target_properties(bz2_old_soname PROPERTIES + COMPILE_FLAGS "${WARNCFLAGS}" + VERSION ${LT_SOVERSION}.${LT_AGE} SOVERSION ${LT_SOVERSION}.${LT_AGE} + OUTPUT_NAME bz2 + ) +- install(TARGETS bz2_old_soname DESTINATION ${CMAKE_INSTALL_LIBDIR}) ++ install(TARGETS bz2_old_soname ++ EXPORT ${PROJECT_NAME}Targets ++ DESTINATION ${CMAKE_INSTALL_LIBDIR}) + endif() + endif() + endif() +@@ -341,9 +359,13 @@ if(ENABLE_STATIC_LIB) + # The libbz2 static library. + add_library(bz2_static STATIC) + target_sources(bz2_static +- PRIVATE ${BZ2_SOURCES} +- PUBLIC ${CMAKE_CURRENT_SOURCE_DIR}/bzlib_private.h +- INTERFACE ${CMAKE_CURRENT_SOURCE_DIR}/bzlib.h) ++ PRIVATE ${BZ2_SOURCES} ++ bzlib_private.h ++ bzlib.h) ++ target_include_directories(bz2_static PUBLIC ++ $ ++ $ ++ ) + + # Use '-fPIC'/'-fPIE' option for static libraries by default. + # You may build with ENABLE_STATIC_LIB_IS_PIC=OFF to disable PIC for the static library. +@@ -357,8 +379,13 @@ if(ENABLE_STATIC_LIB) + SOVERSION ${LT_SOVERSION} + ARCHIVE_OUTPUT_NAME bz2_static) + target_compile_definitions(bz2_static PUBLIC BZ2_STATICLIB) +- install(TARGETS bz2_static DESTINATION ${CMAKE_INSTALL_LIBDIR}) ++ install(TARGETS bz2_static ++ EXPORT ${PROJECT_NAME}Targets ++ DESTINATION ${CMAKE_INSTALL_LIBDIR}) + install(FILES bzlib.h DESTINATION ${CMAKE_INSTALL_INCLUDEDIR}) ++ if(NOT TARGET bz2) ++ add_library(BZip2::BZip2 ALIAS bz2_static) ++ endif() + endif() + + if(ENABLE_APP) +@@ -373,7 +400,9 @@ if(ENABLE_APP) + else() + target_compile_definitions(bzip2 PUBLIC BZ_LCCWIN32=0 BZ_UNIX) + endif() +- install(TARGETS bzip2 DESTINATION ${CMAKE_INSTALL_BINDIR}) ++ install(TARGETS bzip2 ++ EXPORT ${PROJECT_NAME}Targets ++ DESTINATION ${CMAKE_INSTALL_BINDIR}) + + # Create bzip2 copies bzcat and bunzip. + # The default behavior is altered in bzip2.c code by checking the program name. +@@ -391,7 +420,9 @@ if(ENABLE_APP) + else() + target_compile_definitions(bzip2recover PUBLIC BZ_LCCWIN32=0 BZ_UNIX) + endif() +- install(TARGETS bzip2recover DESTINATION ${CMAKE_INSTALL_BINDIR}) ++ install(TARGETS bzip2recover ++ EXPORT ${PROJECT_NAME}Targets ++ DESTINATION ${CMAKE_INSTALL_BINDIR}) + + if(ENABLE_EXAMPLES) + if(ENABLE_SHARED_LIB) +@@ -400,7 +431,9 @@ if(ENABLE_APP) + target_sources(dlltest + PRIVATE dlltest.c) + target_link_libraries(dlltest bz2) +- install(TARGETS dlltest DESTINATION ${CMAKE_INSTALL_BINDIR}) ++ install(TARGETS dlltest ++ EXPORT ${PROJECT_NAME}Targets ++ DESTINATION ${CMAKE_INSTALL_BINDIR}) + endif() + endif() + +@@ -419,6 +452,10 @@ if(ENABLE_APP) + + endif() + ++install(EXPORT ${PROJECT_NAME}Targets ++ NAMESPACE BZip2:: ++ DESTINATION ${CMAKE_INSTALL_LIBDIR}/cmake/${PROJECT_NAME}) ++ + if(ENABLE_APP AND Python3_FOUND) + enable_testing() + add_custom_target(check COMMAND ${CMAKE_CTEST_COMMAND})