this repo has no description
1#
2# Main authors:
3# Victor Zverovich <victor.zverovich@gmail.com>
4#
5# Copyright:
6# Victor Zverovich, 2013
7#
8# This file is part of Gecode, the generic constraint
9# development environment:
10# http://www.gecode.org
11#
12# Permission is hereby granted, free of charge, to any person obtaining
13# a copy of this software and associated documentation files (the
14# "Software"), to deal in the Software without restriction, including
15# without limitation the rights to use, copy, modify, merge, publish,
16# distribute, sublicense, and/or sell copies of the Software, and to
17# permit persons to whom the Software is furnished to do so, subject to
18# the following conditions:
19#
20# The above copyright notice and this permission notice shall be
21# included in all copies or substantial portions of the Software.
22#
23# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
24# EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
25# MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
26# NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
27# LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
28# OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
29# WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
30#
31
32#
33# CMake build script for Gecode.
34#
35
36cmake_minimum_required(VERSION 2.8.8)
37
38project(GECODE)
39
40set(CMAKE_RUNTIME_OUTPUT_DIRECTORY ${PROJECT_BINARY_DIR}/bin)
41
42include(CheckCXXCompilerFlag)
43if (GECODE_DISABLE_WARNINGS)
44 if (MSVC)
45 add_definitions(/wd4244 /wd4267 /wd4345 /wd4355 /wd4800 /wd4068)
46 else ()
47 foreach (flag -Wextra -Wall -pedantic)
48 string(REPLACE ${flag} "" CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS}")
49 endforeach ()
50 if (CMAKE_COMPILER_IS_GNUCXX)
51 add_definitions(-Wno-overloaded-virtual -Wno-unknown-pragmas)
52 elseif (CMAKE_CXX_COMPILER_ID STREQUAL "Clang")
53 add_definitions(-Wno-constant-logical-operand -Wno-switch -Wno-unknown-pragmas)
54 endif ()
55 endif ()
56endif ()
57
58if ( (CMAKE_VERSION VERSION_GREATER 3.1.0) OR (CMAKE_VERSION VERSION_EQUAL 3.1.0) )
59 set (CMAKE_CXX_STANDARD 11)
60endif()
61if(CMAKE_VERSION VERSION_GREATER_EQUAL 3.17.0)
62 cmake_policy(SET CMP0100 NEW)
63endif()
64check_cxx_compiler_flag(-std=c++11 HAS_STDCPP11)
65if (HAS_STDCPP11)
66 set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -std=c++11")
67else()
68 check_cxx_compiler_flag(-std=c++0x HAS_STDCPP0X)
69 if (HAS_STDCPP0X)
70 set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -std=c++0x")
71 else()
72 message("Warning: Initial check for C++11 unsuccessful. This is fine if HAS_CPP11 test below succeeds.")
73 endif()
74endif()
75
76# The following part of config.h is hard to derive from configure.ac.
77file(READ gecode/support/config.hpp.in CONFIG)
78string(REGEX REPLACE "^/\\*([^*]|\\*[^/])*\\*/" "" CONFIG ${CONFIG})
79string(REGEX MATCHALL "[^\n]*\n" CONFIG
80"${CONFIG}
81/* Define to 1 if you have the `getpagesize' function. */
82#undef HAVE_GETPAGESIZE
83
84/* Define to 1 if you have the <inttypes.h> header file. */
85#undef HAVE_INTTYPES_H
86
87/* Define to 1 if you have the <memory.h> header file. */
88#undef HAVE_MEMORY_H
89
90/* Define to 1 if you have a working `mmap' system call. */
91#undef HAVE_MMAP
92
93/* Define to 1 if you have the <stdint.h> header file. */
94#undef HAVE_STDINT_H
95
96/* Define to 1 if you have the <stdlib.h> header file. */
97#undef HAVE_STDLIB_H
98
99/* Define to 1 if you have the <strings.h> header file. */
100#undef HAVE_STRINGS_H
101
102/* Define to 1 if you have the <string.h> header file. */
103#undef HAVE_STRING_H
104
105/* Define to 1 if you have the <sys/param.h> header file. */
106#undef HAVE_SYS_PARAM_H
107
108/* Define to 1 if you have the <sys/stat.h> header file. */
109#undef HAVE_SYS_STAT_H
110
111/* Define to 1 if you have the <sys/types.h> header file. */
112#undef HAVE_SYS_TYPES_H
113
114/* Define to 1 if you have the <unistd.h> header file. */
115#undef HAVE_UNISTD_H
116
117/* Define to the address where bug reports for this package should be sent. */
118#undef PACKAGE_BUGREPORT
119
120/* Define to the full name of this package. */
121#undef PACKAGE_NAME
122
123/* Define to the full name and version of this package. */
124#undef PACKAGE_STRING
125
126/* Define to the one symbol short name of this package. */
127#undef PACKAGE_TARNAME
128
129/* Define to the home page for this package. */
130#undef PACKAGE_URL
131
132/* Define to the version of this package. */
133#undef PACKAGE_VERSION
134
135/* The size of `int', as computed by sizeof. */
136#undef SIZEOF_INT
137
138/* Define to 1 if you have the ANSI C header files. */
139#undef STDC_HEADERS
140")
141
142# Get version numbers and parts of config.h from configure.ac.
143file(READ configure.ac LINES)
144# Replace semicolons with "<semi>" to avoid CMake messing with them.
145string(REPLACE ";" "<semi>" LINES "${LINES}")
146# Split into lines keeping newlines to avoid foreach skipping empty ones.
147string(REGEX MATCHALL "[^\n]*\n" LINES "${LINES}")
148set(ah_command FALSE)
149foreach (line "${EXTRA_CONFIG}" ${LINES})
150 string(REPLACE ";" "" line "${line}")
151 if (ah_command)
152 # Do nothing.
153 elseif (line MATCHES "AC_INIT\\(([^,]*), *([^,]*), *([^)]*)\\)")
154 set(PACKAGE ${CMAKE_MATCH_1})
155 set(VERSION ${CMAKE_MATCH_2})
156 set(PACKAGE_BUGREPORT ${CMAKE_MATCH_3})
157 message(STATUS "Got VERSION=${VERSION} from configure.ac")
158 elseif (line MATCHES "ac_gecode_flatzincversion=(.*)\n")
159 set(GECODE_FLATZINC_VERSION "${CMAKE_MATCH_1}")
160 elseif (line MATCHES "AH_BOTTOM\\(\\[(.*)")
161 set(ah_command bottom)
162 set(line "${CMAKE_MATCH_1}")
163 elseif (line MATCHES "AH_VERBATIM[^,]+,(.*)")
164 set(ah_command verbatim)
165 set(line "${CMAKE_MATCH_1}")
166 endif ()
167 if (ah_command)
168 set(saved_ah_command ${ah_command})
169 if (line MATCHES "^\\[(.*)")
170 set(line "${CMAKE_MATCH_1}")
171 endif ()
172 if (line MATCHES "\\]\\)")
173 set(ah_command FALSE)
174 string(REPLACE "])" "" line "${line}")
175 endif ()
176 # For some reason CMake may bundle several lines together. Split them too.
177 string(REGEX MATCHALL "[^\n]*\n" sublines "${line}")
178 set(config_add "")
179 foreach (subline ${sublines})
180 set(config_add ${config_add} "${subline}")
181 endforeach ()
182 if (saved_ah_command STREQUAL "verbatim")
183 set(CONFIG ${config_add} ${CONFIG})
184 else ()
185 set(CONFIG ${CONFIG} "\n" ${config_add})
186 endif ()
187 endif ()
188endforeach ()
189set(PACKAGE_NAME ${PACKAGE})
190string(TOLOWER ${PACKAGE} PACKAGE_TARNAME)
191set(PACKAGE_URL "")
192set(PACKAGE_VERSION ${VERSION})
193set(${PACKAGE}_VERSION ${VERSION})
194string(REPLACE "." "-" GECODE_LIBRARY_VERSION "${VERSION}")
195set(PACKAGE_STRING "${PACKAGE} ${VERSION}")
196if (VERSION MATCHES "(.*)\\.(.*)\\.(.*)")
197 math(EXPR GECODE_VERSION_NUMBER
198 "${CMAKE_MATCH_1} * 100000 + ${CMAKE_MATCH_2} * 100 + ${CMAKE_MATCH_3}")
199endif ()
200
201set(GECODE_DLL_USERPREFIX "")
202set(GECODE_DLL_USERSUFFIX "")
203set(GECODE_HAS_INT_VARS "/**/")
204set(GECODE_HAS_SET_VARS "/**/")
205set(GECODE_HAS_FLOAT_VARS "/**/")
206set(GECODE_STATIC_LIBS 1)
207set(GECODE_ALLOCATOR "/**/")
208
209check_cxx_compiler_flag(-fvisibility=hidden HAVE_VISIBILITY_HIDDEN_FLAG)
210if (HAVE_VISIBILITY_HIDDEN_FLAG)
211 set(GECODE_GCC_HAS_CLASS_VISIBILITY "/**/")
212endif ()
213
214if (WIN32)
215 set(GECODE_THREADS_WINDOWS 1)
216else ()
217 set(GECODE_THREADS_PTHREADS 1)
218endif ()
219
220option(ENABLE_GIST "Enable gist" OFF)
221if (ENABLE_GIST)
222 set(GECODE_USE_QT TRUE)
223else()
224 set(GECODE_USE_QT FALSE)
225endif()
226
227# Don't use Qt if GECODE_USE_QT is set to FALSE.
228if (NOT DEFINED GECODE_USE_QT OR GECODE_USE_QT)
229 find_package(Qt5 QUIET COMPONENTS Core Gui Widgets PrintSupport)
230 if (Qt5_FOUND)
231 set(GECODE_HAS_QT "/**/")
232 set(GECODE_HAS_GIST "/**/")
233 set(EXTRA_LIBS gist)
234 set(CMAKE_AUTOMOC TRUE)
235 else()
236 find_package(Qt4)
237 if (QT4_FOUND)
238 set(GECODE_HAS_QT "/**/")
239 set(GECODE_HAS_GIST "/**/")
240 set(EXTRA_LIBS gist)
241 set(CMAKE_AUTOMOC TRUE)
242 include(${QT_USE_FILE})
243 endif()
244 endif()
245endif ()
246
247include(CheckSymbolExists)
248check_symbol_exists(getpagesize unistd.h HAVE_GETPAGESIZE)
249check_symbol_exists(mmap sys/mman.h HAVE_MMAP)
250
251# Checks for header files.
252include(CheckIncludeFiles)
253foreach (header inttypes.h memory.h stdint.h stdlib.h strings.h string.h
254 sys/param.h sys/stat.h sys/time.h sys/types.h unistd.h)
255 string(TOUPPER HAVE_${header} var)
256 string(REGEX REPLACE "\\.|/" "_" var ${var})
257 check_include_files(${header} ${var})
258endforeach ()
259check_include_files(stdio.h STDC_HEADERS)
260if (HAVE_SYS_TIME_H)
261 set(GECODE_USE_GETTIMEOFDAY 1)
262else ()
263 set(GECODE_USE_CLOCK 1)
264endif ()
265if (HAVE_UNISTD_H)
266 set(GECODE_HAS_UNISTD_H 1)
267endif ()
268
269include(CheckCXXSourceCompiles)
270check_cxx_source_compiles("
271 #include <ext/hash_map>
272 int main() {}" HAVE_EXT_HASH_MAP)
273if (HAVE_EXT_HASH_MAP)
274 set(GECODE_HAS_GNU_HASH_MAP "/**/")
275endif ()
276
277check_cxx_source_compiles("
278 #include <unordered_map>
279 int main() {}" HAVE_UNORDERED_MAP)
280if (HAVE_UNORDERED_MAP)
281 set(GECODE_HAS_UNORDERED_MAP "/**/")
282endif ()
283
284include(CheckTypeSize)
285check_type_size(int SIZEOF_INT)
286
287# Check for inline.
288include(CheckCSourceCompiles)
289check_c_source_compiles("
290 inline __attribute__ ((__always_inline__)) void foo(void) {}
291 int main() {}" HAVE_ALWAYS_INLINE)
292check_c_source_compiles("
293 __forceinline void foo(void) {}
294 int main() {}" HAVE_FORCE_INLINE)
295set(forceinline inline)
296if (HAVE_ALWAYS_INLINE)
297 set(forceinline "inline __attribute__ ((__always_inline__))")
298endif ()
299if (HAVE_FORCE_INLINE)
300 set(forceinline "__forceinline")
301endif ()
302
303# Check for bit index
304check_c_source_compiles("
305 int main() { return __builtin_ffsl(0); }" HAVE_BUILTIN_FFSL)
306if (HAVE_BUILTIN_FFSL)
307 set(GECODE_HAS_BUILTIN_FFSL "/**/")
308endif ()
309
310# Process config.hpp using autoconf rules.
311list(LENGTH CONFIG length)
312math(EXPR length "${length} - 1")
313foreach (i RANGE ${length})
314 list(GET CONFIG ${i} line)
315 if (line MATCHES "^#( *)undef (.*)\n")
316 set(space "${CMAKE_MATCH_1}")
317 set(var ${CMAKE_MATCH_2})
318 if (NOT DEFINED ${var} OR (var MATCHES "HAVE_.*" AND NOT ${var}))
319 set(line "/* #${space}undef ${var} */\n")
320 else ()
321 if ("${${var}}" STREQUAL "/**/" OR "${var}" STREQUAL "GECODE_VERSION_NUMBER" OR
322 "${var}" STREQUAL "forceinline" OR var MATCHES "SIZEOF_.*")
323 set(value ${${var}})
324 elseif (NOT (var MATCHES ^HAVE OR ${var} EQUAL 0 OR ${var} EQUAL 1))
325 set(value \"${${var}}\")
326 elseif (${var})
327 set(value 1)
328 else ()
329 set(value 0)
330 endif ()
331 set(line "#${space}define ${var} ${value}\n")
332 endif ()
333 endif ()
334 string(REPLACE "<semi>" ";" line "${line}")
335 set(CONFIG_OUT "${CONFIG_OUT}${line}")
336endforeach ()
337file(WRITE ${GECODE_BINARY_DIR}/gecode/support/config.hpp
338"/* gecode/support/config.hpp. Generated from config.hpp.in by configure. */
339/* gecode/support/config.hpp.in. Generated from configure.ac by autoheader. */
340
341/* Disable autolink because all the dependencies are handled by CMake. */
342#define GECODE_BUILD_SUPPORT
343#define GECODE_BUILD_KERNEL
344#define GECODE_BUILD_SEARCH
345#define GECODE_BUILD_INT
346#define GECODE_BUILD_SET
347#define GECODE_BUILD_FLOAT
348#define GECODE_BUILD_MINIMODEL
349#define GECODE_BUILD_FLATZINC
350#define GECODE_BUILD_DRIVER
351#define GECODE_BUILD_GIST
352
353${CONFIG_OUT}")
354
355# Expands a value substituting variables and appends the result to ${var}.
356function (expand var value)
357 if (value MATCHES "\\$\\(([^:]+)(.*)\\)")
358 # Perform substitution.
359 set(pattern ${CMAKE_MATCH_2})
360 set(items ${${CMAKE_MATCH_1}})
361 if (pattern MATCHES ":%=([^%]*)%([^%]*)")
362 set(values )
363 foreach (item ${items})
364 set(values ${values} ${CMAKE_MATCH_1}${item}${CMAKE_MATCH_2})
365 endforeach ()
366 else ()
367 set(values ${items})
368 endif ()
369 else ()
370 set(values ${value})
371 endif ()
372 set(${var} ${${var}} ${values} PARENT_SCOPE)
373endfunction ()
374
375# Parse Makefile.in extracting variables.
376file(READ Makefile.in text)
377string(REPLACE "\\\n" "" text "${text}")
378string(REGEX REPLACE "#[^\n]*\n" "" text "${text}")
379string(REGEX MATCHALL "[^\n]+" lines "${text}")
380foreach (line ${lines})
381 if (line MATCHES "([^ \t]+)[ \t]*=[ \t]*(.*)")
382 set(var ${CMAKE_MATCH_1})
383 set(${var} )
384 string(REGEX MATCHALL "[^ \t]+" items "${CMAKE_MATCH_2}")
385 foreach (item ${items})
386 expand(${var} ${item})
387 endforeach ()
388 endif ()
389endforeach ()
390
391foreach (lib support kernel search int set float
392 minimodel driver flatzinc ${EXTRA_LIBS})
393 if (lib STREQUAL "minimodel")
394 set(libupper MM)
395 else ()
396 string(TOUPPER ${lib} libupper)
397 endif ()
398 if (${libupper}SRC)
399 set(sources )
400 foreach (src ${${libupper}SRC} ${${libupper}_GENSRC})
401 if ((src STREQUAL "gecode/support/thread/pthreads.cpp" AND MSVC) OR
402 src STREQUAL "gecode/float/rounding.cpp")
403 # ignore empty source files to prevent linker warnings
404 else ()
405 set(sources ${sources} ${src})
406 endif ()
407 endforeach ()
408 add_library(gecode${lib} ${sources} ${${libupper}HDR})
409 target_include_directories(gecode${lib}
410 PUBLIC ${CMAKE_CURRENT_SOURCE_DIR} ${CMAKE_CURRENT_BINARY_DIR})
411 list(APPEND GECODE_INSTALL_TARGETS gecode${lib})
412 endif ()
413endforeach ()
414
415option(ENABLE_CPPROFILER "Enable cpprofiler tracer mode" ON)
416if(ENABLE_CPPROFILER)
417 add_definitions(-DGECODE_HAS_CPPROFILER)
418endif()
419
420find_package(Threads)
421target_link_libraries(gecodesupport ${CMAKE_THREAD_LIBS_INIT})
422target_link_libraries(gecodekernel gecodesupport)
423target_link_libraries(gecodesearch gecodekernel)
424target_link_libraries(gecodeint gecodekernel)
425target_link_libraries(gecodeset gecodeint)
426target_link_libraries(gecodefloat gecodeint)
427target_link_libraries(gecodeminimodel gecodeint gecodeset gecodesearch)
428target_link_libraries(gecodedriver gecodeint)
429target_link_libraries(gecodeflatzinc gecodeminimodel gecodedriver)
430
431if (GECODE_HAS_QT)
432 if (Qt5_FOUND)
433 qt5_use_modules(gecodegist Widgets Gui PrintSupport)
434 qt5_use_modules(gecodeflatzinc Core)
435 target_link_libraries(gecodeflatzinc gecodegist)
436 else()
437 target_link_libraries(gecodegist ${QT_LIBRARIES})
438 target_link_libraries(gecodeflatzinc gecodegist ${QT_LIBRARIES})
439 endif()
440endif ()
441
442if (FLOATSRC)
443 target_link_libraries(gecodefloat gecodekernel)
444 target_link_libraries(gecodeminimodel gecodefloat)
445endif ()
446
447add_executable(gecode-test EXCLUDE_FROM_ALL ${TESTSRC} ${TESTHDR})
448target_link_libraries(gecode-test gecodeflatzinc gecodeminimodel)
449
450add_executable(fzn-gecode ${FLATZINCEXESRC})
451target_link_libraries(fzn-gecode gecodeflatzinc gecodeminimodel gecodedriver)
452list(APPEND GECODE_INSTALL_TARGETS fzn-gecode)
453
454set(prefix ${CMAKE_INSTALL_PREFIX})
455set(datarootdir \${prefix}/share)
456set(datadir \${datarootdir})
457if(WIN32)
458 configure_file(
459 ${PROJECT_SOURCE_DIR}/tools/flatzinc/mzn-gecode.bat.in
460 ${PROJECT_BINARY_DIR}/tools/flatzinc/mzn-gecode.bat
461 @ONLY
462 )
463 set(MZN_SCRIPT ${PROJECT_BINARY_DIR}/tools/flatzinc/mzn-gecode.bat)
464else()
465 configure_file(
466 ${PROJECT_SOURCE_DIR}/tools/flatzinc/mzn-gecode.in
467 ${PROJECT_BINARY_DIR}/tools/flatzinc/mzn-gecode
468 @ONLY
469 )
470 set(MZN_SCRIPT ${PROJECT_BINARY_DIR}/tools/flatzinc/mzn-gecode)
471endif()
472configure_file(
473 ${PROJECT_SOURCE_DIR}/tools/flatzinc/gecode.msc.in
474 ${PROJECT_BINARY_DIR}/tools/flatzinc/gecode.msc
475 @ONLY
476)
477
478set_property(GLOBAL PROPERTY USE_FOLDERS ON)
479
480option(BUILD_EXAMPLES "Build examples." OFF)
481if (${BUILD_EXAMPLES})
482 add_subdirectory(examples)
483endif()
484
485enable_testing()
486add_test(test gecode-test
487 -iter 2 -test Branch::Int::Dense::3
488 -test Int::Linear::Int::Int::Eq::Bnd::12::4
489 -test Int::Distinct::Random
490 -test Int::Arithmetic::Mult::XYZ::Bnd::C
491 -test Int::Arithmetic::Mult::XYZ::Dom::A
492 -test Search::BAB::Sol::BalGr::Binary::Binary::Binary::1::1)
493
494## Installation Target
495# Install libraries and executables
496install(
497 TARGETS ${GECODE_INSTALL_TARGETS}
498 RUNTIME DESTINATION bin
499 LIBRARY DESTINATION lib
500 ARCHIVE DESTINATION lib
501)
502install(
503 FILES ${MZN_SCRIPT}
504 DESTINATION bin
505)
506# Install include directory
507install(
508 DIRECTORY gecode
509 DESTINATION include
510 FILES_MATCHING
511 PATTERN "**.hh"
512 PATTERN "**.hpp"
513 PATTERN "LICENSE_1_0.txt"
514 PATTERN "mznlib" EXCLUDE
515 PATTERN "exampleplugin" EXCLUDE
516 PATTERN "standalone-example" EXCLUDE
517 PATTERN "abi*" EXCLUDE
518)
519install(
520 FILES ${PROJECT_BINARY_DIR}/gecode/support/config.hpp
521 DESTINATION include/gecode/support/
522)
523# Install MiniZinc library
524install(
525 DIRECTORY gecode/flatzinc/mznlib
526 DESTINATION share/minizinc/gecode
527)
528install(
529 FILES ${PROJECT_BINARY_DIR}/tools/flatzinc/gecode.msc
530 DESTINATION share/minizinc/solvers
531)