Medical Imaging Interaction Toolkit  2016.11.0
Medical Imaging Interaction Toolkit
All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Properties Friends Macros Modules Pages
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