1.. # Copyright (c) 2017-2019, Lawrence Livermore National Security, LLC and
2.. # other BLT Project Developers. See the top-level COPYRIGHT file for details
3.. #
4.. # SPDX-License-Identifier: (BSD-3-Clause)
5
6Utility Macros
7==============
8
9
10blt_assert_exists
11~~~~~~~~~~~~~~~~~~~
12
13.. code-block:: cmake
14
15    blt_assert_exists(
16      [DIRECTORIES <dir1> [<dir2> ...] ]
17      [FILES <file1> [<file2> ...] ]
18      [TARGETS <target1> [<target2> ...] ] )
19
20Checks if the specified directory, file and/or cmake target exists and throws
21an error message.
22
23.. note::
24
25   The behavior for checking if a given file or directory exists is well-defined
26   only for absolute paths.
27
28.. code-block:: cmake
29   :caption: **Example**
30   :linenos:
31
32   ## check if the directory 'blt' exists in the project
33   blt_assert_exists( DIRECTORIES ${PROJECT_SOURCE_DIR}/cmake/blt )
34
35   ## check if the file 'SetupBLT.cmake' file exists
36   blt_assert_exists( FILES ${PROJECT_SOURCE_DIR}/cmake/blt/SetupBLT.cmake )
37
38   ## checks can also be bundled in one call
39   blt_assert_exists( DIRECTORIES ${PROJECT_SOURCE_DIR}/cmake/blt
40                      FILES ${PROJECT_SOURCE_DIR}/cmake/blt/SetupBLT.cmake )
41
42   ## check if the CMake targets `foo` and `bar` exist
43   blt_assert_exists( TARGETS foo bar )
44
45
46blt_append_custom_compiler_flag
47~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
48
49.. code-block:: cmake
50
51    blt_append_custom_compiler_flag(
52                       FLAGS_VAR  flagsVar       (required)
53                       DEFAULT    defaultFlag    (optional)
54                       GNU        gnuFlag        (optional)
55                       CLANG      clangFlag      (optional)
56                       HCC        hccFlag        (optional)
57                       INTEL      intelFlag      (optional)
58                       XL         xlFlag         (optional)
59                       MSVC       msvcFlag       (optional)
60                       MSVC_INTEL msvcIntelFlag  (optional)
61                       PGI        pgiFlag        (optional)
62                       CRAY       crayFlag       (optional))
63
64Appends compiler-specific flags to a given variable of flags
65
66If a custom flag is given for the current compiler, we use that.
67Otherwise, we will use the DEFAULT flag (if present).
68
69If ENABLE_FORTRAN is On, any flagsVar with "fortran" (any capitalization)
70in its name will pick the compiler family (GNU,CLANG, INTEL, etc) based on
71the fortran compiler family type. This allows mixing C and Fortran compiler
72families, e.g. using Intel fortran compilers with clang C compilers.
73
74When using the Intel toolchain within visual studio, we use the
75MSVC_INTEL flag, when provided, with a fallback to the MSVC flag.
76
77
78blt_find_libraries
79~~~~~~~~~~~~~~~~~~
80
81.. code-block:: cmake
82
83    blt_find_libraries( FOUND_LIBS <FOUND_LIBS variable name>
84                        NAMES      [libname1 [libname2 ...]]
85                        REQUIRED   [TRUE (default) | FALSE ]
86                        PATHS      [path1 [path2 ...]])
87
88This command is used to find a list of libraries.
89
90If the libraries are found the results are appended to the given FOUND_LIBS variable name.
91NAMES lists the names of the libraries that will be searched for in the given PATHS.
92
93If REQUIRED is set to TRUE, BLT will produce an error message if any of the
94given libraries are not found.  The default value is TRUE.
95
96PATH lists the paths in which to search for NAMES. No system paths will be searched.
97
98
99blt_list_append
100~~~~~~~~~~~~~~~
101
102.. code-block:: cmake
103
104    blt_list_append(TO       <list>
105                    ELEMENTS [<element>...]
106                    IF       <bool>)
107
108Appends elements to a list if the specified bool evaluates to true.
109
110This macro is essentially a wrapper around CMake's ``list(APPEND ...)``
111command which allows inlining a conditional check within the same call
112for clarity and convenience.
113
114This macro requires specifying:
115
116    * The target list to append to by passing ``TO <list>``
117    * A condition to check by passing ``IF <bool>``
118    * The list of elements to append by passing ``ELEMENTS [<element>...]``
119
120Note, the argument passed to the IF option has to be a single boolean value
121and cannot be a boolean expression since CMake cannot evaluate those inline.
122
123.. code-block:: cmake
124    :caption: **Example**
125    :linenos:
126
127    set(mylist A B)
128
129    set(ENABLE_C TRUE)
130    blt_list_append( TO mylist ELEMENTS C IF ${ENABLE_C} ) # Appends 'C'
131
132    set(ENABLE_D TRUE)
133    blt_list_append( TO mylist ELEMENTS D IF ENABLE_D ) # Appends 'D'
134
135    set(ENABLE_E FALSE)
136    blt_list_append( TO mylist ELEMENTS E IF ENABLE_E ) # Does not append 'E'
137
138    unset(_undefined)
139    blt_list_append( TO mylist ELEMENTS F IF _undefined ) # Does not append 'F'
140
141
142blt_list_remove_duplicates
143~~~~~~~~~~~~~~~~~~~~~~~~~~
144
145.. code-block:: cmake
146
147    blt_list_remove_duplicates(TO <list>)
148
149Removes duplicate elements from the given TO list.
150
151This macro is essentially a wrapper around CMake's ``list(REMOVE_DUPLICATES ...)``
152command but doesn't throw an error if the list is empty or not defined.
153
154.. code-block:: cmake
155    :caption: **Example**
156    :linenos:
157
158    set(mylist A B A)
159    blt_list_remove_duplicates( TO mylist )
160
161