1# ============================================================================
2#                  SeqAn - The Library for Sequence Analysis
3# ============================================================================
4# Copyright (c) 2006-2018, Knut Reinert, FU Berlin
5# All rights reserved.
6#
7# Redistribution and use in source and binary forms, with or without
8# modification, are permitted provided that the following conditions are met:
9#
10#     * Redistributions of source code must retain the above copyright
11#       notice, this list of conditions and the following disclaimer.
12#     * Redistributions in binary form must reproduce the above copyright
13#       notice, this list of conditions and the following disclaimer in the
14#       documentation and/or other materials provided with the distribution.
15#     * Neither the name of Knut Reinert or the FU Berlin nor the names of
16#       its contributors may be used to endorse or promote products derived
17#       from this software without specific prior written permission.
18#
19# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
20# AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
21# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
22# ARE DISCLAIMED. IN NO EVENT SHALL KNUT REINERT OR THE FU BERLIN BE LIABLE
23# FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
24# DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
25# SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
26# CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
27# LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
28# OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH
29# DAMAGE.
30# ============================================================================
31# Author: Manuel Holtgrewe <manuel.holtgrewe@fu-berlin.de>
32# ============================================================================
33# This CMake file defines the necessary macros for the SeqAn build system.
34#
35# Note that while the SeqAn build system uses the seqan-config.cmake module,
36# the seqan-config.cmake module itself can be used independently from the SeqAn
37# build system.
38# ============================================================================
39
40# ----------------------------------------------------------------------------
41# Set CMAKE policies.
42# ----------------------------------------------------------------------------
43
44if (POLICY CMP0054)  # Disables auto-dereferencing of variables in quoted statements
45  cmake_policy(SET CMP0054 NEW)
46endif()
47
48# Valid values for SEQAN_BUILD_SYSTEM:
49#
50# DEVELOP
51# SEQAN_RELEASE_APPS
52# SEQAN_RELEASE_LIBRARY
53# APP:${app_name}
54
55# require python 2.7, not python3
56set(PythonInterp_FIND_VERSION 2.7)
57set(PythonInterp_FIND_VERSION_MAJOR 2)
58set(PythonInterp_FIND_VERSION_MINOR 7)
59set(PythonInterp_FIND_VERSION_COUNT 2)
60
61include (SeqAnUsabilityAnalyzer)
62include (CheckCXXCompilerFlag)
63
64if (DEFINED CMAKE_INSTALL_DOCDIR)
65    set(CMAKE_INSTALL_DOCDIR_IS_SET ON)
66endif ()
67
68include (GNUInstallDirs)
69
70set (COMPILER_CLANG FALSE)
71set (COMPILER_GCC FALSE)
72set (COMPILER_LINTEL FALSE)
73set (COMPILER_WINTEL FALSE)
74set (COMPILER_MSVC FALSE)
75set (STDLIB_VS ${MSVC})
76
77if (CMAKE_CXX_COMPILER_ID MATCHES "Clang")
78  set (COMPILER_CLANG TRUE)
79elseif (CMAKE_CXX_COMPILER_ID MATCHES "Intel" AND STDLIB_VS)
80  set (COMPILER_WINTEL TRUE)
81elseif (CMAKE_CXX_COMPILER_ID MATCHES "Intel")
82  set (COMPILER_LINTEL TRUE)
83elseif (CMAKE_CXX_COMPILER_ID MATCHES "GNU")
84  set (COMPILER_GCC TRUE)
85elseif (CMAKE_CXX_COMPILER_ID MATCHES "MSVC")
86  set (COMPILER_MSVC TRUE)
87endif ()
88
89# ---------------------------------------------------------------------------
90# Enable /bigobj flag on Windows.
91# ---------------------------------------------------------------------------
92
93# We need the /bigobj switch on windows (for 64 bit builds only actually).
94# Set target system to be Windows Vista and later.
95if (COMPILER_MSVC OR COMPILER_WINTEL)
96    # Set /bigobj for COMPILER_MSVC and COMPILER_WINTEL, but COMPILER_CLANG on
97    # windows (clang/c2 3.7) can not handle it.
98    add_definitions (/bigobj)
99endif()
100
101if (STDLIB_VS)
102    add_definitions (-D_WIN32_WINNT=0x0600 -DWINVER=0x0600)
103endif ()
104
105# ---------------------------------------------------------------------------
106# Is it a 32 bit platform?
107# ---------------------------------------------------------------------------
108if (CMAKE_SIZEOF_VOID_P EQUAL 4)
109    set(SEQAN_32BIT_TARGET_PLATFORM 1)
110    set(SEQAN_64BIT_TARGET_PLATFORM 0)
111else()
112    set(SEQAN_32BIT_TARGET_PLATFORM 0)
113    set(SEQAN_64BIT_TARGET_PLATFORM 1)
114endif()
115
116# ---------------------------------------------------------------------------
117
118# ---------------------------------------------------------------------------
119# Disable false positive terminal detection in Xcode
120# ---------------------------------------------------------------------------
121
122if (CMAKE_GENERATOR STREQUAL Xcode)
123    add_definitions (-DSEQAN_NO_TERMINAL)
124endif (CMAKE_GENERATOR STREQUAL Xcode)
125
126# ---------------------------------------------------------------------------
127# Function add_executable (name [WIN32] [MACOSX_BUNDLE] [EXCLUDE_FROM_ALL]
128#                          source1 source2 ... sourceN)
129#
130# Add an executable with the given name and sources.
131#
132# We overwrite the built-in function add_executable to automatically add
133# behaviour that is required in the SeqAn build system.  This includes:
134#
135# * Adding dependencies to the SeqAn library headers.
136# * Enabling the SeqAn Usability Analyzer (SUA).
137#
138# Note that it is not possible to overwrite the same function two times.
139# ---------------------------------------------------------------------------
140
141function (add_executable NAME)
142    # Call overwritten _add_executable.
143    _add_executable(${ARGV})
144
145    # Add dependencies on the SeqAn library.
146    add_dependencies(${NAME} seqan_library)
147
148    # Add dependency on the SUA target.
149    seqan_add_sua_dependency (${NAME})
150endfunction (add_executable)
151
152# ---------------------------------------------------------------------------
153# Macro seqan_register_apps ()
154#
155# Register all apps by adding their subdirectories if they are to be built
156# (SEQAN_RELEASE and APP:${app} modes).
157# ---------------------------------------------------------------------------
158
159macro (seqan_register_apps)
160    # Get all direct entries of the current source directory into ENTRIES.
161    file (GLOB ENTRIES
162          RELATIVE ${CMAKE_CURRENT_SOURCE_DIR}
163          ${CMAKE_CURRENT_SOURCE_DIR}/[!.]*)
164
165    # Add all values from ${ENTRIES} that are subdirectories and have a file
166    # CMakeListst.txt.
167    foreach (ENTRY ${ENTRIES})
168        if (IS_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR}/${ENTRY})
169            if (EXISTS ${CMAKE_CURRENT_SOURCE_DIR}/${ENTRY}/CMakeLists.txt)
170                if ((("${SEQAN_BUILD_SYSTEM}" STREQUAL "DEVELOP") OR
171                    ("${SEQAN_BUILD_SYSTEM}" STREQUAL "SEQAN_RELEASE_APPS") OR
172                    ("${SEQAN_BUILD_SYSTEM}" STREQUAL "APP:${ENTRY}")) AND
173                    (NOT (${${ENTRY}_NO_BUILD})))
174                    add_subdirectory(${ENTRY})
175                endif ()
176            endif (EXISTS ${CMAKE_CURRENT_SOURCE_DIR}/${ENTRY}/CMakeLists.txt)
177        endif (IS_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR}/${ENTRY})
178    endforeach (ENTRY ${ENTRIES})
179endmacro (seqan_register_apps)
180
181# ---------------------------------------------------------------------------
182# Macro seqan_build_system_init ()
183#
184# Initialize build system.
185# ---------------------------------------------------------------------------
186
187macro (seqan_build_system_init)
188    # Enable CTest and command add_test().
189    enable_testing ()
190
191    # GENERAL SETUP
192    set (_CMAKE_INCLUDE_PATH ${CMAKE_INCLUDE_PATH} "${CMAKE_CURRENT_SOURCE_DIR}/include")
193    set (CMAKE_INCLUDE_PATH ${_CMAKE_INCLUDE_PATH} CACHE STRING "")
194    set (CMAKE_CXX_FLAGS_DEBUG "${CMAKE_CXX_FLAGS_DEBUG} -DSEQAN_ENABLE_DEBUG=1")
195    set (SeqAn_DIR ${SeqAn_DIR} "${CMAKE_CURRENT_SOURCE_DIR}/util/cmake")
196#     set (CMAKE_CXX_FLAGS_DEBUG "${CMAKE_CXX_FLAGS_DEBUG} -DSEQAN_ENABLE_DEBUG=1" PARENT_SCOPE)
197    # Enable global exception handler for all "official" stuff
198    set (SEQAN_DEFINITIONS "${SEQAN_DEFINITIONS} -DSEQAN_GLOBAL_EXCEPTION_HANDLER=1")
199    set (CMAKE_RUNTIME_OUTPUT_DIRECTORY
200         ${PROJECT_BINARY_DIR}/bin)
201
202    if (STDLIB_VS)
203        # Disable warnings about unsecure (although standard) functions
204        # @see https://msdn.microsoft.com/en-us/library/aa985974.aspx
205        set (SEQAN_DEFINITIONS ${SEQAN_DEFINITIONS} -D_SCL_SECURE_NO_WARNINGS)
206
207        # 'strcpy' is deprecated: This function or variable may be unsafe.
208        # Consider using strcpy_s instead. To disable deprecation, use
209        # @see https://msdn.microsoft.com/en-us/library/8ef0s5kh.aspx
210        set (SEQAN_DEFINITIONS ${SEQAN_DEFINITIONS} -D_CRT_SECURE_NO_WARNINGS)
211    endif()
212
213    # Set Warnings
214    # NOTE(marehr): COMPILER_CLANG on windows uses the same flags as on linux,
215    # whereas COMPILER_WINTEL uses on windows the same flags as COMPILER_MSVC.
216    if (COMPILER_MSVC)
217        # TODO(h-2): raise this to W4
218        set (SEQAN_CXX_FLAGS "${SEQAN_CXX_FLAGS} /W2")
219    elseif (COMPILER_WINTEL)
220        # TODO(h-2): raise this to W4
221        set (SEQAN_CXX_FLAGS "${SEQAN_CXX_FLAGS} /W3")
222    else()
223        set (SEQAN_CXX_FLAGS "${SEQAN_CXX_FLAGS} -W -Wall -pedantic")
224        set (SEQAN_DEFINITIONS ${SEQAN_DEFINITIONS} -D_LARGEFILE_SOURCE -D_FILE_OFFSET_BITS=64)
225
226        # disable some warnings on ICC
227        if (COMPILER_LINTEL)
228            # warning #3373: nonstandard use of "auto" to both deduce the type
229            # from an initializer and to announce a trailing return type
230            set (SEQAN_CXX_FLAGS "${SEQAN_CXX_FLAGS} -wd3373,2102")
231        endif ()
232    endif ()
233
234    if (NOT SEQAN_BUILD_SYSTEM)
235        set (SEQAN_BUILD_SYSTEM "DEVELOP" CACHE STRING "Build/Release mode to select. One of DEVELOP SEQAN_RELEASE, APP:\${APP_NAME}. Defaults to DEVELOP.")
236    endif (NOT SEQAN_BUILD_SYSTEM)
237    set (SEQAN_APP_VERSION "0.0.0" CACHE STRING "Version of the application.")
238    set (SEQAN_NIGHTLY_RELEASE FALSE CACHE BOOL "Set to TRUE to enable nightly app releases.")
239
240    ## options
241
242    # SeqAn Version Check
243    if (SEQAN_DISABLE_VERSION_CHECK)  # Disable completely
244        set (SEQAN_DEFINITIONS ${SEQAN_DEFINITIONS} -DSEQAN_DISABLE_VERSION_CHECK)
245    elseif (SEQAN_VERSION_CHECK_OPT_IN)  # Build it but make it opt-in.
246        set (SEQAN_DEFINITIONS ${SEQAN_DEFINITIONS} -DSEQAN_VERSION_CHECK_OPT_IN)
247    endif ()
248
249    # Architecture.
250    if ((NOT SEQAN_64BIT_TARGET_PLATFORM) OR COMPILER_MSVC)
251        set (SEQAN_ARCH_SSE4 FALSE)
252        set (SEQAN_ARCH_AVX2 FALSE)
253        set (SEQAN_ARCH_AVX512_KNL FALSE)
254        set (SEQAN_ARCH_AVX512_SKX FALSE)
255        set (SEQAN_ARCH_AVX512_CNL FALSE)
256    endif ()
257
258    if (COMPILER_MSVC)
259        set (SEQAN_STATIC_APPS FALSE)
260        set (SEQAN_ARCH_NATIVE FALSE)
261    endif ()
262
263    if (${CMAKE_SYSTEM_NAME} STREQUAL "OpenBSD")
264        set (SEQAN_STATIC_APPS FALSE)
265        if (SEQAN_ARCH_NATIVE)
266            set (SEQAN_ARCH_NATIVE FALSE)
267            set (SEQAN_ARCH_SSE4 TRUE)
268            message (STATUS "OpenBSD does not support native, but SSE4 was activated instead.")
269        endif ()
270    endif ()
271
272    # Enable SSE4 if AVX[\d]+ is set. (Other parts in our build system expect it
273    # to be set and it is basically the synonym for 'SIMD is enabled')
274    if (SEQAN_ARCH_AVX2 OR SEQAN_ARCH_AVX512_KNL OR SEQAN_ARCH_AVX512_SKX OR SEQAN_ARCH_AVX512_CNL)
275        set (SEQAN_ARCH_SSE4 TRUE)
276    endif ()
277
278    if (SEQAN_STATIC_APPS)
279        message (STATUS "Building static apps.")
280        # implementation in seqan_register_apps()
281    endif ()
282
283    # machine specific optimizations
284    if (SEQAN_ARCH_NATIVE)
285        message (STATUS "Building binaries optimized for this specific CPU. They might not work elsewhere.")
286        set (SEQAN_CXX_FLAGS "${SEQAN_CXX_FLAGS} -march=native")
287        if (COMPILER_LINTEL)
288            set (SEQAN_CXX_FLAGS "${SEQAN_CXX_FLAGS} -ipo -no-prec-div -fp-model fast=2 -xHOST")
289        endif ()
290    elseif (SEQAN_ARCH_SSE4)
291        include (SeqAnSimdUtility)
292
293        if (NOT ${CMAKE_SYSTEM_NAME} STREQUAL "OpenBSD")
294            set (SEQAN_CXX_FLAGS "${SEQAN_CXX_FLAGS} -mpopcnt")
295        endif ()
296        if (COMPILER_LINTEL)
297            set (SEQAN_CXX_FLAGS "${SEQAN_CXX_FLAGS} -ipo -no-prec-div -fp-model fast=2")
298        endif ()
299
300        if (SEQAN_ARCH_AVX512_CNL)
301            message (STATUS "Building optimized binaries up to AVX512 CNL and POPCNT.")
302            set (SEQAN_CXX_FLAGS "${SEQAN_CXX_FLAGS} ${SEQAN_SIMD_AVX512_CNL_OPTIONS}")
303        elseif (SEQAN_ARCH_AVX512_SKX)
304            message (STATUS "Building optimized binaries up to AVX512 SKX and POPCNT.")
305            set (SEQAN_CXX_FLAGS "${SEQAN_CXX_FLAGS} ${SEQAN_SIMD_AVX512_SKX_OPTIONS}")
306        elseif (SEQAN_ARCH_AVX512_KNL)
307            message (STATUS "Building optimized binaries up to AVX512 KNL and POPCNT.")
308            set (SEQAN_CXX_FLAGS "${SEQAN_CXX_FLAGS} ${SEQAN_SIMD_AVX512_KNL_OPTIONS}")
309        elseif (SEQAN_ARCH_AVX2)
310            message (STATUS "Building optimized binaries up to AVX2 and POPCNT.")
311            set (SEQAN_CXX_FLAGS "${SEQAN_CXX_FLAGS} ${SEQAN_SIMD_AVX2_OPTIONS}")
312        else ()
313            message (STATUS "Building optimized binaries up to SSE4 and POPCNT.")
314            set (SEQAN_CXX_FLAGS "${SEQAN_CXX_FLAGS} ${SEQAN_SIMD_SSE4_OPTIONS}")
315        endif ()
316    endif ()
317    # TODO(h-2): for icc on windows, replace the " -" in SEQAN_CXX_FLAGS with " /"
318    #            find out whether clang/c2 takes - or / options
319
320    # enable static linkage for seqan apps
321    if (SEQAN_STATIC_APPS AND (NOT CMAKE_SYSTEM_NAME MATCHES "Windows"))
322        set(CMAKE_FIND_LIBRARY_SUFFIXES ".a")
323        if (APPLE)
324            # static build not supported on apple, but at least we can include gcc libs
325            if (COMPILER_GCC)
326                set(CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} -static-libgcc -static-libstdc++")
327            endif (COMPILER_GCC)
328        else (APPLE)
329            set(CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} -static")
330
331            # make sure -rdynamic isn't added automatically
332            set(CMAKE_SHARED_LIBRARY_LINK_CXX_FLAGS)
333            # make sure -fPIC isn't added automatically
334            set(CMAKE_SHARED_LIBRARY_CXX_FLAGS)
335
336            # For unknown reasons finding .a only seems to work for libz and
337            # libbzip2; cmake than proceeds to wrap these in
338            # -Wl,-Bstatic -lz -lbz2 -Wl,-Bdynamic
339            # the latter reactivates dynamic linking for the system libs
340            # we override this behaviour here:
341            set(CMAKE_EXE_LINK_DYNAMIC_CXX_FLAGS)
342        endif (APPLE)
343    endif (SEQAN_STATIC_APPS AND (NOT CMAKE_SYSTEM_NAME MATCHES "Windows"))
344
345    # strip binaries when packaging
346    if ((CMAKE_BUILD_TYPE STREQUAL "Release") AND
347        (NOT SEQAN_BUILD_SYSTEM STREQUAL "DEVELOP") AND
348        (NOT APPLE) AND
349        (COMPILER_CLANG OR COMPILER_GCC))
350        set(CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} -s")
351    endif ()
352
353    # search dependencies once, globally, if in DEVELOP
354    if (SEQAN_BUILD_SYSTEM STREQUAL "DEVELOP")
355        message (STATUS "Scanning dependencies once in DEVELOP mode...")
356        find_package(OpenMP)
357        find_package(ZLIB)
358        find_package(BZip2)
359        find_package(Boost)
360        find_package(SeqAn CONFIG REQUIRED)
361    endif ()
362
363endmacro (seqan_build_system_init)
364
365# ---------------------------------------------------------------------------
366# Macro seqan_add_app_test (APP_NAME SUFFIX)
367#
368# Add app test invocation.
369# ---------------------------------------------------------------------------
370
371# App tests are run using Python.  Search for Python and register test if the
372# Python interpreter could be found.
373
374macro (seqan_add_app_test APP_NAME)
375    if (MODEL MATCHES ".*MemCheck.*")
376        set (_VALGRIND_FLAG --valgrind)
377    else ()
378        set (_VALGRIND_FLAG)
379    endif ()
380    find_package (PythonInterp)
381    if (PYTHONINTERP_FOUND)
382      add_test (NAME app_test_${APP_NAME}${ARGV1}
383                COMMAND ${PYTHON_EXECUTABLE}
384                        ${CMAKE_CURRENT_SOURCE_DIR}/tests/run_tests${ARGV1}.py
385                        ${_VALGRIND_FLAG}
386                        ${CMAKE_SOURCE_DIR} ${CMAKE_BINARY_DIR})
387    endif (PYTHONINTERP_FOUND)
388endmacro (seqan_add_app_test APP_NAME)
389
390# ---------------------------------------------------------------------------
391# Macro seqan_setup_library ()
392#
393# * Creates install targets for the library.
394# * Writes list SeqAn headers to ${_SEQAN_HEADERS}
395# ---------------------------------------------------------------------------
396
397macro (seqan_setup_library)
398    # Only install the library if the virtual build packages "SEQAN_RELEASE"
399    # or "SEQAN_LIBRARY_ONLY" are chosen.
400    if (("${SEQAN_BUILD_SYSTEM}" STREQUAL "SEQAN_RELEASE_LIBRARY"))
401
402        # Install SeqAn LICENSE, README.rst, CHANGELOG.rst files.
403        install (FILES LICENSE
404                       README.rst
405                       CHANGELOG.rst
406                 DESTINATION ${CMAKE_INSTALL_DOCDIR})
407        # Install pkg-config file, except on Windows.
408        if (NOT CMAKE_SYSTEM_NAME MATCHES Windows)
409            configure_file("util/pkgconfig/seqan.pc.in" "${CMAKE_BINARY_DIR}/util/pkgconfig/seqan-${SEQAN_VERSION_MAJOR}.pc" @ONLY)
410            install(FILES "${CMAKE_BINARY_DIR}/util/pkgconfig/seqan-${SEQAN_VERSION_MAJOR}.pc" DESTINATION ${CMAKE_INSTALL_DATAROOTDIR}/pkgconfig)
411        endif (NOT CMAKE_SYSTEM_NAME MATCHES Windows)
412        # Install FindSeqAn TODO(h-2) rename seqan-config.cmake to seqan-config${SEQAN_VERSION_MAJOR}.cmake after 2.x cycle
413        install(FILES "${CMAKE_CURRENT_SOURCE_DIR}/util/cmake/seqan-config.cmake" DESTINATION ${CMAKE_INSTALL_DATAROOTDIR}/cmake/seqan/)
414
415        # Install headers
416        file (GLOB HEADERS
417              RELATIVE ${CMAKE_CURRENT_SOURCE_DIR}/include/
418              include/seqan/[A-z]*/[A-z]/[A-z]*.h
419              include/seqan/[A-z]*/[A-z]*.h
420              include/seqan/[A-z]*.h)
421        foreach (HEADER ${HEADERS})
422            get_filename_component (_DESTINATION ${HEADER} PATH)
423            install (FILES ${CMAKE_CURRENT_SOURCE_DIR}/include/${HEADER} DESTINATION ${CMAKE_INSTALL_INCLUDEDIR}/${_DESTINATION})
424        endforeach ()
425    endif ()
426
427    # Get list of header and super header files.
428    file (GLOB SUPER_HEADERS ${CMAKE_CURRENT_SOURCE_DIR}/include/seqan/[A-z]*.h)
429    file (GLOB HEADERS ${CMAKE_CURRENT_SOURCE_DIR}/include/seqan/[A-z]*/[A-z]*.h)
430    file (GLOB SUB_HEADERS ${CMAKE_CURRENT_SOURCE_DIR}/include/seqan/[A-z]*/[A-z]*/[A-z]*.h)
431
432    # Sort headers for Xcode, ...
433    if (SUB_HEADERS)
434        list (SORT SUB_HEADERS)
435    endif (SUB_HEADERS)
436
437    # Sort headers for Xcode, ...
438    if (HEADERS)
439        list (SORT HEADERS)
440    endif (HEADERS)
441
442    # Sort super-headers for Xcode, ...
443    if (SUPER_HEADERS)
444        list (SORT SUPER_HEADERS)
445    endif (SUPER_HEADERS)
446
447    # Create source groups for Visual Studio (and possibly other IDEs).
448    foreach (HEADER ${HEADERS})
449        file (RELATIVE_PATH HEADER_REL ${CMAKE_CURRENT_SOURCE_DIR}/include/seqan ${HEADER})
450        get_filename_component (MODULE ${HEADER_REL} PATH)
451        source_group (seqan\\${MODULE} FILES ${HEADER})
452    endforeach (HEADER ${HEADERS})
453    source_group (seqan FILES ${SUPER_HEADERS})
454
455#    # CMake bug workaround: For Non-IDE generators there is a bug in cmake.
456#    # The SOURCE command in add_custom_target is not recognized there.
457#    set (NONIDE_GENERATORS "Unix Makefiles" "MinGW Makefiles")
458#    list (FIND NONIDE_GENERATORS ${CMAKE_GENERATOR} FOUND)
459#    if (FOUND EQUAL -1)
460#        set (IDE_SOURCES SOURCES ${HEADERS} ${SUPER_HEADERS})
461#    endif (FOUND EQUAL -1)
462
463    # Add pseudo target for the library part.  Note that the IDE_SOURCES
464    # variable includes the "SOURCES" argument for add_custom_target when
465    # building with a generator for an IDE.
466    add_custom_target (seqan_library SOURCES ${SUB_HEADERS} ${HEADERS} ${SUPER_HEADERS})
467endmacro (seqan_setup_library)
468
469# ---------------------------------------------------------------------------
470# Macro seqan_setup_install_vars (APP_NAME)
471#
472# Setup variables for install, depending on build mode.
473# ---------------------------------------------------------------------------
474
475macro (seqan_setup_install_vars APP_NAME)
476    if ("${SEQAN_BUILD_SYSTEM}" STREQUAL "APP:${APP_NAME}")
477        set (SEQAN_PREFIX_SHARE ".")
478        set (SEQAN_PREFIX_SHARE_DOC ".")
479    else ()
480        if (NOT DEFINED CMAKE_INSTALL_DOCDIR_IS_SET)
481            set (CMAKE_INSTALL_DOCDIR "${CMAKE_INSTALL_DATAROOTDIR}/doc" CACHE STRING "Documentation root (DATAROOTDIR/doc)" FORCE)
482        endif ()
483        set (SEQAN_PREFIX_SHARE "${CMAKE_INSTALL_DATADIR}/${APP_NAME}")
484        set (SEQAN_PREFIX_SHARE_DOC "${CMAKE_INSTALL_DOCDIR}/${APP_NAME}")
485    endif ()
486endmacro (seqan_setup_install_vars)
487
488# ---------------------------------------------------------------------------
489# Macro seqan_install_required_system_libraries ()
490#
491# When packaging apps copy needed dlls
492# ---------------------------------------------------------------------------
493
494macro(INTEL_FILES_FOR_VERSION version)
495  # version can be 2016
496  set(v "${version}")
497
498  # set intel architecture
499  if (CMAKE_MSVC_ARCH STREQUAL "x64")
500    set(CMAKE_INTEL_ARCH "intel64")
501  else ()
502    set(CMAKE_INTEL_ARCH "ia32")
503  endif()
504
505  # Find the runtime library redistribution directory.
506  set(programfilesx86 "ProgramFiles(x86)")
507  find_path(INTEL${v}_REDIST_DIR NAMES ${CMAKE_INTEL_ARCH}/compiler
508    PATHS
509      "$ENV{ProgramFiles}/IntelSWTools/compilers_and_libraries_${v}/windows/redist"
510      "$ENV{${programfilesx86}}/IntelSWTools/compilers_and_libraries_${v}/windows/redist"
511    )
512  mark_as_advanced(INTEL${v}_REDIST_DIR)
513  set(INTEL${v}_FILES_DIR "${INTEL${v}_REDIST_DIR}/${CMAKE_INTEL_ARCH}/compiler")
514
515  if(NOT CMAKE_INSTALL_DEBUG_LIBRARIES_ONLY)
516    set(__install__libs
517      "${INTEL${v}_FILES_DIR}/libmmd.dll"
518      )
519
520    if(CMAKE_INSTALL_OPENMP_LIBRARIES)
521      set(__install__libs ${__install__libs}
522        "${INTEL${v}_FILES_DIR}/libiomp5md.dll"
523        )
524    endif()
525  else()
526    set(__install__libs)
527  endif()
528
529  if(CMAKE_INSTALL_DEBUG_LIBRARIES)
530    set(__install__libs ${__install__libs}
531      "${INTEL${v}_FILES_DIR}/libmmdd.dll"
532      )
533  endif()
534
535  foreach(lib
536      ${__install__libs}
537      )
538    if(EXISTS ${lib})
539      set(CMAKE_INSTALL_SYSTEM_RUNTIME_LIBS
540        ${CMAKE_INSTALL_SYSTEM_RUNTIME_LIBS} ${lib})
541    else()
542      if(NOT CMAKE_INSTALL_SYSTEM_RUNTIME_LIBS_NO_WARNINGS)
543        message(WARNING "system runtime library file does not exist: '${lib}'")
544        # This warning indicates an incomplete Visual Studio installation
545        # or a bug somewhere above here in this file.
546        # If you would like to avoid this warning, fix the real problem, or
547        # set CMAKE_INSTALL_SYSTEM_RUNTIME_LIBS_NO_WARNINGS before including
548        # this file.
549      endif()
550    endif()
551  endforeach()
552endmacro()
553
554# TODO: Remove once we have cmake > 3.10.x installed on windows clients, as it should be found automatically.
555macro (seqan_install_required_system_libraries)
556  set (CMAKE_INSTALL_OPENMP_LIBRARIES ${OPENMP_FOUND})
557
558  # include intel dll's
559  if(COMPILER_WINTEL)
560    foreach (wintel_version 2018 2017 2016)
561        INTEL_FILES_FOR_VERSION(wintel_version)
562        if (INTEL${wintel_version}_REDIST_DIR)
563            break()
564        endif ()
565    endforeach ()
566  endif()
567
568  # The following include automates the MS Redistributable installer.
569  set (CMAKE_INSTALL_UCRT_LIBRARIES TRUE)
570  include (InstallRequiredSystemLibraries)
571endmacro()
572
573# ---------------------------------------------------------------------------
574# Macro seqan_configure_cpack_app (APP_NAME APP_DIR)
575#
576# Setup variables for install, depending on build mode.
577#
578# Sets defaults for CPACK_PACKAGE_DESCRIPTION_FILE and CPACK_RESOURCE_FILE_LICENSE
579# ---------------------------------------------------------------------------
580
581macro (seqan_configure_cpack_app APP_NAME APP_DIR)
582  seqan_install_required_system_libraries()
583
584  if (CMAKE_SYSTEM_NAME MATCHES "Windows")
585    set(CPACK_GENERATOR "ZIP;WIX")
586    file(STRINGS "${CMAKE_CURRENT_SOURCE_DIR}/LICENSE" license)
587    file(WRITE "${CMAKE_BINARY_DIR}/apps/${APP_DIR}/LICENSE.txt" "${license}")
588    set (CPACK_RESOURCE_FILE_LICENSE  "${CMAKE_BINARY_DIR}/apps/${APP_DIR}/LICENSE.txt")
589  elseif (CMAKE_SYSTEM_NAME MATCHES "Darwin")
590    set(CPACK_GENERATOR "ZIP;DragNDrop")
591  elseif (CMAKE_VERSION VERSION_LESS "3.1") # TXZ support since 3.1
592    set(CPACK_GENERATOR "TBZ2")
593  else()
594    set(CPACK_GENERATOR "TXZ")
595  endif ()
596
597  if (CMAKE_SYSTEM_NAME MATCHES "Linux")
598    set(CPACK_GENERATOR "${CPACK_GENERATOR};DEB;RPM")
599  endif ()
600
601  # Set defaults for CPACK_PACKAGE_DESCRIPTION_FILE and CPACK_RESOURCE_FILE_LICENSE
602  if (NOT CPACK_PACKAGE_DESCRIPTION_FILE)
603    set (CPACK_PACKAGE_DESCRIPTION_FILE "${CMAKE_CURRENT_SOURCE_DIR}/README")
604  endif ()
605  if (NOT CPACK_RESOURCE_FILE_LICENSE)
606    set (CPACK_RESOURCE_FILE_LICENSE "${CMAKE_CURRENT_SOURCE_DIR}/LICENSE")
607  endif ()
608
609  # Automatically deduce system name for CPack.
610  include (SetCPackSystemName)
611
612  # Get SEQAN_APP_VERSION_{MAJOR,MINOR,PATCH} from SEQAN_APP_VERSION.
613  set (SEQAN_APP_VERSION_MAJOR "0")
614  if (SEQAN_APP_VERSION MATCHES "^([0-9]+).*")
615    string (REGEX REPLACE "^([0-9]+).*" "\\1" _SEQAN_APP_VERSION_MAJOR "${SEQAN_APP_VERSION}")
616  endif ()
617  if (_SEQAN_APP_VERSION_MAJOR)
618    set(SEQAN_APP_VERSION_MAJOR "${_SEQAN_APP_VERSION_MAJOR}")
619  endif ()
620  set (SEQAN_APP_VERSION_MINOR "0")
621  if (SEQAN_APP_VERSION MATCHES "^[0-9]+\\.([0-9]+).*")
622    string (REGEX REPLACE "^[0-9]+\\.([0-9]+).*" "\\1" _SEQAN_APP_VERSION_MINOR "${SEQAN_APP_VERSION}")
623  endif ()
624  if (_SEQAN_APP_VERSION_MINOR)
625    set(SEQAN_APP_VERSION_MINOR "${_SEQAN_APP_VERSION_MINOR}")
626  endif ()
627  set (SEQAN_APP_VERSION_PATCH "0")
628  if (SEQAN_APP_VERSION MATCHES "^[0-9]+\\.[0-9]+\\.([0-9]+)$")
629    string (REGEX REPLACE "^[0-9]+\\.[0-9]+\\.([0-9]+)$" "\\1" _SEQAN_APP_VERSION_PATCH "${SEQAN_APP_VERSION}")
630  endif ()
631  if (_SEQAN_APP_VERSION_PATCH)
632    set(SEQAN_APP_VERSION_PATCH "${_SEQAN_APP_VERSION_PATCH}")
633  endif ()
634
635  # Setup the app version.  SEQAN_APP_VERSION_{MAJOR,MINOR,PATCH} have
636  # to be set.  To create nightly releases, set SEQAN_NIGHTLY_RELEASE to
637  # TRUE on the command line.
638  if (SEQAN_NIGHTLY_RELEASE)
639    include (GetCurrentDate)
640    set (CPACK_PACKAGE_VERSION "${CURRENT_YEAR}${CURRENT_MONTH}${CURRENT_DAY}")
641  else ()
642    set (CPACK_PACKAGE_VERSION "${SEQAN_APP_VERSION_MAJOR}.${SEQAN_APP_VERSION_MINOR}.${SEQAN_APP_VERSION_PATCH}")
643  endif ()
644  set (CPACK_PACKAGE_VERSION_MAJOR "${SEQAN_APP_VERSION_MAJOR}")
645  set (CPACK_PACKAGE_VERSION_MINOR "${SEQAN_APP_VERSION_MINOR}")
646  set (CPACK_PACKAGE_VERSION_PATCH "${SEQAN_APP_VERSION_PATCH}")
647
648  set (CPACK_PACKAGE_INSTALL_DIRECTORY "${APP_DIR} ${CPACK_PACKAGE_VERSION}")
649
650  include (CPack)
651endmacro (seqan_configure_cpack_app)
652
653
654# ---------------------------------------------------------------------------
655# Function seqan_get_version()
656#
657# Sets the variables SEQAN_VERSION, SEQAN_VERSION_MAJOR, SEQAN_VERSION_MINOR,
658# SEQAN_VERSION_PATCH, determined from seqan/version.h
659# ---------------------------------------------------------------------------
660
661macro (seqan_get_version)
662  # Read from CMAKE_SOURCE_DIR the /include/seqan/version.h
663  get_filename_component(_SEQAN_VERSION_H "${CMAKE_SOURCE_DIR}/include/seqan/version.h" ABSOLUTE)
664  # If file wasn't found seqan version is set to 0.0.0
665  set (_SEQAN_VERSION_IDS MAJOR MINOR PATCH PRE_RELEASE)
666  foreach (_ID ${_SEQAN_VERSION_IDS})
667    set(_SEQAN_VERSION_${_ID} "0")
668  endforeach(_ID ${_SEQAN_VERSION_IDS})
669
670  # Error log if version.h not found, otherwise read version from
671  # version.h and cache it.
672  if (NOT EXISTS ${_SEQAN_VERSION_H})
673    message ("")
674    message ("ERROR: Could not determine SeqAn version.")
675    message ("Could not find file: ${_SEQAN_VERSION_H}")
676  else ()
677    foreach (_ID ${_SEQAN_VERSION_IDS})
678      file (STRINGS ${_SEQAN_VERSION_H} _VERSION_${_ID} REGEX ".*SEQAN_VERSION_${_ID}.*")
679      string (REGEX REPLACE ".*SEQAN_VERSION_${_ID}[ |\t]+([0-9a-zA-Z]+).*" "\\1" SEQAN_VERSION_${_ID} ${_VERSION_${_ID}})
680    endforeach(_ID ${_SEQAN_VERSION_IDS})
681  endif ()
682  set (SEQAN_VERSION_STRING "${SEQAN_VERSION_MAJOR}.${SEQAN_VERSION_MINOR}.${SEQAN_VERSION_PATCH}")
683endmacro (seqan_get_version)
684
685# ---------------------------------------------------------------------------
686# Function seqan_get_repository_info()
687#
688# Sets the variables SEQAN_DATE and SEQAN_REVISION determined from git.
689# ---------------------------------------------------------------------------
690
691macro (seqan_get_repository_info)
692  set (_SEQAN_GIT_DIR "${CMAKE_SOURCE_DIR}/.git")
693  message (STATUS "  Selected repository dir: ${CMAKE_SOURCE_DIR}")
694  # Get Git information.
695  if (EXISTS ${_SEQAN_GIT_DIR})
696    find_package (GitInfo QUIET)
697    if (GIT_FOUND)
698      GIT_WC_INFO (${CMAKE_SOURCE_DIR} _SEQAN)
699    endif ()
700  else ()
701    message(STATUS "No revision system found.")
702  endif ()
703
704  # Set SeqAn date of last commit.
705  if (_SEQAN_WC_LAST_CHANGED_DATE)
706    set (SEQAN_DATE "${_SEQAN_WC_LAST_CHANGED_DATE}")
707    # icc doesn't cope with spaces..
708    string(REPLACE " " "_" SEQAN_DATE "${SEQAN_DATE}")
709    message (STATUS "  Determined repository date is ${SEQAN_DATE}")
710  else ()
711    message (STATUS "  Repository date not determined.")
712  endif ()
713
714  # Set SeqAn repository revision.
715  if (_SEQAN_WC_REVISION)
716    set (SEQAN_REVISION "${_SEQAN_WC_REVISION}" CACHE INTERNAL "SeqAn repository revision.")
717    message (STATUS "  Determined repository revision is ${SEQAN_REVISION}")
718   else ()
719    set (SEQAN_REVISION "tarball" CACHE INTERNAL "SeqAn repository revision.")
720    message (STATUS "  Repository revision not determined.")
721  endif ()
722endmacro (seqan_get_repository_info)
723
724# ---------------------------------------------------------------------------
725# Macro _seqan_setup_demo_test(cpp_file executable)
726#
727# When called with the file PATH.cpp, it will check whether PATH.cpp.stdout
728# and/or PATH.cpp.stderr exists.  If this is the case then we will add a test
729# that runs the demo and compares the standard output/error stream with the
730# given file.
731#
732# Used in seqan_build_demos_develop().
733# ---------------------------------------------------------------------------
734macro (_seqan_setup_demo_test CPP_FILE EXECUTABLE)
735    set (STDOUT_PATH "${CMAKE_CURRENT_SOURCE_DIR}/${CPP_FILE}.stdout")
736    set (STDERR_PATH "${CMAKE_CURRENT_SOURCE_DIR}/${CPP_FILE}.stderr")
737    if (EXISTS "${STDOUT_PATH}" OR EXISTS "${STDERR_PATH}")
738        # Build the path to the demo_checker.py script.
739        set (CHECKER_PATH "${CMAKE_SOURCE_DIR}/util/bin/demo_checker.py")
740
741        # Compose arguments to the demo_checker.py script.
742        if (MSVC)
743            # Add buildtype path and ".exe" suffix under Windows.
744            set (ARGS "--binary-path" "${CMAKE_RUNTIME_OUTPUT_DIRECTORY}/${CMAKE_BUILD_TYPE}/${EXECUTABLE}.exe")
745        elseif (WIN32)
746          # Add ".exe" suffix for all other Windows compilers, e.g. MinGW.
747            set (ARGS "--binary-path" "${CMAKE_RUNTIME_OUTPUT_DIRECTORY}/${EXECUTABLE}.exe")
748        else ()
749            set (ARGS "--binary-path" "${CMAKE_RUNTIME_OUTPUT_DIRECTORY}/${EXECUTABLE}")
750        endif ()
751
752        if (EXISTS "${STDOUT_PATH}")
753            set (ARGS ${ARGS} "--stdout-path" "${STDOUT_PATH}")
754        endif ()
755        if (EXISTS "${STDERR_PATH}")
756            set (ARGS ${ARGS} "--stderr-path" "${STDERR_PATH}")
757        endif()
758
759        # Add the test.
760        find_package (PythonInterp)
761        if (PYTHONINTERP_FOUND)
762          add_test (NAME test_${EXECUTABLE}
763                    COMMAND ${PYTHON_EXECUTABLE} ${CHECKER_PATH} ${ARGS})
764          #message(STATUS "add_test (NAME test_${EXECUTABLE} COMMAND ${PYTHON_EXECUTABLE} ${CHECKER_PATH} ${ARGS})")
765        endif (PYTHONINTERP_FOUND)
766    endif ()
767endmacro (_seqan_setup_demo_test CPP_FILE)
768
769# ---------------------------------------------------------------------------
770# Macro seqan_register_demos([prefix])
771#
772# Use this in demos directories and subdirectories.
773#
774# This is only used when doing a Whole SeqAn Release or when developing.
775# When doing a SeqAn Release then we copy over the demos, otherwise we build
776# them.
777# ---------------------------------------------------------------------------
778
779function (seqan_register_demos PREFIX)
780    # Get a list of all .cpp and .cu files in the current directory.
781    file (GLOB_RECURSE ENTRIES
782          RELATIVE ${CMAKE_CURRENT_SOURCE_DIR}
783          ${CMAKE_CURRENT_SOURCE_DIR}/[!.]*.cpp
784          ${CMAKE_CURRENT_SOURCE_DIR}/[!.]*.cu)
785
786    # NOTE(h-2): we do not need to search for dependencies, because this is
787    # done globally for DEVELOP (and demos are only built with DEVELOP)
788
789    # Supress unused parameter warnings for demos.
790    if (COMPILER_GCC OR COMPILER_CLANG)
791        set (SEQAN_CXX_FLAGS "${SEQAN_CXX_FLAGS} -Wno-unused-parameter")
792    endif (COMPILER_GCC OR COMPILER_CLANG)
793
794    # Add SeqAn flags to CXX and NVCC flags.
795    # Set to PARENT_SCOPE since this macro is executed from within a function which declares it's own scope.
796    set (CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} ${SEQAN_CXX_FLAGS}" PARENT_SCOPE)
797    # Setup include directories and definitions for SeqAn; flags follow below.
798    include_directories (${SEQAN_INCLUDE_DIRS})
799    # Disable version check for demos.
800    set (SEQAN_DEFINITIONS ${SEQAN_DEFINITIONS} -DSEQAN_DISABLE_VERSION_CHECK)
801    add_definitions (${SEQAN_DEFINITIONS})
802
803    # Disable the version check for all demos.
804
805    # Add all demos with found flags in SeqAn.
806    foreach (ENTRY ${ENTRIES})
807        set (SKIP FALSE)
808        # workaround a bug in llvm35 on FreeBSD
809        if ((ENTRY MATCHES "zip") AND
810            (${CMAKE_SYSTEM_NAME} STREQUAL "FreeBSD") AND
811            (COMPILER_CLANG) AND
812            (NOT CMAKE_CXX_COMPILER_VERSION VERSION_LESS 3.5.0) AND
813            (CMAKE_CXX_COMPILER_VERSION VERSION_LESS 3.6.0))
814            set (SKIP TRUE)
815        # bug in visual studio
816        elseif ((ENTRY MATCHES "queue_example.cpp") AND COMPILER_MSVC)
817            set (SKIP TRUE)
818        # all demos/* that require ZLIB[_FOUND]
819        elseif (NOT ZLIB_FOUND)
820            if ((ENTRY MATCHES "tabix_io/tabix_vcf.cpp") OR
821                (ENTRY MATCHES "sam_and_bam_io/example7.cpp") OR
822                (ENTRY MATCHES "unassigned_or_unused/bamutil.cpp"))
823                set (SKIP TRUE)
824            endif()
825        endif ()
826
827        if (SKIP)
828            message(STATUS "${ENTRY} skipped on this platform." )
829        else (SKIP)
830            string (REPLACE "/" "_" BIN_NAME "${ENTRY}")
831            string (REPLACE "\\" "_" BIN_NAME "${BIN_NAME}")
832            get_filename_component (BIN_NAME "${BIN_NAME}" NAME_WE)
833
834            get_filename_component (FILE_NAME "${ENTRY}" NAME)
835            add_executable(${PREFIX}${BIN_NAME} ${ENTRY})
836            target_link_libraries (${PREFIX}${BIN_NAME} ${SEQAN_LIBRARIES})
837            _seqan_setup_demo_test (${ENTRY} ${PREFIX}${BIN_NAME})
838        endif (SKIP)
839    endforeach (ENTRY ${ENTRIES})
840endfunction (seqan_register_demos)
841
842# ---------------------------------------------------------------------------
843# Macro seqan_register_tests ()
844# ---------------------------------------------------------------------------
845
846# Switch to testing mode and include all subdirectories with a CMakeLists.txt
847# file inside them.  This function should be called in the CMakeLists.txt in
848# the tests directories before including subdirectories.
849#
850# The following will happen:
851#
852# * Setting definitions SEQAN_ENABLE_DEBUG=1 and SEQAN_ENABLE_TESTING=1.
853# * If the ${MODEL} variable is NightlyCoverage OR ExperimentalCoverage,
854#   and the compiler is GCC C++ then symbols for test coverate are added.
855# * All subdirectories with a CMakeLists.txt file inside will be added.
856
857macro (seqan_register_tests)
858    # Setup flags for tests.
859    set (SEQAN_DEFINITIONS ${SEQAN_DEFINITIONS} -DSEQAN_ENABLE_TESTING=1 -DSEQAN_DISABLE_VERSION_CHECK)
860
861    # Remove NDEBUG definition for tests.
862    string (REGEX REPLACE "-DNDEBUG" ""
863            CMAKE_CXX_FLAGS_RELWITHDEBINFO "${CMAKE_CXX_FLAGS_RELWITHDEBINFO}")
864    string (REGEX REPLACE "-DNDEBUG" ""
865            CMAKE_CXX_FLAGS_RELEASE "${CMAKE_CXX_FLAGS_RELEASE}")
866
867    # Conditionally enable coverage mode by setting the appropriate flags.
868    if (MODEL STREQUAL "NightlyCoverage")
869        if (COMPILER_GCC OR COMPILER_CLANG)
870            set (CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -fprofile-arcs -ftest-coverage")
871            set (LDFLAGS "${LDFLAGS} -fprofile-arcs -ftest-coverage")
872        endif (COMPILER_GCC OR COMPILER_CLANG)
873    endif (MODEL STREQUAL "NightlyCoverage")
874    if (MODEL STREQUAL "ExperimentalCoverage")
875        if (COMPILER_GCC OR COMPILER_CLANG)
876            set (CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -fprofile-arcs -ftest-coverage")
877            set (LDFLAGS "${LDFLAGS} -fprofile-arcs -ftest-coverage")
878        endif (COMPILER_GCC OR COMPILER_CLANG)
879    endif (MODEL STREQUAL "ExperimentalCoverage")
880
881    # Add all subdirectories that have a CMakeLists.txt inside them.
882    file (GLOB ENTRIES
883          RELATIVE ${CMAKE_CURRENT_SOURCE_DIR}
884          ${CMAKE_CURRENT_SOURCE_DIR}/[!.]*)
885    foreach (ENTRY ${ENTRIES})
886        if (IS_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR}/${ENTRY})
887            if (EXISTS ${CMAKE_CURRENT_SOURCE_DIR}/${ENTRY}/CMakeLists.txt)
888                add_subdirectory(${ENTRY})
889            endif (EXISTS ${CMAKE_CURRENT_SOURCE_DIR}/${ENTRY}/CMakeLists.txt)
890        endif (IS_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR}/${ENTRY})
891    endforeach (ENTRY ${ENTRIES})
892endmacro (seqan_register_tests)
893