forked from CESM-Development/CMake_Fortran_utils
-
Notifications
You must be signed in to change notification settings - Fork 0
/
Sourcelist_utils.cmake
134 lines (114 loc) · 4.96 KB
/
Sourcelist_utils.cmake
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
# Utility functions to work with accumulated lists of sources.
#
#==========================================================================
#
# sourcelist_to_parent
#
# Arguments:
# source_list_name - Name of list to send.
#
# Expands relative paths to absolute locations in the source list, then
# copies the value of the list to the list with the same name in the parent
# scope.
#
#==========================================================================
#
# extract_sources
#
# Arguments:
# sources_needed - Base names of sources required for a target.
# all_sources - Absolute locations of available source files.
# source_list_name - Absolute locations of sources to build the target.
#
# Scans through a list of all source files, selects files with the
# requested names, and *appends* them to an output list. If there is more
# than one file with the same name, the *last* match is selected.
#
# This allows you to simulate Makefile idioms that choose from multiple
# versions of a file, based on the order in which they are encountered.
#
#==========================================================================
#
# declare_generated_dependencies.
#
# Arguments:
# target - The target that needs to depend on generated files.
# generated_list - The generated source code files the target requires.
#
# Ensures that generated sources in a different directory are produced
# before compiling and linking the target. This is done by assuming that
# each generated source file corresponds to an existing target. For
# instance, a file called "foo.F90" would be generated by a target called
# "generate_foo". The input target can then be made to depend on each of
# the "generate" targets.
#
# This is unnecessary when source code generation occurs in the directory
# where the target was added. However, CMake does not propagate information
# about source code generation to parent directories, so the intermediate
# "generate" targets must be created to enforce generation in the correct
# order.
#
#==========================================================================
#==========================================================================
# Copyright (c) 2013-2014, University Corporation for Atmospheric Research
#
# This software is distributed under a two-clause BSD license, with no
# warranties, express or implied. See the accompanying LICENSE file for
# details.
#==========================================================================
# For each relative path in ${file_list}, prepend ${base_directory} to make
# an absolute path, and put result in list named by ${new_list_name}.
function(expand_relative_paths file_list base_directory new_list_name)
unset(${new_list_name})
foreach(file IN LISTS file_list)
if(IS_ABSOLUTE "${file}")
set(new_file "${file}")
else()
set(new_file "${base_directory}/${file}")
endif()
list(APPEND ${new_list_name} "${new_file}")
endforeach()
set(${new_list_name} "${${new_list_name}}" PARENT_SCOPE)
endfunction(expand_relative_paths)
# Expand relative paths in a named source list, and export to parent scope.
# The idea here is to communicate the list between a directory added with
# add_subdirectory, and the directory above it.
macro(sourcelist_to_parent source_list_name)
expand_relative_paths("${${source_list_name}}"
${CMAKE_CURRENT_SOURCE_DIR} ${source_list_name})
set(${source_list_name} "${${source_list_name}}" PARENT_SCOPE)
endmacro(sourcelist_to_parent)
# Find an absolute file path in ${all_sources} for each base name in
# ${sources_needed}, and append found paths to the list named by
# ${source_list_name}.
function(extract_sources sources_needed all_sources source_list_name)
foreach(needed_source IN LISTS sources_needed)
set(source_match source-NOTFOUND)
foreach(source IN LISTS all_sources)
get_filename_component(basename ${source} NAME)
if(${basename} STREQUAL ${needed_source})
set(source_match ${source})
endif()
endforeach()
if(NOT source_match)
message(FATAL_ERROR
"Source file not found: ${needed_source}
After searching in list: ${${all_sources}}")
endif()
list(APPEND ${source_list_name} ${source_match})
endforeach()
set(${source_list_name} "${${source_list_name}}" PARENT_SCOPE)
endfunction(extract_sources)
# Handles dependencies between files generated in one directory and a
# target in another.
# Given a target and a list of files, sets the GENERATED property for each
# file, and makes the target depend on a custom target generated from the
# extensionless base file name. (E.g. for /path/to/foo.F90, it will assume
# that it is generated by a custom target called generate_foo).
function(declare_generated_dependencies target generated_list)
foreach(file IN LISTS generated_list)
set_source_files_properties(${file} PROPERTIES GENERATED 1)
get_filename_component(stripped_name ${file} NAME_WE)
add_dependencies(${target} generate_${stripped_name})
endforeach()
endfunction(declare_generated_dependencies)