File: DuneSymlinkOrCopy.cmake

package info (click to toggle)
dune-common 2.9.0-2
  • links: PTS, VCS
  • area: main
  • in suites: bookworm
  • size: 5,112 kB
  • sloc: cpp: 44,714; python: 3,480; sh: 1,590; makefile: 17
file content (211 lines) | stat: -rw-r--r-- 7,217 bytes parent folder | download
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
# SPDX-FileCopyrightInfo: Copyright (C) DUNE Project contributors, see file LICENSE.md in module root
# SPDX-License-Identifier: LicenseRef-GPL-2.0-only-with-DUNE-exception

# This module provides convenience macros to provide files from the source tree in the build tree.
#
# It provides the following macros:
#
#   dune_add_copy_command(filename)
#
# This macro adds a file-copy command.
# The file_name is the name of a file that exists
# in the source tree. This file will be copied
# to the build tree when executing this command.
# Notice that this does not create a top-level
# target. In order to do this you have to additionally
# call add_custom_target(...) with dependency
# on the file.
#
#   dune_add_copy_target(target_name file_name)
#
# This macro adds a file-copy target under given target_name.
# The file_name is the name of a file that exists
# in the source tree. This file will be copied
# to the build tree.
#
#   dune_add_copy_dependency(target file_name)
#
# This macro adds a copy-dependency to a target
# The file_name is the name of a file that exists
# in the source tree. This file will be copied
# to the build tree.
#
#
# .. cmake_function:: dune_add_copy_command
#
#    .. cmake_param:: filename
#       :positional:
#       :single:
#       :required:
#
#    TODO DOC ME!
#
# .. cmake_function:: dune_add_copy_target
#
#    .. cmake_param:: target_name
#       :positional:
#       :single:
#       :required:
#
#    .. cmake_param:: filename
#       :positional:
#       :single:
#       :required:
#
#    TODO DOC ME!
#
# .. cmake_function:: dune_add_copy_dependency
#
#    .. cmake_param:: target
#       :positional:
#       :single:
#       :required:
#
#    .. cmake_param:: filename
#       :positional:
#       :single:
#       :required:
#
#    TODO DOC ME!
#
# .. cmake_function:: dune_symlink_to_source_tree
#
#    .. cmake_param:: NAME
#       :single:
#
#       The name of the symlink, defaults to :code:`src_dir`.
#
#    This function will place a symlink into every subdirectory
#    of the build tree, that allows to jump to the corresponding
#    source directory. Call this from your top-level :code:`CMakeLists.txt`
#    to enable it for a given module. To enable it for all modules,
#    set the variable :ref:`DUNE_SYMLINK_TO_SOURCE_TREE` instead.
#    If used on Windows systems, a warning is issued.
#
# .. cmake_variable:: DUNE_SYMLINK_TO_SOURCE_TREE
#
#    If this variable is set to TRUE, the functionality of
#    :ref:`dune_symlink_to_source_tree` is enabled in all modules.
#    This will place symlinks to the corresponding source directory
#    in every subdirectory of the build directory.
#
# .. cmake_variable:: DUNE_SYMLINK_RELATIVE_LINKS
#
#    If this variable is set to TRUE, the buildsystem will create relative
#    links instead of absolute ones.
#
# .. cmake_function:: dune_symlink_to_source_files
#
#    .. cmake_param:: FILES
#       :multi:
#       :required:
#
#       The list of files to symlink
#
#    .. cmake_param:: DESTINATION
#       :multi:
#       :required:
#
#       Relative path of the target directory
#
#    Create symlinks in the build tree that
#    point to particular files in the source directory. This is usually
#    used for grid and ini files and the like. On Windows systems,
#    a warning is issued and copying is used as a fallback to
#    symlinking.
#
include_guard(GLOBAL)

macro(dune_add_copy_command file_name)
    add_custom_command(
        OUTPUT "${CMAKE_CURRENT_BINARY_DIR}/${file_name}"
        COMMAND    ${CMAKE_COMMAND}
        ARGS       -E copy "${CMAKE_CURRENT_SOURCE_DIR}/${file_name}" "${file_name}"
        DEPENDS "${CMAKE_CURRENT_SOURCE_DIR}/${file_name}"
        )
endmacro(dune_add_copy_command file_name)

macro(dune_add_copy_target target_name file_name)
    dune_add_copy_command(${file_name})
    add_custom_target("${target_name}" ALL DEPENDS "${file_name}")
endmacro(dune_add_copy_target target_name file_name)

macro(dune_add_copy_dependency target file_name)
    message(STATUS "Adding copy-to-build-dir dependency for ${file_name} to target ${target}")
    dune_add_copy_target("${target}_copy_${file_name}" "${file_name}")
    add_dependencies(${target} "${target}_copy_${file_name}")
endmacro(dune_add_copy_dependency)

function(dune_symlink_to_source_tree)
  # if source and binary dir are equal then the symlink will create serious problems
  if(PROJECT_SOURCE_DIR STREQUAL PROJECT_BINARY_DIR)
    return()
  endif()

  # parse arguments
  cmake_parse_arguments(ARG "" "NAME" "" ${ARGN})
  if(NOT ARG_NAME)
    set(ARG_NAME "src_dir")
  endif()

  # check for Windows to issue a warning
  if(${CMAKE_SYSTEM_NAME} STREQUAL "Windows")
    if(NOT DEFINED DUNE_WINDOWS_SYMLINK_WARNING)
      message(WARNING "Your module wanted to create symlinks, but you cannot do that on your platform.")
      set(DUNE_WINDOWS_SYMLINK_WARNING)
    endif()
  else()
    # get a list of all files in the current source directory and below.
    file(GLOB_RECURSE files RELATIVE ${PROJECT_SOURCE_DIR} "*CMakeLists.txt")

    # iterate over all files, extract the directory name and write a symlink in the corresponding build directory
    foreach(f ${files})
      get_filename_component(dir ${f} DIRECTORY)
      set(_target "${PROJECT_SOURCE_DIR}/${dir}")
      if(DUNE_SYMLINK_RELATIVE_LINKS)
        file(RELATIVE_PATH _target "${PROJECT_BINARY_DIR}/${dir}" "${_target}")
      endif()
      execute_process(COMMAND ${CMAKE_COMMAND} "-E" "create_symlink" "${_target}" "${PROJECT_BINARY_DIR}/${dir}/${ARG_NAME}")
    endforeach()
  endif()
endfunction(dune_symlink_to_source_tree)

function(dune_symlink_to_source_files)

  # if source and binary dir are equal then the symlink will create serious problems
  if(PROJECT_SOURCE_DIR STREQUAL PROJECT_BINARY_DIR)
    return()
  endif()

  # parse arguments
  cmake_parse_arguments(ARG "" "DESTINATION" "FILES" ${ARGN})
  if(ARG_UNPARSED_ARGUMENTS)
    message(WARNING "You are using dune_symlink_to_source_files without named arguments (or have typos in your named arguments)!")
  endif()

  # create symlinks for all given files
  foreach(f ${ARG_FILES})
    # check whether there is an explicitly given destination
    if(ARG_DESTINATION)
      set(destination "${ARG_DESTINATION}/")
    else()
      set(destination "")
    endif()
    # check for Windows to issue a warning
    if(${CMAKE_SYSTEM_NAME} STREQUAL "Windows")
      if(NOT DEFINED DUNE_WINDOWS_SYMLINK_WARNING)
        message(WARNING "Your module wanted to create symlinks, but you cannot do that on your platform.")
        set(DUNE_WINDOWS_SYMLINK_WARNING)
      endif()
      # create a copy
      execute_process(COMMAND ${CMAKE_COMMAND} "-E" "copy" "${CMAKE_CURRENT_SOURCE_DIR}/${f}" "${CMAKE_CURRENT_BINARY_DIR}/${destination}${f}")
    else()
      # create symlink
      set(_target "${CMAKE_CURRENT_SOURCE_DIR}/${f}")
      if(DUNE_SYMLINK_RELATIVE_LINKS)
       file(RELATIVE_PATH _target "${CMAKE_CURRENT_BINARY_DIR}/${destination}" "${_target}")
      endif()
      execute_process(COMMAND ${CMAKE_COMMAND} "-E" "create_symlink" "${_target}" "${CMAKE_CURRENT_BINARY_DIR}/${destination}${f}")
    endif()
  endforeach()
endfunction(dune_symlink_to_source_files)