or-tools 0.1.2 → 0.3.0

Sign up to get free protection for your applications and to get access to all the features.
@@ -115,14 +115,22 @@ operations_research::sat::LinearExpr from_ruby
115
115
  auto cvar = (Array) var;
116
116
  // TODO clean up
117
117
  Object o = cvar[0];
118
- if (((Rice::String) o.call("class").call("name")).str() == "ORTools::BoolVar") {
119
- expr.AddVar(from_ruby<operations_research::sat::BoolVar>(cvar[0]));
118
+ std::string type = ((String) o.call("class").call("name")).str();
119
+ if (type == "ORTools::BoolVar") {
120
+ expr.AddTerm(from_ruby<operations_research::sat::BoolVar>(cvar[0]), from_ruby<int64>(cvar[1]));
121
+ } else if (type == "Integer") {
122
+ expr.AddConstant(from_ruby<int64>(cvar[0]));
120
123
  } else {
121
124
  expr.AddTerm(from_ruby<operations_research::sat::IntVar>(cvar[0]), from_ruby<int64>(cvar[1]));
122
125
  }
123
126
  }
124
127
  } else {
125
- expr = from_ruby<operations_research::sat::IntVar>(x);
128
+ std::string type = ((String) x.call("class").call("name")).str();
129
+ if (type == "ORTools::BoolVar") {
130
+ expr = from_ruby<operations_research::sat::BoolVar>(x);
131
+ } else {
132
+ expr = from_ruby<operations_research::sat::IntVar>(x);
133
+ }
126
134
  }
127
135
 
128
136
  return expr;
@@ -141,13 +149,22 @@ class Assignment {
141
149
  int64 Value(const operations_research::IntVar* const var) const {
142
150
  return self->Value(var);
143
151
  }
152
+ int64 Min(const operations_research::IntVar* const var) const {
153
+ return self->Min(var);
154
+ }
155
+ int64 Max(const operations_research::IntVar* const var) const {
156
+ return self->Max(var);
157
+ }
144
158
  };
145
159
 
146
160
  Class rb_cMPVariable;
147
161
  Class rb_cMPConstraint;
148
162
  Class rb_cMPObjective;
149
163
  Class rb_cIntVar;
164
+ Class rb_cIntervalVar;
150
165
  Class rb_cRoutingDimension;
166
+ Class rb_cConstraint;
167
+ Class rb_cSolver2;
151
168
 
152
169
  template<>
153
170
  inline
@@ -177,6 +194,13 @@ Object to_ruby(operations_research::IntVar* const
177
194
  return Rice::Data_Object<operations_research::IntVar>(x, rb_cIntVar, nullptr, nullptr);
178
195
  }
179
196
 
197
+ template<>
198
+ inline
199
+ Object to_ruby<operations_research::IntervalVar*>(operations_research::IntervalVar* const &x)
200
+ {
201
+ return Rice::Data_Object<operations_research::IntervalVar>(x, rb_cIntervalVar, nullptr, nullptr);
202
+ }
203
+
180
204
  template<>
181
205
  inline
182
206
  Object to_ruby<RoutingDimension*>(RoutingDimension* const &x)
@@ -184,6 +208,86 @@ Object to_ruby(RoutingDimension* const &x)
184
208
  return Rice::Data_Object<RoutingDimension>(x, rb_cRoutingDimension, nullptr, nullptr);
185
209
  }
186
210
 
211
+ template<>
212
+ inline
213
+ Object to_ruby<operations_research::Constraint*>(operations_research::Constraint* const &x)
214
+ {
215
+ return Rice::Data_Object<operations_research::Constraint>(x, rb_cConstraint, nullptr, nullptr);
216
+ }
217
+
218
+ template<>
219
+ inline
220
+ Object to_ruby<operations_research::Solver*>(operations_research::Solver* const &x)
221
+ {
222
+ return Rice::Data_Object<operations_research::Solver>(x, rb_cSolver2, nullptr, nullptr);
223
+ }
224
+
225
+ // need a wrapper class since absl::Span doesn't own
226
+ class IntVarSpan {
227
+ std::vector<operations_research::sat::IntVar> vec;
228
+ public:
229
+ IntVarSpan(Object x) {
230
+ Array a = Array(x);
231
+ for (std::size_t i = 0; i < a.size(); ++i) {
232
+ vec.push_back(from_ruby<operations_research::sat::IntVar>(a[i]));
233
+ }
234
+ }
235
+ operator absl::Span<const operations_research::sat::IntVar>() {
236
+ return absl::Span<const operations_research::sat::IntVar>(vec);
237
+ }
238
+ };
239
+
240
+ template<>
241
+ inline
242
+ IntVarSpan from_ruby<IntVarSpan>(Object x)
243
+ {
244
+ return IntVarSpan(x);
245
+ }
246
+
247
+ // need a wrapper class since absl::Span doesn't own
248
+ class IntervalVarSpan {
249
+ std::vector<operations_research::sat::IntervalVar> vec;
250
+ public:
251
+ IntervalVarSpan(Object x) {
252
+ Array a = Array(x);
253
+ for (std::size_t i = 0; i < a.size(); ++i) {
254
+ vec.push_back(from_ruby<operations_research::sat::IntervalVar>(a[i]));
255
+ }
256
+ }
257
+ operator absl::Span<const operations_research::sat::IntervalVar>() {
258
+ return absl::Span<const operations_research::sat::IntervalVar>(vec);
259
+ }
260
+ };
261
+
262
+ template<>
263
+ inline
264
+ IntervalVarSpan from_ruby<IntervalVarSpan>(Object x)
265
+ {
266
+ return IntervalVarSpan(x);
267
+ }
268
+
269
+ // need a wrapper class since absl::Span doesn't own
270
+ class BoolVarSpan {
271
+ std::vector<operations_research::sat::BoolVar> vec;
272
+ public:
273
+ BoolVarSpan(Object x) {
274
+ Array a = Array(x);
275
+ for (std::size_t i = 0; i < a.size(); ++i) {
276
+ vec.push_back(from_ruby<operations_research::sat::BoolVar>(a[i]));
277
+ }
278
+ }
279
+ operator absl::Span<const operations_research::sat::BoolVar>() {
280
+ return absl::Span<const operations_research::sat::BoolVar>(vec);
281
+ }
282
+ };
283
+
284
+ template<>
285
+ inline
286
+ BoolVarSpan from_ruby<BoolVarSpan>(Object x)
287
+ {
288
+ return BoolVarSpan(x);
289
+ }
290
+
187
291
  extern "C"
188
292
  void Init_ext()
189
293
  {
@@ -283,16 +387,26 @@ void Init_ext()
283
387
  .define_method("solution_value", &MPVariable::solution_value)
284
388
  .define_method(
285
389
  "+",
286
- *[](MPVariable& self, MPVariable& other) {
390
+ *[](MPVariable& self, LinearExpr& other) {
287
391
  LinearExpr s(&self);
288
- LinearExpr o(&other);
289
- return s + o;
392
+ return s + other;
393
+ })
394
+ .define_method(
395
+ "-",
396
+ *[](MPVariable& self, LinearExpr& other) {
397
+ LinearExpr s(&self);
398
+ return s - other;
290
399
  })
291
400
  .define_method(
292
401
  "*",
293
402
  *[](MPVariable& self, double other) {
294
403
  LinearExpr s(&self);
295
404
  return s * other;
405
+ })
406
+ .define_method(
407
+ "inspect",
408
+ *[](MPVariable& self) {
409
+ return "#<ORTools::MPVariable @name=\"" + self.name() + "\">";
296
410
  });
297
411
 
298
412
  define_class_under<LinearExpr>(rb_mORTools, "LinearExpr")
@@ -308,6 +422,17 @@ void Init_ext()
308
422
  LinearExpr o(&other);
309
423
  return self + o;
310
424
  })
425
+ .define_method(
426
+ "_gte_double",
427
+ *[](LinearExpr& self, double other) {
428
+ LinearExpr o(other);
429
+ return self >= o;
430
+ })
431
+ .define_method(
432
+ "_gte_linear_expr",
433
+ *[](LinearExpr& self, LinearExpr& other) {
434
+ return self >= other;
435
+ })
311
436
  .define_method(
312
437
  "_lte_double",
313
438
  *[](LinearExpr& self, double other) {
@@ -362,6 +487,11 @@ void Init_ext()
362
487
  .define_method("iterations", &MPSolver::iterations)
363
488
  .define_method("nodes", &MPSolver::nodes)
364
489
  .define_method("objective", &MPSolver::MutableObjective)
490
+ .define_method(
491
+ "maximize",
492
+ *[](MPSolver& self, LinearExpr& expr) {
493
+ return self.MutableObjective()->MaximizeLinearExpr(expr);
494
+ })
365
495
  .define_method(
366
496
  "minimize",
367
497
  *[](MPSolver& self, LinearExpr& expr) {
@@ -401,11 +531,18 @@ void Init_ext()
401
531
  }
402
532
  });
403
533
 
404
- // not to be confused with operations_research::IntVar
405
- define_class_under<operations_research::sat::IntVar>(rb_mORTools, "SatIntVar");
534
+ define_class_under<operations_research::sat::IntVar>(rb_mORTools, "SatIntVar")
535
+ .define_method("name", &operations_research::sat::IntVar::Name);
536
+
537
+ define_class_under<operations_research::sat::IntervalVar>(rb_mORTools, "SatIntervalVar")
538
+ .define_method("name", &operations_research::sat::IntervalVar::Name);
539
+
540
+ define_class_under<operations_research::sat::Constraint>(rb_mORTools, "SatConstraint");
541
+
406
542
  define_class_under<BoolVar>(rb_mORTools, "BoolVar")
407
543
  .define_method("name", &BoolVar::Name)
408
544
  .define_method("index", &BoolVar::index)
545
+ .define_method("not", &BoolVar::Not)
409
546
  .define_method(
410
547
  "inspect",
411
548
  *[](BoolVar& self) {
@@ -426,6 +563,11 @@ void Init_ext()
426
563
  *[](CpModelBuilder& self, std::string name) {
427
564
  return self.NewBoolVar().WithName(name);
428
565
  })
566
+ .define_method(
567
+ "new_interval_var",
568
+ *[](CpModelBuilder& self, operations_research::sat::IntVar start, operations_research::sat::IntVar size, operations_research::sat::IntVar end, std::string name) {
569
+ return self.NewIntervalVar(start, size, end).WithName(name);
570
+ })
429
571
  .define_method(
430
572
  "add_equality",
431
573
  *[](CpModelBuilder& self, operations_research::sat::LinearExpr x, operations_research::sat::LinearExpr y) {
@@ -456,6 +598,27 @@ void Init_ext()
456
598
  *[](CpModelBuilder& self, operations_research::sat::LinearExpr x, operations_research::sat::LinearExpr y) {
457
599
  self.AddLessOrEqual(x, y);
458
600
  })
601
+ .define_method(
602
+ "add_all_different",
603
+ *[](CpModelBuilder& self, IntVarSpan vars) {
604
+ self.AddAllDifferent(vars);
605
+ })
606
+ .define_method(
607
+ "add_max_equality",
608
+ *[](CpModelBuilder& self, operations_research::sat::IntVar target, IntVarSpan vars) {
609
+ self.AddMaxEquality(target, vars);
610
+ })
611
+ .define_method(
612
+ "add_no_overlap",
613
+ *[](CpModelBuilder& self, IntervalVarSpan vars) {
614
+ self.AddNoOverlap(vars);
615
+ })
616
+ .define_method(
617
+ "add_bool_or",
618
+ *[](CpModelBuilder& self, BoolVarSpan literals) {
619
+ self.AddBoolOr(literals);
620
+ })
621
+ .define_method("add_implication", &CpModelBuilder::AddImplication)
459
622
  .define_method(
460
623
  "maximize",
461
624
  *[](CpModelBuilder& self, operations_research::sat::LinearExpr expr) {
@@ -470,13 +633,15 @@ void Init_ext()
470
633
  define_class_under(rb_mORTools, "CpSolver")
471
634
  .define_method(
472
635
  "_solve_with_observer",
473
- *[](Object self, CpModelBuilder& model, Object callback) {
636
+ *[](Object self, CpModelBuilder& model, Object callback, bool all_solutions) {
474
637
  operations_research::sat::Model m;
475
638
 
476
- // set parameters for SearchForAllSolutions
477
- SatParameters parameters;
478
- parameters.set_enumerate_all_solutions(true);
479
- m.Add(NewSatParameters(parameters));
639
+ if (all_solutions) {
640
+ // set parameters for SearchForAllSolutions
641
+ SatParameters parameters;
642
+ parameters.set_enumerate_all_solutions(true);
643
+ m.Add(NewSatParameters(parameters));
644
+ }
480
645
 
481
646
  m.Add(NewFeasibleSolutionObserver(
482
647
  [callback](const CpSolverResponse& r) {
@@ -496,6 +661,11 @@ void Init_ext()
496
661
  "_solution_integer_value",
497
662
  *[](Object self, CpSolverResponse& response, operations_research::sat::IntVar& x) {
498
663
  return SolutionIntegerValue(response, x);
664
+ })
665
+ .define_method(
666
+ "_solution_boolean_value",
667
+ *[](Object self, CpSolverResponse& response, operations_research::sat::BoolVar& x) {
668
+ return SolutionBooleanValue(response, x);
499
669
  });
500
670
 
501
671
  define_class_under<CpSolverResponse>(rb_mORTools, "CpSolverResponse")
@@ -503,7 +673,12 @@ void Init_ext()
503
673
  .define_method("num_conflicts", &CpSolverResponse::num_conflicts)
504
674
  .define_method("num_branches", &CpSolverResponse::num_branches)
505
675
  .define_method("wall_time", &CpSolverResponse::wall_time)
506
- // .define_method("solution_integer_value", &SolutionIntegerValue)
676
+ .define_method(
677
+ "solution_integer_value",
678
+ *[](CpSolverResponse& self, operations_research::sat::IntVar& x) {
679
+ operations_research::sat::LinearExpr expr(x);
680
+ return SolutionIntegerValue(self, expr);
681
+ })
507
682
  .define_method("solution_boolean_value", &operations_research::sat::SolutionBooleanValue)
508
683
  .define_method(
509
684
  "status",
@@ -525,17 +700,72 @@ void Init_ext()
525
700
 
526
701
  define_class_under<RoutingIndexManager>(rb_mORTools, "RoutingIndexManager")
527
702
  .define_constructor(Constructor<RoutingIndexManager, int, int, RoutingNodeIndex>())
528
- .define_method("index_to_node", &RoutingIndexManager::IndexToNode);
703
+ .define_method("index_to_node", &RoutingIndexManager::IndexToNode)
704
+ .define_method("node_to_index", &RoutingIndexManager::NodeToIndex);
529
705
 
530
706
  define_class_under<Assignment>(rb_mORTools, "Assignment")
531
707
  .define_method("objective_value", &Assignment::ObjectiveValue)
532
- .define_method("value", &Assignment::Value);
708
+ .define_method("value", &Assignment::Value)
709
+ .define_method("min", &Assignment::Min)
710
+ .define_method("max", &Assignment::Max);
533
711
 
534
712
  // not to be confused with operations_research::sat::IntVar
535
- rb_cIntVar = define_class_under<operations_research::IntVar>(rb_mORTools, "IntVar");
713
+ rb_cIntVar = define_class_under<operations_research::IntVar>(rb_mORTools, "IntVar")
714
+ .define_method(
715
+ "set_range",
716
+ *[](operations_research::IntVar& self, int64 new_min, int64 new_max) {
717
+ self.SetRange(new_min, new_max);
718
+ });
719
+
720
+ rb_cIntervalVar = define_class_under<operations_research::IntervalVar>(rb_mORTools, "IntervalVar");
536
721
 
537
722
  rb_cRoutingDimension = define_class_under<RoutingDimension>(rb_mORTools, "RoutingDimension")
538
- .define_method("global_span_cost_coefficient=", &RoutingDimension::SetGlobalSpanCostCoefficient);
723
+ .define_method("global_span_cost_coefficient=", &RoutingDimension::SetGlobalSpanCostCoefficient)
724
+ .define_method("cumul_var", &RoutingDimension::CumulVar);
725
+
726
+ rb_cConstraint = define_class_under<operations_research::Constraint>(rb_mORTools, "Constraint");
727
+
728
+ rb_cSolver2 = define_class_under<operations_research::Solver>(rb_mORTools, "Solver2")
729
+ .define_method(
730
+ "add",
731
+ *[](operations_research::Solver& self, Object o) {
732
+ operations_research::Constraint* constraint;
733
+ if (o.respond_to("left")) {
734
+ operations_research::IntExpr* left(from_ruby<operations_research::IntVar*>(o.call("left")));
735
+ operations_research::IntExpr* right(from_ruby<operations_research::IntVar*>(o.call("right")));
736
+ auto op = o.call("operator").to_s().str();
737
+ if (op == "==") {
738
+ constraint = self.MakeEquality(left, right);
739
+ } else if (op == "<=") {
740
+ constraint = self.MakeLessOrEqual(left, right);
741
+ } else {
742
+ throw std::runtime_error("Unknown operator");
743
+ }
744
+ } else {
745
+ constraint = from_ruby<operations_research::Constraint*>(o);
746
+ }
747
+ self.AddConstraint(constraint);
748
+ })
749
+ .define_method(
750
+ "fixed_duration_interval_var",
751
+ *[](operations_research::Solver& self, operations_research::IntVar* const start_variable, int64 duration, const std::string& name) {
752
+ return self.MakeFixedDurationIntervalVar(start_variable, duration, name);
753
+ })
754
+ .define_method(
755
+ "cumulative",
756
+ *[](operations_research::Solver& self, Array rb_intervals, Array rb_demands, int64 capacity, const std::string& name) {
757
+ std::vector<operations_research::IntervalVar*> intervals;
758
+ for (std::size_t i = 0; i < rb_intervals.size(); ++i) {
759
+ intervals.push_back(from_ruby<operations_research::IntervalVar*>(rb_intervals[i]));
760
+ }
761
+
762
+ std::vector<int64> demands;
763
+ for (std::size_t i = 0; i < rb_demands.size(); ++i) {
764
+ demands.push_back(from_ruby<int64>(rb_demands[i]));
765
+ }
766
+
767
+ return self.MakeCumulative(intervals, demands, capacity, name);
768
+ });
539
769
 
540
770
  define_class_under<RoutingModel>(rb_mORTools, "RoutingModel")
541
771
  .define_constructor(Constructor<RoutingModel, RoutingIndexManager>())
@@ -548,13 +778,44 @@ void Init_ext()
548
778
  }
549
779
  );
550
780
  })
781
+ .define_method(
782
+ "register_unary_transit_callback",
783
+ *[](RoutingModel& self, Object callback) {
784
+ return self.RegisterUnaryTransitCallback(
785
+ [callback](int64 from_index) -> int64 {
786
+ return from_ruby<int64>(callback.call("call", from_index));
787
+ }
788
+ );
789
+ })
551
790
  .define_method("depot", &RoutingModel::GetDepot)
791
+ .define_method("size", &RoutingModel::Size)
792
+ .define_method("vehicle_var", &RoutingModel::VehicleVar)
552
793
  .define_method("set_arc_cost_evaluator_of_all_vehicles", &RoutingModel::SetArcCostEvaluatorOfAllVehicles)
553
794
  .define_method("set_arc_cost_evaluator_of_vehicle", &RoutingModel::SetArcCostEvaluatorOfVehicle)
554
795
  .define_method("set_fixed_cost_of_all_vehicles", &RoutingModel::SetFixedCostOfAllVehicles)
555
796
  .define_method("set_fixed_cost_of_vehicle", &RoutingModel::SetFixedCostOfVehicle)
556
797
  .define_method("fixed_cost_of_vehicle", &RoutingModel::GetFixedCostOfVehicle)
557
798
  .define_method("add_dimension", &RoutingModel::AddDimension)
799
+ .define_method(
800
+ "add_dimension_with_vehicle_capacity",
801
+ *[](RoutingModel& self, int evaluator_index, int64 slack_max, Array vc, bool fix_start_cumul_to_zero, const std::string& name) {
802
+ std::vector<int64> vehicle_capacities;
803
+ for (std::size_t i = 0; i < vc.size(); ++i) {
804
+ vehicle_capacities.push_back(from_ruby<int64>(vc[i]));
805
+ }
806
+ self.AddDimensionWithVehicleCapacity(evaluator_index, slack_max, vehicle_capacities, fix_start_cumul_to_zero, name);
807
+ })
808
+ .define_method(
809
+ "add_disjunction",
810
+ *[](RoutingModel& self, Array rb_indices, int64 penalty) {
811
+ std::vector<int64> indices;
812
+ for (std::size_t i = 0; i < rb_indices.size(); ++i) {
813
+ indices.push_back(from_ruby<int64>(rb_indices[i]));
814
+ }
815
+ self.AddDisjunction(indices, penalty);
816
+ })
817
+ .define_method("add_pickup_and_delivery", &RoutingModel::AddPickupAndDelivery)
818
+ .define_method("solver", &RoutingModel::solver)
558
819
  .define_method("start", &RoutingModel::Start)
559
820
  .define_method("end", &RoutingModel::End)
560
821
  .define_method("start?", &RoutingModel::IsStart)
@@ -565,6 +826,7 @@ void Init_ext()
565
826
  .define_method("next_var", &RoutingModel::NextVar)
566
827
  .define_method("arc_cost_for_vehicle", &RoutingModel::GetArcCostForVehicle)
567
828
  .define_method("mutable_dimension", &RoutingModel::GetMutableDimension)
829
+ .define_method("add_variable_minimized_by_finalizer", &RoutingModel::AddVariableMinimizedByFinalizer)
568
830
  .define_method(
569
831
  "solve_with_parameters",
570
832
  *[](RoutingModel& self, const RoutingSearchParameters& search_parameters) {
@@ -1,6 +1,6 @@
1
1
  require "mkmf-rice"
2
2
 
3
- abort "Missing stdc++" unless have_library("stdc++")
3
+ raise "Missing stdc++" unless have_library("stdc++")
4
4
 
5
5
  $CXXFLAGS << " -std=c++11 -DUSE_CBC"
6
6
 
@@ -8,73 +8,31 @@ $CXXFLAGS << " -std=c++11 -DUSE_CBC"
8
8
  $CXXFLAGS << " -Wno-sign-compare -Wno-shorten-64-to-32 -Wno-ignored-qualifiers"
9
9
 
10
10
  inc, lib = dir_config("or-tools")
11
-
12
- inc ||= "/usr/local/include"
13
- lib ||= "/usr/local/lib"
11
+ if inc || lib
12
+ inc ||= "/usr/local/include"
13
+ lib ||= "/usr/local/lib"
14
+ rpath = lib
15
+ else
16
+ # download
17
+ require_relative "vendor"
18
+
19
+ inc = "#{$vendor_path}/include"
20
+ lib = "#{$vendor_path}/lib"
21
+
22
+ # make rpath relative
23
+ # use double dollar sign and single quotes to escape properly
24
+ rpath_prefix = RbConfig::CONFIG["host_os"] =~ /darwin/ ? "@loader_path" : "$$ORIGIN"
25
+ rpath = "'#{rpath_prefix}/../../tmp/or-tools/lib'"
26
+ end
14
27
 
15
28
  $INCFLAGS << " -I#{inc}"
16
29
 
17
- $LDFLAGS << " -Wl,-rpath,#{lib}"
30
+ $LDFLAGS << " -Wl,-rpath,#{rpath}"
18
31
  $LDFLAGS << " -L#{lib}"
19
- $LDFLAGS << " -lortools"
32
+ raise "OR-Tools not found" unless have_library("ortools")
20
33
 
21
- %w(
22
- absl_city
23
- absl_time_zone
24
- absl_spinlock_wait
25
- absl_log_severity
26
- absl_failure_signal_handler
27
- absl_bad_optional_access
28
- absl_hash
29
- absl_raw_logging_internal
30
- absl_random_internal_pool_urbg
31
- absl_base
32
- absl_bad_any_cast_impl
33
- absl_periodic_sampler
34
- absl_random_distributions
35
- absl_flags_usage_internal
36
- absl_random_seed_sequences
37
- absl_throw_delegate
38
- absl_flags_handle
39
- absl_dynamic_annotations
40
- absl_debugging_internal
41
- absl_strings
42
- absl_flags
43
- absl_malloc_internal
44
- absl_str_format_internal
45
- absl_flags_usage
46
- absl_strings_internal
47
- absl_flags_program_name
48
- absl_flags_registry
49
- absl_int128
50
- absl_scoped_set_env
51
- absl_raw_hash_set
52
- absl_random_internal_seed_material
53
- absl_symbolize
54
- absl_random_internal_randen_slow
55
- absl_graphcycles_internal
56
- absl_exponential_biased
57
- absl_random_internal_randen_hwaes_impl
58
- absl_bad_variant_access
59
- absl_stacktrace
60
- absl_random_internal_randen_hwaes
61
- absl_flags_parse
62
- absl_random_internal_randen
63
- absl_random_internal_distribution_test_util
64
- absl_time
65
- absl_flags_config
66
- absl_synchronization
67
- absl_hashtablez_sampler
68
- absl_demangle_internal
69
- absl_leak_check
70
- absl_flags_marshalling
71
- absl_leak_check_disable
72
- absl_examine_stack
73
- absl_flags_internal
74
- absl_random_seed_gen_exception
75
- absl_civil_time
76
- ).each do |lib|
77
- $LDFLAGS << " -l#{lib}"
34
+ Dir["#{lib}/libabsl_*.a"].each do |lib|
35
+ $LDFLAGS << " #{lib}"
78
36
  end
79
37
 
80
38
  create_makefile("or_tools/ext")