2019-08-19 14:19:08 +00:00
#
# All things resource related
#
function ( __qt_get_relative_resource_path_for_file output_alias file )
get_property ( alias SOURCE ${ file } PROPERTY QT_RESOURCE_ALIAS )
if ( NOT alias )
set ( alias "${file}" )
endif ( )
set ( ${ output_alias } ${ alias } PARENT_SCOPE )
endfunction ( )
function ( __qt_propagate_generated_resource target resource_name generated_source_code output_generated_target )
get_target_property ( type ${ target } TYPE )
if ( type STREQUAL STATIC_LIBRARY )
set ( resource_target "${target}_resources_${resourceName}" )
add_library ( "${resource_target}" OBJECT "${generated_source_code}" )
2019-08-29 15:57:04 +00:00
# Use TARGET_NAME genex to map to the correct prefixed target name when it is exported
# via qt_install(EXPORT), so that the consumers of the target can find the object library
# as well.
target_link_libraries ( ${ target } INTERFACE
" $ < T A R G E T _ O B J E C T S : $ < T A R G E T _ N A M E : $ { r e s o u r c e _ t a r g e t } > > " )
2019-08-19 14:19:08 +00:00
set ( ${ output_generated_target } "${resource_target}" PARENT_SCOPE )
else ( )
set ( ${ output_generated_target } "" PARENT_SCOPE )
target_sources ( ${ target } PRIVATE ${ generated_source_code } )
endif ( )
endfunction ( )
2019-11-13 13:03:20 +00:00
# Inspect all files passed to a call to qt_add_resource. If there are any
2019-08-19 14:19:08 +00:00
# files present, invoke the quick compiler and return the remaining resource
2019-08-30 13:06:34 +00:00
# files that have not been processed in OUTPUT_REMAINING_RESOURCES as well as the new
2019-08-19 14:19:08 +00:00
# name for the resource in OUTPUT_RESOURCE_NAME.
function ( __qt_quick_compiler_process_resources target resource_name )
cmake_parse_arguments ( arg
" " " P R E F I X ; O U T P U T _ R E M A I N I N G _ R E S O U R C E S ; O U T P U T _ R E S O U R C E _ N A M E ; O U T P U T _ G E N E R A T E D _ T A R G E T " " F I L E S " $ { A R G N }
)
set ( qml_files )
set ( resource_files )
set ( retained_files )
# scan for qml files
foreach ( file IN LISTS arg_FILES )
# check whether this resource should not be processed by the qt quick
# compiler
get_source_file_property ( skip_compiler_check ${ file } QT_SKIP_QUICKCOMPILER )
get_source_file_property ( retain_compiler_check ${ file } QT_RETAIN_QUICKCOMPILER )
if ( skip_compiler_check )
list ( APPEND resource_files ${ file } )
continue ( )
endif ( )
if ( ${ file } MATCHES "\.js$"
O R $ { f i l e } M A T C H E S " \ . m j s $ "
O R $ { f i l e } M A T C H E S " \ . q m l $ " )
list ( APPEND qml_files ${ file } )
if ( retain_compiler_check )
list ( APPEND retained_files ${ file } )
list ( APPEND resource_files ${ file } )
endif ( )
else ( )
list ( APPEND resource_files ${ file } )
endif ( )
endforeach ( )
if ( NOT TARGET @QT_CMAKE_EXPORT_NAMESPACE@::qmlcachegen AND qml_files )
message ( WARNING "QT@PROJECT_VERSION_MAJOR@_PROCESS_RESOURCE: Qml files were detected but the qmlcachgen target is not defined. Consider adding QmlTools to your find_package command." )
endif ( )
set ( retained_resource_paths )
if ( TARGET @QT_CMAKE_EXPORT_NAMESPACE@::qmlcachegen AND qml_files )
# Enable qt quick compiler support
2019-09-19 10:53:32 +00:00
set ( qml_resource_file "${CMAKE_CURRENT_BINARY_DIR}/.rcc/${resource_name}.qrc" )
2019-08-19 14:19:08 +00:00
if ( resource_files )
set ( chained_resource_name "${resource_name}_qmlcache" )
endif ( )
foreach ( file IN LISTS qml_files )
get_filename_component ( file_absolute ${ file } ABSOLUTE )
file ( RELATIVE_PATH file_relative ${ CMAKE_CURRENT_SOURCE_DIR } ${ file_absolute } )
__qt_get_relative_resource_path_for_file ( file_resource_path ${ file } )
if ( arg_PREFIX STREQUAL "/" )
# TO_CMAKE_PATH does not clean up cases such as //Foo
set ( file_resource_path "/${file_resource_path}" )
else ( )
set ( file_resource_path "${arg_PREFIX}/${file_resource_path}" )
endif ( )
if ( file IN_LIST retained_files )
list ( APPEND retained_resource_paths ${ file_resource_path } )
endif ( )
file ( TO_CMAKE_PATH ${ file_resource_path } file_resource_path )
list ( APPEND file_resource_paths ${ file_resource_path } )
string ( REGEX REPLACE "\.js$" "_js" compiled_file ${ file_relative } )
string ( REGEX REPLACE "\.mjs$" "_mjs" compiled_file ${ compiled_file } )
string ( REGEX REPLACE "\.qml$" "_qml" compiled_file ${ compiled_file } )
2019-08-22 13:41:10 +00:00
string ( REGEX REPLACE "[\$#\?]+" "_" compiled_file ${ compiled_file } )
2019-09-19 10:53:32 +00:00
set ( compiled_file "${CMAKE_CURRENT_BINARY_DIR}/.rcc/qmlcache/${resource_name}/${compiled_file}.cpp" )
2019-10-04 12:58:10 +00:00
get_filename_component ( out_dir ${ compiled_file } DIRECTORY )
if ( NOT EXISTS ${ out_dir } )
file ( MAKE_DIRECTORY ${ out_dir } )
endif ( )
2019-08-19 14:19:08 +00:00
add_custom_command (
O U T P U T $ { c o m p i l e d _ f i l e }
2019-09-04 13:47:11 +00:00
D E P E N D S $ { f i l e _ a b s o l u t e }
$ { Q T _ T O O L _ P A T H _ S E T U P _ C O M M A N D }
2019-08-19 14:19:08 +00:00
C O M M A N D
2019-09-04 13:47:11 +00:00
@ Q T _ C M A K E _ E X P O R T _ N A M E S P A C E @ : : q m l c a c h e g e n
2019-08-19 14:19:08 +00:00
- - r e s o u r c e - p a t h $ { f i l e _ r e s o u r c e _ p a t h }
- o $ { c o m p i l e d _ f i l e }
$ { f i l e _ a b s o l u t e }
)
target_sources ( ${ target } PRIVATE ${ compiled_file } )
endforeach ( )
2019-09-19 10:53:32 +00:00
set ( qmlcache_loader_list "${CMAKE_CURRENT_BINARY_DIR}/.rcc/qmlcache/${resource_name}/qml_loader_file_list.rsp" )
2019-08-19 14:19:08 +00:00
file ( GENERATE
O U T P U T $ { q m l c a c h e _ l o a d e r _ l i s t }
C O N T E N T " $ < J O I N : $ { f i l e _ r e s o u r c e _ p a t h s } , \ n > "
)
2019-09-19 10:53:32 +00:00
set ( qmlcache_loader_file "${CMAKE_CURRENT_BINARY_DIR}/.rcc/qmlcache/${resource_name}/qmlcache_loader.cpp" )
2019-08-19 14:19:08 +00:00
set ( resource_name_arg "${resource_name}.qrc" )
if ( chained_resource_name )
set ( resource_name_arg "${resource_name_arg}=${chained_resource_name}" )
endif ( )
if ( retained_resource_paths )
2019-09-19 10:53:32 +00:00
set ( retained_loader_list "${CMAKE_CURRENT_BINARY_DIR}/.rcc/qmlcache/${resource_name}/retained_file_list.rsp" )
2019-08-19 14:19:08 +00:00
file ( GENERATE
O U T P U T $ { r e t a i n e d _ l o a d e r _ l i s t }
C O N T E N T " $ < J O I N : $ { r e t a i n e d _ r e s o u r c e _ p a t h s } , \ n > "
)
set ( retained_args "--retain" "@${retained_loader_list}" )
endif ( )
add_custom_command (
O U T P U T $ { q m l c a c h e _ l o a d e r _ f i l e }
2019-09-04 13:47:11 +00:00
D E P E N D S $ { q m l c a c h e _ l o a d e r _ l i s t }
$ { Q T _ T O O L _ P A T H _ S E T U P _ C O M M A N D }
2019-08-19 14:19:08 +00:00
C O M M A N D
2019-09-04 13:47:11 +00:00
@ Q T _ C M A K E _ E X P O R T _ N A M E S P A C E @ : : q m l c a c h e g e n
2019-08-19 14:19:08 +00:00
$ { r e t a i n e d _ a r g s }
- - r e s o u r c e - n a m e " $ { r e s o u r c e _ n a m e _ a r g } "
- o $ { q m l c a c h e _ l o a d e r _ f i l e }
" @ $ { q m l c a c h e _ l o a d e r _ l i s t } "
)
__qt_propagate_generated_resource ( ${ target }
$ { r e s o u r c e _ n a m e }
$ { q m l c a c h e _ l o a d e r _ f i l e }
o u t p u t _ t a r g e t )
set ( ${ arg_OUTPUT_GENERATED_TARGET } "${output_target}" PARENT_SCOPE )
if ( resource_files )
set ( resource_name ${ chained_resource_name } )
endif ( )
2019-08-30 13:06:34 +00:00
# The generated qmlcache_loader source file uses private headers of Qml, so make sure
# if the object library was created, it depends on the Qml target. If there's no target,
# that means the target is a shared library and the sources are directly added to the target
# via target_sources, so add dependency in that case as well.
set ( chosen_target "target" ) # shared library case
if ( output_target )
set ( chosen_target "output_target" ) # static library case.
endif ( )
target_link_libraries ( ${ ${chosen_target } } PRIVATE @QT_CMAKE_EXPORT_NAMESPACE@::Qml )
2019-08-19 14:19:08 +00:00
else ( )
set ( resource_files ${ arg_FILES } )
endif ( )
set ( ${ arg_OUTPUT_REMAINING_RESOURCES } ${ resource_files } PARENT_SCOPE )
set ( ${ arg_OUTPUT_RESOURCE_NAME } ${ resource_name } PARENT_SCOPE )
endfunction ( )
#
# Process resources via file path instead of QRC files. Behind the
# scnenes, it will generate a qrc file and apply post processing steps
# when applicable. (e.g.: QtQuickCompiler)
#
# The QRC Prefix is set via the PREFIX parameter.
#
# Alias settings for files need to be set via the QT_RESOURCE_ALIAS property
# via the set_soure_files_properties() command.
#
2019-09-16 07:49:40 +00:00
# When using this command with static libraries, one or more special targets
# will be generated. Should you wish to perform additional processing on these
# targets pass a value to the OUTPUT_TARGETS parameter.
2019-08-19 14:19:08 +00:00
#
function ( QT@PROJECT_VERSION_MAJOR@_PROCESS_RESOURCE target resourceName )
2019-09-20 08:44:22 +00:00
cmake_parse_arguments ( rcc "" "PREFIX;LANG;BASE;OUTPUT_TARGETS" "FILES;OPTIONS" ${ ARGN } )
2019-08-19 14:19:08 +00:00
string ( REPLACE "/" "_" resourceName ${ resourceName } )
string ( REPLACE "." "_" resourceName ${ resourceName } )
2019-09-16 07:49:40 +00:00
set ( output_targets "" )
2019-08-19 14:19:08 +00:00
# Apply base to all files
if ( rcc_BASE )
foreach ( file IN LISTS rcc_FILES )
set ( resource_file "${rcc_BASE}/${file}" )
__qt_get_relative_resource_path_for_file ( alias ${ resource_file } )
# Handle case where resources were generated from a directory
# different than the one where the main .pro file resides.
# Unless otherwise specified, we should use the original file path
# as alias.
if ( alias STREQUAL resource_file )
set_source_files_properties ( ${ resource_file } PROPERTIES QT_RESOURCE_ALIAS ${ file } )
endif ( )
file ( TO_CMAKE_PATH ${ resource_file } resource_file )
list ( APPEND resource_files ${ resource_file } )
endforeach ( )
else ( )
set ( resource_files ${ rcc_FILES } )
endif ( )
if ( NOT rcc_PREFIX )
get_target_property ( rcc_PREFIX ${ target } QT_RESOURCE_PREFIX )
if ( NOT rcc_PREFIX )
message ( FATAL_ERROR "QT@PROJECT_VERSION_MAJOR@_PROCESS_RESOURCE() was called without a PREFIX and the target does not provide QT_RESOURCE_PREFIX. Please either add a PREFIX or make the target ${target} provide a default." )
endif ( )
endif ( )
# Apply quick compiler pass
__qt_quick_compiler_process_resources ( ${ target } ${ resourceName }
F I L E S $ { r e s o u r c e _ f i l e s }
P R E F I X $ { r c c _ P R E F I X }
O U T P U T _ R E M A I N I N G _ R E S O U R C E S r e s o u r c e s
O U T P U T _ R E S O U R C E _ N A M E n e w R e s o u r c e N a m e
2019-09-18 14:18:32 +00:00
O U T P U T _ G E N E R A T E D _ T A R G E T o u t p u t _ t a r g e t _ q u i c k
2019-08-19 14:19:08 +00:00
)
if ( NOT resources )
2019-09-16 07:49:40 +00:00
if ( rcc_OUTPUT_TARGETS )
2019-09-16 12:05:26 +00:00
set ( ${ rcc_OUTPUT_TARGETS } "${output_target_quick}" PARENT_SCOPE )
2019-08-30 13:06:34 +00:00
endif ( )
2019-08-19 14:19:08 +00:00
return ( )
endif ( )
2019-09-16 12:05:26 +00:00
list ( APPEND output_targets ${ output_target_quick } )
2019-09-19 10:53:32 +00:00
set ( generatedResourceFile "${CMAKE_CURRENT_BINARY_DIR}/.rcc/generated_${newResourceName}.qrc" )
set ( generatedSourceCode "${CMAKE_CURRENT_BINARY_DIR}/.rcc/qrc_${newResourceName}.cpp" )
2019-08-19 14:19:08 +00:00
# Generate .qrc file:
# <RCC><qresource ...>
set ( qrcContents "<RCC>\n <qresource" )
if ( rcc_PREFIX )
string ( APPEND qrcContents " prefix=\" ${ rcc_PREFIX } \"")
endif ( )
if ( rcc_LANG )
string ( APPEND qrcContents " lang=\" ${ rcc_LANG } \"")
endif ( )
string ( APPEND qrcContents ">\n" )
2019-10-15 12:01:48 +00:00
set ( resource_dependencies )
2019-08-19 14:19:08 +00:00
foreach ( file IN LISTS resources )
__qt_get_relative_resource_path_for_file ( file_resource_path ${ file } )
if ( NOT IS_ABSOLUTE ${ file } )
set ( file "${CMAKE_CURRENT_SOURCE_DIR}/${file}" )
endif ( )
### FIXME: escape file paths to be XML conform
# <file ...>...</file>
string ( APPEND qrcContents " <file alias=\" ${ file_resource_path } \">")
string ( APPEND qrcContents "${file}</file>\n" )
list ( APPEND files "${file}" )
2019-10-15 12:01:48 +00:00
get_source_file_property ( target_dependency ${ file } QT_RESOURCE_TARGET_DEPENDENCY )
if ( NOT target_dependency )
list ( APPEND resource_dependencies ${ file } )
else ( )
if ( NOT TARGET ${ target_dependency } )
message ( FATAL_ERROR "Target dependency on resource file ${file} is not a cmake target." )
endif ( )
list ( APPEND resource_dependencies ${ target_dependency } )
endif ( )
2019-08-19 14:19:08 +00:00
endforeach ( )
# </qresource></RCC>
string ( APPEND qrcContents " </qresource>\n</RCC>\n" )
file ( GENERATE OUTPUT "${generatedResourceFile}" CONTENT "${qrcContents}" )
2019-09-20 08:44:22 +00:00
set ( rccArgs --name "${newResourceName}"
- - o u t p u t " $ { g e n e r a t e d S o u r c e C o d e } " " $ { g e n e r a t e d R e s o u r c e F i l e } " )
if ( rcc_OPTIONS )
list ( APPEND rccArgs ${ rcc_OPTIONS } )
endif ( )
2019-08-19 14:19:08 +00:00
# Process .qrc file:
add_custom_command ( OUTPUT "${generatedSourceCode}"
C O M M A N D " @ Q T _ C M A K E _ E X P O R T _ N A M E S P A C E @ : : r c c "
2019-09-20 08:44:22 +00:00
A R G S $ { r c c A r g s }
2019-10-15 12:01:48 +00:00
D E P E N D S $ { r e s o u r c e _ d e p e n d e n c i e s } $ { g e n e r a t e d R e s o u r c e F i l e }
2019-08-19 14:19:08 +00:00
C O M M E N T " R C C $ { n e w R e s o u r c e N a m e } "
V E R B A T I M )
get_target_property ( type "${target}" TYPE )
# Only do this if newResourceName is the same as resourceName, since
# the resource will be chainloaded by the qt quickcompiler
# qml cache loader
if ( newResourceName STREQUAL resourceName )
__qt_propagate_generated_resource ( ${ target } ${ resourceName } "${generatedSourceCode}" output_target )
2019-09-16 07:49:40 +00:00
list ( APPEND output_targets ${ output_target } )
2019-08-19 14:19:08 +00:00
else ( )
target_sources ( ${ target } PRIVATE "${generatedSourceCode}" )
endif ( )
2019-09-16 07:49:40 +00:00
if ( rcc_OUTPUT_TARGETS )
set ( ${ rcc_OUTPUT_TARGETS } "${output_targets}" PARENT_SCOPE )
2019-08-19 14:19:08 +00:00
endif ( )
endfunction ( )