Medical Imaging Interaction Toolkit  2016.11.0
Medical Imaging Interaction Toolkit
usFunctionEmbedResources.cmake
Go to the documentation of this file.
1 #! \ingroup MicroServicesCMake
2 #! \brief Embed resources in a library or executable.
3 #!
4 #! This CMake function uses an external command line program to generate a ZIP archive
5 #! containing data from external resources such as text files or images or other ZIP
6 #! archives. The created archive file is appended or embedded as a binary blob to the target file.
7 #!
8 #! \note To set-up correct file dependencies from your module target to your resource
9 #! files, you have to add a special source file to the source list of the target.
10 #! The source file name can be retrieved by using usFunctionGetResourceSoruce.
11 #! This ensures that changed resource files will automatically be re-added to the
12 #! module.
13 #!
14 #! There are two differend modes for including resources: APPEND and LINK. In APPEND mode,
15 #! the generated zip file is appended at the end of the target file. In LINK mode, the
16 #! zip file is compiled / linked into the target using platform specific techniques. LINK
17 #! mode is necessary if certain tools make additional assumptions about the object layout
18 #! of the target file (e.g. codesign on MacOS). LINK mode may result in slower module
19 #! initialization and bigger object files. The default mode is LINK mode on MacOS and
20 #! APPEND mode on all other platforms.
21 #!
22 #! Example usage:
23 #! \code{.cmake}
24 #! set(module_srcs )
25 #! usFunctionEmbedResources(TARGET mylib
26 #! MODULE_NAME org_me_mylib
27 #! FILES config.properties logo.png
28 #! )
29 #! \endcode
30 #!
31 #! \param TARGET (required) The target to which the resource files are added.
32 #! \param MODULE_NAME (required/optional) The module name of the target, as specified in
33 #! the \c US_MODULE_NAME pre-processor definition of that target. This parameter
34 #! is optional if a target property with the name US_MODULE_NAME exists, containing
35 #! the required module name.
36 #! \param APPEND Append the resources zip file to the target file.
37 #! \param LINK Link (embed) the resources zip file if possible.
38 #!
39 #! For the WORKING_DIRECTORY, COMPRESSION_LEVEL, FILES, ZIP_ARCHIVES parameters see the
40 #! documentation of the usFunctionAddResources macro which is called with these parameters if set.
41 #!
42 #! \sa usFunctionAddResources
43 #! \sa usFunctionGetResourceSource
44 #! \sa \ref MicroServices_Resources
45 #!
47 
48  cmake_parse_arguments(US_RESOURCE "APPEND;LINK" "TARGET;MODULE_NAME;WORKING_DIRECTORY;COMPRESSION_LEVEL" "FILES;ZIP_ARCHIVES" ${ARGN})
49 
50  if(NOT US_RESOURCE_TARGET)
51  message(SEND_ERROR "TARGET argument not specified.")
52  endif()
53 
54  if(US_RESOURCE_FILES OR US_RESOURCE_ZIP_ARCHIVES)
55  usFunctionAddResources(TARGET ${US_RESOURCE_TARGET}
56  MODULE_NAME ${US_RESOURCE_MODULE_NAME}
57  WORKING_DIRECTORY ${US_RESOURCE_WORKING_DIRECTORY}
58  COMPRESSION_LEVEL ${US_RESOURCE_COMPRESSION_LEVEL}
59  FILES ${US_RESOURCE_FILES}
60  ZIP_ARCHIVES ${US_RESOURCE_ZIP_ARCHIVES}
61  )
62  endif()
63 
64  get_target_property(_res_zips ${US_RESOURCE_TARGET} _us_resource_zips)
65  if(NOT _res_zips)
66  return()
67  endif()
68 
69  if(US_RESOURCE_APPEND AND US_RESOURCE_LINK)
70  message(WARNING "Both APPEND and LINK options specified. Falling back to default behaviour.")
71  set(US_RESOURCE_APPEND 0)
72  set(US_RESOURCE_LINK 0)
73  endif()
74 
75  if(US_RESOURCE_LINK AND NOT US_RESOURCE_LINKING_AVAILABLE)
76  message(WARNING "Resource linking not available. Falling back to APPEND mode.")
77  set(US_RESOURCE_LINK 0)
78  set(US_RESOURCE_APPEND 1)
79  endif()
80 
81  # Set default resource mode
82  if(NOT US_RESOURCE_APPEND AND NOT US_RESOURCE_LINK)
83  if(US_DEFAULT_RESOURCE_MODE STREQUAL "LINK")
84  set(US_RESOURCE_LINK 1)
85  else()
86  set(US_RESOURCE_APPEND 1)
87  endif()
88  endif()
89 
90  set(_mode )
91  if(US_RESOURCE_LINK)
92  set(_mode LINK)
93  elseif(US_RESOURCE_APPEND)
94  set(_mode APPEND)
95  endif()
96  usFunctionGetResourceSource(TARGET ${US_RESOURCE_TARGET} OUT _source_output ${_mode})
97 
98  if(NOT US_RESOURCE_WORKING_DIRECTORY)
99  set(US_RESOURCE_WORKING_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR})
100  endif()
101  if(NOT IS_ABSOLUTE ${US_RESOURCE_WORKING_DIRECTORY})
102  set(US_RESOURCE_WORKING_DIRECTORY "${CMAKE_CURRENT_SOURCE_DIR}/${US_RESOURCE_WORKING_DIRECTORY}")
103  endif()
104 
105  set(resource_compiler ${US_RCC_EXECUTABLE})
106  if(TARGET ${US_RCC_EXECUTABLE_NAME})
107  set(resource_compiler ${US_RCC_EXECUTABLE_NAME})
108  elseif(NOT resource_compiler)
109  message(FATAL_ERROR "The CppMicroServices resource compiler was not found. Check the US_RCC_EXECUTABLE CMake variable.")
110  endif()
111 
112  set(_zip_archive )
113  get_target_property(_counter ${US_RESOURCE_TARGET} _us_resource_counter)
114  if(_counter EQUAL 0)
115  set(_zip_archive ${_res_zips})
116  else()
117  set(_zip_archive ${CMAKE_CURRENT_BINARY_DIR}/us_${US_RESOURCE_TARGET}/res.zip)
118  add_custom_command(
119  OUTPUT ${_zip_archive}
120  COMMAND ${resource_compiler} ${_zip_archive} dummy -m ${_res_zips}
121  DEPENDS ${_res_zips} ${resource_compiler}
122  COMMENT "Creating resources zip file for ${US_RESOURCE_TARGET}"
123  VERBATIM
124  )
125  endif()
126  get_filename_component(_zip_archive_name ${_zip_archive} NAME)
127  get_filename_component(_zip_archive_path ${_zip_archive} PATH)
128 
129  if(US_RESOURCE_LINK)
130  if(APPLE)
131  add_custom_command(
132  OUTPUT ${_source_output}
133  COMMAND ${CMAKE_CXX_COMPILER} -c ${US_CMAKE_RESOURCE_DEPENDENCIES_CPP} -o stub.o
134  COMMAND ${CMAKE_LINKER} -r -sectcreate __TEXT us_resources ${_zip_archive_name} stub.o -o ${_source_output}
135  DEPENDS ${_zip_archive}
136  WORKING_DIRECTORY ${_zip_archive_path}
137  COMMENT "Linking resources zip file for ${US_RESOURCE_TARGET}"
138  VERBATIM
139  )
140  set_source_files_properties(${_source_output} PROPERTIES EXTERNAL_OBJECT 1 GENERATED 1)
141  elseif(WIN32 AND CMAKE_RC_COMPILER)
142  set(US_RESOURCE_ARCHIVE ${_zip_archive})
143  configure_file(${US_RESOURCE_RC_TEMPLATE} ${_source_output})
144  add_custom_command(
145  OUTPUT ${_source_output}
146  COMMAND ${CMAKE_COMMAND} -E touch ${_source_output}
147  DEPENDS ${_zip_archive}
148  WORKING_DIRECTORY ${_zip_archive_path}
149  COMMENT "Linking resources zip file for ${US_RESOURCE_TARGET}"
150  VERBATIM
151  )
152  elseif(UNIX)
153  add_custom_command(
154  OUTPUT ${_source_output}
155  COMMAND ${CMAKE_LINKER} -r -b binary -o ${_source_output} ${_zip_archive_name}
156  COMMAND objcopy --rename-section .data=.rodata,alloc,load,readonly,data,contents ${_source_output} ${_source_output}
157  DEPENDS ${_zip_archive}
158  WORKING_DIRECTORY ${_zip_archive_path}
159  COMMENT "Linking resources zip file for ${US_RESOURCE_TARGET}"
160  VERBATIM
161  )
162  set_source_files_properties(${_source_output} PROPERTIES EXTERNAL_OBJECT 1 GENERATED 1)
163  else()
164  message(WARNING "Internal error: Resource linking not available. Falling back to APPEND mode.")
165  set(US_RESOURCE_LINK 0)
166  set(US_RESOURCE_APPEND 1)
167  endif()
168  endif()
169 
170  if(US_RESOURCE_APPEND)
171  # This command depends on the given resource files and creates a source
172  # file which must be added to the source list of the related target.
173  # This way, the following command is executed if the resources change
174  # and it just touches the created source file to force a (actually unnecessary)
175  # re-linking and hence the execution of POST_BUILD commands.
176  add_custom_command(
177  OUTPUT ${_source_output}
178  COMMAND ${CMAKE_COMMAND} -E copy ${US_CMAKE_RESOURCE_DEPENDENCIES_CPP} ${_source_output}
179  DEPENDS ${_zip_archive}
180  COMMENT "Checking resource dependencies for ${US_RESOURCE_TARGET}"
181  VERBATIM
182  )
183 
184  add_custom_command(
185  TARGET ${US_RESOURCE_TARGET}
186  POST_BUILD
187  COMMAND ${resource_compiler} --append $<TARGET_FILE:${US_RESOURCE_TARGET}> ${_zip_archive}
188  WORKING_DIRECTORY ${US_RESOURCE_WORKING_DIRECTORY}
189  COMMENT "Appending zipped resources to ${US_RESOURCE_TARGET}"
190  VERBATIM
191  )
192  endif()
193 
194 endfunction()
usFunctionAddResources()
Add resources to a library or executable.
section MAP_FRAME_Mapper_Settings Mapper settings For the mapping of corrected you have several settings available
usFunctionEmbedResources()
Embed resources in a library or executable.
const std::string NAME
usFunctionGetResourceSource()
Get a source file name for handling resource dependencies.
const std::string LINK
const std::string TARGET