diff --git a/Help/manual/cmake-properties.7.rst b/Help/manual/cmake-properties.7.rst index 20970629f..d569e311a 100644 --- a/Help/manual/cmake-properties.7.rst +++ b/Help/manual/cmake-properties.7.rst @@ -141,6 +141,7 @@ Properties on Targets /prop_tgt/INSTALL_NAME_DIR /prop_tgt/INSTALL_RPATH /prop_tgt/INSTALL_RPATH_USE_LINK_PATH + /prop_tgt/INTERFACE_AUTOUIC_OPTIONS /prop_tgt/INTERFACE_COMPILE_DEFINITIONS /prop_tgt/INTERFACE_COMPILE_OPTIONS /prop_tgt/INTERFACE_INCLUDE_DIRECTORIES diff --git a/Help/prop_tgt/AUTOUIC_OPTIONS.rst b/Help/prop_tgt/AUTOUIC_OPTIONS.rst index c6cf885c5..aeec38baa 100644 --- a/Help/prop_tgt/AUTOUIC_OPTIONS.rst +++ b/Help/prop_tgt/AUTOUIC_OPTIONS.rst @@ -15,3 +15,7 @@ This property is initialized by the value of the variable The options set on the target may be overridden by :prop_sf:`AUTOUIC_OPTIONS` set on the .ui source file. + +This property may use "generator expressions" with the syntax "$<...>". +See the :manual:`cmake-generator-expressions(7)` manual for available +expressions. diff --git a/Help/prop_tgt/INTERFACE_AUTOUIC_OPTIONS.rst b/Help/prop_tgt/INTERFACE_AUTOUIC_OPTIONS.rst new file mode 100644 index 000000000..e97d29318 --- /dev/null +++ b/Help/prop_tgt/INTERFACE_AUTOUIC_OPTIONS.rst @@ -0,0 +1,14 @@ +INTERFACE_AUTOUIC_OPTIONS +------------------------- + +List of interface options to pass to uic. + +Targets may populate this property to publish the options +required to use when invoking ``uic``. Consuming targets can add entries to their +own :prop_tgt:`AUTOUIC_OPTIONS` property such as +``$`` to use the uic options +specified in the interface of ``foo``. This is done automatically by +the :command:`target_link_libraries` command. + +This property supports generator expressions. See the +:manual:`cmake-generator-expressions(7)` manual for available expressions. diff --git a/Help/variable/CMAKE_DEBUG_TARGET_PROPERTIES.rst b/Help/variable/CMAKE_DEBUG_TARGET_PROPERTIES.rst index 2ded823d0..6b17f6e69 100644 --- a/Help/variable/CMAKE_DEBUG_TARGET_PROPERTIES.rst +++ b/Help/variable/CMAKE_DEBUG_TARGET_PROPERTIES.rst @@ -6,6 +6,6 @@ Enables tracing output for target properties. This variable can be populated with a list of properties to generate debug output for when evaluating target properties. Currently it can only be used when evaluating the INCLUDE_DIRECTORIES, -COMPILE_DEFINITIONS and COMPILE_OPTIONS target properties. In that -case, it outputs a backtrace for each entry in the target property. +COMPILE_DEFINITIONS, COMPILE_OPTIONS and AUTOUIC_OPTIONS target properties. +In that case, it outputs a backtrace for each entry in the target property. Default is unset. diff --git a/Source/cmExportBuildFileGenerator.cxx b/Source/cmExportBuildFileGenerator.cxx index 50835e295..0d0d05bb6 100644 --- a/Source/cmExportBuildFileGenerator.cxx +++ b/Source/cmExportBuildFileGenerator.cxx @@ -77,6 +77,9 @@ bool cmExportBuildFileGenerator::GenerateMainFile(std::ostream& os) this->PopulateInterfaceProperty("INTERFACE_COMPILE_OPTIONS", te, cmGeneratorExpression::BuildInterface, properties, missingTargets); + this->PopulateInterfaceProperty("INTERFACE_AUTOUIC_OPTIONS", te, + cmGeneratorExpression::BuildInterface, + properties, missingTargets); this->PopulateInterfaceProperty("INTERFACE_POSITION_INDEPENDENT_CODE", te, properties); const bool newCMP0022Behavior = diff --git a/Source/cmExportInstallFileGenerator.cxx b/Source/cmExportInstallFileGenerator.cxx index ad17556a3..79e78df3d 100644 --- a/Source/cmExportInstallFileGenerator.cxx +++ b/Source/cmExportInstallFileGenerator.cxx @@ -140,6 +140,10 @@ bool cmExportInstallFileGenerator::GenerateMainFile(std::ostream& os) te, cmGeneratorExpression::InstallInterface, properties, missingTargets); + this->PopulateInterfaceProperty("INTERFACE_AUTOUIC_OPTIONS", + te, + cmGeneratorExpression::InstallInterface, + properties, missingTargets); const bool newCMP0022Behavior = te->GetPolicyStatusCMP0022() != cmPolicies::WARN diff --git a/Source/cmGeneratorExpressionDAGChecker.cxx b/Source/cmGeneratorExpressionDAGChecker.cxx index 7399c7bfa..92f74f373 100644 --- a/Source/cmGeneratorExpressionDAGChecker.cxx +++ b/Source/cmGeneratorExpressionDAGChecker.cxx @@ -210,3 +210,11 @@ bool cmGeneratorExpressionDAGChecker::EvaluatingCompileOptions() const return (strcmp(prop, "COMPILE_OPTIONS") == 0 || strcmp(prop, "INTERFACE_COMPILE_OPTIONS") == 0 ); } + +//---------------------------------------------------------------------------- +bool cmGeneratorExpressionDAGChecker::EvaluatingAutoUicOptions() const +{ + const char *prop = this->Property.c_str(); + return (strcmp(prop, "AUTOUIC_OPTIONS") == 0 + || strcmp(prop, "INTERFACE_AUTOUIC_OPTIONS") == 0 ); +} diff --git a/Source/cmGeneratorExpressionDAGChecker.h b/Source/cmGeneratorExpressionDAGChecker.h index c8594e773..fd47ad7a7 100644 --- a/Source/cmGeneratorExpressionDAGChecker.h +++ b/Source/cmGeneratorExpressionDAGChecker.h @@ -20,13 +20,15 @@ F(EvaluatingIncludeDirectories) \ F(EvaluatingSystemIncludeDirectories) \ F(EvaluatingCompileDefinitions) \ - F(EvaluatingCompileOptions) + F(EvaluatingCompileOptions) \ + F(EvaluatingAutoUicOptions) #define CM_FOR_EACH_TRANSITIVE_PROPERTY_NAME(F) \ F(INCLUDE_DIRECTORIES) \ F(SYSTEM_INCLUDE_DIRECTORIES) \ F(COMPILE_DEFINITIONS) \ - F(COMPILE_OPTIONS) + F(COMPILE_OPTIONS) \ + F(AUTOUIC_OPTIONS) //---------------------------------------------------------------------------- struct cmGeneratorExpressionDAGChecker diff --git a/Source/cmQtAutoGenerators.cxx b/Source/cmQtAutoGenerators.cxx index 576883fa0..835e3b4f4 100644 --- a/Source/cmQtAutoGenerators.cxx +++ b/Source/cmQtAutoGenerators.cxx @@ -365,6 +365,7 @@ void cmQtAutoGenerators::SetupAutoGenerateTarget(cmTarget* target) std::map configIncludes; std::map configDefines; + std::map configUicOptions; if (target->GetPropertyAsBool("AUTOMOC")) { @@ -373,7 +374,7 @@ void cmQtAutoGenerators::SetupAutoGenerateTarget(cmTarget* target) } if (target->GetPropertyAsBool("AUTOUIC")) { - this->SetupAutoUicTarget(target); + this->SetupAutoUicTarget(target, configUicOptions); } if (target->GetPropertyAsBool("AUTORCC")) { @@ -388,7 +389,9 @@ void cmQtAutoGenerators::SetupAutoGenerateTarget(cmTarget* target) makefile->ConfigureFile(inputFile.c_str(), outputFile.c_str(), false, true, false); - if (!configDefines.empty() || !configIncludes.empty()) + if (!configDefines.empty() + || !configIncludes.empty() + || !configUicOptions.empty()) { std::ofstream infoFile(outputFile.c_str(), std::ios::app); if ( !infoFile ) @@ -419,6 +422,16 @@ void cmQtAutoGenerators::SetupAutoGenerateTarget(cmTarget* target) " " << it->second << ")\n"; } } + if (!configUicOptions.empty()) + { + for (std::map::iterator + it = configUicOptions.begin(), end = configUicOptions.end(); + it != end; ++it) + { + infoFile << "set(AM_UIC_TARGET_OPTIONS_" << it->first << + " " << it->second << ")\n"; + } + } } } @@ -601,7 +614,25 @@ void cmQtAutoGenerators::MergeUicOptions(std::vector &opts, opts.insert(opts.end(), extraOpts.begin(), extraOpts.end()); } -void cmQtAutoGenerators::SetupAutoUicTarget(cmTarget* target) +static void GetUicOpts(cmTarget *target, const char * config, + std::string &optString) +{ + std::vector opts; + target->GetAutoUicOptions(opts, config); + + const char* sep = ""; + for(std::vector::const_iterator optIt = opts.begin(); + optIt != opts.end(); + ++optIt) + { + optString += sep; + sep = ";"; + optString += *optIt; + } +} + +void cmQtAutoGenerators::SetupAutoUicTarget(cmTarget* target, + std::map &configUicOptions) { cmMakefile *makefile = target->GetMakefile(); @@ -650,10 +681,30 @@ void cmQtAutoGenerators::SetupAutoUicTarget(cmTarget* target) const char *qtVersion = makefile->GetDefinition("_target_qt_version"); - if (const char* opts = target->GetProperty("AUTOUIC_OPTIONS")) + std::string _uic_opts; + std::vector configs; + const char *config = makefile->GetConfigurations(configs); + GetUicOpts(target, config, _uic_opts); + + if (!_uic_opts.empty()) { - makefile->AddDefinition("_uic_target_options", - cmLocalGenerator::EscapeForCMake(opts).c_str()); + _uic_opts = cmLocalGenerator::EscapeForCMake(_uic_opts.c_str()); + makefile->AddDefinition("_uic_target_options", _uic_opts.c_str()); + } + for (std::vector::const_iterator li = configs.begin(); + li != configs.end(); ++li) + { + std::string config_uic_opts; + GetUicOpts(target, li->c_str(), config_uic_opts); + if (config_uic_opts != _uic_opts) + { + configUicOptions[*li] = + cmLocalGenerator::EscapeForCMake(config_uic_opts.c_str()); + if(_uic_opts.empty()) + { + _uic_opts = config_uic_opts; + } + } } for(std::vector::const_iterator fileIt = @@ -972,9 +1023,19 @@ bool cmQtAutoGenerators::ReadAutogenInfoFile(cmMakefile* makefile, { const char *uicOptionsFiles = makefile->GetSafeDefinition("AM_UIC_OPTIONS_FILES"); + std::string uicOptionsPropOrig = "AM_UIC_TARGET_OPTIONS"; + std::string uicOptionsProp = uicOptionsPropOrig; + if(config) + { + uicOptionsProp += "_"; + uicOptionsProp += config; + } const char *uicTargetOptions - = makefile->GetSafeDefinition("AM_UIC_TARGET_OPTIONS"); - cmSystemTools::ExpandListArgument(uicTargetOptions, this->UicTargetOptions); + = makefile->GetSafeDefinition(uicOptionsProp.c_str()); + cmSystemTools::ExpandListArgument( + uicTargetOptions ? uicTargetOptions + : makefile->GetSafeDefinition(includesPropOrig.c_str()), + this->UicTargetOptions); const char *uicOptionsOptions = makefile->GetSafeDefinition("AM_UIC_OPTIONS_OPTIONS"); std::vector uicFilesVec; diff --git a/Source/cmQtAutoGenerators.h b/Source/cmQtAutoGenerators.h index 116f1745d..e877f7d93 100644 --- a/Source/cmQtAutoGenerators.h +++ b/Source/cmQtAutoGenerators.h @@ -31,7 +31,8 @@ private: const std::string &autogenTargetName, std::map &configIncludes, std::map &configDefines); - void SetupAutoUicTarget(cmTarget* target); + void SetupAutoUicTarget(cmTarget* target, + std::map &configUicOptions); void SetupAutoRccTarget(cmTarget* target); cmGlobalGenerator* CreateGlobalGenerator(cmake* cm, diff --git a/Source/cmTarget.cxx b/Source/cmTarget.cxx index 2423b27cb..fe68a8a07 100644 --- a/Source/cmTarget.cxx +++ b/Source/cmTarget.cxx @@ -135,6 +135,7 @@ public: }; std::vector IncludeDirectoriesEntries; std::vector CompileOptionsEntries; + std::vector AutoUicOptionsEntries; std::vector CompileDefinitionsEntries; std::vector LinkInterfacePropertyEntries; @@ -142,12 +143,15 @@ public: CachedLinkInterfaceIncludeDirectoriesEntries; mutable std::map > CachedLinkInterfaceCompileOptionsEntries; + mutable std::map > + CachedLinkInterfaceAutoUicOptionsEntries; mutable std::map > CachedLinkInterfaceCompileDefinitionsEntries; mutable std::map CacheLinkInterfaceIncludeDirectoriesDone; mutable std::map CacheLinkInterfaceCompileDefinitionsDone; mutable std::map CacheLinkInterfaceCompileOptionsDone; + mutable std::map CacheLinkInterfaceAutoUicOptionsDone; }; //---------------------------------------------------------------------------- @@ -182,6 +186,7 @@ cmTargetInternals::~cmTargetInternals() { deleteAndClear(this->CachedLinkInterfaceIncludeDirectoriesEntries); deleteAndClear(this->CachedLinkInterfaceCompileOptionsEntries); + deleteAndClear(this->CachedLinkInterfaceAutoUicOptionsEntries); deleteAndClear(this->CachedLinkInterfaceCompileDefinitionsEntries); } @@ -1473,6 +1478,17 @@ void cmTarget::SetProperty(const char* prop, const char* value) new cmTargetInternals::TargetPropertyEntry(cge)); return; } + if(strcmp(prop,"AUTOUIC_OPTIONS") == 0) + { + cmListFileBacktrace lfbt; + this->Makefile->GetBacktrace(lfbt); + cmGeneratorExpression ge(lfbt); + deleteAndClear(this->Internal->AutoUicOptionsEntries); + cmsys::auto_ptr cge = ge.Parse(value); + this->Internal->AutoUicOptionsEntries.push_back( + new cmTargetInternals::TargetPropertyEntry(cge)); + return; + } if(strcmp(prop,"COMPILE_DEFINITIONS") == 0) { cmListFileBacktrace lfbt; @@ -1547,6 +1563,15 @@ void cmTarget::AppendProperty(const char* prop, const char* value, new cmTargetInternals::TargetPropertyEntry(ge.Parse(value))); return; } + if(strcmp(prop,"AUTOUIC_OPTIONS") == 0) + { + cmListFileBacktrace lfbt; + this->Makefile->GetBacktrace(lfbt); + cmGeneratorExpression ge(lfbt); + this->Internal->AutoUicOptionsEntries.push_back( + new cmTargetInternals::TargetPropertyEntry(ge.Parse(value))); + return; + } if(strcmp(prop,"COMPILE_DEFINITIONS") == 0) { cmListFileBacktrace lfbt; @@ -2042,6 +2067,106 @@ static void processCompileOptions(cmTarget const* tgt, dagChecker, config, debugOptions, "options"); } +//---------------------------------------------------------------------------- +void cmTarget::GetAutoUicOptions(std::vector &result, + const char *config) const +{ + std::set uniqueOptions; + cmListFileBacktrace lfbt; + + cmGeneratorExpressionDAGChecker dagChecker(lfbt, + this->GetName(), + "AUTOUIC_OPTIONS", 0, 0); + + std::vector debugProperties; + const char *debugProp = + this->Makefile->GetDefinition("CMAKE_DEBUG_TARGET_PROPERTIES"); + if (debugProp) + { + cmSystemTools::ExpandListArgument(debugProp, debugProperties); + } + + bool debugOptions = !this->DebugCompileOptionsDone + && std::find(debugProperties.begin(), + debugProperties.end(), + "AUTOUIC_OPTIONS") + != debugProperties.end(); + + if (this->Makefile->IsGeneratingBuildSystem()) + { + this->DebugAutoUicOptionsDone = true; + } + + processCompileOptions(this, + this->Internal->AutoUicOptionsEntries, + result, + uniqueOptions, + &dagChecker, + config, + debugOptions); + + std::string configString = config ? config : ""; + if (!this->Internal->CacheLinkInterfaceAutoUicOptionsDone[configString]) + { + for (std::vector::const_iterator + it = this->Internal->LinkInterfacePropertyEntries.begin(), + end = this->Internal->LinkInterfacePropertyEntries.end(); + it != end; ++it) + { + if (!cmGeneratorExpression::IsValidTargetName(it->Value) + && cmGeneratorExpression::Find(it->Value) == std::string::npos) + { + continue; + } + { + cmGeneratorExpression ge(lfbt); + cmsys::auto_ptr cge = + ge.Parse(it->Value); + std::string targetResult = cge->Evaluate(this->Makefile, config, + false, this, 0, 0); + if (!this->Makefile->FindTargetToUse(targetResult.c_str())) + { + continue; + } + } + std::string optionGenex = "$Value + ",INTERFACE_AUTOUIC_OPTIONS>"; + if (cmGeneratorExpression::Find(it->Value) != std::string::npos) + { + // Because it->Value is a generator expression, ensure that it + // evaluates to the non-empty string before being used in the + // TARGET_PROPERTY expression. + optionGenex = "$<$Value + ">:" + optionGenex + ">"; + } + cmGeneratorExpression ge(it->Backtrace); + cmsys::auto_ptr cge = ge.Parse( + optionGenex); + + this->Internal + ->CachedLinkInterfaceAutoUicOptionsEntries[configString].push_back( + new cmTargetInternals::TargetPropertyEntry(cge, + it->Value)); + } + } + + processCompileOptions(this, + this->Internal->CachedLinkInterfaceAutoUicOptionsEntries[configString], + result, + uniqueOptions, + &dagChecker, + config, + debugOptions); + + if (!this->Makefile->IsGeneratingBuildSystem()) + { + deleteAndClear(this->Internal->CachedLinkInterfaceAutoUicOptionsEntries); + } + else + { + this->Internal->CacheLinkInterfaceAutoUicOptionsDone[configString] = true; + } +} + //---------------------------------------------------------------------------- void cmTarget::GetCompileOptions(std::vector &result, const char *config) const @@ -2749,6 +2874,24 @@ const char *cmTarget::GetProperty(const char* prop, } return output.c_str(); } + if(strcmp(prop,"AUTOUIC_OPTIONS") == 0) + { + static std::string output; + output = ""; + std::string sep; + typedef cmTargetInternals::TargetPropertyEntry + TargetPropertyEntry; + for (std::vector::const_iterator + it = this->Internal->AutoUicOptionsEntries.begin(), + end = this->Internal->AutoUicOptionsEntries.end(); + it != end; ++it) + { + output += sep; + output += (*it)->ge->GetInput(); + sep = ";"; + } + return output.c_str(); + } if(strcmp(prop,"COMPILE_DEFINITIONS") == 0) { static std::string output; @@ -5958,6 +6101,7 @@ cmTargetInternalPointer::~cmTargetInternalPointer() { deleteAndClear(this->Pointer->IncludeDirectoriesEntries); deleteAndClear(this->Pointer->CompileOptionsEntries); + deleteAndClear(this->Pointer->AutoUicOptionsEntries); deleteAndClear(this->Pointer->CompileDefinitionsEntries); delete this->Pointer; } diff --git a/Source/cmTarget.h b/Source/cmTarget.h index 35ec68003..c70409c67 100644 --- a/Source/cmTarget.h +++ b/Source/cmTarget.h @@ -532,6 +532,8 @@ public: void GetCompileOptions(std::vector &result, const char *config) const; + void GetAutoUicOptions(std::vector &result, + const char *config) const; bool IsNullImpliedByLinkLibraries(const std::string &p) const; bool IsLinkInterfaceDependentBoolProperty(const std::string &p, @@ -689,6 +691,7 @@ private: bool IsImportedTarget; mutable bool DebugIncludesDone; mutable bool DebugCompileOptionsDone; + mutable bool DebugAutoUicOptionsDone; mutable bool DebugCompileDefinitionsDone; mutable std::set LinkImplicitNullProperties; bool BuildInterfaceIncludesAppended; diff --git a/Tests/CMakeLists.txt b/Tests/CMakeLists.txt index f7a320ab0..9e74b7ddc 100644 --- a/Tests/CMakeLists.txt +++ b/Tests/CMakeLists.txt @@ -1081,8 +1081,10 @@ ${CMake_BINARY_DIR}/bin/cmake -DVERSION=master -P ${CMake_SOURCE_DIR}/Utilities/ # on that platform. if(WIN32) set(run_autogen_test ${CMAKE_CTEST_COMMAND} -V) + set(run_autouic_test ${CMAKE_CTEST_COMMAND} -V) else() set(run_autogen_test QtAutogen) + set(run_autouic_test QtAutoUicInterface) endif() find_package(Qt5Widgets QUIET NO_MODULE) @@ -1100,6 +1102,20 @@ ${CMake_BINARY_DIR}/bin/cmake -DVERSION=master -P ${CMake_SOURCE_DIR}/Utilities/ --test-command ${run_autogen_test} ) list(APPEND TEST_BUILD_DIRS "${CMake_BINARY_DIR}/Tests/Qt5Autogen") + + add_test(Qt5AutoUicInterface ${CMAKE_CTEST_COMMAND} + --build-and-test + "${CMake_SOURCE_DIR}/Tests/QtAutoUicInterface" + "${CMake_BINARY_DIR}/Tests/Qt5AutoUicInterface" + ${build_generator_args} + --build-project QtAutoUicInterface + --build-exe-dir "${CMake_BINARY_DIR}/Tests/Qt5AutoUicInterface" + --force-new-ctest-process + --build-options ${build_options} + -DQT_QMAKE_EXECUTABLE:FILEPATH=${QT_QMAKE_EXECUTABLE} -DQT_TEST_VERSION=5 + --test-command ${run_autouic_test} + ) + list(APPEND TEST_BUILD_DIRS "${CMake_BINARY_DIR}/Tests/Qt5AutoUicInterface") endif() if(QT4_WORKS AND QT_QTGUI_FOUND) add_test(Qt4Autogen ${CMAKE_CTEST_COMMAND} @@ -1116,6 +1132,20 @@ ${CMake_BINARY_DIR}/bin/cmake -DVERSION=master -P ${CMake_SOURCE_DIR}/Utilities/ ) list(APPEND TEST_BUILD_DIRS "${CMake_BINARY_DIR}/Tests/Qt4Autogen") + add_test(Qt4AutoUicInterface ${CMAKE_CTEST_COMMAND} + --build-and-test + "${CMake_SOURCE_DIR}/Tests/QtAutoUicInterface" + "${CMake_BINARY_DIR}/Tests/Qt4AutoUicInterface" + ${build_generator_args} + --build-project QtAutoUicInterface + --build-exe-dir "${CMake_BINARY_DIR}/Tests/Qt4AutoUicInterface" + --force-new-ctest-process + --build-options ${build_options} + -DQT_QMAKE_EXECUTABLE:FILEPATH=${QT_QMAKE_EXECUTABLE} -DQT_TEST_VERSION=4 + --test-command ${run_autouic_test} + ) + list(APPEND TEST_BUILD_DIRS "${CMake_BINARY_DIR}/Tests/Qt4AutoUicInterface") + add_test(Qt4Targets ${CMAKE_CTEST_COMMAND} --build-and-test "${CMake_SOURCE_DIR}/Tests/Qt4Targets" diff --git a/Tests/QtAutoUicInterface/CMakeLists.txt b/Tests/QtAutoUicInterface/CMakeLists.txt new file mode 100644 index 000000000..555f01689 --- /dev/null +++ b/Tests/QtAutoUicInterface/CMakeLists.txt @@ -0,0 +1,70 @@ + +cmake_minimum_required(VERSION 2.8.12) + +project(QtAutoUicInterface) + +if (QT_TEST_VERSION STREQUAL 4) + find_package(Qt4 REQUIRED) + + include(UseQt4) + + set(QT_CORE_TARGET Qt4::QtCore) + set(QT_GUI_TARGET Qt4::QtGui) +else() + if (NOT QT_TEST_VERSION STREQUAL 5) + message(SEND_ERROR "Invalid Qt version specified.") + endif() + find_package(Qt5Widgets REQUIRED) + + set(QT_CORE_TARGET Qt5::Core) + set(QT_GUI_TARGET Qt5::Widgets) +endif() + +set(CMAKE_INCLUDE_CURRENT_DIR_IN_INTERFACE ON) +set(CMAKE_INCLUDE_CURRENT_DIR ON) +set(CMAKE_AUTOMOC ON) +set(CMAKE_AUTOUIC ON) + +# BEGIN Upstream + +set(CMAKE_VERBOSE_MAKEFILE ON) + +add_library(KI18n klocalizedstring.cpp) +target_link_libraries(KI18n ${QT_CORE_TARGET}) + +set(autouic_options + -tr tr2$<$>>:x>i18n +) +if (NOT Qt5Widgets_VERSION VERSION_LESS 5.3.0) + list(APPEND autouic_options -include klocalizedstring.h) +endif() + +set_property(TARGET KI18n APPEND PROPERTY + INTERFACE_AUTOUIC_OPTIONS ${autouic_options} +) + +set(domainProp $) +set(nameLower $>>) +set(domain_logic + $<$:${domainProp}>$<$>:${nameLower}> +) +set_property(TARGET KI18n APPEND PROPERTY + INTERFACE_COMPILE_DEFINITIONS "TRANSLATION_DOMAIN=${domain_logic}" +) + +# END upstream + +add_library(LibWidget libwidget.cpp) +target_link_libraries(LibWidget KI18n ${QT_GUI_TARGET}) +set_property(TARGET LibWidget PROPERTY NO_KUIT_SEMANTIC ON) +set_property(TARGET LibWidget PROPERTY TRANSLATION_DOMAIN customdomain) + +add_library(MyWidget mywidget.cpp) +target_link_libraries(MyWidget KI18n ${QT_GUI_TARGET}) + +add_executable(QtAutoUicInterface main.cpp) +target_compile_definitions(QtAutoUicInterface + PRIVATE + UI_LIBWIDGET_H="${CMAKE_CURRENT_BINARY_DIR}/ui_libwidget.h" + UI_MYWIDGET_H="${CMAKE_CURRENT_BINARY_DIR}/ui_mywidget.h" +) diff --git a/Tests/QtAutoUicInterface/klocalizedstring.cpp b/Tests/QtAutoUicInterface/klocalizedstring.cpp new file mode 100644 index 000000000..f2324bb09 --- /dev/null +++ b/Tests/QtAutoUicInterface/klocalizedstring.cpp @@ -0,0 +1,12 @@ + +#include "klocalizedstring.h" + +QString tr2xi18n(const char *text, const char *) +{ + return QLatin1String("TranslatedX") + QString::fromLatin1(text); +} + +QString tr2i18n(const char *text, const char *) +{ + return QLatin1String("Translated") + QString::fromLatin1(text); +} diff --git a/Tests/QtAutoUicInterface/klocalizedstring.h b/Tests/QtAutoUicInterface/klocalizedstring.h new file mode 100644 index 000000000..559058fa3 --- /dev/null +++ b/Tests/QtAutoUicInterface/klocalizedstring.h @@ -0,0 +1,17 @@ + +#ifndef KLOCALIZEDSTRING_H +#define KLOCALIZEDSTRING_H + +#include + +#ifdef _WIN32 +__declspec(dllexport) +#endif +QString tr2xi18n(const char *text, const char *comment = 0); + +#ifdef _WIN32 +__declspec(dllexport) +#endif +QString tr2i18n(const char *text, const char *comment = 0); + +#endif diff --git a/Tests/QtAutoUicInterface/libwidget.cpp b/Tests/QtAutoUicInterface/libwidget.cpp new file mode 100644 index 000000000..8a921b397 --- /dev/null +++ b/Tests/QtAutoUicInterface/libwidget.cpp @@ -0,0 +1,9 @@ + +#include "libwidget.h" + +LibWidget::LibWidget(QWidget *parent) + : QWidget(parent), + ui(new Ui::LibWidget) +{ + ui->setupUi(this); +} diff --git a/Tests/QtAutoUicInterface/libwidget.h b/Tests/QtAutoUicInterface/libwidget.h new file mode 100644 index 000000000..8b592ecfc --- /dev/null +++ b/Tests/QtAutoUicInterface/libwidget.h @@ -0,0 +1,24 @@ + +#ifndef LIBWIDGET_H +#define LIBWIDGET_H + +#include +#include + +#if QT_VERSION < QT_VERSION_CHECK(5, 3, 0) +#include +#endif + +#include "ui_libwidget.h" + +class LibWidget : public QWidget +{ + Q_OBJECT +public: + explicit LibWidget(QWidget *parent = 0); + +private: + const std::auto_ptr ui; +}; + +#endif diff --git a/Tests/QtAutoUicInterface/libwidget.ui b/Tests/QtAutoUicInterface/libwidget.ui new file mode 100644 index 000000000..897371e4a --- /dev/null +++ b/Tests/QtAutoUicInterface/libwidget.ui @@ -0,0 +1,32 @@ + + + LibWidget + + + + 0 + 0 + 400 + 300 + + + + Form + + + + + 180 + 60 + 57 + 15 + + + + LibLabel + + + + + + diff --git a/Tests/QtAutoUicInterface/main.cpp b/Tests/QtAutoUicInterface/main.cpp new file mode 100644 index 000000000..42d59588e --- /dev/null +++ b/Tests/QtAutoUicInterface/main.cpp @@ -0,0 +1,75 @@ + +#include +#include +#include + +int main(int argc, char **argv) +{ + std::ifstream f; + f.open(UI_LIBWIDGET_H); + if (!f.is_open()) + { + std::cout << "Could not open \"" UI_LIBWIDGET_H "\"." << std::endl; + return -1; + } + + { + bool gotTr2i18n = false; + + while (!f.eof()) + { + std::string output; + getline(f, output); + if (!gotTr2i18n) + { + gotTr2i18n = output.find("tr2i18n") != std::string::npos; + } + if (output.find("tr2xi18n") != std::string::npos) + { + std::cout << "ui_libwidget,h uses tr2xi18n, though it should not." << std::endl; + return -1; + } + } + + if (!gotTr2i18n) + { + std::cout << "Did not find tr2i18n in ui_libwidget.h" << std::endl; + return -1; + } + } + + f.close(); + f.open(UI_MYWIDGET_H); + if (!f.is_open()) + { + std::cout << "Could not open \"" UI_MYWIDGET_H "\"." << std::endl; + return -1; + } + + { + bool gotTr2xi18n = false; + + while (!f.eof()) + { + std::string output; + getline(f, output); + if (!gotTr2xi18n) + { + gotTr2xi18n = output.find("tr2xi18n") != std::string::npos; + } + if (output.find("tr2i18n") != std::string::npos) + { + std::cout << "ui_mywidget,h uses tr2i18n, though it should not." << std::endl; + return -1; + } + } + if (!gotTr2xi18n) + { + std::cout << "Did not find tr2xi18n in ui_mywidget.h" << std::endl; + return -1; + } + } + f.close(); + + return 0; +} diff --git a/Tests/QtAutoUicInterface/mywidget.cpp b/Tests/QtAutoUicInterface/mywidget.cpp new file mode 100644 index 000000000..b528b1a43 --- /dev/null +++ b/Tests/QtAutoUicInterface/mywidget.cpp @@ -0,0 +1,9 @@ + +#include "mywidget.h" + +MyWidget::MyWidget(QWidget *parent) + : QWidget(parent), + ui(new Ui::MyWidget) +{ + ui->setupUi(this); +} diff --git a/Tests/QtAutoUicInterface/mywidget.h b/Tests/QtAutoUicInterface/mywidget.h new file mode 100644 index 000000000..c96fb9828 --- /dev/null +++ b/Tests/QtAutoUicInterface/mywidget.h @@ -0,0 +1,24 @@ + +#ifndef MYWIDGET_H +#define MYWIDGET_H + +#include +#include + +#if QT_VERSION < QT_VERSION_CHECK(5, 3, 0) +#include +#endif + +#include "ui_mywidget.h" + +class MyWidget : public QWidget +{ + Q_OBJECT +public: + explicit MyWidget(QWidget *parent = 0); + +private: + const std::auto_ptr ui; +}; + +#endif diff --git a/Tests/QtAutoUicInterface/mywidget.ui b/Tests/QtAutoUicInterface/mywidget.ui new file mode 100644 index 000000000..b2b9cc592 --- /dev/null +++ b/Tests/QtAutoUicInterface/mywidget.ui @@ -0,0 +1,32 @@ + + + MyWidget + + + + 0 + 0 + 400 + 300 + + + + Form + + + + + 110 + 40 + 81 + 23 + + + + Special button + + + + + +