From c3663076dc93b7df7ea66c048a97260a7c875ad9 Mon Sep 17 00:00:00 2001 From: Alexandru Croitor Date: Fri, 24 May 2019 19:19:51 +0200 Subject: [PATCH] Fix syncqt call and injected file forwarding and add comments about it The location of the forwarding headers when not yet installed, depends on whether we do a prefix or non prefix build. In a prefix build the /include folder should be in the current repo build dir. In a non prefix build, it should be under qtbase/include. But the actual generated files to which the forwarding headers point, are always in the current repo build directory. Also syncqt needs to know both the current repo build directory specified by -builddir, and the output directory specified by -outdir. In a prefix build, both are the same. In a non-prefix build, builddir should be the current repo build dir, and outddir should be qtbase's build dir. Also for non-qtbase repo build directories (like declarative), examples need to have the current_repo_build_dir/include directory as an include path, so that framework style includes like #include work correctly. Take care of all that, and add a bunch of comments explaining the whole injected / generated headers interaction. Change-Id: I612ad7549ce499c4979ee994e998b558716d45ca Reviewed-by: Qt CMake Build Bot Reviewed-by: Alexandru Croitor --- cmake/QtBuild.cmake | 50 ++++++++++++++++++++++++++++++++++++++------- 1 file changed, 43 insertions(+), 7 deletions(-) diff --git a/cmake/QtBuild.cmake b/cmake/QtBuild.cmake index acdeaaca95..41e33f3857 100644 --- a/cmake/QtBuild.cmake +++ b/cmake/QtBuild.cmake @@ -695,41 +695,68 @@ function(qt_install_injections module build_dir install_dir) # examples: # SYNCQT.INJECTIONS = src/corelib/global/qconfig.h:qconfig.h:QtConfig src/corelib/global/qconfig_p.h:5.12.0/QtCore/private/qconfig_p.h # SYNCQT.INJECTIONS = src/gui/vulkan/qvulkanfunctions.h:^qvulkanfunctions.h:QVulkanFunctions:QVulkanDeviceFunctions src/gui/vulkan/qvulkanfunctions_p.h:^5.12.0/QtGui/private/qvulkanfunctions_p.h + # The are 3 parts to the assignment, divded by colons ':'. + # The first part contains a path to a generated file in a build folder. + # The second part contains the file name that the forwarding header should have, which points + # to the file in the first part. + # The third part contains multiple UpperCaseFileNames that should be forwarding headers to the + # header specified in the second part. separate_arguments(injections UNIX_COMMAND "${injections}") foreach(injection ${injections}) string(REPLACE ":" ";" injection ${injection}) + # Part 1. list(GET injection 0 file) + # Part 2. list(GET injection 1 destination) string(REGEX REPLACE "^\\^" "" destination "${destination}") list(REMOVE_AT injection 0 1) + # Part 3. set(fwd_hdrs ${injection}) get_filename_component(destinationdir ${destination} DIRECTORY) get_filename_component(destinationname ${destination} NAME) get_filename_component(original_file_name ${file} NAME) - # Generate lower case forwarding header located in include/${module}, - # which points to the injected (generated) file, for example qconfig.h. + # This describes a concrete example for easier comprehension: + # A file 'qtqml-config.h' is generated by qt_internal_feature_write_file into + # ${qtdeclarative_build_dir}/src/{module}/qtqml-config.h (part 1). + # + # Generate a lower case forwarding header (part 2) 'qtqml-config.h' at the following + # location: + # ${some_prefix}/include/${module}/qtqml-config.h. + # + # Inside this file, we #include the originally generated file, + # ${qtdeclarative_build_dir}/src/{module}/qtqml-config.h. + # + # ${some_prefix}'s value depends on the build type. + # If doing a prefix build, it should point to + # ${current_repo_build_dir} which is ${qtdeclarative_build_dir}. + # If doing a non-prefix build, it should point to + # ${qtbase_build_dir}. + # + # In the code below, ${some_prefix} == ${build_dir}. set(lower_case_forwarding_header_path "${build_dir}/${INSTALL_INCLUDEDIR}/${module}") if(destinationdir) string(APPEND lower_case_forwarding_header_path "/${destinationdir}") endif() + set(current_repo_build_dir "${PROJECT_BINARY_DIR}") file(RELATIVE_PATH relpath "${lower_case_forwarding_header_path}" - "${build_dir}/${file}") + "${current_repo_build_dir}/${file}") set(main_contents "#include \"${relpath}\"") file(GENERATE OUTPUT "${lower_case_forwarding_header_path}/${original_file_name}" CONTENT "${main_contents}") # Copy the actual injected (generated) header file (not the just created forwarding one) - # to its install location. + # to its install location when doing a prefix build. In an non-prefix build, the qt_install + # will be a no-op. qt_path_join(install_destination ${install_dir} ${INSTALL_INCLUDEDIR} ${module} ${destinationdir}) - qt_install(FILES ${build_dir}/${file} + qt_install(FILES ${current_repo_build_dir}/${file} DESTINATION ${install_destination} RENAME ${destinationname} OPTIONAL) - # Generate upper case forwarding headers. + # Generate UpperCaseNamed forwarding headers (part 3). foreach(fwd_hdr ${fwd_hdrs}) set(upper_case_forwarding_header_path "${INSTALL_INCLUDEDIR}/${module}") if(destinationdir) @@ -843,7 +870,15 @@ function(add_qt_module target) # So we either write the generated files into the qtbase non-prefix build root, or the # module specific build root. qt_ensure_sync_qt() - execute_process(COMMAND "${HOST_PERL}" -w "${QT_SYNCQT}" -quiet -module "${module}" -version "${PROJECT_VERSION}" -outdir "${QT_BUILD_DIR}" "${PROJECT_SOURCE_DIR}") + set(syncqt_full_command "${HOST_PERL}" -w "${QT_SYNCQT}" + -quiet + -check-includes + -module "${module}" + -version "${PROJECT_VERSION}" + -outdir "${QT_BUILD_DIR}" + -builddir "${PROJECT_BINARY_DIR}" + "${PROJECT_SOURCE_DIR}") + execute_process(COMMAND ${syncqt_full_command}) set_target_properties("${target}" PROPERTIES MODULE_HAS_HEADERS ON) @@ -869,6 +904,7 @@ function(add_qt_module target) extend_target("${target}" SOURCES ${arg_SOURCES} PUBLIC_INCLUDE_DIRECTORIES + $ $ $ ${arg_PUBLIC_INCLUDE_DIRECTORIES}