Skip to content

Commit

Permalink
cmake: Fix and enabled shared lib support with MSVC
Browse files Browse the repository at this point in the history
* Add decldll to proto
* rework init to make it working for MSVC
* fix test_xprs_interface build
dotnet: Fix MSVC shared libs support
  * Fix csproj to include libortools.dll
java: Fix MSVC shared_libs support
  * Fix runtime jar to include libortools.dll
python: Fix MSVC shared_libs support
  * fix __init__.py.in loading for MSVC
  • Loading branch information
Mizux committed Feb 3, 2025
1 parent befa5f7 commit 0951780
Show file tree
Hide file tree
Showing 34 changed files with 181 additions and 95 deletions.
2 changes: 1 addition & 1 deletion CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -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})
Expand Down
19 changes: 16 additions & 3 deletions cmake/cpp.cmake
Original file line number Diff line number Diff line change
Expand Up @@ -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")
Expand Down Expand Up @@ -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}"
Expand All @@ -383,6 +387,12 @@ function(generate_proto_library)
#$<TARGET_PROPERTY:protobuf::libprotobuf,INTERFACE_INCLUDE_DIRECTORIES>
)
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)
Expand Down Expand Up @@ -447,6 +457,9 @@ set_target_properties(${PROJECT_NAME} PROPERTIES
target_compile_features(${PROJECT_NAME} PUBLIC
$<IF:$<CXX_COMPILER_ID:MSVC>,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
Expand Down
2 changes: 2 additions & 0 deletions cmake/dotnet.cmake
Original file line number Diff line number Diff line change
Expand Up @@ -395,6 +395,8 @@ set(need_unix_highs_lib "$<AND:${is_not_windows},$<BOOL:${BUILD_HIGHS}>>")
set(need_windows_highs_lib "$<AND:${is_windows},$<BOOL:${BUILD_HIGHS}>>")

set(is_ortools_shared "$<STREQUAL:$<TARGET_PROPERTY:ortools,TYPE>,SHARED_LIBRARY>")
set(need_unix_ortools_lib "$<AND:${is_not_windows},${is_ortools_shared}>")
set(need_windows_ortools_lib "$<AND:${is_windows},${is_ortools_shared}>")

configure_file(
${PROJECT_SOURCE_DIR}/ortools/dotnet/${DOTNET_PACKAGE}.runtime.csproj.in
Expand Down
17 changes: 13 additions & 4 deletions cmake/java.cmake
Original file line number Diff line number Diff line change
Expand Up @@ -298,14 +298,13 @@ set(need_unix_highs_lib "$<AND:${is_not_windows},$<BOOL:${BUILD_HIGHS}>>")
set(need_windows_highs_lib "$<AND:${is_windows},$<BOOL:${BUILD_HIGHS}>>")

set(is_ortools_shared "$<STREQUAL:$<TARGET_PROPERTY:ortools,TYPE>,SHARED_LIBRARY>")
set(need_unix_ortools_lib "$<AND:${is_not_windows},${is_ortools_shared}>")
set(need_windows_ortools_lib "$<AND:${is_windows},${is_ortools_shared}>")

add_custom_command(
OUTPUT ${JAVA_NATIVE_PROJECT_DIR}/timestamp
COMMAND ${CMAKE_COMMAND} -E remove -f timestamp
COMMAND ${CMAKE_COMMAND} -E copy
$<TARGET_FILE:jni${JAVA_ARTIFACT}>
$<${is_ortools_shared}:$<TARGET_SONAME_FILE:ortools>>
${JAVA_RESSOURCES_PATH}/${JAVA_NATIVE_PROJECT}/
COMMAND ${CMAKE_COMMAND} -E make_directory ${JAVA_RESSOURCES_PATH}/${JAVA_NATIVE_PROJECT}
COMMAND ${CMAKE_COMMAND} -E
$<IF:$<BOOL:${BUILD_ZLIB}>,copy,true>
$<${need_unix_zlib_lib}:$<TARGET_SONAME_FILE:ZLIB::ZLIB>>
Expand Down Expand Up @@ -445,6 +444,16 @@ add_custom_command(
$<${need_windows_highs_lib}:$<TARGET_FILE:highs>>
${JAVA_RESSOURCES_PATH}/${JAVA_NATIVE_PROJECT}/

COMMAND ${CMAKE_COMMAND} -E
$<IF:${is_ortools_shared},copy,true>
$<${need_unix_ortools_lib}:$<TARGET_SONAME_FILE:${PROJECT_NAMESPACE}::ortools>>
$<${need_windows_ortools_lib}:$<TARGET_FILE:${PROJECT_NAMESPACE}::ortools>>
${JAVA_RESSOURCES_PATH}/${JAVA_NATIVE_PROJECT}/

COMMAND ${CMAKE_COMMAND} -E copy
$<TARGET_FILE:jni${JAVA_ARTIFACT}>
${JAVA_RESSOURCES_PATH}/${JAVA_NATIVE_PROJECT}/

COMMAND ${MAVEN_EXECUTABLE} compile -B
COMMAND ${MAVEN_EXECUTABLE} package -B $<$<BOOL:${BUILD_FAT_JAR}>:-Dfatjar=true>
COMMAND ${MAVEN_EXECUTABLE} install -B $<$<BOOL:${SKIP_GPG}>:-Dgpg.skip=true>
Expand Down
5 changes: 4 additions & 1 deletion cmake/python.cmake
Original file line number Diff line number Diff line change
Expand Up @@ -450,6 +450,8 @@ set(need_unix_highs_lib "$<AND:${is_not_windows},$<BOOL:${BUILD_HIGHS}>>")
set(need_windows_highs_lib "$<AND:${is_windows},$<BOOL:${BUILD_HIGHS}>>")

set(is_ortools_shared "$<STREQUAL:$<TARGET_PROPERTY:ortools,TYPE>,SHARED_LIBRARY>")
set(need_unix_ortools_lib "$<AND:${is_not_windows},${is_ortools_shared}>")
set(need_windows_ortools_lib "$<AND:${is_windows},${is_ortools_shared}>")

add_custom_command(
OUTPUT python/ortools_timestamp
Expand Down Expand Up @@ -596,7 +598,8 @@ add_custom_command(

COMMAND ${CMAKE_COMMAND} -E
$<IF:${is_ortools_shared},copy,true>
$<${is_ortools_shared}:$<TARGET_SONAME_FILE:ortools>>
$<${need_unix_ortools_lib}:$<TARGET_SONAME_FILE:${PROJECT_NAMESPACE}::ortools>>
$<${need_windows_ortools_lib}:$<TARGET_FILE:${PROJECT_NAMESPACE}::ortools>>
${PYTHON_PROJECT}/.libs
COMMAND ${CMAKE_COMMAND} -E touch ${PROJECT_BINARY_DIR}/python/ortools_timestamp
MAIN_DEPENDENCY
Expand Down
1 change: 0 additions & 1 deletion examples/cpp/nqueens.cc
Original file line number Diff line number Diff line change
Expand Up @@ -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};
Expand Down
8 changes: 8 additions & 0 deletions ortools/base/BUILD.bazel
Original file line number Diff line number Diff line change
Expand Up @@ -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(
Expand Down
5 changes: 3 additions & 2 deletions ortools/base/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -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}
Expand Down
16 changes: 8 additions & 8 deletions ortools/base/base_export.h
Original file line number Diff line number Diff line change
Expand Up @@ -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_
2 changes: 2 additions & 0 deletions ortools/base/macros.h
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,8 @@

#include <cstdlib> // for size_t.

#include "ortools/base/base_export.h" // for OR_DLL

#define COMPILE_ASSERT(x, msg)

#ifdef NDEBUG
Expand Down
4 changes: 4 additions & 0 deletions ortools/constraint_solver/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -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})
Expand Down
3 changes: 2 additions & 1 deletion ortools/constraint_solver/constraint_solver.h
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand Down
2 changes: 1 addition & 1 deletion ortools/constraint_solver/constraint_solveri.h
Original file line number Diff line number Diff line change
Expand Up @@ -2291,7 +2291,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<IntVar*>& vars);
~IntVarLocalSearchFilter() override;
Expand Down
4 changes: 2 additions & 2 deletions ortools/constraint_solver/routing.h
Original file line number Diff line number Diff line change
Expand Up @@ -251,7 +251,7 @@ class PathsMetadata {
std::vector<int64_t> path_of_node_;
};

class RoutingModel {
class OR_DLL RoutingModel {
public:
/// Types of precedence policy applied to pickup and delivery pairs.
enum PickupAndDeliveryPolicy {
Expand Down Expand Up @@ -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[];
Expand Down
5 changes: 3 additions & 2 deletions ortools/dotnet/Google.OrTools.runtime.csproj.in
Original file line number Diff line number Diff line change
Expand Up @@ -26,8 +26,6 @@
<!-- If ortools is built as a STATIC_LIBRARY (e.g. Windows) then we don't have to include it -->
<Content Include="
$<TARGET_FILE:google-ortools-native>
$<@is_ortools_shared@:;$<TARGET_SONAME_FILE:ortools>>

$<@need_unix_zlib_lib@:;$<TARGET_SONAME_FILE:ZLIB::ZLIB>>
$<@need_windows_zlib_lib@:;$<TARGET_FILE:ZLIB::ZLIB>>

Expand Down Expand Up @@ -133,6 +131,9 @@

$<@need_unix_highs_lib@:;$<TARGET_SONAME_FILE:highs>>
$<@need_windows_highs_lib@:;$<TARGET_FILE:highs>>

$<@need_unix_ortools_lib@:;$<TARGET_SONAME_FILE:ortools>>
$<@need_windows_ortools_lib@:;$<TARGET_FILE:ortools>>
">
<PackagePath>runtimes/@DOTNET_RID@/native/%(Filename)%(Extension)</PackagePath>
<Pack>true</Pack>
Expand Down
4 changes: 4 additions & 0 deletions ortools/graph/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -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})
Expand Down
6 changes: 3 additions & 3 deletions ortools/graph/linear_assignment.h
Original file line number Diff line number Diff line change
Expand Up @@ -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 {
Expand Down
2 changes: 0 additions & 2 deletions ortools/graph/linear_assignment_test.cc
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand Down
2 changes: 2 additions & 0 deletions ortools/init/BUILD.bazel
Original file line number Diff line number Diff line change
Expand Up @@ -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",
Expand Down
6 changes: 5 additions & 1 deletion ortools/init/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand All @@ -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})
Expand Down
46 changes: 46 additions & 0 deletions ortools/init/init.cc
Original file line number Diff line number Diff line change
@@ -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
Loading

0 comments on commit 0951780

Please sign in to comment.