forked from vigente/gerardus
-
Notifications
You must be signed in to change notification settings - Fork 0
/
CMakeLists.txt
869 lines (735 loc) · 35.2 KB
/
CMakeLists.txt
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
689
690
691
692
693
694
695
696
697
698
699
700
701
702
703
704
705
706
707
708
709
710
711
712
713
714
715
716
717
718
719
720
721
722
723
724
725
726
727
728
729
730
731
732
733
734
735
736
737
738
739
740
741
742
743
744
745
746
747
748
749
750
751
752
753
754
755
756
757
758
759
760
761
762
763
764
765
766
767
768
769
770
771
772
773
774
775
776
777
778
779
780
781
782
783
784
785
786
787
788
789
790
791
792
793
794
795
796
797
798
799
800
801
802
803
804
805
806
807
808
809
810
811
812
813
814
815
816
817
818
819
820
821
822
823
824
825
826
827
828
829
830
831
832
833
834
835
836
837
838
839
840
841
842
843
844
845
846
847
848
849
850
851
852
853
854
855
856
857
858
859
860
861
862
863
864
865
866
867
868
869
# Author: Ramon Casero <[email protected]>
# Copyright © 2011-2017 University of Oxford
# Version: 0.9.7
#
# University of Oxford means the Chancellor, Masters and Scholars of
# the University of Oxford, having an administrative office at
# Wellington Square, Oxford OX1 2JD, UK.
#
# This file is part of Gerardus.
#
# This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation, either version 3 of the License, or
# (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details. The offer of this
# program under the terms of the License is subject to the License
# being interpreted in accordance with English Law and subject to any
# action against the University of Oxford being under the jurisdiction
# of the English Courts.
#
# You should have received a copy of the GNU General Public License
# along with this program. If not, see
# <http://www.gnu.org/licenses/>.
# You need to run the following cmake command, with the appropriate
# paths, if you want to generate the project files that allow to
# develop this project from the Eclipse IDE
#
# cmake -DITK_DIR=/usr/local/lib/InsightToolkit -G"Eclipse CDT4 - Unix Makefiles" -DCMAKE_BUILD_TYPE=Release ./src
#############################################################################################
## Preliminary configuration, prior to defining the Gerardus project
#############################################################################################
CMAKE_MINIMUM_REQUIRED(VERSION 2.8)
# for Visual Studio or other multi-configuration systems, make
# available only the Debug and Release configurations. This needs to
# go before PROJECT() or it will be ignored
SET(CMAKE_CONFIGURATION_TYPES Release Debug)
SET(CMAKE_CONFIGURATION_TYPES "${CMAKE_CONFIGURATION_TYPES}" CACHE STRING
"Reset the configurations to Debug/Release only"
FORCE)
# for single configuration systems (Unix-like), by default, choose the
# Release configuration
IF(NOT CMAKE_BUILD_TYPE)
SET(CMAKE_BUILD_TYPE Release CACHE STRING
"Choose the type of build, options are: Debug Release"
FORCE)
ENDIF(NOT CMAKE_BUILD_TYPE)
# display type of build (e.g. Release)
message(STATUS "Build type: ${CMAKE_BUILD_TYPE}")
# make directory with FindMatlab.cmake module visible to cmake. This
# makes FindMatlab.cmake available to be used in the next line to find
# and configure Matlab
set(CMAKE_MODULE_PATH
${CMAKE_MODULE_PATH};${CMAKE_CURRENT_SOURCE_DIR}/matlab)
#############################################################################################
## Matlab configuration
#############################################################################################
# hack to avoid error messages from CMake in Windows. The problem is that we must run
# project() after we have set up the compiler version, to avoid an infinite loop in cmake.
# And we can only set up the compiler version once we know Matlab's version. Additionally,
# FindMatlab.cmake requires some variables to be set (CMAKE_FIND_LIBRARY_PREFIXES,
# CMAKE_FIND_LIBRARY_SUFFIXES), which only happens after project(). Thus, we have a Catch22.
# This hack is simply to set the offending variables to the values they would have in Windows
if(WIN32)
set(CMAKE_FIND_LIBRARY_PREFIXES "")
set(CMAKE_FIND_LIBRARY_SUFFIXES ".lib")
endif(WIN32)
# find Matlab
find_package(Matlab REQUIRED)
if(MATLAB_FOUND)
message(STATUS "Matlab " ${MATLAB_VERSION} ": " ${MATLAB_ROOT})
else()
message(FATAL_ERROR "Matlab not found")
endif(MATLAB_FOUND)
# Some versions of Matlab or some libraries are not compatible with
# more advanced gcc versions
#
# The compiler version has to be set up before project(), otherwise we
# will get an infinite loop. We force the compiler version setting the
# corresponding environmental variables (equivalent to running e.g.
# $ CC=gcc-4.4 CXX=g++-4.4 cmake ..
#
# We also set MAKE_C_COMPILER and CMAKE_CXX_COMPILER, because CGAL uses those
if(NOT WIN32)
if("${MATLAB_VERSION}" MATCHES "R2012a")
set(GCC_VERSION_REQUIRED_BY_MATLAB "4.4")
elseif("${MATLAB_VERSION}" MATCHES "R2012b")
set(GCC_VERSION_REQUIRED_BY_MATLAB "4.4")
elseif("${MATLAB_VERSION}" MATCHES "R2013a")
set(GCC_VERSION_REQUIRED_BY_MATLAB "4.4")
elseif("${MATLAB_VERSION}" MATCHES "R2013b")
set(GCC_VERSION_REQUIRED_BY_MATLAB "4.7")
elseif("${MATLAB_VERSION}" MATCHES "R2014a")
set(GCC_VERSION_REQUIRED_BY_MATLAB "4.7")
elseif("${MATLAB_VERSION}" MATCHES "R2014b")
set(GCC_VERSION_REQUIRED_BY_MATLAB "4.7")
elseif("${MATLAB_VERSION}" MATCHES "R2015a")
set(GCC_VERSION_REQUIRED_BY_MATLAB "4.7")
elseif("${MATLAB_VERSION}" MATCHES "R2015b")
set(GCC_VERSION_REQUIRED_BY_MATLAB "4.7")
elseif("${MATLAB_VERSION}" MATCHES "R2016a")
set(GCC_VERSION_REQUIRED_BY_MATLAB "4.7")
elseif("${MATLAB_VERSION}" MATCHES "R2016b")
set(GCC_VERSION_REQUIRED_BY_MATLAB "4.9")
elseif("${MATLAB_VERSION}" MATCHES "R2017a")
set(GCC_VERSION_REQUIRED_BY_MATLAB "4.9")
elseif("${MATLAB_VERSION}" MATCHES "R2017b")
set(GCC_VERSION_REQUIRED_BY_MATLAB "4.9")
else()
message(FATAL_ERROR
"I do not know which version of gcc/g++ is needed for Matlab ${MATLAB_VERSION}.\nPlease update gerardus/CMakeLists.txt with this information.")
endif()
message(STATUS "Matlab ${MATLAB_VERSION} requires gcc and g++ version: ${GCC_VERSION_REQUIRED_BY_MATLAB}")
message(STATUS "Switching to gcc and g++ ${GCC_VERSION_REQUIRED_BY_MATLAB}")
################# gcc version
find_program(FULL_PATH_TO_GCC "gcc-${GCC_VERSION_REQUIRED_BY_MATLAB}")
set(ENV{CC} "${FULL_PATH_TO_GCC}" CACHE FILEPATH "Compiler required by current Matlab version" FORCE)
set(CMAKE_C_COMPILER "${FULL_PATH_TO_GCC}" CACHE FILEPATH "Compiler required by current Matlab version" FORCE)
################# g++ version
find_program(FULL_PATH_TO_GXX "g++-${GCC_VERSION_REQUIRED_BY_MATLAB}")
set(ENV{CXX} "${FULL_PATH_TO_GXX}" CACHE FILEPATH "Compiler required by current Matlab version" FORCE)
set(CMAKE_CXX_COMPILER "${FULL_PATH_TO_GXX}" CACHE FILEPATH "Compiler required by current Matlab version" FORCE)
################# gfortran version
# if(DEFINED ENV{F77})
# message(STATUS "User wants to use as gfortran the following binary: $ENV{F77}")
# # get version of the Fortran compiler
# exec_program(
# $ENV{F77}
# ARGS --version
# OUTPUT_VARIABLE _compiler_output)
# string(REGEX MATCH "[0-9]\\.[0-9]\\.[0-9]"
# gfortran_compiler_version ${_compiler_output})
# message(STATUS "This binary corresponds to version: ${gfortran_compiler_version}")
# string(REGEX MATCH "[0-9]\\.[0-9]"
# gfortran_compiler_version ${gfortran_compiler_version})
# if(NOT gfortran_compiler_version VERSION_EQUAL "${GCC_VERSION_REQUIRED_BY_MATLAB}")
# message(FATAL_ERROR "Matlab ${MATLAB_VERSION} requires gfortran ${GCC_VERSION_REQUIRED_BY_MATLAB}")
# else()
# message(STATUS "This compiler version is valid for Matlab ${MATLAB_VERSION}")
# endif()
# else()
# # if the user does not provide an environmental variable with
# # the compiler, we set it up
# set(ENV{F77} "gfortran-${GCC_VERSION_REQUIRED_BY_MATLAB}")
# endif()
endif(NOT WIN32)
#############################################################################################
## Start of Gerardus project
#############################################################################################
# project name
project(GERARDUS)
# CMake doesn't work for Windows when Gerardus is on a network share (e.g. cmake -E untar fails
# without a reason, running bootstrap.bat fails too...)
if (WIN32)
# get the two first characters of the path to Gerardus
string(SUBSTRING "${GERARDUS_SOURCE_DIR}" 0 2 AUX)
if (AUX STREQUAL "//")
message(FATAL_ERROR "Gerardus cannot be built on a Windows share, e.g. \\\\my_share\\gerardus. It needs to be on C:, D:, etc. Otherwise, CMake doesn't work well.")
endif()
endif()
#############################################################################################
## Third-party libraries: GMP and MRPF
#############################################################################################
if(WIN32 AND NOT CYGWIN)
# for Windows builds, we use the pre-compiled 64-bit libraries
# provided by the CGAL Windows installer, that we distribute with
# Gerardus
set(GMP_INCLUDE_DIR "${GERARDUS_SOURCE_DIR}/cpp/src/third-party/CGAL-4.2/auxiliary/gmp/include")
set(MPFR_INCLUDE_DIR "${GMP_INCLUDE_DIR}")
set(GMP_LIBRARY_DIR "${GERARDUS_SOURCE_DIR}/cpp/src/third-party/CGAL-4.2/auxiliary/gmp/lib")
set(MPFR_LIBRARY_DIR "${GMP_LIBRARY_DIR}")
add_library(gmp SHARED IMPORTED GLOBAL)
set_property(TARGET gmp PROPERTY IMPORTED_LOCATION "${GMP_LIBRARY_DIR}/libgmp-10.dll")
set_property(TARGET gmp PROPERTY IMPORTED_IMPLIB "${GMP_LIBRARY_DIR}/libgmp-10.lib")
add_library(mpfr SHARED IMPORTED GLOBAL)
set_property(TARGET mpfr PROPERTY IMPORTED_LOCATION "${GMP_LIBRARY_DIR}/libmpfr-4.dll")
set_property(TARGET mpfr PROPERTY IMPORTED_IMPLIB "${GMP_LIBRARY_DIR}/libmpfr-4.lib")
set(GMP_FOUND TRUE
CACHE BOOL "GMP library is part of Gerardus, so this is always true")
set(GMP_LIBRARY_DIRS "${GMP_LIBRARY_DIR}"
CACHE PATH "Path to GMP library")
set(GMP_LIBRARIES_DIR "${GMP_LIBRARY_DIR}"
CACHE PATH "Path to GMP library")
set(MPFR_FOUND TRUE
CACHE BOOL "MPFR library is part of Gerardus, so this is always true")
set(MPFR_LIBRARY_DIRS "${MPFR_LIBRARY_DIR}"
CACHE PATH "Path to MPFR library")
set(MPFR_LIBRARIES_DIR "${MPFR_LIBRARY_DIR}"
CACHE PATH "Path to MPFR library")
else(WIN32 AND NOT CYGWIN) # linux builds
# for Unix-like builds, we have to build the GMP and MPFR libraries from the source code
set(GMP_SOURCE_DIR ${GERARDUS_SOURCE_DIR}/cpp/src/third-party/gmp-5.1.2)
set(MPFR_SOURCE_DIR ${GERARDUS_SOURCE_DIR}/cpp/src/third-party/mpfr-3.1.2)
include(ExternalProject)
# GMP depends on the m4 binary
find_program(M4 m4)
if (NOT M4)
message(FATAL_ERROR
"Program m4 needs to be installed in the system in order to configure GMP. "
"In Debian/Ubuntu, you can install it running: "
"\"sudo apt-get install m4\"")
endif (NOT M4)
# build and install GMP
message(STATUS "Building and installing GMP")
# to avoid repeating this every time we run cmake, we use libgmp.so as
# an indicator of whether GMP has been built and installed
if (NOT EXISTS ${GMP_SOURCE_DIR}/output/lib/libgmp.so)
execute_process(
COMMAND ./configure --prefix=${GMP_SOURCE_DIR}/output
CC=gcc-${GCC_VERSION_REQUIRED_BY_MATLAB} CXX=g++-${GCC_VERSION_REQUIRED_BY_MATLAB}
WORKING_DIRECTORY ${GMP_SOURCE_DIR}
)
execute_process(
COMMAND make
WORKING_DIRECTORY ${GMP_SOURCE_DIR}
)
execute_process(
COMMAND make check
WORKING_DIRECTORY ${GMP_SOURCE_DIR}
)
execute_process(
COMMAND make install
WORKING_DIRECTORY ${GMP_SOURCE_DIR}
)
endif(NOT EXISTS ${GMP_SOURCE_DIR}/output/lib/libgmp.so)
add_library(gmp SHARED IMPORTED GLOBAL)
set_property(TARGET gmp PROPERTY IMPORTED_LOCATION ${GMP_SOURCE_DIR}/output/lib/libgmp.so)
# set(GMP_FOUND TRUE
# CACHE BOOL "GMP library is part of Gerardus, so this is always true")
set(GMP_INCLUDE_DIR ${GMP_SOURCE_DIR}
CACHE PATH "Path to GMP include files")
set(GMP_LIBRARY_DIR ${GMP_SOURCE_DIR}/output/lib
CACHE PATH "Path to GMP library")
set(GMP_LIBRARY_DIRS ${GMP_SOURCE_DIR}/output/lib
CACHE PATH "Path to GMP library")
set(GMP_LIBRARIES_DIR ${GMP_SOURCE_DIR}/output/lib
CACHE PATH "Path to GMP library")
# this line needed by CGAL to avoid looking for GMP in the system
set(GMP_LIBRARIES "${GMP_SOURCE_DIR}/output/lib/libgmp.so")
# build and install MPFR
message(STATUS "Building and installing MPFR")
# to avoid repeating this every time we run cmake, we use libmpfr.so as
# an indicator of whether GMP has been built and installed
if (NOT EXISTS ${MPFR_SOURCE_DIR}/output/lib/libmpfr.so)
execute_process(
COMMAND ./configure --prefix=${MPFR_SOURCE_DIR}/output
--with-gmp-include=${GMP_SOURCE_DIR}/output/include --with-gmp-lib=${GMP_SOURCE_DIR}/output/lib
CC=gcc-${GCC_VERSION_REQUIRED_BY_MATLAB} CXX=g++-${GCC_VERSION_REQUIRED_BY_MATLAB}
WORKING_DIRECTORY ${MPFR_SOURCE_DIR}
)
execute_process(
COMMAND make
WORKING_DIRECTORY ${MPFR_SOURCE_DIR}
)
execute_process(
COMMAND make check
WORKING_DIRECTORY ${MPFR_SOURCE_DIR}
)
execute_process(
COMMAND make install
WORKING_DIRECTORY ${MPFR_SOURCE_DIR}
)
endif(NOT EXISTS ${MPFR_SOURCE_DIR}/output/lib/libmpfr.so)
add_library(mpfr SHARED IMPORTED GLOBAL)
set_property(TARGET mpfr PROPERTY IMPORTED_LOCATION ${MPFR_SOURCE_DIR}/output/lib/libmpfr.so)
# set(MPFR_FOUND TRUE
# CACHE BOOL "MPFR library is part of Gerardus, so this is always true")
set(MPFR_INCLUDE_DIR ${MPFR_SOURCE_DIR}/src
CACHE PATH "Path to MPFR include files")
set(MPFR_LIBRARY_DIR ${MPFR_SOURCE_DIR}/output/lib
CACHE PATH "Path to MPFR library")
set(MPFR_LIBRARY_DIRS ${MPFR_SOURCE_DIR}/output/lib
CACHE PATH "Path to MPFR library")
set(MPFR_LIBRARIES_DIR ${MPFR_SOURCE_DIR}/output/lib
CACHE PATH "Path to MPFR library")
# this line needed by CGAL to avoid looking for MPRF in the system
set(MPFR_LIBRARIES "${MPFR_SOURCE_DIR}/output/lib/libmpfr.so")
endif(WIN32 AND NOT CYGWIN)
#############################################################################################
## Third-party library: IPOPT
#############################################################################################
# # currently, only linux build available in Gerardus
# if(NOT WIN32)
# enable_language(Fortran)
# set(IPOPT_SOURCE_DIR ${GERARDUS_SOURCE_DIR}/cpp/src/third-party/Ipopt-3.11.6)
# # build IPOPT
# include(ExternalProject)
# ExternalProject_Add(IPOPT_GERARDUS
# PREFIX "${IPOPT_SOURCE_DIR}"
# STAMP_DIR "${IPOPT_SOURCE_DIR}/output"
# SOURCE_DIR "${IPOPT_SOURCE_DIR}"
# DOWNLOAD_COMMAND ""
# CONFIGURE_COMMAND ./configure CC=$ENV{CC} CXX=$ENV{CXX} F77=$ENV{F77} --prefix=${IPOPT_SOURCE_DIR}/output
# BINARY_DIR "${IPOPT_SOURCE_DIR}"
# BUILD_COMMAND make
# TEST_BEFORE_INSTALL 1
# # we don't run the test, because tests for any of the linear solvers
# # that we don't use will fail, as they won't be installed in the
# # system, and this will make cmake stop with an error
# #
# # TEST_COMMAND make test
# TEST_COMMAND ""
# INSTALL_DIR "${IPOPT_SOURCE_DIR}/output"
# INSTALL_COMMAND ""
# LOG_CONFIGURE 0
# LOG_BUILD 0
# LOG_TEST 0
# LOG_INSTALL 0
# )
# endif(NOT WIN32)
#############################################################################################
## Third-party library: SCIP
#############################################################################################
# # currently, only linux build available in Gerardus
# if(NOT WIN32)
# set(SCIPLIB_SOURCE_DIR ${GERARDUS_SOURCE_DIR}/cpp/src/third-party/scipoptsuite-3.0.2)
# set(GERARDUSLDFLAGS_SCIPLIB "-L${GMP_SOURCE_DIR}/output/lib -L${GERARDUS_SOURCE_DIR}/cpp/src/third-party/scipoptsuite-3.0.2/zimpl-3.3.1/lib")
# # build SCIP
# include(ExternalProject)
# ExternalProject_Add(SCIP_GERARDUS
# PREFIX "${SCIPLIB_SOURCE_DIR}"
# STAMP_DIR "${SCIPLIB_SOURCE_DIR}/output"
# SOURCE_DIR "${SCIPLIB_SOURCE_DIR}"
# DOWNLOAD_COMMAND ""
# CONFIGURE_COMMAND ""
# BINARY_DIR "${SCIPLIB_SOURCE_DIR}"
# BUILD_COMMAND make CC=$ENV{CC} CXX=$ENV{CXX} LINKCC=$ENV{CC} LINKCXX=$ENV{CXX} GERARDUSLDFLAGS=${GERARDUSLDFLAGS_SCIPLIB} GERARDUSCXXFLAGS=-I${GMP_SOURCE_DIR} READLINE=false
# TEST_BEFORE_INSTALL 1
# TEST_COMMAND make check
# INSTALL_DIR "${SCIPLIB_SOURCE_DIR}/output"
# INSTALL_COMMAND ""
# LOG_CONFIGURE 1
# LOG_BUILD 1
# LOG_TEST 1
# LOG_INSTALL 1
# )
# add_dependencies(SCIP_GERARDUS GMP IPOPT)
# # contrary to custom in the rest of Gerardus, we are calling the scip
# # library "sciplib", instead of "scip". The reason is that the actual
# # MEX Matlab function file will be called scip.mexa64, so that it has
# # the same name as OptiToolbox gives it in Windows
# add_library(sciplib STATIC IMPORTED GLOBAL)
# set_property(TARGET sciplib PROPERTY IMPORTED_LOCATION ${SCIP_SOURCE_DIR}/scip-3.0.2/lib/libscip.a)
# endif(NOT WIN32)
#############################################################################################
## Third-party library: ITK
#############################################################################################
# find ITK
if(WIN32)
set(ITK_DIR "C:/Program Files/ITK/lib/cmake/ITK-4.3")
endif()
find_package(ITK NO_MODULE)
if(NOT ITK_FOUND)
if (WIN32)
message(FATAL_ERROR "You need to download and install ITK v4.3.2: https://sourceforge.net/projects/itk/files/itk/4.3/InsightToolkit-4.3.2.zip")
else(WIN32)
# to make things easier for the user, we are going to build ITK
set(ITK_TARBALL_URL "https://sourceforge.net/projects/itk/files/itk/4.3/InsightToolkit-4.3.2.tar.gz/download")
set(ITK_TARBALL_FILENAME "${CMAKE_BINARY_DIR}/InsightToolkit-4.3.2.tar.gz")
set(ITK_SOURCE_DIR "${GERARDUS_SOURCE_DIR}/cpp/src/third-party/InsightToolkit-4.3.2")
if(EXISTS ${ITK_TARBALL_FILENAME})
message(STATUS "ITK source code previously downloaded: ${ITK_TARBALL_FILENAME}")
else(EXISTS ${ITK_TARBALL_FILENAME})
# download the tarball with the ITK source code
message(STATUS "Downloading ${ITK_TARBALL_URL}\nto ${ITK_TARBALL_FILENAME}")
file(DOWNLOAD
${ITK_TARBALL_URL}
${ITK_TARBALL_FILENAME}
SHOW_PROGRESS
STATUS ITK_DOWNLOAD_STATUS)
if ((ITK_DOWNLOAD_STATUS MATCHES "0;\"No error\"")
OR (ITK_DOWNLOAD_STATUS MATCHES "0;\"no error\""))
message(STATUS "ITK source tarball downloaded: ${ITK_TARBALL_FILENAME}")
else()
message(FATAL_ERROR "${ITK_DOWNLOAD_STATUS}\nCould not download ITK source code from\n${ITK_TARBALL_URL}")
endif()
endif(EXISTS ${ITK_TARBALL_FILENAME})
# uncompress the ITK tarball if necessary
if(NOT EXISTS "${ITK_SOURCE_DIR}")
execute_process(
COMMAND ${CMAKE_COMMAND} -E tar xzf ${ITK_TARBALL_FILENAME}
WORKING_DIRECTORY "${GERARDUS_SOURCE_DIR}/cpp/src/third-party"
RESULT_VARIABLE ITK_UNTAR_ERROR)
# it is possible that the download seems correct, but the
# tarball is an empty file. We need to detect these cases, and
# exit the build with an error. In those cases, the user should
# just download the tarball, e.g. with wget from Linux, copy it
# to the expected ${ITK_TARBALL_FILENAME}, and re-run cmake
if(ITK_UNTAR_ERROR)
message(FATAL_ERROR "ITK tarball cannot be uncompressed: ${ITK_TARBALL_FILENAME}")
endif()
endif(NOT EXISTS "${ITK_SOURCE_DIR}")
# configure ITK
message(STATUS "Configuring ITK")
set(ITK_CMAKE_COMMAND_FLAGS -DBUILD_TESTING:BOOL=OFF -DBUILD_SHARED_LIBS:BOOL=ON -DBUILD_DOCUMENTATION:BOOL=OFF -DBUILD_EXAMPLES:BOOL=OFF -DITK_USE_REVIEW=ON -DCMAKE_BUILD_TYPE=Release -DITK_LEGACY_REMOVE=ON -DCMAKE_C_COMPILER=/usr/bin/gcc-${GCC_VERSION_REQUIRED_BY_MATLAB} -DCMAKE_CXX_COMPILER=/usr/bin/g++-${GCC_VERSION_REQUIRED_BY_MATLAB})
execute_process(
COMMAND ${CMAKE_COMMAND} -E make_directory "bin"
WORKING_DIRECTORY "${ITK_SOURCE_DIR}"
RESULT_VARIABLE ITK_MKDIR_ERROR)
execute_process(
COMMAND ${CMAKE_COMMAND} ${ITK_CMAKE_COMMAND_FLAGS} ..
WORKING_DIRECTORY "${ITK_SOURCE_DIR}/bin"
RESULT_VARIABLE ITK_CMAKE_ERROR)
if(ITK_CMAKE_ERROR)
message(FATAL_ERROR "Running cmake to configure the ITK source code failed")
endif()
# build ITK
message(STATUS "Building ITK")
execute_process(
COMMAND make -j6
WORKING_DIRECTORY "${ITK_SOURCE_DIR}/bin"
RESULT_VARIABLE ITK_MAKE_ERROR)
if(ITK_MAKE_ERROR)
message(FATAL_ERROR "Running make to build the ITK source code failed")
endif()
# it's better if ITK gets installed in the system, but this means
# that we need superuser privileges. We don't want the user to
# enter his password in the script, so until we find a better
# solution, we are just going to ask the user to go to the ITK bin
# directory to run "sudo make install", and the exit the script
message(STATUS "******************************************************************************")
message(STATUS "ITK built successfully. Now you need to install it manually. For that, run")
message(STATUS " pushd \"${ITK_SOURCE_DIR}/bin\"")
message(STATUS " sudo make install; popd")
message(STATUS "If ITK installed successfully, you can then run")
message(STATUS " cmake ..")
message(STATUS "again to finish configuring Gerardus.")
message(STATUS "******************************************************************************")
return()
endif(WIN32)
else(NOT ITK_FOUND)
# ITK has been found, so we add the include directory and display its version
include(${ITK_USE_FILE})
message(STATUS "ITK v" ${ITK_VERSION_MAJOR}.${ITK_VERSION_MINOR}.${ITK_VERSION_PATCH})
endif(NOT ITK_FOUND)
## flags for all targets
IF(WIN32)
# to remove warnings from MSVC compiler asking to use fopen_s() an other unportable
# functions exclusive to Microsoft
ADD_DEFINITIONS("-D_CRT_SECURE_NO_DEPRECATE")
ELSE(WIN32)
# optimise and show all warnings
ADD_DEFINITIONS("-O2 -Wall")
# For Mac OSX, we need to specify the system architecture.
# If this hasn't been set, we choose 64-bit intel.
IF(${CMAKE_SYSTEM_NAME} MATCHES "Darwin")
IF(NOT CMAKE_OSX_ARCHITECTURES)
SET(CMAKE_OSX_ARCHITECTURES x86_64)
ENDIF(NOT CMAKE_OSX_ARCHITECTURES)
ENDIF(${CMAKE_SYSTEM_NAME} MATCHES "Darwin")
ENDIF(WIN32)
#############################################################################################
## Third-party library: Boost
#############################################################################################
# Boost libraries are required by the executable programs in Gerardus,
# and anything that uses CGAL. In the past, we tried to build the
# Boost libraries we needed and link to them. However, Matlab also
# uses and provides its own Boost libraries in the same directory
# where it keeps the mex libraries. This created error prone
# situations where MEX functions where linked to two different
# versions of the same Boost library.
#
# To avoid that trouble, we now avoid that duplication. Instead, we
# figure out what version of Boost Matlab is using, download the
# corresponding header files, install them in Gerardus, and link to
# the Boost libraries already distributed with Matlab.
# get the version of Boost distributed with Matlab
if(WIN32)
set(MATLAB_BOOST_LIB_PATH "${MATLAB_ROOT}/bin/win64")
else()
get_filename_component(MATLAB_BOOST_LIB_PATH ${MATLAB_MEX_LIBRARY} PATH)
endif()
file(GLOB AUX_BOOST_VERSION "${MATLAB_BOOST_LIB_PATH}/*boost_system*")
get_filename_component(AUX_BOOST_VERSION ${AUX_BOOST_VERSION} NAME)
if(WIN32)
string(REGEX MATCH "[0-9]+[._][0-9]+" AUX_BOOST_VERSION ${AUX_BOOST_VERSION}) # e.g. 1_44
# set(AUX_BOOST_VERSION ${AUX_BOOST_VERSION}_0) # e.g. 1_44_0
string(REPLACE "_" "." AUX_BOOST_VERSION ${AUX_BOOST_VERSION}) # e.g. 1.44
else()
string(REGEX MATCH "[0-9]+[._][0-9]+[._][0-9]+" AUX_BOOST_VERSION ${AUX_BOOST_VERSION}) # e.g. 1.44.0
# or 1.44
endif()
message(STATUS "Matlab is linked to Boost version ${AUX_BOOST_VERSION}")
string(REPLACE "." "_" AUX_BOOST_VERSION_ ${AUX_BOOST_VERSION}) # e.g. 1_44_0
# or 1_44
# path to where the Boost header files will be found in Gerardus
if(WIN32)
set(BOOST_SOURCE_DIR
${GERARDUS_SOURCE_DIR}/cpp/src/third-party/boost_${AUX_BOOST_VERSION_}_0)
set(Boost_INCLUDE_DIR "${GERARDUS_SOURCE_DIR}/include/boost-${AUX_BOOST_VERSION_}")
else()
set(BOOST_SOURCE_DIR
${GERARDUS_SOURCE_DIR}/cpp/src/third-party/boost_${AUX_BOOST_VERSION_})
set(Boost_INCLUDE_DIR "${GERARDUS_SOURCE_DIR}/include")
endif()
# path to where the Boost libraries will be found in Gerardus
if(WIN32)
set(Boost_LIBRARY_DIR "${GERARDUS_SOURCE_DIR}/lib")
else()
set(Boost_LIBRARY_DIR "${MATLAB_BOOST_LIB_PATH}")
endif()
# we want to know whether Boost has already been installed. As
# checking for the whole project is complicated, we are going to check
# only whether file /boost/version.hpp is in its expected location. If
# it isn't, then we install the boost libraries (in linux, we just
# soft link to them; in Windows, we need to build and install them)
find_file(Boost_version_hpp version.hpp
PATHS "${Boost_INCLUDE_DIR}/boost/"
NO_DEFAULT_PATH)
if(NOT Boost_version_hpp)
message(STATUS "${Boost_INCLUDE_DIR}/boost/version.hpp not found.\nPreparing to install Boost libraries")
if(WIN32)
set(BOOST_TARBALL_URL
https://sourceforge.net/projects/boost/files/boost/${AUX_BOOST_VERSION}.0/boost_${AUX_BOOST_VERSION_}_0.tar.gz)
set(BOOST_TARBALL_FILENAME
${GERARDUS_SOURCE_DIR}/cpp/src/third-party/boost_${AUX_BOOST_VERSION_}_0.tar.gz)
else()
set(BOOST_TARBALL_URL
https://sourceforge.net/projects/boost/files/boost/${AUX_BOOST_VERSION}/boost_${AUX_BOOST_VERSION_}.tar.gz)
set(BOOST_TARBALL_FILENAME
${GERARDUS_SOURCE_DIR}/cpp/src/third-party/boost_${AUX_BOOST_VERSION_}.tar.gz)
endif()
# check whether we need to download the tarball with the Boost
# source code, or whether it's already been downloaded
if(EXISTS ${BOOST_TARBALL_FILENAME})
message(STATUS "Boost source code previously downloaded")
else()
# download the tarball with the Boost source code that corresponds
# to the Boost version in Matlab
message(STATUS "Downloading ${BOOST_TARBALL_URL}\nto ${BOOST_TARBALL_FILENAME}")
file(DOWNLOAD
${BOOST_TARBALL_URL}
${BOOST_TARBALL_FILENAME}
SHOW_PROGRESS
STATUS Boost_DOWNLOAD_STATUS)
if ((Boost_DOWNLOAD_STATUS MATCHES "0;\"No error\"")
OR (Boost_DOWNLOAD_STATUS MATCHES "0;\"no error\""))
message(STATUS "Boost source tarball downloaded")
else()
message(FATAL_ERROR "${Boost_DOWNLOAD_STATUS}\nCould not download Boost source code from\n${BOOST_TARBALL_URL}")
endif()
endif()
# uncompress the Boost tarball if necessary
if(NOT EXISTS "${BOOST_SOURCE_DIR}")
execute_process(
COMMAND ${CMAKE_COMMAND} -E tar xzf ${BOOST_TARBALL_FILENAME}
WORKING_DIRECTORY ${GERARDUS_SOURCE_DIR}/cpp/src/third-party
RESULT_VARIABLE BOOST_UNTAR_ERROR)
# it is possible that the download seems correct, but the
# tarball is an empty file. We need to detect these cases, and
# exit the build with an error. In those cases, the user should
# just download the tarball, e.g. with wget from Linux, copy it
# to the expected ${BOOST_TARBALL_FILENAME}, and re-run cmake
if(BOOST_UNTAR_ERROR)
message(FATAL_ERROR "Boost tarball cannot be uncompressed: ${BOOST_TARBALL_FILENAME}")
endif()
endif()
# In Windows, we need to build and install the libraries, because
# Matlab only makes the .dll Boost files available, and we need the
# .lib for linking, even for dynamic linking
#
# We don't use ExternalProject_Add() because we need the Boost
# libraries to be available for FindBoost() and the rest of the
# targets in Gerardus that link to them at configuration time
if (WIN32)
# for the build, we need to tell the Boost builder whether this is
# a 32 or 64 bit system
if(CMAKE_SIZEOF_VOID_P EQUAL 8)
set(Boost_address_model 64)
else()
set(Boost_address_model 32)
endif()
message(STATUS "Configuring Boost libraries")
execute_process(
COMMAND bootstrap.bat
WORKING_DIRECTORY ${BOOST_SOURCE_DIR}
RESULT_VARIABLE COMMAND_RESULT)
if(${COMMAND_RESULT} MATCHES 0)
message(STATUS "Boost libraries configured")
else()
message(FATAL_ERROR "Boost libraries configuration error:\n${COMMAND_RESULT}")
endif()
message(STATUS "Building and installing Boost libraries and header files")
execute_process(
COMMAND bjam.exe install variant=release
--prefix=${GERARDUS_SOURCE_DIR}
--build-dir=./bin address-model=${Boost_address_model}
--build-type=complete
--with-system --with-filesystem --with-thread --with-date_time --with-serialization
WORKING_DIRECTORY ${BOOST_SOURCE_DIR}
RESULT_VARIABLE COMMAND_RESULT)
if(${COMMAND_RESULT} MATCHES 0)
message(STATUS "Boost libraries and header files built and installed")
else()
message(FATAL_ERROR "Boost libraries build error:\n${COMMAND_RESULT}")
endif()
# In Linux it's easier, because we can link directly to the .so
# files provided by Matlab
else()
# copy the header files to Gerardus' include directory
file(COPY "${BOOST_SOURCE_DIR}/boost"
DESTINATION "${Boost_INCLUDE_DIR}")
# patch the Boost include files if necessary
# version 1.44.0: https://bbs.archlinux.org/viewtopic.php?pid=1126374
# version 1.49.0: ditto
# this problem was solved in boost 1.50
if (${AUX_BOOST_VERSION} LESS "1.50.0")
message(STATUS "This version of Boost needs patching")
file(READ "${Boost_INCLUDE_DIR}/boost/thread/xtime.hpp" AUX)
string(REPLACE TIME_UTC TIME_UTC_ AUX "${AUX}")
file(WRITE "${Boost_INCLUDE_DIR}/boost/thread/xtime.hpp" "${AUX}")
endif()
message(STATUS "Boost header files have been patched and installed")
endif()
else()
message(STATUS "${Boost_INCLUDE_DIR}/boost/version.hpp found.")
message(STATUS "Assuming that Boost libraries and headers are installed")
endif(NOT Boost_version_hpp)
#set(BOOST_ROOT "${MATLAB_BOOST_LIB_PATH}")
set(Boost_INCLUDE_DIRS "${Boost_INCLUDE_DIR}")
set(Boost_LIBRARY_DIRS "${Boost_LIBRARY_DIR}")
message(STATUS "Boost include path: ${Boost_INCLUDE_DIRS}")
message(STATUS "Boost lib path: ${Boost_LIBRARY_DIRS}")
set(BOOST_INCLUDEDIR "${Boost_INCLUDE_DIR}")
set(BOOST_LIBRARYDIR "${Boost_LIBRARY_DIR}")
set(Boost_DEBUG FALSE)
set(Boost_NO_SYSTEM_PATHS TRUE)
if (WIN32)
set(Boost_USE_STATIC_LIBS OFF)
else()
set(Boost_USE_STATIC_LIBS OFF)
endif()
set(Boost_USE_MULTITHREADED ON)
set(Boost_USE_STATIC_RUNTIME OFF)
add_definitions(${Boost_LIB_DIAGNOSTIC_DEFINITIONS})
# integrate the local Boost libraries with the rest of the CMake
# build system
if(WIN32)
# in Windows, we can just look for the library files
find_package(Boost ${AUX_BOOST_VERSION}
COMPONENTS date_time filesystem serialization system thread)
else()
# FindBoost.cmake will not find the boost libraries in linux because
# Matlab saves them as e.g. libboost_system.so.1.44.0, so we need to
# add them by hand
# library suffixes get automatically added to the end of the name
# when looking for libraries. Because we are looking for libraries
# with names like e.g. libboost_system.so.1.44.0, we are going to
# temporarily allow that kind of suffix
set(AUX "${CMAKE_FIND_LIBRARY_SUFFIXES}")
set(CMAKE_FIND_LIBRARY_SUFFIXES ".so.${AUX_BOOST_VERSION}")
find_package(Boost ${AUX_BOOST_VERSION}
COMPONENTS date_time filesystem system thread)
# recover the library suffixes
set(CMAKE_FIND_LIBRARY_SUFFIXES "${AUX}")
endif()
#############################################################################################
## Third-party library: OpenGL
#############################################################################################
# Required by CGAL_ImageIO
find_package(OpenGL REQUIRED)
#############################################################################################
## Third-party library: CGAL
#############################################################################################
# note that CGAL depends on Boost, but it's too cumbersome to add
# an explicit dependency
# call the subproject, as CGAL is distributed with a CMake build
add_subdirectory(cpp/src/third-party/CGAL-4.2)
# after CGAL builds, we need to copy the header file compiler_config.h
# it generates to the CGAL include directory, so that it's available
# for the other sub-projects that use CGAL (e.g. itk_imfilter)
add_custom_command(
OUTPUT ${CGAL_SOURCE_DIR}/include/CGAL/compiler_config.h
COMMAND ${CMAKE_COMMAND} -E copy "${CMAKE_CURRENT_BINARY_DIR}/include/CGAL/compiler_config.h" "${CGAL_SOURCE_DIR}/include/CGAL/"
MAIN_DEPENDENCY ${CMAKE_CURRENT_BINARY_DIR/../../include/CGAL/compiler_config.h}
DEPENDS CGAL
)
add_custom_target(copy_compiler_config.h DEPENDS "${CGAL_SOURCE_DIR}/include/CGAL/compiler_config.h")
#############################################################################################
## Configuration options for all Gerardus
#############################################################################################
# make the libraries that live in the Gerardus lib directory available
# to all targets
link_directories(
${GERARDUS_SOURCE_DIR}/lib
)
##################################################################
## Block so that rpaths are added to both the MEX file in the build
## tree and in the installation directory. Otherwise, the rpath is
## stripped when installing, and the function will crash as it won't be
## able to find the ITK shared libraries
# auxiliary libraries built within Gerardus will not be installed in
# the system, but locally. If at some point we need to install in the
# system, the following line will have to be changed, and we'll have
# to uncomment the lines at the end of the rpath block, and use those
# for non-system installs
SET(CMAKE_INSTALL_PREFIX ${GERARDUS_SOURCE_DIR}/lib)
# use, i.e. don't skip the full RPATH for the build tree
SET(CMAKE_SKIP_BUILD_RPATH FALSE)
# when building, don't use the install RPATH already
# (but later on when installing)
SET(CMAKE_BUILD_WITH_INSTALL_RPATH FALSE)
SET(CMAKE_INSTALL_RPATH ${CMAKE_INSTALL_PREFIX})
# add the automatically determined parts of the RPATH
# which point to directories outside the build tree to the install RPATH
SET(CMAKE_INSTALL_RPATH_USE_LINK_PATH TRUE)
# the RPATH to be used when installing, but only if it's not a system directory
#LIST(FIND CMAKE_PLATFORM_IMPLICIT_LINK_DIRECTORIES "${CMAKE_INSTALL_PREFIX}/lib" isSystemDir)
#IF("${isSystemDir}" STREQUAL "-1")
# SET(CMAKE_INSTALL_RPATH "${CMAKE_INSTALL_PREFIX}/lib")
#ENDIF("${isSystemDir}" STREQUAL "-1")
## End rpath block
##################################################################
## flags for all targets
IF(WIN32)
# to remove warnings from MSVC compiler asking to use fopen_s() an other unportable
# functions exclusive to Microsoft
ADD_DEFINITIONS("-D_CRT_SECURE_NO_DEPRECATE")
# avoid MSVC compiler warnings like
# 'std::copy': Function call with parameters that may be unsafe
# given by ITK functions
ADD_DEFINITIONS("-D_SCL_SECURE_NO_WARNINGS")
ELSE(WIN32)
# optimise and show all warnings
ADD_DEFINITIONS("-O2 -Wall")
ENDIF(WIN32)
#############################################################################################
## Call the subprojects
#############################################################################################
ADD_SUBDIRECTORY(cpp/src)
ADD_SUBDIRECTORY(cpp/src/third-party/mba)
ADD_SUBDIRECTORY(matlab)