diff --git a/CMakeLists.txt b/CMakeLists.txt index 960a224b27..9ba9748d80 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -74,7 +74,7 @@ if(UNIX) endforeach() else() # Currently Only support static build for windows - option(BUILD_SHARED_LIBS "Build shared libraries (.dll)." OFF) + option(BUILD_SHARED_LIBS "Build shared libraries (.dll)." ON) 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}) diff --git a/cmake/cpp.cmake b/cmake/cpp.cmake index e0ca148deb..132bf49dbf 100644 --- a/cmake/cpp.cmake +++ b/cmake/cpp.cmake @@ -45,9 +45,13 @@ set(OR_TOOLS_COMPILE_DEFINITIONS) set(OR_TOOLS_COMPILE_OPTIONS) set(OR_TOOLS_LINK_OPTIONS) -if(BUILD_SHARED_LIBS) - list(APPEND OR_TOOLS_COMPILE_DEFINITIONS "OR_TOOLS_AS_DYNAMIC_LIB") +if(MSVC AND BUILD_SHARED_LIBS) + list(APPEND OR_TOOLS_COMPILE_DEFINITIONS "OR_BUILD_DLL") + list(APPEND OR_TOOLS_COMPILE_DEFINITIONS "OR_PROTO_DLL=__declspec(dllimport)") + else() + list(APPEND OR_TOOLS_COMPILE_DEFINITIONS "OR_PROTO_DLL=") endif() + # Optional built-in components if(BUILD_LP_PARSER) list(APPEND OR_TOOLS_COMPILE_DEFINITIONS "USE_LP_PARSER") @@ -356,7 +360,7 @@ function(generate_proto_library) COMMAND ${PROTOC_PRG} "--proto_path=${PROJECT_SOURCE_DIR}" ${PROTO_DIRS} - "--cpp_out=${PROJECT_BINARY_DIR}" + "--cpp_out=dllexport_decl=OR_PROTO_DLL:${PROJECT_BINARY_DIR}" ${PROTO_FILE} DEPENDS ${PROTO_FILE} ${PROTOC_PRG} COMMENT "Generate C++ protocol buffer for ${PROTO_FILE}" @@ -383,6 +387,12 @@ function(generate_proto_library) #$ ) target_compile_definitions(${PROTO_NAME}_proto PUBLIC ${OR_TOOLS_COMPILE_DEFINITIONS}) + if(MSVC AND BUILD_SHARED_LIBS) + target_compile_definitions(${PROTO_NAME}_proto INTERFACE "OR_PROTO_DLL=__declspec(dllimport)") + target_compile_definitions(${PROTO_NAME}_proto PRIVATE "OR_PROTO_DLL=__declspec(dllexport)") + else() + target_compile_definitions(${PROTO_NAME}_proto PUBLIC "OR_PROTO_DLL=") +endif() target_compile_options(${PROTO_NAME}_proto PUBLIC ${OR_TOOLS_COMPILE_OPTIONS}) target_link_libraries(${PROTO_NAME}_proto PUBLIC protobuf::libprotobuf ${PROTO_LINK_LIBRARIES}) add_library(${PROJECT_NAMESPACE}::${PROTO_NAME}_proto ALIAS ${PROTO_NAME}_proto) @@ -456,6 +466,9 @@ set_target_properties(${PROJECT_NAME} PROPERTIES target_compile_features(${PROJECT_NAME} PUBLIC $,cxx_std_20,cxx_std_17>) target_compile_definitions(${PROJECT_NAME} PUBLIC ${OR_TOOLS_COMPILE_DEFINITIONS}) +if(MSVC AND BUILD_SHARED_LIBS) + target_compile_definitions(${PROJECT_NAME} PRIVATE OR_EXPORT) +endif() target_compile_options(${PROJECT_NAME} PUBLIC ${OR_TOOLS_COMPILE_OPTIONS}) target_link_options(${PROJECT_NAME} INTERFACE ${OR_TOOLS_LINK_OPTIONS}) # Properties diff --git a/cmake/docker/web/Dockerfile b/cmake/docker/web/Dockerfile index 1ebec3a45c..1dcefb864f 100644 --- a/cmake/docker/web/Dockerfile +++ b/cmake/docker/web/Dockerfile @@ -4,7 +4,7 @@ FROM archlinux:latest AS env # Install system build dependencies ENV PATH=/usr/local/bin:$PATH -RUN pacman -Syu --noconfirm git base-devel cmake +RUN pacman -Syu --noconfirm git base-devel glibc cmake RUN cmake -version RUN pacman -Syu --noconfirm nodejs emscripten ENV PATH=/usr/lib/emscripten:$PATH diff --git a/cmake/dotnet.cmake b/cmake/dotnet.cmake index 99c898c3ea..d85b6596de 100644 --- a/cmake/dotnet.cmake +++ b/cmake/dotnet.cmake @@ -31,6 +31,7 @@ include(UseSWIG) if(UNIX AND NOT APPLE) list(APPEND CMAKE_SWIG_FLAGS "-DSWIGWORDSIZE64") endif() +list(APPEND CMAKE_SWIG_FLAGS "-DOR_DLL=") # Find dotnet cli find_program(DOTNET_EXECUTABLE NAMES dotnet) @@ -397,6 +398,8 @@ set(need_unix_highs_lib "$>") set(need_windows_highs_lib "$>") set(is_ortools_shared "$,SHARED_LIBRARY>") +set(need_unix_ortools_lib "$") +set(need_windows_ortools_lib "$") configure_file( ${PROJECT_SOURCE_DIR}/ortools/dotnet/${DOTNET_PACKAGE}.runtime.csproj.in diff --git a/cmake/java.cmake b/cmake/java.cmake index d002876da1..cd34ecc44e 100644 --- a/cmake/java.cmake +++ b/cmake/java.cmake @@ -31,6 +31,7 @@ endif() if(UNIX AND NOT APPLE) list(APPEND CMAKE_SWIG_FLAGS "-DSWIGWORDSIZE64") endif() +list(APPEND CMAKE_SWIG_FLAGS "-DOR_DLL=") # Find Java and JNI find_package(Java 1.8 COMPONENTS Development REQUIRED) @@ -300,14 +301,13 @@ set(need_unix_highs_lib "$>") set(need_windows_highs_lib "$>") set(is_ortools_shared "$,SHARED_LIBRARY>") +set(need_unix_ortools_lib "$") +set(need_windows_ortools_lib "$") add_custom_command( OUTPUT ${JAVA_NATIVE_PROJECT_DIR}/timestamp COMMAND ${CMAKE_COMMAND} -E remove -f timestamp - COMMAND ${CMAKE_COMMAND} -E copy - $ - $<${is_ortools_shared}:$> - ${JAVA_RESSOURCES_PATH}/${JAVA_NATIVE_PROJECT}/ + COMMAND ${CMAKE_COMMAND} -E make_directory ${JAVA_RESSOURCES_PATH}/${JAVA_NATIVE_PROJECT} COMMAND ${CMAKE_COMMAND} -E $,copy,true> $<${need_unix_zlib_lib}:$> @@ -447,6 +447,16 @@ add_custom_command( $<${need_windows_highs_lib}:$> ${JAVA_RESSOURCES_PATH}/${JAVA_NATIVE_PROJECT}/ + COMMAND ${CMAKE_COMMAND} -E + $ + $<${need_unix_ortools_lib}:$> + $<${need_windows_ortools_lib}:$> + ${JAVA_RESSOURCES_PATH}/${JAVA_NATIVE_PROJECT}/ + + COMMAND ${CMAKE_COMMAND} -E copy + $ + ${JAVA_RESSOURCES_PATH}/${JAVA_NATIVE_PROJECT}/ + COMMAND ${MAVEN_EXECUTABLE} compile -B COMMAND ${MAVEN_EXECUTABLE} package -B $<$:-Dfatjar=true> COMMAND ${MAVEN_EXECUTABLE} install -B $<$:-Dgpg.skip=true> diff --git a/cmake/python.cmake b/cmake/python.cmake index 62c544a3cf..8e641b016a 100644 --- a/cmake/python.cmake +++ b/cmake/python.cmake @@ -38,6 +38,7 @@ if(UNIX AND NOT APPLE AND NOT (CMAKE_SYSTEM_NAME STREQUAL "OpenBSD")) list(APPEND CMAKE_SWIG_FLAGS "-DSWIGWORDSIZE32") endif() endif() +list(APPEND CMAKE_SWIG_FLAGS "-DOR_DLL=") # Find Python 3 find_package(Python3 REQUIRED COMPONENTS Interpreter Development.Module) @@ -456,6 +457,8 @@ set(need_unix_highs_lib "$>") set(need_windows_highs_lib "$>") set(is_ortools_shared "$,SHARED_LIBRARY>") +set(need_unix_ortools_lib "$") +set(need_windows_ortools_lib "$") add_custom_command( OUTPUT python/ortools_timestamp @@ -556,8 +559,9 @@ add_custom_command( ${PYTHON_PROJECT}/.libs COMMAND ${CMAKE_COMMAND} -E - $ + $,copy,true> $<${need_unix_re2_lib}:$> + $<${need_windows_re2_lib}:$> ${PYTHON_PROJECT}/.libs COMMAND ${CMAKE_COMMAND} -E @@ -601,7 +605,8 @@ add_custom_command( COMMAND ${CMAKE_COMMAND} -E $ - $<${is_ortools_shared}:$> + $<${need_unix_ortools_lib}:$> + $<${need_windows_ortools_lib}:$> ${PYTHON_PROJECT}/.libs COMMAND ${CMAKE_COMMAND} -E touch ${PROJECT_BINARY_DIR}/python/ortools_timestamp MAIN_DEPENDENCY diff --git a/examples/cpp/nqueens.cc b/examples/cpp/nqueens.cc index ff2a0ae1d0..88b184d8f7 100644 --- a/examples/cpp/nqueens.cc +++ b/examples/cpp/nqueens.cc @@ -39,7 +39,6 @@ ABSL_FLAG( int, size, 0, "Size of the problem. If equal to 0, will test several increasing sizes."); ABSL_FLAG(bool, use_symmetry, false, "Use Symmetry Breaking methods"); -ABSL_DECLARE_FLAG(bool, cp_disable_solve); static const int kNumSolutions[] = { 1, 0, 0, 2, 10, 4, 40, 92, 352, 724, 2680, 14200, 73712, 365596, 2279184}; diff --git a/ortools/base/BUILD.bazel b/ortools/base/BUILD.bazel index d6a379da6b..5132337dd3 100644 --- a/ortools/base/BUILD.bazel +++ b/ortools/base/BUILD.bazel @@ -379,9 +379,17 @@ cc_library( ], ) +cc_library( + name = "base_export", + hdrs = ["base_export.h"], +) + cc_library( name = "macros", hdrs = ["macros.h"], + deps = [ + ":base_export", + ], ) cc_library( diff --git a/ortools/base/CMakeLists.txt b/ortools/base/CMakeLists.txt index a0eed94909..c05028a50e 100644 --- a/ortools/base/CMakeLists.txt +++ b/ortools/base/CMakeLists.txt @@ -26,8 +26,9 @@ target_compile_definitions(${NAME} PRIVATE -DOR_TOOLS_MAJOR=${PROJECT_VERSION_MAJOR} -DOR_TOOLS_MINOR=${PROJECT_VERSION_MINOR} -DOR_TOOLS_PATCH=${PROJECT_VERSION_PATCH}) -if(MSVC) - target_compile_definitions(${NAME} PRIVATE -DOR_TOOLS_EXPORTS) +if(MSVC AND BUILD_SHARED_LIBS) + target_compile_definitions(${NAME} PUBLIC "OR_BUILD_DLL") + target_compile_definitions(${NAME} PRIVATE "OR_EXPORT") endif() target_include_directories(${NAME} PRIVATE ${PROJECT_SOURCE_DIR} diff --git a/ortools/base/base_export.h b/ortools/base/base_export.h index 0d0a8be967..fd779a4a29 100644 --- a/ortools/base/base_export.h +++ b/ortools/base/base_export.h @@ -14,17 +14,17 @@ #ifndef OR_TOOLS_BASE_BASE_EXPORT_H_ #define OR_TOOLS_BASE_BASE_EXPORT_H_ -#if defined(_MSC_VER) && defined(OR_TOOLS_AS_DYNAMIC_LIB) +#if defined(_MSC_VER) && defined(OR_BUILD_DLL) // Annoying stuff for windows -- makes sure clients can import these functions -#if defined(OR_TOOLS_EXPORTS) -#define BASE_EXPORT __declspec(dllexport) +#if defined(OR_EXPORT) +#define OR_DLL __declspec(dllexport) #else -#define BASE_EXPORT __declspec(dllimport) -#endif // defined(OR_TOOLS_EXPORT) -#endif // _MSC_VER && OR_TOOLS_AS_DYNAMIC_LIB +#define OR_DLL __declspec(dllimport) +#endif // defined(OR_EXPORT) +#endif // _MSC_VER && OR_BUILD_DLL -#ifndef BASE_EXPORT -#define BASE_EXPORT +#ifndef OR_DLL +#define OR_DLL #endif #endif // OR_TOOLS_BASE_BASE_EXPORT_H_ diff --git a/ortools/base/macros.h b/ortools/base/macros.h index fd8fcc7fa8..85dc470feb 100644 --- a/ortools/base/macros.h +++ b/ortools/base/macros.h @@ -16,6 +16,8 @@ #include // for size_t. +#include "ortools/base/base_export.h" // for OR_DLL + #define COMPILE_ASSERT(x, msg) #ifdef NDEBUG diff --git a/ortools/constraint_solver/CMakeLists.txt b/ortools/constraint_solver/CMakeLists.txt index 3cb19a91b9..a578370fa6 100644 --- a/ortools/constraint_solver/CMakeLists.txt +++ b/ortools/constraint_solver/CMakeLists.txt @@ -20,6 +20,10 @@ add_library(${NAME} OBJECT ${_SRCS}) set_target_properties(${NAME} PROPERTIES POSITION_INDEPENDENT_CODE ON ) +if(MSVC AND BUILD_SHARED_LIBS) + target_compile_definitions(${NAME} PUBLIC "OR_BUILD_DLL") + target_compile_definitions(${NAME} PRIVATE "OR_EXPORT") +endif() target_include_directories(${NAME} PRIVATE ${PROJECT_SOURCE_DIR} ${PROJECT_BINARY_DIR}) diff --git a/ortools/constraint_solver/constraint_solver.h b/ortools/constraint_solver/constraint_solver.h index 6c7b426073..1b01e0be65 100644 --- a/ortools/constraint_solver/constraint_solver.h +++ b/ortools/constraint_solver/constraint_solver.h @@ -104,7 +104,8 @@ #include "ortools/util/tuple_set.h" #if !defined(SWIG) -ABSL_DECLARE_FLAG(int64_t, cp_random_seed); +OR_DLL ABSL_DECLARE_FLAG(int64_t, cp_random_seed); +OR_DLL ABSL_DECLARE_FLAG(bool, cp_disable_solve); #endif // !defined(SWIG) class File; @@ -3606,7 +3607,7 @@ class Demon : public BaseObject { }; /// Model visitor. -class ModelVisitor : public BaseObject { +class OR_DLL ModelVisitor : public BaseObject { public: /// Constraint and Expression types. static const char kAbs[]; @@ -4822,7 +4823,7 @@ class ImprovementSearchLimit : public SearchLimit { /// cannot be accessed any more. An interval var is automatically marked /// as unperformed when it is not consistent anymore (start greater /// than end, duration < 0...) -class IntervalVar : public PropagationBaseObject { +class OR_DLL IntervalVar : public PropagationBaseObject { public: /// The smallest acceptable value to be returned by StartMin() static const int64_t kMinValidValue; diff --git a/ortools/constraint_solver/constraint_solveri.h b/ortools/constraint_solver/constraint_solveri.h index fea1f454c0..b55e09dcaa 100644 --- a/ortools/constraint_solver/constraint_solveri.h +++ b/ortools/constraint_solver/constraint_solveri.h @@ -2303,7 +2303,7 @@ class LocalSearchFilterManager : public BaseObject { int64_t accepted_value_; }; -class IntVarLocalSearchFilter : public LocalSearchFilter { +class OR_DLL IntVarLocalSearchFilter : public LocalSearchFilter { public: explicit IntVarLocalSearchFilter(const std::vector& vars); ~IntVarLocalSearchFilter() override; @@ -2433,7 +2433,7 @@ class LocalSearchMonitor : public SearchMonitor { void Install() override; }; -class BooleanVar : public IntVar { +class OR_DLL BooleanVar : public IntVar { public: static const int kUnboundBooleanVarValue; diff --git a/ortools/dotnet/Google.OrTools.runtime.csproj.in b/ortools/dotnet/Google.OrTools.runtime.csproj.in index 50a23ea38a..82f1dd13f7 100644 --- a/ortools/dotnet/Google.OrTools.runtime.csproj.in +++ b/ortools/dotnet/Google.OrTools.runtime.csproj.in @@ -26,8 +26,6 @@ runtimes/@DOTNET_RID@/native/%(Filename)%(Extension) true diff --git a/ortools/graph/CMakeLists.txt b/ortools/graph/CMakeLists.txt index 0a54e293e7..0f8dfd65b4 100644 --- a/ortools/graph/CMakeLists.txt +++ b/ortools/graph/CMakeLists.txt @@ -26,6 +26,10 @@ add_library(${NAME} OBJECT ${_SRCS}) set_target_properties(${NAME} PROPERTIES POSITION_INDEPENDENT_CODE ON ) +if(MSVC AND BUILD_SHARED_LIBS) + target_compile_definitions(${NAME} PUBLIC "OR_BUILD_DLL") + target_compile_definitions(${NAME} PRIVATE "OR_EXPORT") +endif() target_include_directories(${NAME} PRIVATE ${PROJECT_SOURCE_DIR} ${PROJECT_BINARY_DIR}) diff --git a/ortools/graph/linear_assignment.h b/ortools/graph/linear_assignment.h index 562f0a8069..4b53dda3b4 100644 --- a/ortools/graph/linear_assignment.h +++ b/ortools/graph/linear_assignment.h @@ -214,9 +214,9 @@ #include "ortools/util/zvector.h" #ifndef SWIG -ABSL_DECLARE_FLAG(int64_t, assignment_alpha); -ABSL_DECLARE_FLAG(int, assignment_progress_logging_period); -ABSL_DECLARE_FLAG(bool, assignment_stack_order); +OR_DLL ABSL_DECLARE_FLAG(int64_t, assignment_alpha); +OR_DLL ABSL_DECLARE_FLAG(int, assignment_progress_logging_period); +OR_DLL ABSL_DECLARE_FLAG(bool, assignment_stack_order); #endif namespace operations_research { diff --git a/ortools/graph/linear_assignment_test.cc b/ortools/graph/linear_assignment_test.cc index 66b5eb3d83..20814bf791 100644 --- a/ortools/graph/linear_assignment_test.cc +++ b/ortools/graph/linear_assignment_test.cc @@ -29,8 +29,6 @@ #include "ortools/base/gmock.h" #include "ortools/graph/graph.h" -ABSL_DECLARE_FLAG(bool, assignment_stack_order); - namespace operations_research { using ::testing::Eq; diff --git a/ortools/init/BUILD.bazel b/ortools/init/BUILD.bazel index efe615cddb..95b55c918c 100644 --- a/ortools/init/BUILD.bazel +++ b/ortools/init/BUILD.bazel @@ -16,10 +16,12 @@ package(default_visibility = ["//visibility:public"]) cc_library( name = "init", hdrs = ["init.h"], + srcs = ["init.cc"], deps = [ "//ortools/base", "//ortools/gurobi:environment", "//ortools/sat:cp_model_solver", + "//ortools/sat:cp_model_solver_helpers", "@com_google_absl//absl/flags:flag", "@com_google_absl//absl/log", "@com_google_absl//absl/log:globals", diff --git a/ortools/init/CMakeLists.txt b/ortools/init/CMakeLists.txt index ff9d22ea23..25f6fa98dc 100644 --- a/ortools/init/CMakeLists.txt +++ b/ortools/init/CMakeLists.txt @@ -11,7 +11,7 @@ # See the License for the specific language governing permissions and # limitations under the License. -file(GLOB _SRCS "*.h") +file(GLOB _SRCS "*.h" "*.cc") set(NAME ${PROJECT_NAME}_init) # Will be merge in libortools.so @@ -21,6 +21,10 @@ set_target_properties(${NAME} PROPERTIES LINKER_LANGUAGE CXX POSITION_INDEPENDENT_CODE ON ) +if(MSVC AND BUILD_SHARED_LIBS) + target_compile_definitions(${NAME} PUBLIC "OR_BUILD_DLL") + target_compile_definitions(${NAME} PRIVATE "OR_EXPORT") +endif() target_include_directories(${NAME} PRIVATE ${PROJECT_SOURCE_DIR} ${PROJECT_BINARY_DIR}) diff --git a/ortools/init/init.cc b/ortools/init/init.cc new file mode 100644 index 0000000000..c02a33f709 --- /dev/null +++ b/ortools/init/init.cc @@ -0,0 +1,46 @@ +// Copyright 2010-2025 Google LLC +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +#include "ortools/init/init.h" + +#include "absl/flags/flag.h" +#include "absl/flags/usage.h" +#include "absl/log/globals.h" +#include "absl/log/initialize.h" +#include "ortools/gurobi/environment.h" +#include "ortools/sat/cp_model_solver.h" +#include "ortools/sat/cp_model_solver_helpers.h" + +namespace operations_research { + void CppBridge::InitLogging(const std::string& usage) { + absl::SetProgramUsageMessage(usage); + absl::InitializeLog(); + } + + void CppBridge::SetFlags(const CppFlags& flags) { + absl::SetFlag(&FLAGS_stderrthreshold, flags.stderrthreshold); + absl::EnableLogPrefix(flags.log_prefix); + if (!flags.cp_model_dump_prefix.empty()) { + absl::SetFlag(&FLAGS_cp_model_dump_prefix, flags.cp_model_dump_prefix); + } + absl::SetFlag(&FLAGS_cp_model_dump_models, flags.cp_model_dump_models); + absl::SetFlag(&FLAGS_cp_model_dump_submodels, + flags.cp_model_dump_submodels); + absl::SetFlag(&FLAGS_cp_model_dump_response, flags.cp_model_dump_response); + } + + bool CppBridge::LoadGurobiSharedLibrary(const std::string& full_library_path) { + return LoadGurobiDynamicLibrary({full_library_path}).ok(); + } + +} // namespace operations_research diff --git a/ortools/init/init.h b/ortools/init/init.h index 76e182f3bc..142ecd449e 100644 --- a/ortools/init/init.h +++ b/ortools/init/init.h @@ -18,20 +18,9 @@ #include #include -#include "absl/flags/flag.h" -#include "absl/flags/usage.h" -#include "absl/log/globals.h" -#include "absl/log/initialize.h" #include "ortools/base/logging.h" #include "ortools/base/version.h" -#include "ortools/gurobi/environment.h" -#include "ortools/sat/cp_model_solver.h" - -ABSL_DECLARE_FLAG(std::string, cp_model_dump_prefix); -ABSL_DECLARE_FLAG(bool, cp_model_dump_models); -ABSL_DECLARE_FLAG(bool, cp_model_dump_submodels); -ABSL_DECLARE_FLAG(bool, cp_model_dump_response); -ABSL_DECLARE_FLAG(int, stderrthreshold); +#include "ortools/sat/cp_model_solver_helpers.h" namespace operations_research { @@ -97,10 +86,7 @@ class CppBridge { * * This must be called once before any other library from OR-Tools are used. */ - static void InitLogging(const std::string& usage) { - absl::SetProgramUsageMessage(usage); - absl::InitializeLog(); - } + static void InitLogging(const std::string& usage); /** * Shutdown the C++ logging layer. @@ -115,17 +101,7 @@ class CppBridge { /** * Sets all the C++ flags contained in the CppFlags structure. */ - static void SetFlags(const CppFlags& flags) { - absl::SetFlag(&FLAGS_stderrthreshold, flags.stderrthreshold); - absl::EnableLogPrefix(flags.log_prefix); - if (!flags.cp_model_dump_prefix.empty()) { - absl::SetFlag(&FLAGS_cp_model_dump_prefix, flags.cp_model_dump_prefix); - } - absl::SetFlag(&FLAGS_cp_model_dump_models, flags.cp_model_dump_models); - absl::SetFlag(&FLAGS_cp_model_dump_submodels, - flags.cp_model_dump_submodels); - absl::SetFlag(&FLAGS_cp_model_dump_response, flags.cp_model_dump_response); - } + static void SetFlags(const CppFlags& flags); /** * Load the gurobi shared library. @@ -135,9 +111,7 @@ class CppBridge { * You need to pass the full path, including the shared library file. * It returns true if the library was found and correctly loaded. */ - static bool LoadGurobiSharedLibrary(const std::string& full_library_path) { - return LoadGurobiDynamicLibrary({full_library_path}).ok(); - } + static bool LoadGurobiSharedLibrary(const std::string& full_library_path); /** * Delete a temporary C++ byte array. diff --git a/ortools/java/com/google/ortools/Loader.java b/ortools/java/com/google/ortools/Loader.java index 43af427071..8fa3bf913f 100644 --- a/ortools/java/com/google/ortools/Loader.java +++ b/ortools/java/com/google/ortools/Loader.java @@ -143,7 +143,7 @@ public static synchronized void loadNativeLibraries() { Path tempPath = unpackNativeResources(resourceURI); // libraries order does matter ! List dlls = Arrays.asList( - "zlib1", "abseil_dll", "re2", "utf8_validity", "libprotobuf", "highs", "jniortools"); + "zlib1", "abseil_dll", "re2", "utf8_validity", "libprotobuf", "highs", "ortools", "jniortools"); for (String dll : dlls) { try { // System.out.println("System.load(" + dll + ")"); diff --git a/ortools/linear_solver/CMakeLists.txt b/ortools/linear_solver/CMakeLists.txt index aadecdab2b..9902bd9239 100644 --- a/ortools/linear_solver/CMakeLists.txt +++ b/ortools/linear_solver/CMakeLists.txt @@ -29,6 +29,10 @@ add_library(${NAME} OBJECT ${_SRCS}) set_target_properties(${NAME} PROPERTIES POSITION_INDEPENDENT_CODE ON ) +if(MSVC AND BUILD_SHARED_LIBS) + target_compile_definitions(${NAME} PUBLIC "OR_BUILD_DLL") + target_compile_definitions(${NAME} PRIVATE "OR_EXPORT") +endif() target_include_directories(${NAME} PUBLIC $ $) diff --git a/ortools/linear_solver/linear_solver.h b/ortools/linear_solver/linear_solver.h index 4dee0ee7c3..884067c3ba 100644 --- a/ortools/linear_solver/linear_solver.h +++ b/ortools/linear_solver/linear_solver.h @@ -165,9 +165,9 @@ #include "ortools/port/proto_utils.h" #include "ortools/util/lazy_mutable_copy.h" -ABSL_DECLARE_FLAG(bool, linear_solver_enable_verbose_output); -ABSL_DECLARE_FLAG(bool, log_verification_errors); -ABSL_DECLARE_FLAG(bool, verify_solution); +OR_DLL ABSL_DECLARE_FLAG(bool, linear_solver_enable_verbose_output); +OR_DLL ABSL_DECLARE_FLAG(bool, log_verification_errors); +OR_DLL ABSL_DECLARE_FLAG(bool, verify_solution); namespace operations_research { @@ -1469,7 +1469,7 @@ class MPConstraint { * instead. We need to figure out how to deal with the subtleties of * the default values. */ -class MPSolverParameters { +class OR_DLL MPSolverParameters { public: /// Enumeration of parameters that take continuous values. enum DoubleParam { diff --git a/ortools/linear_solver/solve.cc b/ortools/linear_solver/solve.cc index d8321a0954..aca36f20d5 100644 --- a/ortools/linear_solver/solve.cc +++ b/ortools/linear_solver/solve.cc @@ -120,13 +120,6 @@ ABSL_FLAG(std::string, sol_file, "", ABSL_FLAG(std::string, dump_mps, "", "If non-empty, dumps the model in mps format there."); -ABSL_DECLARE_FLAG(bool, verify_solution); // Defined in ./linear_solver.cc -ABSL_DECLARE_FLAG(bool, - log_verification_errors); // Defined in ./linear_solver.cc -ABSL_DECLARE_FLAG( - bool, - linear_solver_enable_verbose_output); // Defined in ./linear_solver.cc - static const char kUsageStr[] = "Run MPSolver on the given input file. Many formats are supported: \n" " - a .mps or .mps.gz file,\n" diff --git a/ortools/math_opt/core/BUILD.bazel b/ortools/math_opt/core/BUILD.bazel index 5baa479cf1..6ce22e35e0 100644 --- a/ortools/math_opt/core/BUILD.bazel +++ b/ortools/math_opt/core/BUILD.bazel @@ -146,6 +146,7 @@ cc_library( name = "solver_debug", srcs = ["solver_debug.cc"], hdrs = ["solver_debug.h"], + deps = ["//ortools/base:base_export"], ) cc_library( diff --git a/ortools/math_opt/core/CMakeLists.txt b/ortools/math_opt/core/CMakeLists.txt index 6d01327ad7..904366ea97 100644 --- a/ortools/math_opt/core/CMakeLists.txt +++ b/ortools/math_opt/core/CMakeLists.txt @@ -20,6 +20,10 @@ list(FILTER _SRCS EXCLUDE REGEX "/[^/]*_test\\.cc$") set(NAME ${PROJECT_NAME}_math_opt_core) add_library(${NAME} OBJECT ${_SRCS}) set_target_properties(${NAME} PROPERTIES POSITION_INDEPENDENT_CODE ON) +if(MSVC AND BUILD_SHARED_LIBS) + target_compile_definitions(${NAME} PUBLIC "OR_BUILD_DLL") + target_compile_definitions(${NAME} PRIVATE "OR_EXPORT") +endif() target_include_directories(${NAME} PUBLIC $ $) diff --git a/ortools/math_opt/core/solver_debug.h b/ortools/math_opt/core/solver_debug.h index 44d0088ccc..aaf59048fe 100644 --- a/ortools/math_opt/core/solver_debug.h +++ b/ortools/math_opt/core/solver_debug.h @@ -17,6 +17,8 @@ #include #include +#include "ortools/base/base_export.h" + namespace operations_research { namespace math_opt { namespace internal { @@ -26,7 +28,7 @@ namespace internal { // This variable is intended to be used by MathOpt unit tests in other languages // to test the proper garbage collection. It should never be used in any other // context. -extern std::atomic debug_num_solver; +OR_DLL extern std::atomic debug_num_solver; } // namespace internal } // namespace math_opt diff --git a/ortools/python/__init__.py.in b/ortools/python/__init__.py.in index 196bb9c1d7..fb4d7d6488 100644 --- a/ortools/python/__init__.py.in +++ b/ortools/python/__init__.py.in @@ -55,11 +55,11 @@ def _load_ortools_libs(): except: pass else: - for dll in ["zlib1.dll", "abseil_dll.dll", "utf8_validity.dll", "libprotobuf.dll", "highs.dll"]: - dll_path = os.path.join(basedir, ".libs", dll) - if os.path.exists(dll_path): - print(f"load {dll_path}...") - WinDLL(dll_path) + for dll in ["zlib1.dll", "abseil_dll.dll", "utf8_validity.dll", "re2.dll", "libprotobuf.dll", "highs.dll", "ortools.dll"]: + dll_path = os.path.join(basedir, ".libs", dll) + if os.path.exists(dll_path): + print(f"load {dll_path}...") + WinDLL(dll_path) -_load_ortools_libs() \ No newline at end of file +_load_ortools_libs() diff --git a/ortools/python/setup.py.in b/ortools/python/setup.py.in index 697011f6da..54ae24adda 100644 --- a/ortools/python/setup.py.in +++ b/ortools/python/setup.py.in @@ -51,8 +51,7 @@ setup( ], package_data={ '@PYTHON_PROJECT@':[ - '.libs/*', - $<$,SHARED_LIBRARY>:'../$'> + '.libs/*' ], '@PYTHON_PROJECT@.init.python':[ '$', diff --git a/ortools/routing/index_manager.h b/ortools/routing/index_manager.h index adab7e7847..a318b2eb2b 100644 --- a/ortools/routing/index_manager.h +++ b/ortools/routing/index_manager.h @@ -47,7 +47,7 @@ namespace operations_research::routing { /// indices range between 0 and n-1, where n = number of vehicles * 2 (for start /// and end nodes) + number of non-start or end nodes. /// -class RoutingIndexManager { +class OR_DLL RoutingIndexManager { public: typedef RoutingNodeIndex NodeIndex; static const int64_t kUnassigned; diff --git a/ortools/routing/routing.h b/ortools/routing/routing.h index 74eb6371d6..0cd828283e 100644 --- a/ortools/routing/routing.h +++ b/ortools/routing/routing.h @@ -251,7 +251,7 @@ class PathsMetadata { std::vector path_of_node_; }; -class RoutingModel { +class OR_DLL RoutingModel { public: /// Types of precedence policy applied to pickup and delivery pairs. enum PickupAndDeliveryPolicy { @@ -2837,7 +2837,7 @@ class RoutingModel { }; /// Routing model visitor. -class RoutingModelVisitor : public BaseObject { +class OR_DLL RoutingModelVisitor : public BaseObject { public: /// Constraint types. static const char kLightElement[]; diff --git a/ortools/sat/cp_model_solver.h b/ortools/sat/cp_model_solver.h index 3bec9b5278..90ef155a70 100644 --- a/ortools/sat/cp_model_solver.h +++ b/ortools/sat/cp_model_solver.h @@ -21,6 +21,8 @@ #include "ortools/sat/model.h" #include "ortools/sat/sat_parameters.pb.h" +ABSL_DECLARE_FLAG(bool, cp_model_dump_response); + namespace operations_research { namespace sat { diff --git a/ortools/util/CMakeLists.txt b/ortools/util/CMakeLists.txt index dca41aa851..808a058604 100644 --- a/ortools/util/CMakeLists.txt +++ b/ortools/util/CMakeLists.txt @@ -22,6 +22,10 @@ add_library(${NAME} OBJECT ${_SRCS}) set_target_properties(${NAME} PROPERTIES POSITION_INDEPENDENT_CODE ON ) +if(MSVC AND BUILD_SHARED_LIBS) + target_compile_definitions(${NAME} PUBLIC "OR_BUILD_DLL") + target_compile_definitions(${NAME} PRIVATE "OR_EXPORT") +endif() target_include_directories(${NAME} PRIVATE ${PROJECT_SOURCE_DIR} ${PROJECT_BINARY_DIR}) diff --git a/ortools/util/time_limit.h b/ortools/util/time_limit.h index 0d25a597ee..4599724723 100644 --- a/ortools/util/time_limit.h +++ b/ortools/util/time_limit.h @@ -38,7 +38,7 @@ * Enables changing the behavior of the TimeLimit class to use -b usertime * instead of \b walltime. This is mainly useful for benchmarks. */ -ABSL_DECLARE_FLAG(bool, time_limit_use_usertime); +OR_DLL ABSL_DECLARE_FLAG(bool, time_limit_use_usertime); namespace operations_research { @@ -91,7 +91,7 @@ namespace operations_research { */ // TODO(user): The expression "deterministic time" should be replaced with // "number of operations" to avoid confusion with "real" time. -class TimeLimit { +class OR_DLL TimeLimit { public: static const double kSafetyBufferSeconds; // See the .cc for the value. static const int kHistorySize; diff --git a/ortools/xpress/CMakeLists.txt b/ortools/xpress/CMakeLists.txt index 51ae702b99..add1ace6ac 100644 --- a/ortools/xpress/CMakeLists.txt +++ b/ortools/xpress/CMakeLists.txt @@ -21,6 +21,10 @@ set_target_properties(${NAME} PROPERTIES CXX_EXTENSIONS OFF POSITION_INDEPENDENT_CODE ON ) +if(MSVC AND BUILD_SHARED_LIBS) + target_compile_definitions(${NAME} PUBLIC "OR_BUILD_DLL") + target_compile_definitions(${NAME} PRIVATE "OR_EXPORT") +endif() target_include_directories(${NAME} PRIVATE ${PROJECT_SOURCE_DIR} ${PROJECT_BINARY_DIR}) diff --git a/ortools/xpress/environment.h b/ortools/xpress/environment.h index fc075b0dd4..e066ad94a3 100644 --- a/ortools/xpress/environment.h +++ b/ortools/xpress/environment.h @@ -20,6 +20,7 @@ #include #include "absl/status/status.h" +#include "ortools/base/macros.h" extern "C" { typedef struct xo_prob_struct* XPRSprob; @@ -487,21 +488,21 @@ extern std::function XPRSsetintcontr extern std::function XPRSsetintcontrol64; extern std::function XPRSsetdblcontrol; extern std::function XPRSsetstrcontrol; -extern std::function XPRSgetintcontrol; -extern std::function XPRSgetintcontrol64; -extern std::function XPRSgetdblcontrol; -extern std::function XPRSgetstringcontrol; -extern std::function XPRSgetintattrib; -extern std::function XPRSgetdblattrib; +OR_DLL extern std::function XPRSgetintcontrol; +OR_DLL extern std::function XPRSgetintcontrol64; +OR_DLL extern std::function XPRSgetdblcontrol; +OR_DLL extern std::function XPRSgetstringcontrol; +OR_DLL extern std::function XPRSgetintattrib; +OR_DLL extern std::function XPRSgetdblattrib; extern std::function XPRSgetcontrolinfo; extern std::function XPRSloadlp; extern std::function XPRSloadlp64; -extern std::function XPRSgetobj; -extern std::function XPRSgetrhs; -extern std::function XPRSgetrhsrange; -extern std::function XPRSgetlb; -extern std::function XPRSgetub; -extern std::function XPRSgetcoef; +OR_DLL extern std::function XPRSgetobj; +OR_DLL extern std::function XPRSgetrhs; +OR_DLL extern std::function XPRSgetrhsrange; +OR_DLL extern std::function XPRSgetlb; +OR_DLL extern std::function XPRSgetub; +OR_DLL extern std::function XPRSgetcoef; extern std::function XPRSgetduals; extern std::function XPRSgetredcosts; extern std::function XPRSaddrows; @@ -517,8 +518,8 @@ extern std::function XPRSchgobjsense; extern std::function XPRSgetlasterror; extern std::function XPRSgetbasis; extern std::function XPRSwriteprob; -extern std::function XPRSgetrowtype; -extern std::function XPRSgetcoltype; +OR_DLL extern std::function XPRSgetrowtype; +OR_DLL extern std::function XPRSgetcoltype; extern std::function XPRSchgbounds; extern std::function XPRSaddmipsol; extern std::function XPRSgetlpsol;