diff options
151 files changed, 2101 insertions, 579 deletions
diff --git a/Help/generator/Visual Studio 10 2010.rst b/Help/generator/Visual Studio 10 2010.rst new file mode 100644 index 0000000..000677a --- /dev/null +++ b/Help/generator/Visual Studio 10 2010.rst @@ -0,0 +1,12 @@ +Visual Studio 10 2010 +--------------------- + +Generates Visual Studio 10 (VS 2010) project files. + +It is possible to append a space followed by the platform name to +create project files for a specific target platform. E.g. +"Visual Studio 10 2010 Win64" will create project files for the +x64 processor; "Visual Studio 10 2010 IA64" for Itanium. + +For compatibility with CMake versions prior to 3.0, one may specify this +generator using the name "Visual Studio 10" without the year component. diff --git a/Help/generator/Visual Studio 10.rst b/Help/generator/Visual Studio 10.rst deleted file mode 100644 index 9ea7970..0000000 --- a/Help/generator/Visual Studio 10.rst +++ /dev/null @@ -1,9 +0,0 @@ -Visual Studio 10 ----------------- - -Generates Visual Studio 10 (2010) project files. - -It is possible to append a space followed by the platform name to -create project files for a specific target platform. E.g. "Visual -Studio 10 Win64" will create project files for the x64 processor; -"Visual Studio 10 IA64" for Itanium. diff --git a/Help/generator/Visual Studio 11 2012.rst b/Help/generator/Visual Studio 11 2012.rst new file mode 100644 index 0000000..42f6f91 --- /dev/null +++ b/Help/generator/Visual Studio 11 2012.rst @@ -0,0 +1,12 @@ +Visual Studio 11 2012 +--------------------- + +Generates Visual Studio 11 (VS 2012) project files. + +It is possible to append a space followed by the platform name to +create project files for a specific target platform. E.g. +"Visual Studio 11 2012 Win64" will create project files for the +x64 processor; "Visual Studio 11 2012 ARM" for ARM. + +For compatibility with CMake versions prior to 3.0, one may specify this +generator using the name "Visual Studio 11" without the year component. diff --git a/Help/generator/Visual Studio 11.rst b/Help/generator/Visual Studio 11.rst deleted file mode 100644 index 4115c8d..0000000 --- a/Help/generator/Visual Studio 11.rst +++ /dev/null @@ -1,9 +0,0 @@ -Visual Studio 11 ----------------- - -Generates Visual Studio 11 (2012) project files. - -It is possible to append a space followed by the platform name to -create project files for a specific target platform. E.g. "Visual -Studio 11 Win64" will create project files for the x64 processor; -"Visual Studio 11 ARM" for ARM. diff --git a/Help/generator/Visual Studio 12 2013.rst b/Help/generator/Visual Studio 12 2013.rst new file mode 100644 index 0000000..d2f4912 --- /dev/null +++ b/Help/generator/Visual Studio 12 2013.rst @@ -0,0 +1,12 @@ +Visual Studio 12 2013 +--------------------- + +Generates Visual Studio 12 (VS 2013) project files. + +It is possible to append a space followed by the platform name to +create project files for a specific target platform. E.g. +"Visual Studio 12 2013 Win64" will create project files for the +x64 processor; "Visual Studio 12 2013 ARM" for ARM. + +For compatibility with CMake versions prior to 3.0, one may specify this +generator using the name "Visual Studio 12" without the year component. diff --git a/Help/generator/Visual Studio 12.rst b/Help/generator/Visual Studio 12.rst deleted file mode 100644 index 51bcab7..0000000 --- a/Help/generator/Visual Studio 12.rst +++ /dev/null @@ -1,9 +0,0 @@ -Visual Studio 12 ----------------- - -Generates Visual Studio 12 (2013) project files. - -It is possible to append a space followed by the platform name to -create project files for a specific target platform. E.g. "Visual -Studio 12 Win64" will create project files for the x64 processor; -"Visual Studio 12 ARM" for ARM. diff --git a/Help/index.rst b/Help/index.rst index 850660e..dea1463 100644 --- a/Help/index.rst +++ b/Help/index.rst @@ -1,30 +1,50 @@ -CMake Reference Documentation -############################# +.. title:: CMake Reference Documentation -.. only:: html - - Reference Manuals: +Command-Line Tools +################## .. toctree:: :maxdepth: 1 - /manual/ccmake.1 /manual/cmake.1 - /manual/cmake-gui.1 - /manual/cpack.1 /manual/ctest.1 + /manual/cpack.1 + +Interactive Dialogs +################### + +.. toctree:: + :maxdepth: 1 + + /manual/cmake-gui.1 + /manual/ccmake.1 + +Reference Manuals +################# + +.. toctree:: + :maxdepth: 1 + /manual/cmake-commands.7 /manual/cmake-generators.7 /manual/cmake-modules.7 /manual/cmake-policies.7 /manual/cmake-properties.7 /manual/cmake-variables.7 - /manual/cmake-generator-expressions.7 + +Other Manuals +############# + +.. toctree:: + :maxdepth: 1 + /manual/cmake-developer.7 + /manual/cmake-generator-expressions.7 .. only:: html - Index and Search: + Index and Search + ################ * :ref:`genindex` * :ref:`search` diff --git a/Help/manual/ccmake.1.rst b/Help/manual/ccmake.1.rst index 62a7dcf..0c4f47e 100644 --- a/Help/manual/ccmake.1.rst +++ b/Help/manual/ccmake.1.rst @@ -1,3 +1,5 @@ +.. cmake-manual-description: CMake Curses Dialog Command-Line Reference + ccmake(1) ********* diff --git a/Help/manual/cmake-commands.7.rst b/Help/manual/cmake-commands.7.rst index 71d7375..9b23efa 100644 --- a/Help/manual/cmake-commands.7.rst +++ b/Help/manual/cmake-commands.7.rst @@ -1,3 +1,5 @@ +.. cmake-manual-description: CMake Language Command Reference + cmake-commands(7) ***************** diff --git a/Help/manual/cmake-developer.7.rst b/Help/manual/cmake-developer.7.rst index 198a240..ee2016f 100644 --- a/Help/manual/cmake-developer.7.rst +++ b/Help/manual/cmake-developer.7.rst @@ -1,3 +1,5 @@ +.. cmake-manual-description: CMake Developer Reference + cmake-developer(7) ****************** diff --git a/Help/manual/cmake-generator-expressions.7.rst b/Help/manual/cmake-generator-expressions.7.rst index 849ee36..ddde183 100644 --- a/Help/manual/cmake-generator-expressions.7.rst +++ b/Help/manual/cmake-generator-expressions.7.rst @@ -1,3 +1,5 @@ +.. cmake-manual-description: CMake Generator Expressions + cmake-generator-expressions(7) ****************************** diff --git a/Help/manual/cmake-generators.7.rst b/Help/manual/cmake-generators.7.rst index c73d587..a290d1a 100644 --- a/Help/manual/cmake-generators.7.rst +++ b/Help/manual/cmake-generators.7.rst @@ -1,3 +1,5 @@ +.. cmake-manual-description: CMake Generators Reference + cmake-generators(7) ******************* @@ -30,9 +32,9 @@ All Generators /generator/Sublime Text 2 - NMake Makefiles /generator/Sublime Text 2 - Unix Makefiles /generator/Unix Makefiles - /generator/Visual Studio 10 - /generator/Visual Studio 11 - /generator/Visual Studio 12 + /generator/Visual Studio 10 2010 + /generator/Visual Studio 11 2012 + /generator/Visual Studio 12 2013 /generator/Visual Studio 6 /generator/Visual Studio 7 .NET 2003 /generator/Visual Studio 7 diff --git a/Help/manual/cmake-gui.1.rst b/Help/manual/cmake-gui.1.rst index e773ee1..ff01332 100644 --- a/Help/manual/cmake-gui.1.rst +++ b/Help/manual/cmake-gui.1.rst @@ -1,3 +1,5 @@ +.. cmake-manual-description: CMake GUI Command-Line Reference + cmake-gui(1) ************ diff --git a/Help/manual/cmake-modules.7.rst b/Help/manual/cmake-modules.7.rst index da518d3..1f3e59f 100644 --- a/Help/manual/cmake-modules.7.rst +++ b/Help/manual/cmake-modules.7.rst @@ -1,3 +1,5 @@ +.. cmake-manual-description: CMake Modules Reference + cmake-modules(7) **************** diff --git a/Help/manual/cmake-policies.7.rst b/Help/manual/cmake-policies.7.rst index fcbccba..e3cf74d 100644 --- a/Help/manual/cmake-policies.7.rst +++ b/Help/manual/cmake-policies.7.rst @@ -1,3 +1,5 @@ +.. cmake-manual-description: CMake Policies Reference + cmake-policies(7) ***************** diff --git a/Help/manual/cmake-properties.7.rst b/Help/manual/cmake-properties.7.rst index 658da20..7fe1bf2 100644 --- a/Help/manual/cmake-properties.7.rst +++ b/Help/manual/cmake-properties.7.rst @@ -1,3 +1,5 @@ +.. cmake-manual-description: CMake Properties Reference + cmake-properties(7) ******************* @@ -10,6 +12,7 @@ Properties of Global Scope .. toctree:: /prop_gbl/ALLOW_DUPLICATE_CUSTOM_TARGETS + /prop_gbl/AUTOGEN_TARGETS_FOLDER /prop_gbl/AUTOMOC_TARGETS_FOLDER /prop_gbl/DEBUG_CONFIGURATIONS /prop_gbl/DISABLED_FEATURES @@ -72,6 +75,10 @@ Properties on Targets /prop_tgt/ARCHIVE_OUTPUT_NAME /prop_tgt/AUTOMOC_MOC_OPTIONS /prop_tgt/AUTOMOC + /prop_tgt/AUTOUIC + /prop_tgt/AUTOUIC_OPTIONS + /prop_tgt/AUTORCC + /prop_tgt/AUTORCC_OPTIONS /prop_tgt/BUILD_WITH_INSTALL_RPATH /prop_tgt/BUNDLE_EXTENSION /prop_tgt/BUNDLE @@ -235,6 +242,8 @@ Properties on Source Files .. toctree:: /prop_sf/ABSTRACT + /prop_sf/AUTOUIC_OPTIONS + /prop_sf/AUTORCC_OPTIONS /prop_sf/COMPILE_DEFINITIONS_CONFIG /prop_sf/COMPILE_DEFINITIONS /prop_sf/COMPILE_FLAGS diff --git a/Help/manual/cmake-variables.7.rst b/Help/manual/cmake-variables.7.rst index 2311ac8..dccaf64 100644 --- a/Help/manual/cmake-variables.7.rst +++ b/Help/manual/cmake-variables.7.rst @@ -1,3 +1,5 @@ +.. cmake-manual-description: CMake Variables Reference + cmake-variables(7) ****************** @@ -155,6 +157,10 @@ Variables that Control the Build /variable/CMAKE_ARCHIVE_OUTPUT_DIRECTORY /variable/CMAKE_AUTOMOC_MOC_OPTIONS /variable/CMAKE_AUTOMOC + /variable/CMAKE_AUTORCC + /variable/CMAKE_AUTORCC_OPTIONS + /variable/CMAKE_AUTOUIC + /variable/CMAKE_AUTOUIC_OPTIONS /variable/CMAKE_BUILD_WITH_INSTALL_RPATH /variable/CMAKE_CONFIG_POSTFIX /variable/CMAKE_DEBUG_POSTFIX diff --git a/Help/manual/cmake.1.rst b/Help/manual/cmake.1.rst index d2a45aa..f74402e 100644 --- a/Help/manual/cmake.1.rst +++ b/Help/manual/cmake.1.rst @@ -1,3 +1,5 @@ +.. cmake-manual-description: CMake Command-Line Reference + cmake(1) ******** diff --git a/Help/manual/cpack.1.rst b/Help/manual/cpack.1.rst index 5c6567c..22e5d5a 100644 --- a/Help/manual/cpack.1.rst +++ b/Help/manual/cpack.1.rst @@ -1,3 +1,5 @@ +.. cmake-manual-description: CPack Command-Line Reference + cpack(1) ******** diff --git a/Help/manual/ctest.1.rst b/Help/manual/ctest.1.rst index 43fb961..4a5f12e 100644 --- a/Help/manual/ctest.1.rst +++ b/Help/manual/ctest.1.rst @@ -1,3 +1,5 @@ +.. cmake-manual-description: CTest Command-Line Reference + ctest(1) ******** diff --git a/Help/prop_gbl/AUTOGEN_TARGETS_FOLDER.rst b/Help/prop_gbl/AUTOGEN_TARGETS_FOLDER.rst new file mode 100644 index 0000000..48cc8a1 --- /dev/null +++ b/Help/prop_gbl/AUTOGEN_TARGETS_FOLDER.rst @@ -0,0 +1,8 @@ +AUTOGEN_TARGETS_FOLDER +---------------------- + +Name of FOLDER for ``*_automoc`` targets that are added automatically by CMake for targets for which AUTOMOC is enabled. + +If not set, CMake uses the FOLDER property of the parent target as a +default value for this property. See also the documentation for the +FOLDER target property and the AUTOMOC target property. diff --git a/Help/prop_gbl/AUTOMOC_TARGETS_FOLDER.rst b/Help/prop_gbl/AUTOMOC_TARGETS_FOLDER.rst index c83fb8b..185e0ec 100644 --- a/Help/prop_gbl/AUTOMOC_TARGETS_FOLDER.rst +++ b/Help/prop_gbl/AUTOMOC_TARGETS_FOLDER.rst @@ -3,6 +3,8 @@ AUTOMOC_TARGETS_FOLDER Name of FOLDER for ``*_automoc`` targets that are added automatically by CMake for targets for which AUTOMOC is enabled. +This property is obsolete. Use AUTOGEN_TARGETS_FOLDER instead. + If not set, CMake uses the FOLDER property of the parent target as a default value for this property. See also the documentation for the FOLDER target property and the AUTOMOC target property. diff --git a/Help/prop_sf/AUTORCC_OPTIONS.rst b/Help/prop_sf/AUTORCC_OPTIONS.rst new file mode 100644 index 0000000..4b6bb10 --- /dev/null +++ b/Help/prop_sf/AUTORCC_OPTIONS.rst @@ -0,0 +1,14 @@ +AUTORCC_OPTIONS +--------------- + +Additional options for rcc when using autorcc (see the :prop_tgt:`AUTORCC` target +property) + +This property holds additional command line options which will be used when +rcc is executed during the build via autorcc, i.e. it is equivalent to the +optional OPTIONS argument of the qt4_add_resources() macro. + +By default it is empty. + +The options set on the .qrc source file may override :prop_tgt:`AUTORCC_OPTIONS` set +on the target. diff --git a/Help/prop_sf/AUTOUIC_OPTIONS.rst b/Help/prop_sf/AUTOUIC_OPTIONS.rst new file mode 100644 index 0000000..a38b2f8 --- /dev/null +++ b/Help/prop_sf/AUTOUIC_OPTIONS.rst @@ -0,0 +1,14 @@ +AUTOUIC_OPTIONS +--------------- + +Additional options for uic when using autouic (see the :prop_tgt:`AUTOUIC` target property) + +This property holds additional command line options +which will be used when uic is executed during the build via autouic, +i.e. it is equivalent to the optional OPTIONS argument of the +qt4_wrap_ui() macro. + +By default it is empty. + +The options set on the .ui source file may override :prop_tgt:`AUTOUIC_OPTIONS` set +on the target. diff --git a/Help/prop_tgt/AUTORCC.rst b/Help/prop_tgt/AUTORCC.rst new file mode 100644 index 0000000..ef2c9c8 --- /dev/null +++ b/Help/prop_tgt/AUTORCC.rst @@ -0,0 +1,21 @@ + +AUTORCC +------- + +Should the target be processed with autorcc (for Qt projects). + +AUTORCC is a boolean specifying whether CMake will handle +the Qt rcc code generator automatically, i.e. without having to use +the QT4_ADD_RESOURCES() or QT5_ADD_RESOURCES() macro. Currently Qt4 and Qt5 are +supported. + +When this property is set to TRUE, CMake will handle .qrc files added +as target sources at build time and invoke rcc accordingly. +This property is initialized by the value of the :variable:`CMAKE_AUTORCC` +variable if it is set when a target is created. + +Additional command line options for rcc can be set via the +:prop_sf:`AUTORCC_OPTIONS` source file property on the .qrc file. + +The global property :prop_gbl:`AUTOGEN_TARGETS_FOLDER` can be used to group the +autouic targets together in an IDE, e.g. in MSVS. diff --git a/Help/prop_tgt/AUTORCC_OPTIONS.rst b/Help/prop_tgt/AUTORCC_OPTIONS.rst new file mode 100644 index 0000000..489e277 --- /dev/null +++ b/Help/prop_tgt/AUTORCC_OPTIONS.rst @@ -0,0 +1,17 @@ +AUTORCC_OPTIONS +--------------- + +Additional options for rcc when using autorcc (see the :prop_tgt:`AUTORCC` target property) + +This property holds additional command line options +which will be used when rcc is executed during the build via autorcc, +i.e. it is equivalent to the optional OPTIONS argument of the +qt4_add_resources() macro. + +By default it is empty. + +This property is initialized by the value of the variable +:variable:`CMAKE_AUTORCC` if it is set when a target is created. + +The options set on the target may be overridden by :prop_sf:`AUTORCC_OPTIONS` set +on the .qrc source file. diff --git a/Help/prop_tgt/AUTOUIC.rst b/Help/prop_tgt/AUTOUIC.rst new file mode 100644 index 0000000..548c259 --- /dev/null +++ b/Help/prop_tgt/AUTOUIC.rst @@ -0,0 +1,22 @@ +AUTOUIC +------- + +Should the target be processed with autouic (for Qt projects). + +AUTOUIC is a boolean specifying whether CMake will handle +the Qt uic code generator automatically, i.e. without having to use +the QT4_WRAP_UI() or QT5_WRAP_UI() macro. Currently Qt4 and Qt5 are +supported. + +When this property is set to TRUE, CMake will scan the source files +at build time and invoke uic accordingly. +If an #include statement like #include "ui_foo.h" is found in +foo.cpp, a foo.ui file is expected next to foo.cpp, and uic is +run on the foo.ui file. +This property is initialized by the value of the :variable:`CMAKE_AUTOUIC` +variable if it is set when a target is created. + +Additional command line options for uic can be set via the +:prop_sf:`AUTOUIC_OPTIONS` source file property on the foo.ui file. +The global property :prop_gbl:`AUTOGEN_TARGETS_FOLDER` can be used to group the +autouic targets together in an IDE, e.g. in MSVS. diff --git a/Help/prop_tgt/AUTOUIC_OPTIONS.rst b/Help/prop_tgt/AUTOUIC_OPTIONS.rst new file mode 100644 index 0000000..c6cf885 --- /dev/null +++ b/Help/prop_tgt/AUTOUIC_OPTIONS.rst @@ -0,0 +1,17 @@ +AUTOUIC_OPTIONS +--------------- + +Additional options for uic when using autouic (see the :prop_tgt:`AUTOUIC` target property) + +This property holds additional command line options +which will be used when uic is executed during the build via autouic, +i.e. it is equivalent to the optional OPTIONS argument of the +qt4_wrap_ui() macro. + +By default it is empty. + +This property is initialized by the value of the variable +:variable:`CMAKE_AUTOUIC` if it is set when a target is created. + +The options set on the target may be overridden by :prop_sf:`AUTOUIC_OPTIONS` set +on the .ui source file. diff --git a/Help/variable/CMAKE_AUTORCC.rst b/Help/variable/CMAKE_AUTORCC.rst new file mode 100644 index 0000000..d213993 --- /dev/null +++ b/Help/variable/CMAKE_AUTORCC.rst @@ -0,0 +1,7 @@ +CMAKE_AUTORCC +------------- + +Whether to handle rcc automatically for Qt targets. + +This variable is used to initialize the :prop_tgt:`AUTORCC` property on all the targets. +See that target property for additional information. diff --git a/Help/variable/CMAKE_AUTORCC_OPTIONS.rst b/Help/variable/CMAKE_AUTORCC_OPTIONS.rst new file mode 100644 index 0000000..5efbfa3 --- /dev/null +++ b/Help/variable/CMAKE_AUTORCC_OPTIONS.rst @@ -0,0 +1,7 @@ +CMAKE_AUTORCC_OPTIONS +--------------------- + +Whether to handle rcc automatically for Qt targets. + +This variable is used to initialize the :prop_tgt:`AUTORCC_OPTIONS` property on +all the targets. See that target property for additional information. diff --git a/Help/variable/CMAKE_AUTOUIC.rst b/Help/variable/CMAKE_AUTOUIC.rst new file mode 100644 index 0000000..3b016b0 --- /dev/null +++ b/Help/variable/CMAKE_AUTOUIC.rst @@ -0,0 +1,7 @@ +CMAKE_AUTOUIC +------------- + +Whether to handle uic automatically for Qt targets. + +This variable is used to initialize the :prop_tgt:`AUTOUIC` property on all the targets. +See that target property for additional information. diff --git a/Help/variable/CMAKE_AUTOUIC_OPTIONS.rst b/Help/variable/CMAKE_AUTOUIC_OPTIONS.rst new file mode 100644 index 0000000..6a88669 --- /dev/null +++ b/Help/variable/CMAKE_AUTOUIC_OPTIONS.rst @@ -0,0 +1,7 @@ +CMAKE_AUTOUIC_OPTIONS +--------------------- + +Whether to handle uic automatically for Qt targets. + +This variable is used to initialize the :prop_tgt:`AUTOUIC_OPTIONS` property on +all the targets. See that target property for additional information. diff --git a/Modules/AutomocInfo.cmake.in b/Modules/AutogenInfo.cmake.in index 9cff735..7554213 100644 --- a/Modules/AutomocInfo.cmake.in +++ b/Modules/AutogenInfo.cmake.in @@ -1,4 +1,7 @@ set(AM_SOURCES @_moc_files@ ) +set(AM_RCC_SOURCES @_rcc_files@ ) +set(AM_SKIP_MOC @_skip_moc@ ) +set(AM_SKIP_UIC @_skip_uic@ ) set(AM_HEADERS @_moc_headers@ ) set(AM_MOC_COMPILE_DEFINITIONS @_moc_compile_defs@) set(AM_MOC_INCLUDES @_moc_incs@) @@ -7,8 +10,15 @@ set(AM_CMAKE_INCLUDE_DIRECTORIES_PROJECT_BEFORE "@CMAKE_INCLUDE_DIRECTORIES_PROJ set(AM_CMAKE_BINARY_DIR "@CMAKE_BINARY_DIR@/") set(AM_CMAKE_SOURCE_DIR "@CMAKE_SOURCE_DIR@/") set(AM_QT_MOC_EXECUTABLE "@_qt_moc_executable@") +set(AM_QT_UIC_EXECUTABLE "@_qt_uic_executable@") +set(AM_QT_RCC_EXECUTABLE "@_qt_rcc_executable@") set(AM_CMAKE_CURRENT_SOURCE_DIR "@CMAKE_CURRENT_SOURCE_DIR@/") set(AM_CMAKE_CURRENT_BINARY_DIR "@CMAKE_CURRENT_BINARY_DIR@/") set(AM_QT_VERSION_MAJOR "@_target_qt_version@") set(AM_TARGET_NAME @_moc_target_name@) set(AM_RELAXED_MODE "@_moc_relaxed_mode@") +set(AM_UIC_TARGET_OPTIONS @_uic_target_options@) +set(AM_UIC_OPTIONS_FILES @_qt_uic_options_files@) +set(AM_UIC_OPTIONS_OPTIONS @_qt_uic_options_options@) +set(AM_RCC_OPTIONS_FILES @_qt_rcc_options_files@) +set(AM_RCC_OPTIONS_OPTIONS @_qt_rcc_options_options@) diff --git a/Modules/CMakeCCompiler.cmake.in b/Modules/CMakeCCompiler.cmake.in index 3e8d4ff..804cce2 100644 --- a/Modules/CMakeCCompiler.cmake.in +++ b/Modules/CMakeCCompiler.cmake.in @@ -55,4 +55,4 @@ set(CMAKE_C_IMPLICIT_LINK_DIRECTORIES "@CMAKE_C_IMPLICIT_LINK_DIRECTORIES@") set(CMAKE_C_IMPLICIT_LINK_FRAMEWORK_DIRECTORIES "@CMAKE_C_IMPLICIT_LINK_FRAMEWORK_DIRECTORIES@") @SET_CMAKE_CMCLDEPS_EXECUTABLE@ -@SET_CMAKE_CL_SHOWINCLUDE_PREFIX@ +@SET_CMAKE_CL_SHOWINCLUDES_PREFIX@ diff --git a/Modules/CMakeCCompilerId.c.in b/Modules/CMakeCCompilerId.c.in index 871cccd..d53247a 100644 --- a/Modules/CMakeCCompilerId.c.in +++ b/Modules/CMakeCCompilerId.c.in @@ -228,6 +228,7 @@ char const* info_simulate = "INFO" ":" "simulate[" SIMULATE_ID "]"; #endif @CMAKE_C_COMPILER_ID_PLATFORM_CONTENT@ +@CMAKE_C_COMPILER_ID_ERROR_FOR_TEST@ /*--------------------------------------------------------------------------*/ diff --git a/Modules/CMakeCXXCompiler.cmake.in b/Modules/CMakeCXXCompiler.cmake.in index 777f007..35aa6c4 100644 --- a/Modules/CMakeCXXCompiler.cmake.in +++ b/Modules/CMakeCXXCompiler.cmake.in @@ -56,4 +56,4 @@ set(CMAKE_CXX_IMPLICIT_LINK_DIRECTORIES "@CMAKE_CXX_IMPLICIT_LINK_DIRECTORIES@") set(CMAKE_CXX_IMPLICIT_LINK_FRAMEWORK_DIRECTORIES "@CMAKE_CXX_IMPLICIT_LINK_FRAMEWORK_DIRECTORIES@") @SET_CMAKE_CMCLDEPS_EXECUTABLE@ -@SET_CMAKE_CL_SHOWINCLUDE_PREFIX@ +@SET_CMAKE_CL_SHOWINCLUDES_PREFIX@ diff --git a/Modules/CMakeCXXCompilerId.cpp.in b/Modules/CMakeCXXCompilerId.cpp.in index f32fee0..b5d498d 100644 --- a/Modules/CMakeCXXCompilerId.cpp.in +++ b/Modules/CMakeCXXCompilerId.cpp.in @@ -221,6 +221,7 @@ char const* info_simulate = "INFO" ":" "simulate[" SIMULATE_ID "]"; #endif @CMAKE_CXX_COMPILER_ID_PLATFORM_CONTENT@ +@CMAKE_CXX_COMPILER_ID_ERROR_FOR_TEST@ /*--------------------------------------------------------------------------*/ diff --git a/Modules/CMakeClDeps.cmake b/Modules/CMakeClDeps.cmake index 0214ead..b46e7c2 100644 --- a/Modules/CMakeClDeps.cmake +++ b/Modules/CMakeClDeps.cmake @@ -20,7 +20,7 @@ # in front of each include path, so it can remove it. # -if(MSVC_C_ARCHITECTURE_ID AND CMAKE_GENERATOR MATCHES "Ninja" AND CMAKE_C_COMPILER AND CMAKE_COMMAND) +if(CMAKE_GENERATOR MATCHES "Ninja" AND CMAKE_C_COMPILER AND CMAKE_COMMAND) string(REPLACE "cmake.exe" "cmcldeps.exe" CMAKE_CMCLDEPS_EXECUTABLE ${CMAKE_COMMAND}) set(showdir ${CMAKE_BINARY_DIR}/CMakeFiles/ShowIncludes) file(WRITE ${showdir}/foo.h "\n") @@ -30,5 +30,5 @@ if(MSVC_C_ARCHITECTURE_ID AND CMAKE_GENERATOR MATCHES "Ninja" AND CMAKE_C_COMPIL string(REGEX MATCH "\n([^:]*:[^:]*:[ \t]*)" tmp "${outLine}") set(localizedPrefix "${CMAKE_MATCH_1}") set(SET_CMAKE_CMCLDEPS_EXECUTABLE "set(CMAKE_CMCLDEPS_EXECUTABLE \"${CMAKE_CMCLDEPS_EXECUTABLE}\")") - set(SET_CMAKE_CL_SHOWINCLUDE_PREFIX "set(CMAKE_CL_SHOWINCLUDE_PREFIX \"${localizedPrefix}\")") + set(SET_CMAKE_CL_SHOWINCLUDES_PREFIX "set(CMAKE_CL_SHOWINCLUDES_PREFIX \"${localizedPrefix}\")") endif() diff --git a/Modules/CMakeDetermineASMCompiler.cmake b/Modules/CMakeDetermineASMCompiler.cmake index 0fecb5d..1adfadb 100644 --- a/Modules/CMakeDetermineASMCompiler.cmake +++ b/Modules/CMakeDetermineASMCompiler.cmake @@ -59,10 +59,10 @@ else() get_filename_component(_CMAKE_USER_ASM${ASM_DIALECT}_COMPILER_PATH "${CMAKE_ASM${ASM_DIALECT}_COMPILER}" PATH) if(NOT _CMAKE_USER_ASM${ASM_DIALECT}_COMPILER_PATH) find_program(CMAKE_ASM${ASM_DIALECT}_COMPILER_WITH_PATH NAMES ${CMAKE_ASM${ASM_DIALECT}_COMPILER}) - mark_as_advanced(CMAKE_ASM${ASM_DIALECT}_COMPILER_WITH_PATH) if(CMAKE_ASM${ASM_DIALECT}_COMPILER_WITH_PATH) set(CMAKE_ASM${ASM_DIALECT}_COMPILER ${CMAKE_ASM${ASM_DIALECT}_COMPILER_WITH_PATH} CACHE FILEPATH "Assembler" FORCE) endif() + unset(CMAKE_ASM${ASM_DIALECT}_COMPILER_WITH_PATH CACHE) endif() endif() mark_as_advanced(CMAKE_ASM${ASM_DIALECT}_COMPILER) diff --git a/Modules/CMakeDetermineCCompiler.cmake b/Modules/CMakeDetermineCCompiler.cmake index a1713ce..1ae84ee 100644 --- a/Modules/CMakeDetermineCCompiler.cmake +++ b/Modules/CMakeDetermineCCompiler.cmake @@ -92,10 +92,10 @@ else() get_filename_component(_CMAKE_USER_C_COMPILER_PATH "${CMAKE_C_COMPILER}" PATH) if(NOT _CMAKE_USER_C_COMPILER_PATH) find_program(CMAKE_C_COMPILER_WITH_PATH NAMES ${CMAKE_C_COMPILER}) - mark_as_advanced(CMAKE_C_COMPILER_WITH_PATH) if(CMAKE_C_COMPILER_WITH_PATH) set(CMAKE_C_COMPILER ${CMAKE_C_COMPILER_WITH_PATH} CACHE STRING "C compiler" FORCE) endif() + unset(CMAKE_C_COMPILER_WITH_PATH CACHE) endif() endif() mark_as_advanced(CMAKE_C_COMPILER) @@ -176,12 +176,13 @@ if (CMAKE_CROSSCOMPILING AND NOT _CMAKE_TOOLCHAIN_PREFIX) endif () -include(${CMAKE_ROOT}/Modules/CMakeClDeps.cmake) include(CMakeFindBinUtils) if(MSVC_C_ARCHITECTURE_ID) + include(${CMAKE_ROOT}/Modules/CMakeClDeps.cmake) set(SET_MSVC_C_ARCHITECTURE_ID "set(MSVC_C_ARCHITECTURE_ID ${MSVC_C_ARCHITECTURE_ID})") endif() + # configure variables set in this file for fast reload later on configure_file(${CMAKE_ROOT}/Modules/CMakeCCompiler.cmake.in ${CMAKE_PLATFORM_INFO_DIR}/CMakeCCompiler.cmake diff --git a/Modules/CMakeDetermineCXXCompiler.cmake b/Modules/CMakeDetermineCXXCompiler.cmake index d28aa2c..ffb8504 100644 --- a/Modules/CMakeDetermineCXXCompiler.cmake +++ b/Modules/CMakeDetermineCXXCompiler.cmake @@ -91,10 +91,10 @@ else() get_filename_component(_CMAKE_USER_CXX_COMPILER_PATH "${CMAKE_CXX_COMPILER}" PATH) if(NOT _CMAKE_USER_CXX_COMPILER_PATH) find_program(CMAKE_CXX_COMPILER_WITH_PATH NAMES ${CMAKE_CXX_COMPILER}) - mark_as_advanced(CMAKE_CXX_COMPILER_WITH_PATH) if(CMAKE_CXX_COMPILER_WITH_PATH) set(CMAKE_CXX_COMPILER ${CMAKE_CXX_COMPILER_WITH_PATH} CACHE STRING "CXX compiler" FORCE) endif() + unset(CMAKE_CXX_COMPILER_WITH_PATH CACHE) endif() endif() mark_as_advanced(CMAKE_CXX_COMPILER) @@ -175,12 +175,13 @@ if (CMAKE_CROSSCOMPILING AND NOT _CMAKE_TOOLCHAIN_PREFIX) endif () -include(${CMAKE_ROOT}/Modules/CMakeClDeps.cmake) include(CMakeFindBinUtils) if(MSVC_CXX_ARCHITECTURE_ID) + include(${CMAKE_ROOT}/Modules/CMakeClDeps.cmake) set(SET_MSVC_CXX_ARCHITECTURE_ID "set(MSVC_CXX_ARCHITECTURE_ID ${MSVC_CXX_ARCHITECTURE_ID})") endif() + # configure all variables set in this file configure_file(${CMAKE_ROOT}/Modules/CMakeCXXCompiler.cmake.in ${CMAKE_PLATFORM_INFO_DIR}/CMakeCXXCompiler.cmake diff --git a/Modules/CMakeDetermineCompilerId.cmake b/Modules/CMakeDetermineCompilerId.cmake index 6fccb16..4087060 100644 --- a/Modules/CMakeDetermineCompilerId.cmake +++ b/Modules/CMakeDetermineCompilerId.cmake @@ -67,12 +67,10 @@ function(CMAKE_DETERMINE_COMPILER_ID lang flagvar src) endif() # Check if compiler id detection gave us the compiler tool. - if(NOT CMAKE_${lang}_COMPILER) - if(CMAKE_${lang}_COMPILER_ID_TOOL) - set(CMAKE_${lang}_COMPILER "${CMAKE_${lang}_COMPILER_ID_TOOL}" PARENT_SCOPE) - else() - set(CMAKE_${lang}_COMPILER "CMAKE_${lang}_COMPILER-NOTFOUND" PARENT_SCOPE) - endif() + if(CMAKE_${lang}_COMPILER_ID_TOOL) + set(CMAKE_${lang}_COMPILER "${CMAKE_${lang}_COMPILER_ID_TOOL}" PARENT_SCOPE) + elseif(NOT CMAKE_${lang}_COMPILER) + set(CMAKE_${lang}_COMPILER "CMAKE_${lang}_COMPILER-NOTFOUND" PARENT_SCOPE) endif() set(CMAKE_${lang}_COMPILER_ID "${CMAKE_${lang}_COMPILER_ID}" PARENT_SCOPE) @@ -87,7 +85,9 @@ endfunction() #----------------------------------------------------------------------------- # Function to write the compiler id source file. function(CMAKE_DETERMINE_COMPILER_ID_WRITE lang src) - file(READ ${CMAKE_ROOT}/Modules/${src}.in ID_CONTENT_IN) + find_file(src_in ${src}.in PATHS ${CMAKE_ROOT}/Modules ${CMAKE_MODULE_PATH} NO_DEFAULT_PATH) + file(READ ${src_in} ID_CONTENT_IN) + unset(src_in CACHE) string(CONFIGURE "${ID_CONTENT_IN}" ID_CONTENT_OUT @ONLY) file(WRITE ${CMAKE_${lang}_COMPILER_ID_DIR}/${src} "${ID_CONTENT_OUT}") endfunction() diff --git a/Modules/CMakeDetermineFortranCompiler.cmake b/Modules/CMakeDetermineFortranCompiler.cmake index 13cfb00..10574b1 100644 --- a/Modules/CMakeDetermineFortranCompiler.cmake +++ b/Modules/CMakeDetermineFortranCompiler.cmake @@ -109,11 +109,11 @@ else() get_filename_component(_CMAKE_USER_Fortran_COMPILER_PATH "${CMAKE_Fortran_COMPILER}" PATH) if(NOT _CMAKE_USER_Fortran_COMPILER_PATH) find_program(CMAKE_Fortran_COMPILER_WITH_PATH NAMES ${CMAKE_Fortran_COMPILER}) - mark_as_advanced(CMAKE_Fortran_COMPILER_WITH_PATH) if(CMAKE_Fortran_COMPILER_WITH_PATH) set(CMAKE_Fortran_COMPILER ${CMAKE_Fortran_COMPILER_WITH_PATH} CACHE STRING "Fortran compiler" FORCE) endif() + unset(CMAKE_Fortran_COMPILER_WITH_PATH CACHE) endif() endif() mark_as_advanced(CMAKE_Fortran_COMPILER) diff --git a/Source/CMakeLists.txt b/Source/CMakeLists.txt index fd97a20..c01245c 100644 --- a/Source/CMakeLists.txt +++ b/Source/CMakeLists.txt @@ -250,8 +250,8 @@ set(SRCS cmPropertyDefinitionMap.h cmPropertyMap.cxx cmPropertyMap.h - cmQtAutomoc.cxx - cmQtAutomoc.h + cmQtAutoGenerators.cxx + cmQtAutoGenerators.h cmRST.cxx cmRST.h cmScriptGenerator.h diff --git a/Source/CMakeVersion.cmake b/Source/CMakeVersion.cmake index ae1ff94..785fc87 100644 --- a/Source/CMakeVersion.cmake +++ b/Source/CMakeVersion.cmake @@ -2,5 +2,5 @@ set(CMake_VERSION_MAJOR 2) set(CMake_VERSION_MINOR 8) set(CMake_VERSION_PATCH 12) -set(CMake_VERSION_TWEAK 20131027) +set(CMake_VERSION_TWEAK 20131031) #set(CMake_VERSION_RC 1) diff --git a/Source/CTest/cmCTestCoverageHandler.cxx b/Source/CTest/cmCTestCoverageHandler.cxx index ef071b9..33b084e 100644 --- a/Source/CTest/cmCTestCoverageHandler.cxx +++ b/Source/CTest/cmCTestCoverageHandler.cxx @@ -142,6 +142,7 @@ void cmCTestCoverageHandler::Initialize() this->Superclass::Initialize(); this->CustomCoverageExclude.clear(); this->SourceLabels.clear(); + this->TargetDirs.clear(); this->LabelIdMap.clear(); this->Labels.clear(); this->LabelFilter.clear(); diff --git a/Source/CTest/cmCTestMultiProcessHandler.cxx b/Source/CTest/cmCTestMultiProcessHandler.cxx index 2cae179..6e9d0e3 100644 --- a/Source/CTest/cmCTestMultiProcessHandler.cxx +++ b/Source/CTest/cmCTestMultiProcessHandler.cxx @@ -445,12 +445,13 @@ void cmCTestMultiProcessHandler::CreateTestCostList() priorityStack.push_back(TestSet()); TestSet &topLevel = priorityStack.back(); - // Add previously failed tests to the front of the cost list - // and queue other tests for further sorting + // In parallel test runs add previously failed tests to the front + // of the cost list and queue other tests for further sorting for(TestMap::const_iterator i = this->Tests.begin(); i != this->Tests.end(); ++i) { - if(std::find(this->LastTestsFailed.begin(), this->LastTestsFailed.end(), + if(this->ParallelLevel > 1 && + std::find(this->LastTestsFailed.begin(), this->LastTestsFailed.end(), this->Properties[i->first]->Name) != this->LastTestsFailed.end()) { //If the test failed last time, it should be run first. diff --git a/Source/cmGeneratorTarget.cxx b/Source/cmGeneratorTarget.cxx index 7ba554a..b512675 100644 --- a/Source/cmGeneratorTarget.cxx +++ b/Source/cmGeneratorTarget.cxx @@ -126,7 +126,10 @@ std::vector<cmSourceFile*> const& cmGeneratorTarget::GetSourceFiles() void cmGeneratorTarget::ClassifySources() { cmsys::RegularExpression header(CM_HEADER_REGEX); - bool isObjLib = this->Target->GetType() == cmTarget::OBJECT_LIBRARY; + + cmTarget::TargetType targetType = this->Target->GetType(); + bool isObjLib = targetType == cmTarget::OBJECT_LIBRARY; + std::vector<cmSourceFile*> badObjLib; std::vector<cmSourceFile*> const& sources = this->Target->GetSourceFiles(); for(std::vector<cmSourceFile*>::const_iterator si = sources.begin(); @@ -138,6 +141,10 @@ void cmGeneratorTarget::ClassifySources() { this->CustomCommands.push_back(sf); } + else if(targetType == cmTarget::UTILITY) + { + this->ExtraSources.push_back(sf); + } else if(sf->GetPropertyAsBool("HEADER_FILE_ONLY")) { this->HeaderSources.push_back(sf); diff --git a/Source/cmGlobalGenerator.cxx b/Source/cmGlobalGenerator.cxx index 1b0ec4d..8a8d61a 100644 --- a/Source/cmGlobalGenerator.cxx +++ b/Source/cmGlobalGenerator.cxx @@ -18,7 +18,7 @@ #include "cmExternalMakefileProjectGenerator.h" #include "cmake.h" #include "cmMakefile.h" -#include "cmQtAutomoc.h" +#include "cmQtAutoGenerators.h" #include "cmSourceFile.h" #include "cmVersion.h" #include "cmTargetExport.h" @@ -138,15 +138,7 @@ void cmGlobalGenerator::ResolveLanguageCompiler(const std::string &lang, if((path.size() == 0 || !cmSystemTools::FileExists(path.c_str())) && (optional==false)) { - std::string message = "your "; - message += lang; - message += " compiler: \""; - message += name; - message += "\" was not found. Please set "; - message += langComp; - message += " to a valid compiler path or name."; - cmSystemTools::Error(message.c_str()); - path = name; + return; } std::string doc = lang; doc += " compiler."; @@ -334,7 +326,7 @@ void cmGlobalGenerator::FindMakeProgram(cmMakefile* mf) void cmGlobalGenerator::EnableLanguage(std::vector<std::string>const& languages, - cmMakefile *mf, bool) + cmMakefile *mf, bool optional) { if(languages.size() == 0) { @@ -370,6 +362,8 @@ cmGlobalGenerator::EnableLanguage(std::vector<std::string>const& languages, } } + bool fatalError = false; + mf->AddDefinition("RUN_CONFIGURE", true); std::string rootBin = mf->GetHomeOutputDirectory(); rootBin += cmake::GetCMakeFilesDirectory(); @@ -556,6 +550,65 @@ cmGlobalGenerator::EnableLanguage(std::vector<std::string>const& languages, this->SetLanguageEnabled("NONE", mf); continue; } + + // Check that the compiler was found. + std::string compilerName = "CMAKE_"; + compilerName += lang; + compilerName += "_COMPILER"; + std::string compilerEnv = "CMAKE_"; + compilerEnv += lang; + compilerEnv += "_COMPILER_ENV_VAR"; + cmOStringStream noCompiler; + const char* compilerFile = mf->GetDefinition(compilerName.c_str()); + if(!compilerFile || !*compilerFile || + cmSystemTools::IsNOTFOUND(compilerFile)) + { + noCompiler << + "No " << compilerName << " could be found.\n" + ; + } + else if(strcmp(lang, "RC") != 0) + { + if(!cmSystemTools::FileIsFullPath(compilerFile)) + { + noCompiler << + "The " << compilerName << ":\n" + " " << compilerFile << "\n" + "is not a full path and was not found in the PATH.\n" + ; + } + else if(!cmSystemTools::FileExists(compilerFile)) + { + noCompiler << + "The " << compilerName << ":\n" + " " << compilerFile << "\n" + "is not a full path to an existing compiler tool.\n" + ; + } + } + if(!noCompiler.str().empty()) + { + // Skip testing this language since the compiler is not found. + needTestLanguage[lang] = false; + if(!optional) + { + // The compiler was not found and it is not optional. Remove + // CMake(LANG)Compiler.cmake so we try again next time CMake runs. + std::string compilerLangFile = rootBin; + compilerLangFile += "/CMake"; + compilerLangFile += lang; + compilerLangFile += "Compiler.cmake"; + cmSystemTools::RemoveFile(compilerLangFile.c_str()); + if(!this->CMakeInstance->GetIsInTryCompile()) + { + this->PrintCompilerAdvice(noCompiler, lang, + mf->GetDefinition(compilerEnv.c_str())); + mf->IssueMessage(cmake::FATAL_ERROR, noCompiler.str()); + fatalError = true; + } + } + } + std::string langLoadedVar = "CMAKE_"; langLoadedVar += lang; langLoadedVar += "_INFORMATION_LOADED"; @@ -582,26 +635,12 @@ cmGlobalGenerator::EnableLanguage(std::vector<std::string>const& languages, } this->LanguagesReady.insert(lang); - std::string compilerName = "CMAKE_"; - compilerName += lang; - compilerName += "_COMPILER"; - std::string compilerLangFile = rootBin; - compilerLangFile += "/CMake"; - compilerLangFile += lang; - compilerLangFile += "Compiler.cmake"; // Test the compiler for the language just setup // (but only if a compiler has been actually found) // At this point we should have enough info for a try compile // which is used in the backward stuff // If the language is untested then test it now with a try compile. - if (!mf->IsSet(compilerName.c_str())) - { - // if the compiler did not work, then remove the - // CMake(LANG)Compiler.cmake file so that it will get tested the - // next time cmake is run - cmSystemTools::RemoveFile(compilerLangFile.c_str()); - } - else if(needTestLanguage[lang]) + if(needTestLanguage[lang]) { if (!this->CMakeInstance->GetIsInTryCompile()) { @@ -622,6 +661,10 @@ cmGlobalGenerator::EnableLanguage(std::vector<std::string>const& languages, // next time cmake is run if(!mf->IsOn(compilerWorks.c_str())) { + std::string compilerLangFile = rootBin; + compilerLangFile += "/CMake"; + compilerLangFile += lang; + compilerLangFile += "Compiler.cmake"; cmSystemTools::RemoveFile(compilerLangFile.c_str()); } } // end if in try compile @@ -652,6 +695,33 @@ cmGlobalGenerator::EnableLanguage(std::vector<std::string>const& languages, { mf->ReadListFile(0,projectCompatibility.c_str()); } + + if(fatalError) + { + cmSystemTools::SetFatalErrorOccured(); + } +} + +//---------------------------------------------------------------------------- +void cmGlobalGenerator::PrintCompilerAdvice(std::ostream& os, + std::string lang, + const char* envVar) +{ + // Subclasses override this method if they do not support this advice. + os << + "Tell CMake where to find the compiler by setting " + ; + if(envVar) + { + os << + "either the environment variable \"" << envVar << "\" or " + ; + } + os << + "the CMake cache entry CMAKE_" << lang << "_COMPILER " + "to the full path to the compiler, or to the compiler name " + "if it is in the PATH." + ; } //---------------------------------------------------------------------------- @@ -1026,8 +1096,8 @@ void cmGlobalGenerator::Generate() } // Iterate through all targets and set up automoc for those which have - // the AUTOMOC property set - this->CreateAutomocTargets(); + // the AUTOMOC, AUTOUIC or AUTORCC property set + this->CreateQtAutoGeneratorsTargets(); // For each existing cmLocalGenerator unsigned int i; @@ -1185,11 +1255,11 @@ bool cmGlobalGenerator::CheckTargets() } //---------------------------------------------------------------------------- -void cmGlobalGenerator::CreateAutomocTargets() +void cmGlobalGenerator::CreateQtAutoGeneratorsTargets() { #ifdef CMAKE_BUILD_WITH_CMAKE - typedef std::vector<std::pair<cmQtAutomoc, cmTarget*> > Automocs; - Automocs automocs; + typedef std::vector<std::pair<cmQtAutoGenerators, cmTarget*> > Autogens; + Autogens autogens; for(unsigned int i=0; i < this->LocalGenerators.size(); ++i) { cmTargets& targets = @@ -1204,21 +1274,24 @@ void cmGlobalGenerator::CreateAutomocTargets() target.GetType() == cmTarget::MODULE_LIBRARY || target.GetType() == cmTarget::OBJECT_LIBRARY) { - if(target.GetPropertyAsBool("AUTOMOC") && !target.IsImported()) + if((target.GetPropertyAsBool("AUTOMOC") + || target.GetPropertyAsBool("AUTOUIC") + || target.GetPropertyAsBool("AUTORCC")) + && !target.IsImported()) { - cmQtAutomoc automoc; - if(automoc.InitializeMocSourceFile(&target)) + cmQtAutoGenerators autogen; + if(autogen.InitializeMocSourceFile(&target)) { - automocs.push_back(std::make_pair(automoc, &target)); + autogens.push_back(std::make_pair(autogen, &target)); } } } } } - for (Automocs::iterator it = automocs.begin(); it != automocs.end(); + for (Autogens::iterator it = autogens.begin(); it != autogens.end(); ++it) { - it->first.SetupAutomocTarget(it->second); + it->first.SetupAutoGenerateTarget(it->second); } #endif } diff --git a/Source/cmGlobalGenerator.h b/Source/cmGlobalGenerator.h index 4bd1d40..4d6e10f 100644 --- a/Source/cmGlobalGenerator.h +++ b/Source/cmGlobalGenerator.h @@ -52,6 +52,10 @@ public: ///! Get the name for this generator virtual const char *GetName() const { return "Generic"; }; + /** Check whether the given name matches the current generator. */ + virtual bool MatchesGeneratorName(const char* name) const + { return strcmp(this->GetName(), name) == 0; } + /** Set the generator-specific toolset name. Returns true if toolset is supported and false otherwise. */ virtual bool SetGeneratorToolset(std::string const& ts); @@ -319,7 +323,7 @@ protected: virtual bool CheckALLOW_DUPLICATE_CUSTOM_TARGETS(); bool CheckTargets(); - void CreateAutomocTargets(); + void CreateQtAutoGeneratorsTargets(); // Fill the ProjectMap, this must be called after LocalGenerators @@ -392,6 +396,8 @@ private: void WriteSummary(); void WriteSummary(cmTarget* target); + virtual void PrintCompilerAdvice(std::ostream& os, std::string lang, + const char* envVar); void CheckCompilerIdCompatibility(cmMakefile* mf, std::string lang); cmExternalMakefileProjectGenerator* ExtraGenerator; diff --git a/Source/cmGlobalNinjaGenerator.cxx b/Source/cmGlobalNinjaGenerator.cxx index bdc08b3..d262397 100644 --- a/Source/cmGlobalNinjaGenerator.cxx +++ b/Source/cmGlobalNinjaGenerator.cxx @@ -102,6 +102,13 @@ std::string cmGlobalNinjaGenerator::EncodePath(const std::string &path) return EncodeLiteral(result); } +std::string cmGlobalNinjaGenerator::EncodeDepfileSpace(const std::string &path) +{ + std::string result = path; + cmSystemTools::ReplaceString(result, " ", "\\ "); + return result; +} + void cmGlobalNinjaGenerator::WriteBuild(std::ostream& os, const std::string& comment, const std::string& rule, @@ -236,9 +243,11 @@ void cmGlobalNinjaGenerator::AddCustomCommandRule() "$DESC", "Rule for running custom commands.", /*depfile*/ "", + /*deptype*/ "", /*rspfile*/ "", /*rspcontent*/ "", - /*restat*/ true); + /*restat*/ true, + /*generator*/ false); } void @@ -247,7 +256,7 @@ cmGlobalNinjaGenerator::WriteCustomCommandBuild(const std::string& command, const std::string& comment, const cmNinjaDeps& outputs, const cmNinjaDeps& deps, - const cmNinjaDeps& orderOnlyDeps) + const cmNinjaDeps& orderOnly) { std::string cmd = command; #ifdef _WIN32 @@ -268,7 +277,7 @@ cmGlobalNinjaGenerator::WriteCustomCommandBuild(const std::string& command, outputs, deps, cmNinjaDeps(), - orderOnlyDeps, + orderOnly, vars); } @@ -287,9 +296,13 @@ cmGlobalNinjaGenerator::AddMacOSXContentRule() this->AddRule("COPY_OSX_CONTENT", cmd.str(), "Copying OS X Content $out", - "Rule for copying OS X bundle content file." + "Rule for copying OS X bundle content file.", /*depfile*/ "", - /*rspfile*/ ""); + /*deptype*/ "", + /*rspfile*/ "", + /*rspcontent*/ "", + /*restat*/ false, + /*generator*/ false); } void @@ -320,6 +333,7 @@ void cmGlobalNinjaGenerator::WriteRule(std::ostream& os, const std::string& description, const std::string& comment, const std::string& depfile, + const std::string& deptype, const std::string& rspfile, const std::string& rspcontent, bool restat, @@ -355,6 +369,13 @@ void cmGlobalNinjaGenerator::WriteRule(std::ostream& os, os << "depfile = " << depfile << "\n"; } + // Write the deptype if any. + if (!deptype.empty()) + { + cmGlobalNinjaGenerator::Indent(os, 1); + os << "deps = " << deptype << "\n"; + } + // Write the command. cmGlobalNinjaGenerator::Indent(os, 1); os << "command = " << command << "\n"; @@ -579,6 +600,7 @@ void cmGlobalNinjaGenerator::AddRule(const std::string& name, const std::string& description, const std::string& comment, const std::string& depfile, + const std::string& deptype, const std::string& rspfile, const std::string& rspcontent, bool restat, @@ -597,6 +619,7 @@ void cmGlobalNinjaGenerator::AddRule(const std::string& name, description, comment, depfile, + deptype, rspfile, rspcontent, restat, @@ -1085,6 +1108,7 @@ void cmGlobalNinjaGenerator::WriteTargetRebuildManifest(std::ostream& os) "Re-running CMake...", "Rule for re-running cmake.", /*depfile=*/ "", + /*deptype=*/ "", /*rspfile=*/ "", /*rspcontent*/ "", /*restat=*/ false, @@ -1138,6 +1162,7 @@ void cmGlobalNinjaGenerator::WriteTargetClean(std::ostream& os) "Cleaning all built files...", "Rule for cleaning all built files.", /*depfile=*/ "", + /*deptype=*/ "", /*rspfile=*/ "", /*rspcontent*/ "", /*restat=*/ false, @@ -1160,6 +1185,7 @@ void cmGlobalNinjaGenerator::WriteTargetHelp(std::ostream& os) "All primary targets available:", "Rule for printing all primary targets available.", /*depfile=*/ "", + /*deptype=*/ "", /*rspfile=*/ "", /*rspcontent*/ "", /*restat=*/ false, diff --git a/Source/cmGlobalNinjaGenerator.h b/Source/cmGlobalNinjaGenerator.h index e046c7c..be58df1 100644 --- a/Source/cmGlobalNinjaGenerator.h +++ b/Source/cmGlobalNinjaGenerator.h @@ -64,6 +64,7 @@ public: static std::string EncodeIdent(const std::string &ident, std::ostream &vars); static std::string EncodeLiteral(const std::string &lit); static std::string EncodePath(const std::string &path); + static std::string EncodeDepfileSpace(const std::string &path); /** * Write the given @a comment to the output stream @a os. It @@ -104,7 +105,7 @@ public: const std::string& comment, const cmNinjaDeps& outputs, const cmNinjaDeps& deps = cmNinjaDeps(), - const cmNinjaDeps& orderOnlyDeps = cmNinjaDeps()); + const cmNinjaDeps& orderOnly = cmNinjaDeps()); void WriteMacOSXContentBuild(const std::string& input, const std::string& output); @@ -120,6 +121,7 @@ public: const std::string& description, const std::string& comment, const std::string& depfile, + const std::string& deptype, const std::string& rspfile, const std::string& rspcontent, bool restat, @@ -239,11 +241,12 @@ public: const std::string& command, const std::string& description, const std::string& comment, - const std::string& depfile = "", - const std::string& rspfile = "", - const std::string& rspcontent = "", - bool restat = false, - bool generator = false); + const std::string& depfile, + const std::string& deptype, + const std::string& rspfile, + const std::string& rspcontent, + bool restat, + bool generator); bool HasRule(const std::string& name); diff --git a/Source/cmGlobalVisualStudio10Generator.cxx b/Source/cmGlobalVisualStudio10Generator.cxx index 07ccc33..5e29fd7 100644 --- a/Source/cmGlobalVisualStudio10Generator.cxx +++ b/Source/cmGlobalVisualStudio10Generator.cxx @@ -18,42 +18,65 @@ #include "cmVisualStudioSlnParser.h" #include "cmake.h" -static const char vs10Win32generatorName[] = "Visual Studio 10"; -static const char vs10Win64generatorName[] = "Visual Studio 10 Win64"; -static const char vs10IA64generatorName[] = "Visual Studio 10 IA64"; +static const char vs10generatorName[] = "Visual Studio 10 2010"; + +// Map generator name without year to name with year. +static const char* cmVS10GenName(const char* name, std::string& genName) +{ + if(strncmp(name, vs10generatorName, sizeof(vs10generatorName)-6) != 0) + { + return 0; + } + const char* p = name + sizeof(vs10generatorName) - 6; + if(strncmp(p, " 2010", 5) == 0) + { + p += 5; + } + genName = std::string(vs10generatorName) + p; + return p; +} class cmGlobalVisualStudio10Generator::Factory : public cmGlobalGeneratorFactory { public: - virtual cmGlobalGenerator* CreateGlobalGenerator(const char* name) const { - if(!strcmp(name, vs10Win32generatorName)) + virtual cmGlobalGenerator* CreateGlobalGenerator(const char* name) const + { + std::string genName; + const char* p = cmVS10GenName(name, genName); + if(!p) + { return 0; } + name = genName.c_str(); + if(strcmp(p, "") == 0) { return new cmGlobalVisualStudio10Generator( name, NULL, NULL); } - if(!strcmp(name, vs10Win64generatorName)) + if(strcmp(p, " Win64") == 0) { return new cmGlobalVisualStudio10Generator( name, "x64", "CMAKE_FORCE_WIN64"); } - if(!strcmp(name, vs10IA64generatorName)) + if(strcmp(p, " IA64") == 0) { return new cmGlobalVisualStudio10Generator( name, "Itanium", "CMAKE_FORCE_IA64"); } return 0; - } + } - virtual void GetDocumentation(cmDocumentationEntry& entry) const { - entry.Name = "Visual Studio 10"; - entry.Brief = "Generates Visual Studio 10 (2010) project files."; - } + virtual void GetDocumentation(cmDocumentationEntry& entry) const + { + entry.Name = vs10generatorName; + entry.Brief = "Generates Visual Studio 10 (VS 2010) project files."; + } - virtual void GetGenerators(std::vector<std::string>& names) const { - names.push_back(vs10Win32generatorName); - names.push_back(vs10Win64generatorName); - names.push_back(vs10IA64generatorName); } + virtual void GetGenerators(std::vector<std::string>& names) const + { + names.push_back(vs10generatorName); + names.push_back(vs10generatorName + std::string(" IA64")); + names.push_back(vs10generatorName + std::string(" Win64")); + } }; //---------------------------------------------------------------------------- @@ -79,6 +102,18 @@ cmGlobalVisualStudio10Generator::cmGlobalVisualStudio10Generator( //---------------------------------------------------------------------------- bool +cmGlobalVisualStudio10Generator::MatchesGeneratorName(const char* name) const +{ + std::string genName; + if(cmVS10GenName(name, genName)) + { + return genName == this->GetName(); + } + return false; +} + +//---------------------------------------------------------------------------- +bool cmGlobalVisualStudio10Generator::SetGeneratorToolset(std::string const& ts) { this->PlatformToolset = ts; diff --git a/Source/cmGlobalVisualStudio10Generator.h b/Source/cmGlobalVisualStudio10Generator.h index 31e122e..e9e7cb1 100644 --- a/Source/cmGlobalVisualStudio10Generator.h +++ b/Source/cmGlobalVisualStudio10Generator.h @@ -28,6 +28,8 @@ public: const char* platformName, const char* additionalPlatformDefinition); static cmGlobalGeneratorFactory* NewFactory(); + virtual bool MatchesGeneratorName(const char* name) const; + virtual bool SetGeneratorToolset(std::string const& ts); virtual std::string diff --git a/Source/cmGlobalVisualStudio11Generator.cxx b/Source/cmGlobalVisualStudio11Generator.cxx index 41a349e..d968c6d 100644 --- a/Source/cmGlobalVisualStudio11Generator.cxx +++ b/Source/cmGlobalVisualStudio11Generator.cxx @@ -13,42 +13,54 @@ #include "cmLocalVisualStudio10Generator.h" #include "cmMakefile.h" -static const char vs11generatorName[] = "Visual Studio 11"; +static const char vs11generatorName[] = "Visual Studio 11 2012"; + +// Map generator name without year to name with year. +static const char* cmVS11GenName(const char* name, std::string& genName) +{ + if(strncmp(name, vs11generatorName, sizeof(vs11generatorName)-6) != 0) + { + return 0; + } + const char* p = name + sizeof(vs11generatorName) - 6; + if(strncmp(p, " 2012", 5) == 0) + { + p += 5; + } + genName = std::string(vs11generatorName) + p; + return p; +} class cmGlobalVisualStudio11Generator::Factory : public cmGlobalGeneratorFactory { public: - virtual cmGlobalGenerator* CreateGlobalGenerator(const char* name) const { - if(strstr(name, vs11generatorName) != name) - { - return 0; - } - - const char* p = name + sizeof(vs11generatorName) - 1; - if(p[0] == '\0') + virtual cmGlobalGenerator* CreateGlobalGenerator(const char* name) const + { + std::string genName; + const char* p = cmVS11GenName(name, genName); + if(!p) + { return 0; } + name = genName.c_str(); + if(strcmp(p, "") == 0) { return new cmGlobalVisualStudio11Generator( name, NULL, NULL); } - - if(p[0] != ' ') + if(strcmp(p, " Win64") == 0) { - return 0; + return new cmGlobalVisualStudio11Generator( + name, "x64", "CMAKE_FORCE_WIN64"); } - - ++p; - - if(!strcmp(p, "ARM")) + if(strcmp(p, " ARM") == 0) { return new cmGlobalVisualStudio11Generator( name, "ARM", NULL); } - if(!strcmp(p, "Win64")) + if(*p++ != ' ') { - return new cmGlobalVisualStudio11Generator( - name, "x64", "CMAKE_FORCE_WIN64"); + return 0; } std::set<std::string> installedSDKs = @@ -63,14 +75,16 @@ public: new cmGlobalVisualStudio11Generator(name, p, NULL); ret->WindowsCEVersion = "8.00"; return ret; - } + } - virtual void GetDocumentation(cmDocumentationEntry& entry) const { - entry.Name = "Visual Studio 11"; - entry.Brief = "Generates Visual Studio 11 (2012) project files."; - } + virtual void GetDocumentation(cmDocumentationEntry& entry) const + { + entry.Name = vs11generatorName; + entry.Brief = "Generates Visual Studio 11 (VS 2012) project files."; + } - virtual void GetGenerators(std::vector<std::string>& names) const { + virtual void GetGenerators(std::vector<std::string>& names) const + { names.push_back(vs11generatorName); names.push_back(vs11generatorName + std::string(" ARM")); names.push_back(vs11generatorName + std::string(" Win64")); @@ -80,9 +94,9 @@ public: for(std::set<std::string>::const_iterator i = installedSDKs.begin(); i != installedSDKs.end(); ++i) { - names.push_back("Visual Studio 11 " + *i); + names.push_back(std::string(vs11generatorName) + " " + *i); } - } + } }; //---------------------------------------------------------------------------- @@ -107,6 +121,18 @@ cmGlobalVisualStudio11Generator::cmGlobalVisualStudio11Generator( } //---------------------------------------------------------------------------- +bool +cmGlobalVisualStudio11Generator::MatchesGeneratorName(const char* name) const +{ + std::string genName; + if(cmVS11GenName(name, genName)) + { + return genName == this->GetName(); + } + return false; +} + +//---------------------------------------------------------------------------- void cmGlobalVisualStudio11Generator::WriteSLNHeader(std::ostream& fout) { fout << "Microsoft Visual Studio Solution File, Format Version 12.00\n"; diff --git a/Source/cmGlobalVisualStudio11Generator.h b/Source/cmGlobalVisualStudio11Generator.h index 7cc7e69..7ef77e7 100644 --- a/Source/cmGlobalVisualStudio11Generator.h +++ b/Source/cmGlobalVisualStudio11Generator.h @@ -24,6 +24,8 @@ public: const char* platformName, const char* additionalPlatformDefinition); static cmGlobalGeneratorFactory* NewFactory(); + virtual bool MatchesGeneratorName(const char* name) const; + virtual void WriteSLNHeader(std::ostream& fout); ///! create the correct local generator diff --git a/Source/cmGlobalVisualStudio12Generator.cxx b/Source/cmGlobalVisualStudio12Generator.cxx index c2cdc0b..f3806df 100644 --- a/Source/cmGlobalVisualStudio12Generator.cxx +++ b/Source/cmGlobalVisualStudio12Generator.cxx @@ -13,42 +13,65 @@ #include "cmLocalVisualStudio10Generator.h" #include "cmMakefile.h" -static const char vs12Win32generatorName[] = "Visual Studio 12"; -static const char vs12Win64generatorName[] = "Visual Studio 12 Win64"; -static const char vs12ARMgeneratorName[] = "Visual Studio 12 ARM"; +static const char vs12generatorName[] = "Visual Studio 12 2013"; + +// Map generator name without year to name with year. +static const char* cmVS12GenName(const char* name, std::string& genName) +{ + if(strncmp(name, vs12generatorName, sizeof(vs12generatorName)-6) != 0) + { + return 0; + } + const char* p = name + sizeof(vs12generatorName) - 6; + if(strncmp(p, " 2013", 5) == 0) + { + p += 5; + } + genName = std::string(vs12generatorName) + p; + return p; +} class cmGlobalVisualStudio12Generator::Factory : public cmGlobalGeneratorFactory { public: - virtual cmGlobalGenerator* CreateGlobalGenerator(const char* name) const { - if(!strcmp(name, vs12Win32generatorName)) + virtual cmGlobalGenerator* CreateGlobalGenerator(const char* name) const + { + std::string genName; + const char* p = cmVS12GenName(name, genName); + if(!p) + { return 0; } + name = genName.c_str(); + if(strcmp(p, "") == 0) { return new cmGlobalVisualStudio12Generator( name, NULL, NULL); } - if(!strcmp(name, vs12Win64generatorName)) + if(strcmp(p, " Win64") == 0) { return new cmGlobalVisualStudio12Generator( name, "x64", "CMAKE_FORCE_WIN64"); } - if(!strcmp(name, vs12ARMgeneratorName)) + if(strcmp(p, " ARM") == 0) { return new cmGlobalVisualStudio12Generator( name, "ARM", NULL); } return 0; - } + } - virtual void GetDocumentation(cmDocumentationEntry& entry) const { - entry.Name = "Visual Studio 12"; - entry.Brief = "Generates Visual Studio 12 (2013) project files."; - } + virtual void GetDocumentation(cmDocumentationEntry& entry) const + { + entry.Name = vs12generatorName; + entry.Brief = "Generates Visual Studio 12 (VS 2013) project files."; + } - virtual void GetGenerators(std::vector<std::string>& names) const { - names.push_back(vs12Win32generatorName); - names.push_back(vs12Win64generatorName); - names.push_back(vs12ARMgeneratorName); } + virtual void GetGenerators(std::vector<std::string>& names) const + { + names.push_back(vs12generatorName); + names.push_back(vs12generatorName + std::string(" ARM")); + names.push_back(vs12generatorName + std::string(" Win64")); + } }; //---------------------------------------------------------------------------- @@ -73,6 +96,18 @@ cmGlobalVisualStudio12Generator::cmGlobalVisualStudio12Generator( } //---------------------------------------------------------------------------- +bool +cmGlobalVisualStudio12Generator::MatchesGeneratorName(const char* name) const +{ + std::string genName; + if(cmVS12GenName(name, genName)) + { + return genName == this->GetName(); + } + return false; +} + +//---------------------------------------------------------------------------- void cmGlobalVisualStudio12Generator::WriteSLNHeader(std::ostream& fout) { fout << "Microsoft Visual Studio Solution File, Format Version 12.00\n"; diff --git a/Source/cmGlobalVisualStudio12Generator.h b/Source/cmGlobalVisualStudio12Generator.h index 8c8aeb1..5a4a78d 100644 --- a/Source/cmGlobalVisualStudio12Generator.h +++ b/Source/cmGlobalVisualStudio12Generator.h @@ -24,6 +24,8 @@ public: const char* platformName, const char* additionalPlatformDefinition); static cmGlobalGeneratorFactory* NewFactory(); + virtual bool MatchesGeneratorName(const char* name) const; + virtual void WriteSLNHeader(std::ostream& fout); ///! create the correct local generator diff --git a/Source/cmGlobalVisualStudioGenerator.h b/Source/cmGlobalVisualStudioGenerator.h index b665158..ce03a0e 100644 --- a/Source/cmGlobalVisualStudioGenerator.h +++ b/Source/cmGlobalVisualStudioGenerator.h @@ -107,6 +107,7 @@ protected: const char* AdditionalPlatformDefinition; private: + void PrintCompilerAdvice(std::ostream&, std::string, const char*) {} void ComputeTargetObjects(cmGeneratorTarget* gt) const; void FollowLinkDepends(cmTarget* target, std::set<cmTarget*>& linked); diff --git a/Source/cmGlobalXCodeGenerator.h b/Source/cmGlobalXCodeGenerator.h index c053943..97072b2 100644 --- a/Source/cmGlobalXCodeGenerator.h +++ b/Source/cmGlobalXCodeGenerator.h @@ -210,6 +210,7 @@ protected: std::vector<cmXCodeObject*> XCodeObjects; cmXCodeObject* RootObject; private: + void PrintCompilerAdvice(std::ostream&, std::string, const char*) {} void ComputeTargetObjects(cmGeneratorTarget* gt) const; std::string GetObjectsNormalDirectory( diff --git a/Source/cmLocalNinjaGenerator.cxx b/Source/cmLocalNinjaGenerator.cxx index 89b05d7..f1d5e2c 100644 --- a/Source/cmLocalNinjaGenerator.cxx +++ b/Source/cmLocalNinjaGenerator.cxx @@ -48,7 +48,21 @@ void cmLocalNinjaGenerator::Generate() this->WriteProcessedMakefile(this->GetRulesFileStream()); #endif - this->WriteBuildFileTop(); + // We do that only once for the top CMakeLists.txt file. + if(this->isRootMakefile()) + { + this->WriteBuildFileTop(); + + const std::string showIncludesPrefix = this->GetMakefile() + ->GetSafeDefinition("CMAKE_CL_SHOWINCLUDES_PREFIX"); + if (!showIncludesPrefix.empty()) + { + cmGlobalNinjaGenerator::WriteComment(this->GetRulesFileStream(), + "localized /showIncludes string"); + this->GetRulesFileStream() + << "msvc_deps_prefix = " << showIncludesPrefix << "\n\n"; + } + } cmTargets& targets = this->GetMakefile()->GetTargets(); for(cmTargets::iterator t = targets.begin(); t != targets.end(); ++t) @@ -163,10 +177,6 @@ bool cmLocalNinjaGenerator::isRootMakefile() const void cmLocalNinjaGenerator::WriteBuildFileTop() { - // We do that only once for the top CMakeLists.txt file. - if(!this->isRootMakefile()) - return; - // For the build file. this->WriteProjectHeader(this->GetBuildFileStream()); this->WriteNinjaFilesInclusion(this->GetBuildFileStream()); @@ -308,9 +318,13 @@ void cmLocalNinjaGenerator::AppendCustomCommandLines(const cmCustomCommand *cc, cdCmd << cdStr << this->ConvertToOutputFormat(wd, SHELL); cmdLines.push_back(cdCmd.str()); } + + std::string launcher = this->MakeCustomLauncher(*cc); + for (unsigned i = 0; i != ccg.GetNumberOfCommands(); ++i) { - cmdLines.push_back(this->ConvertToOutputFormat(ccg.GetCommand(i).c_str(), - SHELL)); + cmdLines.push_back(launcher + + this->ConvertToOutputFormat(ccg.GetCommand(i).c_str(), SHELL)); + std::string& cmd = cmdLines.back(); ccg.AppendArguments(i, cmd); } @@ -397,3 +411,39 @@ void cmLocalNinjaGenerator::WriteCustomCommandBuildStatements() this->WriteCustomCommandBuildStatement(i->first, ccTargetDeps); } } + +std::string cmLocalNinjaGenerator::MakeCustomLauncher( + const cmCustomCommand& cc) +{ + const char* property = "RULE_LAUNCH_CUSTOM"; + const char* property_value = this->Makefile->GetProperty(property); + + if(!property_value || !*property_value) + { + return std::string(); + } + + // Expand rules in the empty string. It may insert the launcher and + // perform replacements. + RuleVariables vars; + vars.RuleLauncher = property; + std::string output; + const std::vector<std::string>& outputs = cc.GetOutputs(); + if(!outputs.empty()) + { + RelativeRoot relative_root = + cc.GetWorkingDirectory() ? NONE : START_OUTPUT; + + output = this->Convert(outputs[0].c_str(), relative_root, SHELL); + } + vars.Output = output.c_str(); + + std::string launcher; + this->ExpandRuleVariables(launcher, vars); + if(!launcher.empty()) + { + launcher += " "; + } + + return launcher; +} diff --git a/Source/cmLocalNinjaGenerator.h b/Source/cmLocalNinjaGenerator.h index c450841..8eb63c5 100644 --- a/Source/cmLocalNinjaGenerator.h +++ b/Source/cmLocalNinjaGenerator.h @@ -121,6 +121,7 @@ private: void WriteCustomCommandBuildStatements(); + std::string MakeCustomLauncher(const cmCustomCommand& cc); std::string ConfigName; std::string HomeRelativeOutputPath; diff --git a/Source/cmMakefile.cxx b/Source/cmMakefile.cxx index ade4252..c18a7eb 100644 --- a/Source/cmMakefile.cxx +++ b/Source/cmMakefile.cxx @@ -4207,6 +4207,18 @@ bool cmMakefile::EnforceUniqueDir(const char* srcPath, const char* binPath) } //---------------------------------------------------------------------------- +void cmMakefile::AddQtUiFileWithOptions(cmSourceFile *sf) +{ + this->QtUiFilesWithOptions.push_back(sf); +} + +//---------------------------------------------------------------------------- +std::vector<cmSourceFile*> cmMakefile::GetQtUiFilesWithOptions() const +{ + return this->QtUiFilesWithOptions; +} + +//---------------------------------------------------------------------------- cmPolicies::PolicyStatus cmMakefile::GetPolicyStatus(cmPolicies::PolicyID id) { diff --git a/Source/cmMakefile.h b/Source/cmMakefile.h index 918c8bf..76958ca 100644 --- a/Source/cmMakefile.h +++ b/Source/cmMakefile.h @@ -877,6 +877,9 @@ public: bool IsGeneratingBuildSystem(){ return this->GeneratingBuildSystem; } void SetGeneratingBuildSystem(){ this->GeneratingBuildSystem = true; } + void AddQtUiFileWithOptions(cmSourceFile *sf); + std::vector<cmSourceFile*> GetQtUiFilesWithOptions() const; + std::set<cmStdString> const & GetSystemIncludeDirectories() const { return this->SystemIncludeDirectories; } @@ -1054,6 +1057,8 @@ private: cmSourceFile* source); void UpdateOutputToSourceMap(std::string const& output, cmSourceFile* source); + + std::vector<cmSourceFile*> QtUiFilesWithOptions; }; //---------------------------------------------------------------------------- diff --git a/Source/cmNinjaNormalTargetGenerator.cxx b/Source/cmNinjaNormalTargetGenerator.cxx index 57adeba..015654b 100644 --- a/Source/cmNinjaNormalTargetGenerator.cxx +++ b/Source/cmNinjaNormalTargetGenerator.cxx @@ -261,8 +261,11 @@ cmNinjaNormalTargetGenerator description.str(), comment.str(), /*depfile*/ "", + /*deptype*/ "", rspfile, - rspcontent); + rspcontent, + /*restat*/ false, + /*generator*/ false); } if (this->TargetNameOut != this->TargetNameReal && @@ -277,14 +280,28 @@ cmNinjaNormalTargetGenerator " -E cmake_symlink_executable" " $in $out && $POST_BUILD", "Creating executable symlink $out", - "Rule for creating executable symlink."); + "Rule for creating " + "executable symlink.", + /*depfile*/ "", + /*deptype*/ "", + /*rspfile*/ "", + /*rspcontent*/ "", + /*restat*/ false, + /*generator*/ false); else this->GetGlobalGenerator()->AddRule("CMAKE_SYMLINK_LIBRARY", cmakeCommand + " -E cmake_symlink_library" " $in $SONAME $out && $POST_BUILD", "Creating library symlink $out", - "Rule for creating library symlink."); + "Rule for creating " + "library symlink.", + /*depfile*/ "", + /*deptype*/ "", + /*rspfile*/ "", + /*rspcontent*/ "", + /*restat*/ false, + /*generator*/ false); } } diff --git a/Source/cmNinjaTargetGenerator.cxx b/Source/cmNinjaTargetGenerator.cxx index 898aa0e..a6f8159 100644 --- a/Source/cmNinjaTargetGenerator.cxx +++ b/Source/cmNinjaTargetGenerator.cxx @@ -187,6 +187,21 @@ cmNinjaTargetGenerator::ComputeFlagsForObject(cmSourceFile *source, return flags; } + +bool cmNinjaTargetGenerator::needsDepFile(const std::string& lang) +{ + cmMakefile* mf = this->GetMakefile(); + + const bool usingMSVC = std::string("MSVC") == + (mf->GetDefinition("CMAKE_C_COMPILER_ID") ? + mf->GetSafeDefinition("CMAKE_C_COMPILER_ID") : + mf->GetSafeDefinition("CMAKE_CXX_COMPILER_ID")); + + return !usingMSVC || lang == "RC"; +} + + + // TODO: Refactor with // void cmMakefileTargetGenerator::WriteTargetLanguageFlags(). std::string @@ -331,77 +346,75 @@ cmNinjaTargetGenerator void cmNinjaTargetGenerator -::WriteCompileRule(const std::string& language) +::WriteCompileRule(const std::string& lang) { cmLocalGenerator::RuleVariables vars; vars.RuleLauncher = "RULE_LAUNCH_COMPILE"; vars.CMTarget = this->GetTarget(); - std::string lang = language; vars.Language = lang.c_str(); vars.Source = "$in"; vars.Object = "$out"; - std::string flags = "$FLAGS"; vars.Defines = "$DEFINES"; vars.TargetPDB = "$TARGET_PDB"; vars.ObjectDir = "$OBJECT_DIR"; cmMakefile* mf = this->GetMakefile(); - bool useClDeps = false; - std::string clBinary; - std::string clDepsBinary; - std::string clShowPrefix; - if (lang == "C" || lang == "CXX" || lang == "RC") + const bool usingMSVC = std::string("MSVC") == + (mf->GetDefinition("CMAKE_C_COMPILER_ID") ? + mf->GetSafeDefinition("CMAKE_C_COMPILER_ID") : + mf->GetSafeDefinition("CMAKE_CXX_COMPILER_ID")); + + // Tell ninja dependency format so all deps can be loaded into a database + std::string deptype; + std::string depfile; + std::string cldeps; + std::string flags = "$FLAGS"; + if (usingMSVC) { - clDepsBinary = mf->GetSafeDefinition("CMAKE_CMCLDEPS_EXECUTABLE"); - if (!clDepsBinary.empty() && !mf->GetIsSourceFileTryCompile()) + if (!mf->GetIsSourceFileTryCompile() && lang == "RC") { - clShowPrefix = mf->GetSafeDefinition("CMAKE_CL_SHOWINCLUDE_PREFIX"); - clBinary = mf->GetDefinition("CMAKE_C_COMPILER") ? - mf->GetSafeDefinition("CMAKE_C_COMPILER") : - mf->GetSafeDefinition("CMAKE_CXX_COMPILER"); - if (!clBinary.empty() && !clShowPrefix.empty()) - { - useClDeps = true; - const std::string quote = " \""; - clBinary = quote + clBinary + "\" "; - clDepsBinary = quote + clDepsBinary + "\" "; - clShowPrefix = quote + clShowPrefix + "\" "; - vars.DependencyFile = "$DEP_FILE"; - } + deptype = "gcc"; + depfile = "$DEP_FILE"; + const std::string cl = mf->GetDefinition("CMAKE_C_COMPILER") ? + mf->GetSafeDefinition("CMAKE_C_COMPILER") : + mf->GetSafeDefinition("CMAKE_CXX_COMPILER"); + cldeps = "\""; + cldeps += mf->GetSafeDefinition("CMAKE_CMCLDEPS_EXECUTABLE"); + cldeps += "\" " + lang + " $in \"$DEP_FILE\" $out \""; + cldeps += mf->GetSafeDefinition("CMAKE_CL_SHOWINCLUDES_PREFIX"); + cldeps += "\" \"" + cl + "\" "; + } + else + { + deptype = "msvc"; + depfile = ""; + flags += " /showIncludes"; } } - - - std::string depfile; - std::string depfileFlagsName = "CMAKE_DEPFILE_FLAGS_" + language; - const char *depfileFlags = mf->GetDefinition(depfileFlagsName.c_str()); - if (depfileFlags || useClDeps) { - std::string depFlagsStr = depfileFlags ? depfileFlags : ""; + else + { + deptype = "gcc"; depfile = "$DEP_FILE"; - cmSystemTools::ReplaceString(depFlagsStr, "<DEPFILE>", "\"$DEP_FILE\""); - cmSystemTools::ReplaceString(depFlagsStr, "<OBJECT>", "$out"); - cmSystemTools::ReplaceString(depFlagsStr, "<CMAKE_C_COMPILER>", - mf->GetDefinition("CMAKE_C_COMPILER")); - flags += " " + depFlagsStr; - } - vars.Flags = flags.c_str(); + const std::string flagsName = "CMAKE_DEPFILE_FLAGS_" + lang; + std::string depfileFlags = mf->GetSafeDefinition(flagsName.c_str()); + cmSystemTools::ReplaceString(depfileFlags, "<DEPFILE>", "$DEP_FILE"); + cmSystemTools::ReplaceString(depfileFlags, "<OBJECT>", "$out"); + cmSystemTools::ReplaceString(depfileFlags, "<CMAKE_C_COMPILER>", + mf->GetDefinition("CMAKE_C_COMPILER")); + flags += " " + depfileFlags; + } + vars.Flags = flags.c_str(); + vars.DependencyFile = depfile.c_str(); // Rule for compiling object file. - std::string compileCmdVar = "CMAKE_"; - compileCmdVar += language; - compileCmdVar += "_COMPILE_OBJECT"; - std::string compileCmd = mf->GetRequiredDefinition(compileCmdVar.c_str()); + const std::string cmdVar = std::string("CMAKE_") + lang + "_COMPILE_OBJECT"; + std::string compileCmd = mf->GetRequiredDefinition(cmdVar.c_str()); std::vector<std::string> compileCmds; cmSystemTools::ExpandListArgument(compileCmd, compileCmds); - if(useClDeps) - { - std::string cmdPrefix = clDepsBinary + lang + " $in \"$DEP_FILE\" $out " + - clShowPrefix + clBinary; - compileCmds.front().insert(0, cmdPrefix); - } + compileCmds.front().insert(0, cldeps); for (std::vector<std::string>::iterator i = compileCmds.begin(); i != compileCmds.end(); ++i) @@ -413,14 +426,19 @@ cmNinjaTargetGenerator // Write the rule for compiling file of the given language. cmOStringStream comment; - comment << "Rule for compiling " << language << " files."; + comment << "Rule for compiling " << lang << " files."; cmOStringStream description; - description << "Building " << language << " object $out"; - this->GetGlobalGenerator()->AddRule(this->LanguageCompilerRule(language), + description << "Building " << lang << " object $out"; + this->GetGlobalGenerator()->AddRule(this->LanguageCompilerRule(lang), cmdLine, description.str(), comment.str(), - depfile); + depfile, + deptype, + /*rspfile*/ "", + /*rspcontent*/ "", + /*restat*/ false, + /*generator*/ false); } void @@ -540,7 +558,10 @@ cmNinjaTargetGenerator cmNinjaVars vars; vars["FLAGS"] = this->ComputeFlagsForObject(source, language); vars["DEFINES"] = this->ComputeDefines(source, language); - vars["DEP_FILE"] = objectFileName + ".d";; + if (needsDepFile(language)) { + vars["DEP_FILE"] = + cmGlobalNinjaGenerator::EncodeDepfileSpace(objectFileName + ".d"); + } EnsureParentDirectoryExists(objectFileName); std::string objectDir = cmSystemTools::GetFilenamePath(objectFileName); diff --git a/Source/cmNinjaTargetGenerator.h b/Source/cmNinjaTargetGenerator.h index cf06bfd..1cf811a 100644 --- a/Source/cmNinjaTargetGenerator.h +++ b/Source/cmNinjaTargetGenerator.h @@ -42,6 +42,8 @@ public: std::string GetTargetName() const; + bool needsDepFile(const std::string& lang); + protected: bool SetMsvcTargetPdbVariable(cmNinjaVars&) const; diff --git a/Source/cmQtAutomoc.cxx b/Source/cmQtAutoGenerators.cxx index 651e0ad..5f7a26f 100644 --- a/Source/cmQtAutomoc.cxx +++ b/Source/cmQtAutoGenerators.cxx @@ -23,13 +23,14 @@ #include <cmsys/Terminal.h> #include <cmsys/ios/sstream> +#include <assert.h> #include <string.h> #if defined(__APPLE__) #include <unistd.h> #endif -#include "cmQtAutomoc.h" +#include "cmQtAutoGenerators.h" static bool requiresMocing(const std::string& text, std::string ¯oName) @@ -113,10 +114,12 @@ static void copyTargetProperty(cmTarget* destinationTarget, } -cmQtAutomoc::cmQtAutomoc() +cmQtAutoGenerators::cmQtAutoGenerators() :Verbose(cmsys::SystemTools::GetEnv("VERBOSE") != 0) ,ColorOutput(true) ,RunMocFailed(false) +,RunUicFailed(false) +,RunRccFailed(false) ,GenerateAll(false) { @@ -135,7 +138,7 @@ cmQtAutomoc::cmQtAutomoc() } } -bool cmQtAutomoc::InitializeMocSourceFile(cmTarget* target) +bool cmQtAutoGenerators::InitializeMocSourceFile(cmTarget* target) { cmMakefile* makefile = target->GetMakefile(); // don't do anything if there is no Qt4 or Qt5Core (which contains moc): @@ -149,18 +152,22 @@ bool cmQtAutomoc::InitializeMocSourceFile(cmTarget* target) return false; } - std::string automocTargetName = target->GetName(); - automocTargetName += "_automoc"; - std::string mocCppFile = makefile->GetCurrentOutputDirectory(); - mocCppFile += "/"; - mocCppFile += automocTargetName; - mocCppFile += ".cpp"; - cmSourceFile* mocCppSource = makefile->GetOrCreateSource(mocCppFile.c_str(), - true); - makefile->AppendProperty("ADDITIONAL_MAKE_CLEAN_FILES", - mocCppFile.c_str(), false); - - target->AddSourceFile(mocCppSource); + if (target->GetPropertyAsBool("AUTOMOC")) + { + std::string automocTargetName = target->GetName(); + automocTargetName += "_automoc"; + std::string mocCppFile = makefile->GetCurrentOutputDirectory(); + mocCppFile += "/"; + mocCppFile += automocTargetName; + mocCppFile += ".cpp"; + cmSourceFile* mocCppSource = makefile->GetOrCreateSource( + mocCppFile.c_str(), + true); + makefile->AppendProperty("ADDITIONAL_MAKE_CLEAN_FILES", + mocCppFile.c_str(), false); + + target->AddSourceFile(mocCppSource); + } return true; } @@ -201,27 +208,46 @@ static void GetCompileDefinitionsAndDirectories(cmTarget *target, } } -void cmQtAutomoc::SetupAutomocTarget(cmTarget* target) +void cmQtAutoGenerators::SetupAutoGenerateTarget(cmTarget* target) { cmMakefile* makefile = target->GetMakefile(); const char* targetName = target->GetName(); - bool relaxedMode = makefile->IsOn("CMAKE_AUTOMOC_RELAXED_MODE"); + // forget the variables added here afterwards again: + cmMakefile::ScopePushPop varScope(makefile); + static_cast<void>(varScope); - // create a custom target for running automoc at buildtime: - std::string automocTargetName = targetName; - automocTargetName += "_automoc"; + const char *qtVersion = makefile->GetDefinition("Qt5Core_VERSION_MAJOR"); + if (!qtVersion) + { + qtVersion = makefile->GetDefinition("QT_VERSION_MAJOR"); + } + if (const char *targetQtVersion = + target->GetLinkInterfaceDependentStringProperty("QT_MAJOR_VERSION", 0)) + { + qtVersion = targetQtVersion; + } + if (qtVersion) + { + makefile->AddDefinition("_target_qt_version", qtVersion); + } + // create a custom target for running generators at buildtime: + std::string autogenTargetName = targetName; + autogenTargetName += "_automoc"; + + makefile->AddDefinition("_moc_target_name", + cmLocalGenerator::EscapeForCMake(autogenTargetName.c_str()).c_str()); std::string targetDir = makefile->GetCurrentOutputDirectory(); targetDir += makefile->GetCMakeInstance()->GetCMakeFilesDirectory(); targetDir += "/"; - targetDir += automocTargetName; + targetDir += autogenTargetName; targetDir += ".dir/"; cmCustomCommandLine currentLine; currentLine.push_back(makefile->GetSafeDefinition("CMAKE_COMMAND")); currentLine.push_back("-E"); - currentLine.push_back("cmake_automoc"); + currentLine.push_back("cmake_autogen"); currentLine.push_back(targetDir); currentLine.push_back("$<CONFIGURATION>"); @@ -232,8 +258,33 @@ void cmQtAutomoc::SetupAutomocTarget(cmTarget* target) "", makefile->GetCurrentOutputDirectory()); std::vector<std::string> depends; - std::string automocComment = "Automoc for target "; - automocComment += targetName; + std::vector<std::string> toolNames; + if (target->GetPropertyAsBool("AUTOMOC")) + { + toolNames.push_back("moc"); + } + if (target->GetPropertyAsBool("AUTOUIC")) + { + toolNames.push_back("uic"); + } + if (target->GetPropertyAsBool("AUTORCC")) + { + toolNames.push_back("rcc"); + } + + std::string tools = toolNames[0]; + toolNames.erase(toolNames.begin()); + while (toolNames.size() > 1) + { + tools += ", " + toolNames[0]; + toolNames.erase(toolNames.begin()); + } + if (toolNames.size() == 1) + { + tools += " and " + toolNames[0]; + } + std::string autogenComment = "Automatic " + tools + " for target "; + autogenComment += targetName; #if defined(_WIN32) && !defined(__CYGWIN__) bool usePRE_BUILD = false; @@ -256,7 +307,7 @@ void cmQtAutomoc::SetupAutomocTarget(cmTarget* target) // PRE_BUILD will work for an OBJECT_LIBRARY in this specific case. std::vector<std::string> no_output; cmCustomCommand cc(makefile, no_output, depends, - commandLines, automocComment.c_str(), + commandLines, autogenComment.c_str(), workingDirectory.c_str()); cc.SetEscapeOldStyle(false); cc.SetEscapeAllowMakeVars(true); @@ -265,27 +316,97 @@ void cmQtAutomoc::SetupAutomocTarget(cmTarget* target) else #endif { - cmTarget* automocTarget = makefile->AddUtilityCommand( - automocTargetName.c_str(), true, + cmTarget* autogenTarget = makefile->AddUtilityCommand( + autogenTargetName.c_str(), true, workingDirectory.c_str(), depends, - commandLines, false, automocComment.c_str()); + commandLines, false, autogenComment.c_str()); // Set target folder - const char* automocFolder = makefile->GetCMakeInstance()->GetProperty( + const char* autogenFolder = makefile->GetCMakeInstance()->GetProperty( "AUTOMOC_TARGETS_FOLDER"); - if (automocFolder && *automocFolder) + if (!autogenFolder) { - automocTarget->SetProperty("FOLDER", automocFolder); + autogenFolder = makefile->GetCMakeInstance()->GetProperty( + "AUTOGEN_TARGETS_FOLDER"); + } + if (autogenFolder && *autogenFolder) + { + autogenTarget->SetProperty("FOLDER", autogenFolder); } else { // inherit FOLDER property from target (#13688) - copyTargetProperty(automocTarget, target, "FOLDER"); + copyTargetProperty(autogenTarget, target, "FOLDER"); } - target->AddUtility(automocTargetName.c_str()); + target->AddUtility(autogenTargetName.c_str()); + } + + std::map<std::string, std::string> configIncludes; + std::map<std::string, std::string> configDefines; + + if (target->GetPropertyAsBool("AUTOMOC")) + { + this->SetupAutoMocTarget(target, autogenTargetName, + configIncludes, configDefines); + } + if (target->GetPropertyAsBool("AUTOUIC")) + { + this->SetupAutoUicTarget(target); + } + if (target->GetPropertyAsBool("AUTORCC")) + { + this->SetupAutoRccTarget(target); } - // configure a file to get all information to automoc at buildtime: + const char* cmakeRoot = makefile->GetSafeDefinition("CMAKE_ROOT"); + std::string inputFile = cmakeRoot; + inputFile += "/Modules/AutogenInfo.cmake.in"; + std::string outputFile = targetDir; + outputFile += "/AutogenInfo.cmake"; + makefile->ConfigureFile(inputFile.c_str(), outputFile.c_str(), + false, true, false); + + if (!configDefines.empty() || !configIncludes.empty()) + { + std::ofstream infoFile(outputFile.c_str(), std::ios::app); + if ( !infoFile ) + { + std::string error = "Internal CMake error when trying to open file: "; + error += outputFile.c_str(); + error += " for writing."; + cmSystemTools::Error(error.c_str()); + return; + } + if (!configDefines.empty()) + { + for (std::map<std::string, std::string>::iterator + it = configDefines.begin(), end = configDefines.end(); + it != end; ++it) + { + infoFile << "set(AM_MOC_COMPILE_DEFINITIONS_" << it->first << + " " << it->second << ")\n"; + } + } + if (!configIncludes.empty()) + { + for (std::map<std::string, std::string>::iterator + it = configIncludes.begin(), end = configIncludes.end(); + it != end; ++it) + { + infoFile << "set(AM_MOC_INCLUDES_" << it->first << + " " << it->second << ")\n"; + } + } + } +} + +void cmQtAutoGenerators::SetupAutoMocTarget(cmTarget* target, + const std::string &autogenTargetName, + std::map<std::string, std::string> &configIncludes, + std::map<std::string, std::string> &configDefines) +{ + cmMakefile* makefile = target->GetMakefile(); + std::string _moc_files; std::string _moc_headers; const char* sepFiles = ""; @@ -293,6 +414,9 @@ void cmQtAutomoc::SetupAutomocTarget(cmTarget* target) const std::vector<cmSourceFile*>& srcFiles = target->GetSourceFiles(); + std::string skip_moc; + const char *sep = ""; + for(std::vector<cmSourceFile*>::const_iterator fileIt = srcFiles.begin(); fileIt != srcFiles.end(); ++fileIt) @@ -303,41 +427,46 @@ void cmQtAutomoc::SetupAutomocTarget(cmTarget* target) bool skip = cmSystemTools::IsOn(sf->GetPropertyForUser("SKIP_AUTOMOC")); bool generated = cmSystemTools::IsOn(sf->GetPropertyForUser("GENERATED")); - if ((skip==false) && (generated == false)) + if (!generated) { - std::string ext = sf->GetExtension(); - cmSystemTools::FileFormat fileType = cmSystemTools::GetFileFormat( - ext.c_str()); - if (fileType == cmSystemTools::CXX_FILE_FORMAT) + if (skip) { - _moc_files += sepFiles; - _moc_files += absFile; - sepFiles = ";"; + skip_moc += sep; + skip_moc += absFile; + sep = ";"; } - else if (fileType == cmSystemTools::HEADER_FILE_FORMAT) + else { - _moc_headers += sepHeaders; - _moc_headers += absFile; - sepHeaders = ";"; + std::string ext = sf->GetExtension(); + cmSystemTools::FileFormat fileType = cmSystemTools::GetFileFormat( + ext.c_str()); + if (fileType == cmSystemTools::CXX_FILE_FORMAT) + { + _moc_files += sepFiles; + _moc_files += absFile; + sepFiles = ";"; + } + else if (fileType == cmSystemTools::HEADER_FILE_FORMAT) + { + _moc_headers += sepHeaders; + _moc_headers += absFile; + sepHeaders = ";"; + } } } } const char* tmp = target->GetProperty("AUTOMOC_MOC_OPTIONS"); std::string _moc_options = (tmp!=0 ? tmp : ""); - - // forget the variables added here afterwards again: - cmMakefile::ScopePushPop varScope(makefile); - static_cast<void>(varScope); - - makefile->AddDefinition("_moc_target_name", - cmLocalGenerator::EscapeForCMake(automocTargetName.c_str()).c_str()); makefile->AddDefinition("_moc_options", cmLocalGenerator::EscapeForCMake(_moc_options.c_str()).c_str()); makefile->AddDefinition("_moc_files", cmLocalGenerator::EscapeForCMake(_moc_files.c_str()).c_str()); + makefile->AddDefinition("_skip_moc", + cmLocalGenerator::EscapeForCMake(skip_moc.c_str()).c_str()); makefile->AddDefinition("_moc_headers", cmLocalGenerator::EscapeForCMake(_moc_headers.c_str()).c_str()); + bool relaxedMode = makefile->IsOn("CMAKE_AUTOMOC_RELAXED_MODE"); makefile->AddDefinition("_moc_relaxed_mode", relaxedMode ? "TRUE" : "FALSE"); std::string _moc_incs; @@ -352,9 +481,6 @@ void cmQtAutomoc::SetupAutomocTarget(cmTarget* target) makefile->AddDefinition("_moc_compile_defs", cmLocalGenerator::EscapeForCMake(_moc_compile_defs.c_str()).c_str()); - std::map<std::string, std::string> configIncludes; - std::map<std::string, std::string> configDefines; - for (std::vector<std::string>::const_iterator li = configs.begin(); li != configs.end(); ++li) { @@ -383,33 +509,17 @@ void cmQtAutomoc::SetupAutomocTarget(cmTarget* target) } } - const char *qtVersion = makefile->GetDefinition("Qt5Core_VERSION_MAJOR"); - if (!qtVersion) - { - qtVersion = makefile->GetDefinition("QT_VERSION_MAJOR"); - } - if (const char *targetQtVersion = - target->GetLinkInterfaceDependentStringProperty("QT_MAJOR_VERSION", 0)) - { - qtVersion = targetQtVersion; - } - if (qtVersion) - { - makefile->AddDefinition("_target_qt_version", qtVersion); - } - - { const char *qtMoc = makefile->GetSafeDefinition("QT_MOC_EXECUTABLE"); makefile->AddDefinition("_qt_moc_executable", qtMoc); - } + const char *qtVersion = makefile->GetDefinition("_target_qt_version"); if (strcmp(qtVersion, "5") == 0) { cmTarget *qt5Moc = makefile->FindTargetToUse("Qt5::moc"); if (!qt5Moc) { cmSystemTools::Error("Qt5::moc target not found ", - automocTargetName.c_str()); + autogenTargetName.c_str()); return; } makefile->AddDefinition("_qt_moc_executable", qt5Moc->GetLocation(0)); @@ -419,68 +529,338 @@ void cmQtAutomoc::SetupAutomocTarget(cmTarget* target) if (strcmp(qtVersion, "4") != 0) { cmSystemTools::Error("The CMAKE_AUTOMOC feature supports only Qt 4 and " - "Qt 5 ", automocTargetName.c_str()); + "Qt 5 ", autogenTargetName.c_str()); } } +} - const char* cmakeRoot = makefile->GetSafeDefinition("CMAKE_ROOT"); - std::string inputFile = cmakeRoot; - inputFile += "/Modules/AutomocInfo.cmake.in"; - std::string outputFile = targetDir; - outputFile += "/AutomocInfo.cmake"; - makefile->ConfigureFile(inputFile.c_str(), outputFile.c_str(), - false, true, false); +void cmQtAutoGenerators::MergeUicOptions(std::vector<std::string> &opts, + const std::vector<std::string> &fileOpts, + bool isQt5) +{ + static const char* valueOptions[] = { + "tr", + "translate", + "postfix", + "generator", + "g" + }; + std::vector<std::string> extraOpts; + for(std::vector<std::string>::const_iterator it = fileOpts.begin(); + it != fileOpts.end(); ++it) + { + std::vector<std::string>::iterator existingIt + = std::find(opts.begin(), opts.end(), *it); + if (existingIt != opts.end()) + { + const char *o = it->c_str(); + if (*o == '-') + { + ++o; + } + if (isQt5 && *o == '-') + { + ++o; + } + if (std::find_if(cmArrayBegin(valueOptions), cmArrayEnd(valueOptions), + cmStrCmp(o)) != cmArrayEnd(valueOptions)) + { + assert(existingIt + 1 != opts.end()); + *(existingIt + 1) = *(it + 1); + ++it; + } + } + else + { + extraOpts.push_back(*it); + } + } + opts.insert(opts.end(), extraOpts.begin(), extraOpts.end()); +} - if (!configDefines.empty() || !configIncludes.empty()) +void cmQtAutoGenerators::SetupAutoUicTarget(cmTarget* target) +{ + cmMakefile *makefile = target->GetMakefile(); + + const char *qtUic = makefile->GetSafeDefinition("QT_UIC_EXECUTABLE"); + makefile->AddDefinition("_qt_uic_executable", qtUic); + + const std::vector<cmSourceFile*>& srcFiles = target->GetSourceFiles(); + + std::string skip_uic; + const char *sep = ""; + + bool skip = target->GetPropertyAsBool("SKIP_AUTOUIC"); + + std::set<cmStdString> skipped; + + for(std::vector<cmSourceFile*>::const_iterator fileIt = srcFiles.begin(); + fileIt != srcFiles.end(); + ++fileIt) { - std::ofstream infoFile(outputFile.c_str(), std::ios::app); - if ( !infoFile ) + cmSourceFile* sf = *fileIt; + std::string absFile = cmsys::SystemTools::GetRealPath( + sf->GetFullPath().c_str()); + if (!skip) { - std::string error = "Internal CMake error when trying to open file: "; - error += outputFile.c_str(); - error += " for writing."; - cmSystemTools::Error(error.c_str()); - return; + skip = cmSystemTools::IsOn(sf->GetPropertyForUser("SKIP_AUTOUIC")); } - if (!configDefines.empty()) + + if (skip) { - for (std::map<std::string, std::string>::iterator - it = configDefines.begin(), end = configDefines.end(); - it != end; ++it) + skip_uic += sep; + skip_uic += absFile; + sep = ";"; + skipped.insert(absFile); + } + } + + makefile->AddDefinition("_skip_uic", + cmLocalGenerator::EscapeForCMake(skip_uic.c_str()).c_str()); + + std::vector<cmSourceFile*> uiFilesWithOptions + = makefile->GetQtUiFilesWithOptions(); + + std::string uiFileFiles; + std::string uiFileOptions; + sep = ""; + + const char *qtVersion = makefile->GetDefinition("_target_qt_version"); + + if (const char* opts = target->GetProperty("AUTOUIC_OPTIONS")) + { + makefile->AddDefinition("_uic_target_options", + cmLocalGenerator::EscapeForCMake(opts).c_str()); + } + + for(std::vector<cmSourceFile*>::const_iterator fileIt = + uiFilesWithOptions.begin(); + fileIt != uiFilesWithOptions.end(); + ++fileIt) + { + cmSourceFile* sf = *fileIt; + std::string absFile = cmsys::SystemTools::GetRealPath( + sf->GetFullPath().c_str()); + + if (!skipped.insert(absFile).second) + { + continue; + } + uiFileFiles += sep; + uiFileFiles += absFile; + uiFileOptions += sep; + std::string opts = sf->GetProperty("AUTOUIC_OPTIONS"); + cmSystemTools::ReplaceString(opts, ";", "@list_sep@"); + uiFileOptions += opts; + sep = ";"; + } + + makefile->AddDefinition("_qt_uic_options_files", + cmLocalGenerator::EscapeForCMake(uiFileFiles.c_str()).c_str()); + makefile->AddDefinition("_qt_uic_options_options", + cmLocalGenerator::EscapeForCMake(uiFileOptions.c_str()).c_str()); + + const char* targetName = target->GetName(); + if (strcmp(qtVersion, "5") == 0) + { + cmTarget *qt5Uic = makefile->FindTargetToUse("Qt5::uic"); + if (!qt5Uic) + { + // Project does not use Qt5Widgets, but has AUTOUIC ON anyway + makefile->RemoveDefinition("_qt_uic_executable"); + } + else + { + makefile->AddDefinition("_qt_uic_executable", qt5Uic->GetLocation(0)); + } + } + else + { + if (strcmp(qtVersion, "4") != 0) + { + cmSystemTools::Error("The CMAKE_AUTOUIC feature supports only Qt 4 and " + "Qt 5 ", targetName); + } + } +} + +void cmQtAutoGenerators::MergeRccOptions(std::vector<std::string> &opts, + const std::vector<std::string> &fileOpts, + bool isQt5) +{ + static const char* valueOptions[] = { + "name", + "root", + "compress", + "threshold" + }; + std::vector<std::string> extraOpts; + for(std::vector<std::string>::const_iterator it = fileOpts.begin(); + it != fileOpts.end(); ++it) + { + std::vector<std::string>::iterator existingIt + = std::find(opts.begin(), opts.end(), *it); + if (existingIt != opts.end()) + { + const char *o = it->c_str(); + if (*o == '-') { - infoFile << "set(AM_MOC_COMPILE_DEFINITIONS_" << it->first << - " " << it->second << ")\n"; + ++o; + } + if (isQt5 && *o == '-') + { + ++o; + } + if (std::find_if(cmArrayBegin(valueOptions), cmArrayEnd(valueOptions), + cmStrCmp(o)) != cmArrayEnd(valueOptions)) + { + assert(existingIt + 1 != opts.end()); + *(existingIt + 1) = *(it + 1); + ++it; } } - if (!configIncludes.empty()) + else { - for (std::map<std::string, std::string>::iterator - it = configIncludes.begin(), end = configIncludes.end(); - it != end; ++it) + extraOpts.push_back(*it); + } + } + opts.insert(opts.end(), extraOpts.begin(), extraOpts.end()); +} + +void cmQtAutoGenerators::SetupAutoRccTarget(cmTarget* target) +{ + std::string _rcc_files; + const char* sepRccFiles = ""; + cmMakefile *makefile = target->GetMakefile(); + + std::vector<cmSourceFile*> newFiles; + + const std::vector<cmSourceFile*>& srcFiles = target->GetSourceFiles(); + + std::string rccFileFiles; + std::string rccFileOptions; + const char *sep = ""; + + const char *qtVersion = makefile->GetDefinition("_target_qt_version"); + + std::vector<std::string> rccOptions; + if (const char* opts = target->GetProperty("AUTORCC_OPTIONS")) + { + cmSystemTools::ExpandListArgument(opts, rccOptions); + } + + for(std::vector<cmSourceFile*>::const_iterator fileIt = srcFiles.begin(); + fileIt != srcFiles.end(); + ++fileIt) + { + cmSourceFile* sf = *fileIt; + std::string ext = sf->GetExtension(); + if (ext == "qrc") + { + std::string absFile = cmsys::SystemTools::GetRealPath( + sf->GetFullPath().c_str()); + bool skip = cmSystemTools::IsOn(sf->GetPropertyForUser("SKIP_AUTORCC")); + + if (!skip) { - infoFile << "set(AM_MOC_INCLUDES_" << it->first << - " " << it->second << ")\n"; + _rcc_files += sepRccFiles; + _rcc_files += absFile; + sepRccFiles = ";"; + + std::string basename = cmsys::SystemTools:: + GetFilenameWithoutLastExtension(absFile); + + std::string rcc_output_file = makefile->GetCurrentOutputDirectory(); + rcc_output_file += "/qrc_" + basename + ".cpp"; + makefile->AppendProperty("ADDITIONAL_MAKE_CLEAN_FILES", + rcc_output_file.c_str(), false); + cmSourceFile* rccCppSource + = makefile->GetOrCreateSource(rcc_output_file.c_str(), true); + newFiles.push_back(rccCppSource); + + if (const char *prop = sf->GetProperty("AUTORCC_OPTIONS")) + { + std::vector<std::string> optsVec; + cmSystemTools::ExpandListArgument(prop, optsVec); + this->MergeRccOptions(rccOptions, optsVec, + strcmp(qtVersion, "5") == 0); + } + + if (!rccOptions.empty()) + { + rccFileFiles += sep; + rccFileFiles += absFile; + rccFileOptions += sep; + } + const char *listSep = ""; + for(std::vector<std::string>::const_iterator it = rccOptions.begin(); + it != rccOptions.end(); + ++it) + { + rccFileOptions += listSep; + rccFileOptions += *it; + listSep = "@list_sep@"; + } + sep = ";"; } } } -} + for(std::vector<cmSourceFile*>::const_iterator fileIt = newFiles.begin(); + fileIt != newFiles.end(); + ++fileIt) + { + target->AddSourceFile(*fileIt); + } + + makefile->AddDefinition("_rcc_files", + cmLocalGenerator::EscapeForCMake(_rcc_files.c_str()).c_str()); -bool cmQtAutomoc::Run(const char* targetDirectory, const char *config) + makefile->AddDefinition("_qt_rcc_options_files", + cmLocalGenerator::EscapeForCMake(rccFileFiles.c_str()).c_str()); + makefile->AddDefinition("_qt_rcc_options_options", + cmLocalGenerator::EscapeForCMake(rccFileOptions.c_str()).c_str()); + + const char *qtRcc = makefile->GetSafeDefinition("QT_RCC_EXECUTABLE"); + makefile->AddDefinition("_qt_rcc_executable", qtRcc); + + const char* targetName = target->GetName(); + if (strcmp(qtVersion, "5") == 0) + { + cmTarget *qt5Rcc = makefile->FindTargetToUse("Qt5::rcc"); + if (!qt5Rcc) + { + cmSystemTools::Error("Qt5::rcc target not found ", + targetName); + return; + } + makefile->AddDefinition("_qt_rcc_executable", qt5Rcc->GetLocation(0)); + } + else + { + if (strcmp(qtVersion, "4") != 0) + { + cmSystemTools::Error("The CMAKE_AUTORCC feature supports only Qt 4 and " + "Qt 5 ", targetName); + } + } +} + +bool cmQtAutoGenerators::Run(const char* targetDirectory, const char *config) { bool success = true; cmake cm; cmGlobalGenerator* gg = this->CreateGlobalGenerator(&cm, targetDirectory); cmMakefile* makefile = gg->GetCurrentLocalGenerator()->GetMakefile(); - this->ReadAutomocInfoFile(makefile, targetDirectory, config); + this->ReadAutogenInfoFile(makefile, targetDirectory, config); this->ReadOldMocDefinitionsFile(makefile, targetDirectory); this->Init(); if (this->QtMajorVersion == "4" || this->QtMajorVersion == "5") { - success = this->RunAutomoc(makefile); + success = this->RunAutogen(makefile); } this->WriteOldMocDefinitionsFile(targetDirectory); @@ -492,7 +872,7 @@ bool cmQtAutomoc::Run(const char* targetDirectory, const char *config) } -cmGlobalGenerator* cmQtAutomoc::CreateGlobalGenerator(cmake* cm, +cmGlobalGenerator* cmQtAutoGenerators::CreateGlobalGenerator(cmake* cm, const char* targetDirectory) { cmGlobalGenerator* gg = new cmGlobalGenerator(); @@ -509,13 +889,13 @@ cmGlobalGenerator* cmQtAutomoc::CreateGlobalGenerator(cmake* cm, } -bool cmQtAutomoc::ReadAutomocInfoFile(cmMakefile* makefile, +bool cmQtAutoGenerators::ReadAutogenInfoFile(cmMakefile* makefile, const char* targetDirectory, const char *config) { std::string filename(cmSystemTools::CollapseFullPath(targetDirectory)); cmSystemTools::ConvertToUnixSlashes(filename); - filename += "/AutomocInfo.cmake"; + filename += "/AutogenInfo.cmake"; if (!makefile->ReadListFile(0, filename.c_str())) { @@ -530,12 +910,17 @@ bool cmQtAutomoc::ReadAutomocInfoFile(cmMakefile* makefile, "AM_Qt5Core_VERSION_MAJOR"); } this->Sources = makefile->GetSafeDefinition("AM_SOURCES"); + this->RccSources = makefile->GetSafeDefinition("AM_RCC_SOURCES"); + this->SkipMoc = makefile->GetSafeDefinition("AM_SKIP_MOC"); + this->SkipUic = makefile->GetSafeDefinition("AM_SKIP_UIC"); this->Headers = makefile->GetSafeDefinition("AM_HEADERS"); this->IncludeProjectDirsBefore = makefile->IsOn( "AM_CMAKE_INCLUDE_DIRECTORIES_PROJECT_BEFORE"); this->Srcdir = makefile->GetSafeDefinition("AM_CMAKE_CURRENT_SOURCE_DIR"); this->Builddir = makefile->GetSafeDefinition("AM_CMAKE_CURRENT_BINARY_DIR"); this->MocExecutable = makefile->GetSafeDefinition("AM_QT_MOC_EXECUTABLE"); + this->UicExecutable = makefile->GetSafeDefinition("AM_QT_UIC_EXECUTABLE"); + this->RccExecutable = makefile->GetSafeDefinition("AM_QT_RCC_EXECUTABLE"); std::string compileDefsPropOrig = "AM_MOC_COMPILE_DEFINITIONS"; std::string compileDefsProp = compileDefsPropOrig; if(config) @@ -561,6 +946,53 @@ bool cmQtAutomoc::ReadAutomocInfoFile(cmMakefile* makefile, this->ProjectSourceDir = makefile->GetSafeDefinition("AM_CMAKE_SOURCE_DIR"); this->TargetName = makefile->GetSafeDefinition("AM_TARGET_NAME"); + { + const char *uicOptionsFiles + = makefile->GetSafeDefinition("AM_UIC_OPTIONS_FILES"); + const char *uicTargetOptions + = makefile->GetSafeDefinition("AM_UIC_TARGET_OPTIONS"); + cmSystemTools::ExpandListArgument(uicTargetOptions, this->UicTargetOptions); + const char *uicOptionsOptions + = makefile->GetSafeDefinition("AM_UIC_OPTIONS_OPTIONS"); + std::vector<std::string> uicFilesVec; + cmSystemTools::ExpandListArgument(uicOptionsFiles, uicFilesVec); + std::vector<std::string> uicOptionsVec; + cmSystemTools::ExpandListArgument(uicOptionsOptions, uicOptionsVec); + if (uicFilesVec.size() != uicOptionsVec.size()) + { + return false; + } + for (std::vector<std::string>::iterator fileIt = uicFilesVec.begin(), + optionIt = uicOptionsVec.begin(); + fileIt != uicFilesVec.end(); + ++fileIt, ++optionIt) + { + cmSystemTools::ReplaceString(*optionIt, "@list_sep@", ";"); + this->UicOptions[*fileIt] = *optionIt; + } + } + { + const char *rccOptionsFiles + = makefile->GetSafeDefinition("AM_RCC_OPTIONS_FILES"); + const char *rccOptionsOptions + = makefile->GetSafeDefinition("AM_RCC_OPTIONS_OPTIONS"); + std::vector<std::string> rccFilesVec; + cmSystemTools::ExpandListArgument(rccOptionsFiles, rccFilesVec); + std::vector<std::string> rccOptionsVec; + cmSystemTools::ExpandListArgument(rccOptionsOptions, rccOptionsVec); + if (rccFilesVec.size() != rccOptionsVec.size()) + { + return false; + } + for (std::vector<std::string>::iterator fileIt = rccFilesVec.begin(), + optionIt = rccOptionsVec.begin(); + fileIt != rccFilesVec.end(); + ++fileIt, ++optionIt) + { + cmSystemTools::ReplaceString(*optionIt, "@list_sep@", ";"); + this->RccOptions[*fileIt] = *optionIt; + } + } this->CurrentCompileSettingsStr = this->MakeCompileSettingsString(makefile); this->RelaxedMode = makefile->IsOn("AM_RELAXED_MODE"); @@ -569,7 +1001,7 @@ bool cmQtAutomoc::ReadAutomocInfoFile(cmMakefile* makefile, } -std::string cmQtAutomoc::MakeCompileSettingsString(cmMakefile* makefile) +std::string cmQtAutoGenerators::MakeCompileSettingsString(cmMakefile* makefile) { std::string s; s += makefile->GetSafeDefinition("AM_MOC_COMPILE_DEFINITIONS"); @@ -586,7 +1018,7 @@ std::string cmQtAutomoc::MakeCompileSettingsString(cmMakefile* makefile) } -bool cmQtAutomoc::ReadOldMocDefinitionsFile(cmMakefile* makefile, +bool cmQtAutoGenerators::ReadOldMocDefinitionsFile(cmMakefile* makefile, const char* targetDirectory) { std::string filename(cmSystemTools::CollapseFullPath(targetDirectory)); @@ -602,7 +1034,8 @@ bool cmQtAutomoc::ReadOldMocDefinitionsFile(cmMakefile* makefile, } -void cmQtAutomoc::WriteOldMocDefinitionsFile(const char* targetDirectory) +void +cmQtAutoGenerators::WriteOldMocDefinitionsFile(const char* targetDirectory) { std::string filename(cmSystemTools::CollapseFullPath(targetDirectory)); cmSystemTools::ConvertToUnixSlashes(filename); @@ -619,7 +1052,7 @@ void cmQtAutomoc::WriteOldMocDefinitionsFile(const char* targetDirectory) } -void cmQtAutomoc::Init() +void cmQtAutoGenerators::Init() { this->OutMocCppFilename = this->Builddir; this->OutMocCppFilename += this->TargetName; @@ -706,7 +1139,7 @@ void cmQtAutomoc::Init() } -bool cmQtAutomoc::RunAutomoc(cmMakefile* makefile) +bool cmQtAutoGenerators::RunAutogen(cmMakefile* makefile) { if (!cmsys::SystemTools::FileExists(this->OutMocCppFilename.c_str()) || (this->OldCompileSettingsStr != this->CurrentCompileSettingsStr)) @@ -733,26 +1166,56 @@ bool cmQtAutomoc::RunAutomoc(cmMakefile* makefile) const std::vector<std::string>& headerExtensions = makefile->GetHeaderExtensions(); + std::vector<std::string> includedUis; + std::vector<std::string> skippedUis; + std::vector<std::string> uicSkipped; + cmSystemTools::ExpandListArgument(this->SkipUic, uicSkipped); + for (std::vector<std::string>::const_iterator it = sourceFiles.begin(); it != sourceFiles.end(); ++it) { + const bool skipUic = std::find(uicSkipped.begin(), uicSkipped.end(), *it) + != uicSkipped.end(); + std::vector<std::string>& uiFiles = skipUic ? skippedUis : includedUis; const std::string &absFilename = *it; if (this->Verbose) { - std::cout << "AUTOMOC: Checking " << absFilename << std::endl; + std::cout << "AUTOGEN: Checking " << absFilename << std::endl; } if (this->RelaxedMode) { - this->ParseCppFile(absFilename, headerExtensions, includedMocs); + this->ParseCppFile(absFilename, headerExtensions, includedMocs, + uiFiles); } else { - this->StrictParseCppFile(absFilename, headerExtensions, includedMocs); + this->StrictParseCppFile(absFilename, headerExtensions, includedMocs, + uiFiles); } this->SearchHeadersForCppFile(absFilename, headerExtensions, headerFiles); } + { + std::vector<std::string> mocSkipped; + cmSystemTools::ExpandListArgument(this->SkipMoc, mocSkipped); + for (std::vector<std::string>::const_iterator it = mocSkipped.begin(); + it != mocSkipped.end(); + ++it) + { + if (std::find(uicSkipped.begin(), uicSkipped.end(), *it) + != uicSkipped.end()) + { + const std::string &absFilename = *it; + if (this->Verbose) + { + std::cout << "AUTOGEN: Checking " << absFilename << std::endl; + } + this->ParseForUic(absFilename, includedUis); + } + } + } + std::vector<std::string> headerFilesVec; cmSystemTools::ExpandListArgument(this->Headers, headerFilesVec); for (std::vector<std::string>::const_iterator it = headerFilesVec.begin(); @@ -764,7 +1227,7 @@ bool cmQtAutomoc::RunAutomoc(cmMakefile* makefile) // key = moc source filepath, value = moc output filename std::map<std::string, std::string> notIncludedMocs; - this->ParseHeaders(headerFiles, includedMocs, notIncludedMocs); + this->ParseHeaders(headerFiles, includedMocs, notIncludedMocs, includedUis); // run moc on all the moc's that are #included in source files for(std::map<std::string, std::string>::const_iterator @@ -774,6 +1237,17 @@ bool cmQtAutomoc::RunAutomoc(cmMakefile* makefile) { this->GenerateMoc(it->first, it->second); } + for(std::vector<std::string>::const_iterator it = includedUis.begin(); + it != includedUis.end(); + ++it) + { + this->GenerateUi(*it); + } + + if(!this->RccExecutable.empty()) + { + this->GenerateQrc(); + } cmsys_ios::stringstream outStream; outStream << "/* This file is autogenerated, do not edit*/\n"; @@ -806,6 +1280,17 @@ bool cmQtAutomoc::RunAutomoc(cmMakefile* makefile) std::cerr << "moc failed..."<< std::endl; return false; } + + if (this->RunUicFailed) + { + std::cerr << "uic failed..."<< std::endl; + return false; + } + if (this->RunRccFailed) + { + std::cerr << "rcc failed..."<< std::endl; + return false; + } outStream.flush(); std::string automocSource = outStream.str(); if (!automocCppChanged) @@ -830,9 +1315,10 @@ bool cmQtAutomoc::RunAutomoc(cmMakefile* makefile) } -void cmQtAutomoc::ParseCppFile(const std::string& absFilename, +void cmQtAutoGenerators::ParseCppFile(const std::string& absFilename, const std::vector<std::string>& headerExtensions, - std::map<std::string, std::string>& includedMocs) + std::map<std::string, std::string>& includedMocs, + std::vector<std::string> &includedUis) { cmsys::RegularExpression mocIncludeRegExp( "[\n][ \t]*#[ \t]*include[ \t]+" @@ -841,7 +1327,7 @@ void cmQtAutomoc::ParseCppFile(const std::string& absFilename, const std::string contentsString = this->ReadAll(absFilename); if (contentsString.empty()) { - std::cerr << "AUTOMOC: warning: " << absFilename << ": file is empty\n" + std::cerr << "AUTOGEN: warning: " << absFilename << ": file is empty\n" << std::endl; return; } @@ -901,7 +1387,7 @@ void cmQtAutomoc::ParseCppFile(const std::string& absFilename, } else { - std::cerr << "AUTOMOC: error: " << absFilename << " The file " + std::cerr << "AUTOGEN: error: " << absFilename << " The file " << "includes the moc file \"" << currentMoc << "\", " << "but could not find header \"" << basename << '{' << this->Join(headerExtensions, ',') << "}\" "; @@ -932,7 +1418,7 @@ void cmQtAutomoc::ParseCppFile(const std::string& absFilename, fileToMoc = headerToMoc; if ((requiresMoc==false) &&(basename==scannedFileBasename)) { - std::cerr << "AUTOMOC: warning: " << absFilename << ": The file " + std::cerr << "AUTOGEN: warning: " << absFilename << ": The file " "includes the moc file \"" << currentMoc << "\", but does not contain a " << macroName << " macro. Running moc on " @@ -943,7 +1429,7 @@ void cmQtAutomoc::ParseCppFile(const std::string& absFilename, } else { - std::cerr << "AUTOMOC: warning: " << absFilename << ": The file " + std::cerr << "AUTOGEN: warning: " << absFilename << ": The file " "includes the moc file \"" << currentMoc << "\" instead of \"moc_" << basename << ".cpp\". " "Running moc on " @@ -955,7 +1441,7 @@ void cmQtAutomoc::ParseCppFile(const std::string& absFilename, } else { - std::cerr <<"AUTOMOC: error: " << absFilename << ": The file " + std::cerr <<"AUTOGEN: error: " << absFilename << ": The file " "includes the moc file \"" << currentMoc << "\", which seems to be the moc file from a different " "source file. CMake also could not find a matching " @@ -973,6 +1459,7 @@ void cmQtAutomoc::ParseCppFile(const std::string& absFilename, matchOffset += mocIncludeRegExp.end(); } while(mocIncludeRegExp.find(contentsString.c_str() + matchOffset)); } + this->ParseForUic(absFilename, contentsString, includedUis); // In this case, check whether the scanned file itself contains a Q_OBJECT. // If this is the case, the moc_foo.cpp should probably be generated from @@ -983,7 +1470,7 @@ void cmQtAutomoc::ParseCppFile(const std::string& absFilename, if (mocUnderscoreIncluded == true) { // this is for KDE4 compatibility: - std::cerr << "AUTOMOC: warning: " << absFilename << ": The file " + std::cerr << "AUTOGEN: warning: " << absFilename << ": The file " << "contains a " << macroName << " macro, but does not " "include " << "\"" << scannedFileBasename << ".moc\", but instead " @@ -999,7 +1486,7 @@ void cmQtAutomoc::ParseCppFile(const std::string& absFilename, else { // otherwise always error out since it will not compile: - std::cerr << "AUTOMOC: error: " << absFilename << ": The file " + std::cerr << "AUTOGEN: error: " << absFilename << ": The file " << "contains a " << macroName << " macro, but does not " "include " << "\"" << scannedFileBasename << ".moc\" !\n" @@ -1011,9 +1498,10 @@ void cmQtAutomoc::ParseCppFile(const std::string& absFilename, } -void cmQtAutomoc::StrictParseCppFile(const std::string& absFilename, +void cmQtAutoGenerators::StrictParseCppFile(const std::string& absFilename, const std::vector<std::string>& headerExtensions, - std::map<std::string, std::string>& includedMocs) + std::map<std::string, std::string>& includedMocs, + std::vector<std::string>& includedUis) { cmsys::RegularExpression mocIncludeRegExp( "[\n][ \t]*#[ \t]*include[ \t]+" @@ -1022,7 +1510,7 @@ void cmQtAutomoc::StrictParseCppFile(const std::string& absFilename, const std::string contentsString = this->ReadAll(absFilename); if (contentsString.empty()) { - std::cerr << "AUTOMOC: warning: " << absFilename << ": file is empty\n" + std::cerr << "AUTOGEN: warning: " << absFilename << ": file is empty\n" << std::endl; return; } @@ -1069,7 +1557,7 @@ void cmQtAutomoc::StrictParseCppFile(const std::string& absFilename, } else { - std::cerr << "AUTOMOC: error: " << absFilename << " The file " + std::cerr << "AUTOGEN: error: " << absFilename << " The file " << "includes the moc file \"" << currentMoc << "\", " << "but could not find header \"" << basename << '{' << this->Join(headerExtensions, ',') << "}\" "; @@ -1090,7 +1578,7 @@ void cmQtAutomoc::StrictParseCppFile(const std::string& absFilename, { if (basename != scannedFileBasename) { - std::cerr <<"AUTOMOC: error: " << absFilename << ": The file " + std::cerr <<"AUTOGEN: error: " << absFilename << ": The file " "includes the moc file \"" << currentMoc << "\", which seems to be the moc file from a different " "source file. This is not supported. " @@ -1104,6 +1592,7 @@ void cmQtAutomoc::StrictParseCppFile(const std::string& absFilename, matchOffset += mocIncludeRegExp.end(); } while(mocIncludeRegExp.find(contentsString.c_str() + matchOffset)); } + this->ParseForUic(absFilename, contentsString, includedUis); // In this case, check whether the scanned file itself contains a Q_OBJECT. // If this is the case, the moc_foo.cpp should probably be generated from @@ -1114,7 +1603,7 @@ void cmQtAutomoc::StrictParseCppFile(const std::string& absFilename, macroName))) { // otherwise always error out since it will not compile: - std::cerr << "AUTOMOC: error: " << absFilename << ": The file " + std::cerr << "AUTOGEN: error: " << absFilename << ": The file " << "contains a " << macroName << " macro, but does not include " << "\"" << scannedFileBasename << ".moc\" !\n" << std::endl; @@ -1124,7 +1613,63 @@ void cmQtAutomoc::StrictParseCppFile(const std::string& absFilename, } -void cmQtAutomoc::SearchHeadersForCppFile(const std::string& absFilename, +void cmQtAutoGenerators::ParseForUic(const std::string& absFilename, + std::vector<std::string>& includedUis) +{ + if (this->UicExecutable.empty()) + { + return; + } + const std::string contentsString = this->ReadAll(absFilename); + if (contentsString.empty()) + { + std::cerr << "AUTOGEN: warning: " << absFilename << ": file is empty\n" + << std::endl; + return; + } + this->ParseForUic(absFilename, contentsString, includedUis); +} + + +void cmQtAutoGenerators::ParseForUic(const std::string&, + const std::string& contentsString, + std::vector<std::string>& includedUis) +{ + if (this->UicExecutable.empty()) + { + return; + } + cmsys::RegularExpression uiIncludeRegExp( + "[\n][ \t]*#[ \t]*include[ \t]+" + "[\"<](([^ \">]+/)?ui_[^ \">/]+\\.h)[\">]"); + + std::string::size_type matchOffset = 0; + + matchOffset = 0; + if ((strstr(contentsString.c_str(), "ui_") != NULL) + && (uiIncludeRegExp.find(contentsString))) + { + do + { + const std::string currentUi = uiIncludeRegExp.match(1); + + std::string basename = cmsys::SystemTools:: + GetFilenameWithoutLastExtension(currentUi); + + // basename should be the part of the ui filename used for + // finding the correct header, so we need to remove the ui_ part + basename = basename.substr(3); + + includedUis.push_back(basename); + + matchOffset += uiIncludeRegExp.end(); + } while(uiIncludeRegExp.find(contentsString.c_str() + matchOffset)); + } +} + + +void +cmQtAutoGenerators::SearchHeadersForCppFile(const std::string& absFilename, const std::vector<std::string>& headerExtensions, std::set<std::string>& absHeaders) { @@ -1160,28 +1705,29 @@ void cmQtAutomoc::SearchHeadersForCppFile(const std::string& absFilename, } -void cmQtAutomoc::ParseHeaders(const std::set<std::string>& absHeaders, +void cmQtAutoGenerators::ParseHeaders(const std::set<std::string>& absHeaders, const std::map<std::string, std::string>& includedMocs, - std::map<std::string, std::string>& notIncludedMocs) + std::map<std::string, std::string>& notIncludedMocs, + std::vector<std::string>& includedUis) { for(std::set<std::string>::const_iterator hIt=absHeaders.begin(); hIt!=absHeaders.end(); ++hIt) { const std::string& headerName = *hIt; + const std::string contents = this->ReadAll(headerName); if (includedMocs.find(headerName) == includedMocs.end()) { if (this->Verbose) { - std::cout << "AUTOMOC: Checking " << headerName << std::endl; + std::cout << "AUTOGEN: Checking " << headerName << std::endl; } const std::string basename = cmsys::SystemTools:: GetFilenameWithoutLastExtension(headerName); const std::string currentMoc = "moc_" + basename + ".cpp"; - const std::string contents = this->ReadAll(headerName); std::string macroName; if (requiresMocing(contents, macroName)) { @@ -1189,12 +1735,11 @@ void cmQtAutomoc::ParseHeaders(const std::set<std::string>& absHeaders, notIncludedMocs[headerName] = currentMoc; } } + this->ParseForUic(headerName, contents, includedUis); } - } - -bool cmQtAutomoc::GenerateMoc(const std::string& sourceFile, +bool cmQtAutoGenerators::GenerateMoc(const std::string& sourceFile, const std::string& mocFileName) { const std::string mocFilePath = this->Builddir + mocFileName; @@ -1260,7 +1805,7 @@ bool cmQtAutomoc::GenerateMoc(const std::string& sourceFile, bool result = cmSystemTools::RunSingleCommand(command, &output, &retVal); if (!result || retVal) { - std::cerr << "AUTOMOC: error: process for " << mocFilePath <<" failed:\n" + std::cerr << "AUTOGEN: error: process for " << mocFilePath <<" failed:\n" << output << std::endl; this->RunMocFailed = true; cmSystemTools::RemoveFile(mocFilePath.c_str()); @@ -1270,8 +1815,152 @@ bool cmQtAutomoc::GenerateMoc(const std::string& sourceFile, return false; } +bool cmQtAutoGenerators::GenerateUi(const std::string& uiFileName) +{ + if (!cmsys::SystemTools::FileExists(this->Builddir.c_str(), false)) + { + cmsys::SystemTools::MakeDirectory(this->Builddir.c_str()); + } + + std::string ui_output_file = "ui_" + uiFileName + ".h"; + std::string ui_input_file = this->Srcdir + uiFileName + ".ui"; + + int sourceNewerThanUi = 0; + bool success = cmsys::SystemTools::FileTimeCompare(ui_input_file.c_str(), + (this->Builddir + ui_output_file).c_str(), + &sourceNewerThanUi); + if (this->GenerateAll || !success || sourceNewerThanUi >= 0) + { + std::string msg = "Generating "; + msg += ui_output_file; + cmSystemTools::MakefileColorEcho(cmsysTerminal_Color_ForegroundBlue + |cmsysTerminal_Color_ForegroundBold, + msg.c_str(), true, this->ColorOutput); + + std::vector<cmStdString> command; + command.push_back(this->UicExecutable); + + std::string options; + std::vector<std::string> opts = this->UicTargetOptions; + std::map<std::string, std::string>::const_iterator optionIt + = this->UicOptions.find(ui_input_file); + if (optionIt != this->UicOptions.end()) + { + std::vector<std::string> fileOpts; + cmSystemTools::ExpandListArgument(optionIt->second, fileOpts); + this->MergeUicOptions(opts, fileOpts, this->QtMajorVersion == "5"); + } + for(std::vector<std::string>::const_iterator optIt = opts.begin(); + optIt != opts.end(); + ++optIt) + { + command.push_back(*optIt); + } + + command.push_back("-o"); + command.push_back(this->Builddir + ui_output_file); + command.push_back(ui_input_file); + + if (this->Verbose) + { + for(std::vector<cmStdString>::const_iterator cmdIt = command.begin(); + cmdIt != command.end(); + ++cmdIt) + { + std::cout << *cmdIt << " "; + } + std::cout << std::endl; + } + std::string output; + int retVal = 0; + bool result = cmSystemTools::RunSingleCommand(command, &output, &retVal); + if (!result || retVal) + { + std::cerr << "AUTOUIC: error: process for " << ui_output_file << + " failed:\n" << output << std::endl; + this->RunUicFailed = true; + cmSystemTools::RemoveFile(ui_output_file.c_str()); + return false; + } + return true; + } + return false; +} + +bool cmQtAutoGenerators::GenerateQrc() +{ + std::vector<std::string> sourceFiles; + cmSystemTools::ExpandListArgument(this->RccSources, sourceFiles); + + for(std::vector<std::string>::const_iterator si = sourceFiles.begin(); + si != sourceFiles.end(); ++si) + { + std::string ext = cmsys::SystemTools::GetFilenameLastExtension(*si); + + if (ext != ".qrc") + { + continue; + } + std::vector<cmStdString> command; + command.push_back(this->RccExecutable); + + std::string basename = cmsys::SystemTools:: + GetFilenameWithoutLastExtension(*si); + + std::string rcc_output_file = this->Builddir + "qrc_" + basename + ".cpp"; + + int sourceNewerThanQrc = 0; + bool success = cmsys::SystemTools::FileTimeCompare(si->c_str(), + rcc_output_file.c_str(), + &sourceNewerThanQrc); + if (this->GenerateAll || !success || sourceNewerThanQrc >= 0) + { + std::string options; + std::map<std::string, std::string>::const_iterator optionIt + = this->RccOptions.find(*si); + if (optionIt != this->RccOptions.end()) + { + std::vector<std::string> opts; + cmSystemTools::ExpandListArgument(optionIt->second, opts); + for(std::vector<std::string>::const_iterator optIt = opts.begin(); + optIt != opts.end(); + ++optIt) + { + command.push_back(*optIt); + } + } + + command.push_back("-o"); + command.push_back(rcc_output_file); + command.push_back(*si); + + if (this->Verbose) + { + for(std::vector<cmStdString>::const_iterator cmdIt = command.begin(); + cmdIt != command.end(); + ++cmdIt) + { + std::cout << *cmdIt << " "; + } + std::cout << std::endl; + } + std::string output; + int retVal = 0; + bool result = cmSystemTools::RunSingleCommand(command, &output, &retVal); + if (!result || retVal) + { + std::cerr << "AUTORCC: error: process for " << rcc_output_file << + " failed:\n" << output << std::endl; + this->RunRccFailed = true; + cmSystemTools::RemoveFile(rcc_output_file.c_str()); + return false; + } + } + } + return true; +} -std::string cmQtAutomoc::Join(const std::vector<std::string>& lst, +std::string cmQtAutoGenerators::Join(const std::vector<std::string>& lst, char separator) { if (lst.empty()) @@ -1291,13 +1980,15 @@ std::string cmQtAutomoc::Join(const std::vector<std::string>& lst, } -bool cmQtAutomoc::StartsWith(const std::string& str, const std::string& with) +bool cmQtAutoGenerators::StartsWith(const std::string& str, + const std::string& with) { return (str.substr(0, with.length()) == with); } -bool cmQtAutomoc::EndsWith(const std::string& str, const std::string& with) +bool cmQtAutoGenerators::EndsWith(const std::string& str, + const std::string& with) { if (with.length() > (str.length())) { @@ -1307,7 +1998,7 @@ bool cmQtAutomoc::EndsWith(const std::string& str, const std::string& with) } -std::string cmQtAutomoc::ReadAll(const std::string& filename) +std::string cmQtAutoGenerators::ReadAll(const std::string& filename) { std::ifstream file(filename.c_str()); cmsys_ios::stringstream stream; diff --git a/Source/cmQtAutomoc.h b/Source/cmQtAutoGenerators.h index ebeeb0e..696abc8 100644 --- a/Source/cmQtAutomoc.h +++ b/Source/cmQtAutoGenerators.h @@ -11,26 +11,33 @@ See the License for more information. ============================================================================*/ -#ifndef cmQtAutomoc_h -#define cmQtAutomoc_h +#ifndef cmQtAutoGenerators_h +#define cmQtAutoGenerators_h class cmGlobalGenerator; class cmMakefile; -class cmQtAutomoc +class cmQtAutoGenerators { public: - cmQtAutomoc(); + cmQtAutoGenerators(); bool Run(const char* targetDirectory, const char *config); bool InitializeMocSourceFile(cmTarget* target); - void SetupAutomocTarget(cmTarget* target); + void SetupAutoGenerateTarget(cmTarget* target); private: + void SetupAutoMocTarget(cmTarget* target, + const std::string &autogenTargetName, + std::map<std::string, std::string> &configIncludes, + std::map<std::string, std::string> &configDefines); + void SetupAutoUicTarget(cmTarget* target); + void SetupAutoRccTarget(cmTarget* target); + cmGlobalGenerator* CreateGlobalGenerator(cmake* cm, const char* targetDirectory); - bool ReadAutomocInfoFile(cmMakefile* makefile, + bool ReadAutogenInfoFile(cmMakefile* makefile, const char* targetDirectory, const char *config); bool ReadOldMocDefinitionsFile(cmMakefile* makefile, @@ -39,22 +46,34 @@ private: std::string MakeCompileSettingsString(cmMakefile* makefile); - bool RunAutomoc(cmMakefile* makefile); + bool RunAutogen(cmMakefile* makefile); bool GenerateMoc(const std::string& sourceFile, const std::string& mocFileName); + bool GenerateUi(const std::string& uiFileName); + bool GenerateQrc(); void ParseCppFile(const std::string& absFilename, const std::vector<std::string>& headerExtensions, - std::map<std::string, std::string>& includedMocs); + std::map<std::string, std::string>& includedMocs, + std::vector<std::string>& includedUis); void StrictParseCppFile(const std::string& absFilename, const std::vector<std::string>& headerExtensions, - std::map<std::string, std::string>& includedMocs); + std::map<std::string, std::string>& includedMocs, + std::vector<std::string>& includedUis); void SearchHeadersForCppFile(const std::string& absFilename, const std::vector<std::string>& headerExtensions, std::set<std::string>& absHeaders); void ParseHeaders(const std::set<std::string>& absHeaders, const std::map<std::string, std::string>& includedMocs, - std::map<std::string, std::string>& notIncludedMocs); + std::map<std::string, std::string>& notIncludedMocs, + std::vector<std::string>& includedUis); + + void ParseForUic(const std::string& fileName, + const std::string& contentsString, + std::vector<std::string>& includedUis); + + void ParseForUic(const std::string& fileName, + std::vector<std::string>& includedUis); void Init(); @@ -63,13 +82,24 @@ private: bool StartsWith(const std::string& str, const std::string& with); std::string ReadAll(const std::string& filename); + void MergeUicOptions(std::vector<std::string> &opts, + const std::vector<std::string> &fileOpts, bool isQt5); + + void MergeRccOptions(std::vector<std::string> &opts, + const std::vector<std::string> &fileOpts, bool isQt5); + std::string QtMajorVersion; std::string Sources; + std::string RccSources; + std::string SkipMoc; + std::string SkipUic; std::string Headers; bool IncludeProjectDirsBefore; std::string Srcdir; std::string Builddir; std::string MocExecutable; + std::string UicExecutable; + std::string RccExecutable; std::string MocCompileDefinitionsStr; std::string MocIncludesStr; std::string MocOptionsStr; @@ -84,10 +114,15 @@ private: std::list<std::string> MocIncludes; std::list<std::string> MocDefinitions; std::vector<std::string> MocOptions; + std::vector<std::string> UicTargetOptions; + std::map<std::string, std::string> UicOptions; + std::map<std::string, std::string> RccOptions; bool Verbose; bool ColorOutput; bool RunMocFailed; + bool RunUicFailed; + bool RunRccFailed; bool GenerateAll; bool RelaxedMode; diff --git a/Source/cmSourceFile.cxx b/Source/cmSourceFile.cxx index d747309..ec98c2c 100644 --- a/Source/cmSourceFile.cxx +++ b/Source/cmSourceFile.cxx @@ -287,6 +287,17 @@ void cmSourceFile::SetProperty(const char* prop, const char* value) } this->Properties.SetProperty(prop, value, cmProperty::SOURCE_FILE); + + std::string ext = + cmSystemTools::GetFilenameLastExtension(this->Location.GetName()); + if (ext == ".ui") + { + cmMakefile* mf = this->Location.GetMakefile(); + if (strcmp(prop, "AUTOUIC_OPTIONS") == 0) + { + mf->AddQtUiFileWithOptions(this); + } + } } //---------------------------------------------------------------------------- diff --git a/Source/cmTarget.cxx b/Source/cmTarget.cxx index 7f484e0..92eca0f 100644 --- a/Source/cmTarget.cxx +++ b/Source/cmTarget.cxx @@ -266,7 +266,11 @@ void cmTarget::SetMakefile(cmMakefile* mf) this->SetPropertyDefault("GNUtoMS", 0); this->SetPropertyDefault("OSX_ARCHITECTURES", 0); this->SetPropertyDefault("AUTOMOC", 0); + this->SetPropertyDefault("AUTOUIC", 0); + this->SetPropertyDefault("AUTORCC", 0); this->SetPropertyDefault("AUTOMOC_MOC_OPTIONS", 0); + this->SetPropertyDefault("AUTOUIC_OPTIONS", 0); + this->SetPropertyDefault("AUTORCC_OPTIONS", 0); this->SetPropertyDefault("LINK_DEPENDS_NO_SHARED", 0); this->SetPropertyDefault("LINK_INTERFACE_LIBRARIES", 0); this->SetPropertyDefault("WIN32_EXECUTABLE", 0); diff --git a/Source/cmake.cxx b/Source/cmake.cxx index 186d4e6..f786691 100644 --- a/Source/cmake.cxx +++ b/Source/cmake.cxx @@ -1468,9 +1468,9 @@ int cmake::ActualConfigure() {"7.1", "Visual Studio 7 .NET 2003"}, {"8.0", "Visual Studio 8 2005"}, {"9.0", "Visual Studio 9 2008"}, - {"10.0", "Visual Studio 10"}, - {"11.0", "Visual Studio 11"}, - {"12.0", "Visual Studio 12"}, + {"10.0", "Visual Studio 10 2010"}, + {"11.0", "Visual Studio 11 2012"}, + {"12.0", "Visual Studio 12 2013"}, {0, 0}}; for(int i=0; version[i].MSVersion != 0; i++) { @@ -1509,7 +1509,7 @@ int cmake::ActualConfigure() const char* genName = this->CacheManager->GetCacheValue("CMAKE_GENERATOR"); if(genName) { - if(strcmp(this->GlobalGenerator->GetName(), genName) != 0) + if(!this->GlobalGenerator->MatchesGeneratorName(genName)) { std::string message = "Error: generator : "; message += this->GlobalGenerator->GetName(); diff --git a/Source/cmcmd.cxx b/Source/cmcmd.cxx index 9814aea..26251b3 100644 --- a/Source/cmcmd.cxx +++ b/Source/cmcmd.cxx @@ -13,7 +13,7 @@ #include "cmMakefile.h" #include "cmLocalGenerator.h" #include "cmGlobalGenerator.h" -#include "cmQtAutomoc.h" +#include "cmQtAutoGenerators.h" #include "cmVersion.h" #if defined(CMAKE_BUILD_WITH_CMAKE) @@ -632,12 +632,12 @@ int cmcmd::ExecuteCMakeCommand(std::vector<std::string>& args) { return cmcmd::ExecuteEchoColor(args); } - else if (args[1] == "cmake_automoc") + else if (args[1] == "cmake_autogen") { - cmQtAutomoc automoc; + cmQtAutoGenerators autogen; const char *config = args[3].empty() ? 0 : args[3].c_str(); - bool automocSuccess = automoc.Run(args[2].c_str(), config); - return automocSuccess ? 0 : 1; + bool autogenSuccess = autogen.Run(args[2].c_str(), config); + return autogenSuccess ? 0 : 1; } #endif diff --git a/Tests/CMakeLists.txt b/Tests/CMakeLists.txt index 5ffd9d7..7c939ed 100644 --- a/Tests/CMakeLists.txt +++ b/Tests/CMakeLists.txt @@ -1029,34 +1029,43 @@ ${CMake_BINARY_DIR}/bin/cmake -DVERSION=master -P ${CMake_SOURCE_DIR}/Utilities/ ) list(APPEND TEST_BUILD_DIRS "${CMake_BINARY_DIR}/Tests/QtAutomocNoQt") + # On Windows there is no RPATH, so while Qt might be available for building, + # the required dlls may not be in the PATH, so we can't run the executables + # on that platform. + if(WIN32) + set(run_autogen_test ${CMAKE_CTEST_COMMAND} -V) + else() + set(run_autogen_test QtAutogen) + endif() + find_package(Qt5Widgets QUIET NO_MODULE) if(Qt5Widgets_FOUND) - add_test(Qt5Automoc ${CMAKE_CTEST_COMMAND} + add_test(Qt5Autogen ${CMAKE_CTEST_COMMAND} --build-and-test - "${CMake_SOURCE_DIR}/Tests/QtAutomoc" - "${CMake_BINARY_DIR}/Tests/Qt5Automoc" + "${CMake_SOURCE_DIR}/Tests/QtAutogen" + "${CMake_BINARY_DIR}/Tests/Qt5Autogen" ${build_generator_args} - --build-project QtAutomoc - --build-exe-dir "${CMake_BINARY_DIR}/Tests/Qt5Automoc" + --build-project QtAutogen + --build-exe-dir "${CMake_BINARY_DIR}/Tests/Qt5Autogen" --force-new-ctest-process --build-options -DQT_QMAKE_EXECUTABLE:FILEPATH=${QT_QMAKE_EXECUTABLE} -DQT_TEST_VERSION=5 - --test-command ${CMAKE_CTEST_COMMAND} -V + --test-command ${run_autogen_test} ) - list(APPEND TEST_BUILD_DIRS "${CMake_BINARY_DIR}/Tests/Qt5Automoc") + list(APPEND TEST_BUILD_DIRS "${CMake_BINARY_DIR}/Tests/Qt5Autogen") endif() if(QT4_WORKS AND QT_QTGUI_FOUND) - add_test(Qt4Automoc ${CMAKE_CTEST_COMMAND} + add_test(Qt4Autogen ${CMAKE_CTEST_COMMAND} --build-and-test - "${CMake_SOURCE_DIR}/Tests/QtAutomoc" - "${CMake_BINARY_DIR}/Tests/Qt4Automoc" + "${CMake_SOURCE_DIR}/Tests/QtAutogen" + "${CMake_BINARY_DIR}/Tests/Qt4Autogen" ${build_generator_args} - --build-project QtAutomoc - --build-exe-dir "${CMake_BINARY_DIR}/Tests/Qt4Automoc" + --build-project QtAutogen + --build-exe-dir "${CMake_BINARY_DIR}/Tests/Qt4Autogen" --force-new-ctest-process --build-options -DQT_QMAKE_EXECUTABLE:FILEPATH=${QT_QMAKE_EXECUTABLE} -DQT_TEST_VERSION=4 - --test-command ${CMAKE_CTEST_COMMAND} -V + --test-command ${run_autogen_test} ) - list(APPEND TEST_BUILD_DIRS "${CMake_BINARY_DIR}/Tests/Qt4Automoc") + list(APPEND TEST_BUILD_DIRS "${CMake_BINARY_DIR}/Tests/Qt4Autogen") add_test(Qt4Targets ${CMAKE_CTEST_COMMAND} --build-and-test @@ -2335,6 +2344,17 @@ ${CMake_BINARY_DIR}/bin/cmake -DVERSION=master -P ${CMake_SOURCE_DIR}/Utilities/ --output-log "${CMake_BINARY_DIR}/Tests/CTestTest2/testOutput.log" ) + if("${CMAKE_TEST_GENERATOR}" MATCHES "Makefiles" OR "${CMAKE_TEST_GENERATOR}" MATCHES "Ninja") + configure_file("${CMake_SOURCE_DIR}/Tests/CTestTestLaunchers/test.cmake.in" + "${CMake_BINARY_DIR}/Tests/CTestTestLaunchers/test.cmake" @ONLY ESCAPE_QUOTES) + add_test(CTestTestLaunchers ${CMAKE_CTEST_COMMAND} + -S "${CMake_BINARY_DIR}/Tests/CTestTestLaunchers/test.cmake" -V + --output-log "${CMake_BINARY_DIR}/Tests/CTestTestLaunchers/testOutput.log" + ) + set_tests_properties(CTestTestLaunchers PROPERTIES + PASS_REGULAR_EXPRESSION "CTEST_TEST_LAUNCHER_SUCCESS") + endif() + configure_file("${CMake_SOURCE_DIR}/Tests/CTestTestChecksum/test.cmake.in" "${CMake_BINARY_DIR}/Tests/CTestTestChecksum/test.cmake" @ONLY ESCAPE_QUOTES) diff --git a/Tests/CTestTestLaunchers/launcher_test_project/CMakeLists.txt b/Tests/CTestTestLaunchers/launcher_test_project/CMakeLists.txt new file mode 100644 index 0000000..06c5725 --- /dev/null +++ b/Tests/CTestTestLaunchers/launcher_test_project/CMakeLists.txt @@ -0,0 +1,19 @@ +cmake_minimum_required(VERSION 2.8.12) + +project(launcher_test_project) + +include(CTest) + +add_custom_command( + OUTPUT test1.txt + COMMAND ${CMAKE_COMMAND} + ARGS -DTESTID=1 -P "${CMAKE_CURRENT_SOURCE_DIR}/command.cmake" +) + +add_custom_command( + OUTPUT test2.txt + COMMAND ${CMAKE_COMMAND} + ARGS -DTESTID=2 -P "${CMAKE_CURRENT_SOURCE_DIR}/command.cmake" +) + +add_custom_target(mytarget ALL DEPENDS test1.txt test2.txt) diff --git a/Tests/CTestTestLaunchers/launcher_test_project/CTestConfig.cmake b/Tests/CTestTestLaunchers/launcher_test_project/CTestConfig.cmake new file mode 100644 index 0000000..bf404ab --- /dev/null +++ b/Tests/CTestTestLaunchers/launcher_test_project/CTestConfig.cmake @@ -0,0 +1,8 @@ +set(CTEST_USE_LAUNCHERS 1) +set(CTEST_PROJECT_NAME "CTestTestLaunchers") +set(CTEST_NIGHTLY_START_TIME "21:00:00 EDT") +set(CTEST_DART_SERVER_VERSION "2") +set(CTEST_DROP_METHOD "http") +set(CTEST_DROP_SITE "www.cdash.org") +set(CTEST_DROP_LOCATION "/CDash/submit.php?project=PublicDashboard") +set(CTEST_DROP_SITE_CDASH TRUE) diff --git a/Tests/CTestTestLaunchers/launcher_test_project/command.cmake b/Tests/CTestTestLaunchers/launcher_test_project/command.cmake new file mode 100644 index 0000000..7f31af9 --- /dev/null +++ b/Tests/CTestTestLaunchers/launcher_test_project/command.cmake @@ -0,0 +1,5 @@ +if("${TESTID}" STREQUAL "1") + message("success") +elseif("${TESTID}" STREQUAL "2") + message(FATAL_ERROR "failure") +endif() diff --git a/Tests/CTestTestLaunchers/test.cmake.in b/Tests/CTestTestLaunchers/test.cmake.in new file mode 100644 index 0000000..43a6533 --- /dev/null +++ b/Tests/CTestTestLaunchers/test.cmake.in @@ -0,0 +1,39 @@ +cmake_minimum_required(VERSION 2.8.12) + +# Settings: +set(CTEST_DASHBOARD_SOURCE "@CMake_SOURCE_DIR@/Tests/CTestTestLaunchers") +set(CTEST_DASHBOARD_ROOT "@CMake_BINARY_DIR@/Tests/CTestTestLaunchers") +set(CTEST_SITE "@SITE@") +set(CTEST_BUILD_NAME "Launchers-@BUILDNAME@-CTestTestLaunchers") + +set(CTEST_SOURCE_DIRECTORY "${CTEST_DASHBOARD_SOURCE}/launcher_test_project") +set(CTEST_BINARY_DIRECTORY "${CTEST_DASHBOARD_ROOT}/launcher_test_project-bin") +set(CTEST_CMAKE_GENERATOR "@CMAKE_GENERATOR@") +set(CTEST_CMAKE_GENERATOR_TOOLSET "@CMAKE_GENERATOR_TOOLSET@") +set(CTEST_BUILD_CONFIGURATION "$ENV{CMAKE_CONFIG_TYPE}") +set(CTEST_NOTES_FILES "${CTEST_SCRIPT_DIRECTORY}/${CTEST_SCRIPT_NAME}") + +ctest_empty_binary_directory(${CTEST_BINARY_DIRECTORY}) + +file(WRITE "${CTEST_BINARY_DIRECTORY}/CMakeCache.txt" " +CMAKE_CXX_FLAGS:STRING=@CMAKE_CXX_FLAGS@ +CMAKE_C_FLAGS:STRING=@CMAKE_C_FLAGS@ +CMAKE_C_COMPILER:STRING=@CMAKE_C_COMPILER@ +CMAKE_CXX_COMPILER:STRING=@CMAKE_CXX_COMPILER@ +CMAKE_C_COMPILER_ARG1:STRING=@CMAKE_C_COMPILER_ARG1@ +CMAKE_CXX_COMPILER_ARG1:STRING=@CMAKE_CXX_COMPILER_ARG1@ +") + +set(TEST_SUCCESS FALSE) + +ctest_start(Experimental) +ctest_configure(OPTIONS "-DCTEST_USE_LAUNCHERS=1") +ctest_build(NUMBER_ERRORS error_count) + +if("${error_count}" STREQUAL "1") + set(TEST_SUCCESS TRUE) +endif() + +if(TEST_SUCCESS) + message("CTEST_TEST_LAUNCHER_SUCCESS") +endif() diff --git a/Tests/CTestTestStopTime/GetDate.cmake b/Tests/CTestTestStopTime/GetDate.cmake index fc55031..edc6519 100644 --- a/Tests/CTestTestStopTime/GetDate.cmake +++ b/Tests/CTestTestStopTime/GetDate.cmake @@ -1,4 +1,4 @@ -cmake_minimum_required(VERSION 2.4) +cmake_minimum_required(VERSION 2.8.11) macro(GET_DATE) # @@ -13,10 +13,7 @@ macro(GET_DATE) # ${GD_PREFIX}PREFIX (if '${GD_PREFIX}' is not 'GD_'...!) # ${GD_PREFIX}VERBOSE # - # ${GD_PREFIX}CMD - # ${GD_PREFIX}ARGS # ${GD_PREFIX}OV - # ${GD_PREFIX}RV # # ${GD_PREFIX}REGEX # ${GD_PREFIX}YEAR @@ -25,8 +22,6 @@ macro(GET_DATE) # ${GD_PREFIX}HOUR # ${GD_PREFIX}MINUTE # ${GD_PREFIX}SECOND - # ${GD_PREFIX}FRACTIONAL_SECOND - # ${GD_PREFIX}DAY_OF_WEEK # # Caller can then use these variables to construct names based on # date and time stamps... @@ -51,31 +46,10 @@ macro(GET_DATE) # Retrieve the current date and time in the format: # - # Thu 01/12/2006 8:55:12.01 - # dow mm/dd/YYYY HH:MM:SS.ssssss + # 01/12/2006 08:55:12 + # mm/dd/YYYY HH:MM:SS # - # Use "echo %DATE% %TIME%" on Windows. - # Otherwise, try "date" as implemented on most Unix flavors. - # - if(WIN32) - # - # Use "cmd" shell with %DATE% and %TIME% support... - # May need adjustment in different locales or for custom date/time formats - # set in the Windows Control Panel. - # - set(${GD_PREFIX}CMD "cmd") - set(${GD_PREFIX}ARGS "/c echo %DATE% %TIME%") - else() - # - # Match the format returned by default in US English Windows: - # - set(${GD_PREFIX}CMD "date") - set(${GD_PREFIX}ARGS "\"+%a %m/%d/%Y %H:%M:%S.00\"") - endif() - - exec_program("${${GD_PREFIX}CMD}" "." ARGS "${${GD_PREFIX}ARGS}" - OUTPUT_VARIABLE ${GD_PREFIX}OV RETURN_VALUE ${GD_PREFIX}RV - ) + string(TIMESTAMP "${GD_PREFIX}OV" "%m/%d/%Y %H:%M:%S") if(${GD_PREFIX}VERBOSE) message(STATUS "") @@ -87,114 +61,39 @@ macro(GET_DATE) endif() message(STATUS "${GD_PREFIX}VERBOSE='${${GD_PREFIX}VERBOSE}'") message(STATUS "") - message(STATUS "${GD_PREFIX}CMD='${${GD_PREFIX}CMD}'") - message(STATUS "${GD_PREFIX}ARGS='${${GD_PREFIX}ARGS}'") message(STATUS "${GD_PREFIX}OV='${${GD_PREFIX}OV}'") - message(STATUS "${GD_PREFIX}RV='${${GD_PREFIX}RV}'") message(STATUS "") endif() - if("${${GD_PREFIX}RV}" STREQUAL "0") - # - # Extract eight individual components by matching a regex with paren groupings. - # Use the replace functionality and \\1 thru \\8 to extract components. - # - set(${GD_PREFIX}REGEX "([^ ]+) +([^/]+)/([^/]+)/([^ ]+) +([^:]+):([^:]+):([^\\.]+)\\.(.*)") - - string(REGEX REPLACE "${${GD_PREFIX}REGEX}" "\\1" ${GD_PREFIX}DAY_OF_WEEK "${${GD_PREFIX}OV}") - string(REGEX REPLACE "${${GD_PREFIX}REGEX}" "\\2" ${GD_PREFIX}MONTH "${${GD_PREFIX}OV}") - string(REGEX REPLACE "${${GD_PREFIX}REGEX}" "\\3" ${GD_PREFIX}DAY "${${GD_PREFIX}OV}") - string(REGEX REPLACE "${${GD_PREFIX}REGEX}" "\\4" ${GD_PREFIX}YEAR "${${GD_PREFIX}OV}") - string(REGEX REPLACE "${${GD_PREFIX}REGEX}" "\\5" ${GD_PREFIX}HOUR "${${GD_PREFIX}OV}") - string(REGEX REPLACE "${${GD_PREFIX}REGEX}" "\\6" ${GD_PREFIX}MINUTE "${${GD_PREFIX}OV}") - string(REGEX REPLACE "${${GD_PREFIX}REGEX}" "\\7" ${GD_PREFIX}SECOND "${${GD_PREFIX}OV}") - string(REGEX REPLACE "${${GD_PREFIX}REGEX}" "\\8" ${GD_PREFIX}FRACTIONAL_SECOND "${${GD_PREFIX}OV}") - - # - # Verify that extracted components don't have anything obviously - # wrong with them... Emit warnings if something looks suspicious... - # - - # Expecting a four digit year: - # - if(NOT "${${GD_PREFIX}YEAR}" MATCHES "^[0-9][0-9][0-9][0-9]$") - message(STATUS "WARNING: Extracted ${GD_PREFIX}YEAR='${${GD_PREFIX}YEAR}' is not a four digit number...") - endif() - - # Expecting month to be <= 12: - # - if(${${GD_PREFIX}MONTH} GREATER 12) - message(STATUS "WARNING: Extracted ${GD_PREFIX}MONTH='${${GD_PREFIX}MONTH}' is greater than 12!") - endif() - - # Expecting day to be <= 31: - # - if(${${GD_PREFIX}DAY} GREATER 31) - message(STATUS "WARNING: Extracted ${GD_PREFIX}DAY='${${GD_PREFIX}DAY}' is greater than 31!") - endif() - - # Expecting hour to be <= 23: - # - if(${${GD_PREFIX}HOUR} GREATER 23) - message(STATUS "WARNING: Extracted ${GD_PREFIX}HOUR='${${GD_PREFIX}HOUR}' is greater than 23!") - endif() - - # Expecting minute to be <= 59: - # - if(${${GD_PREFIX}MINUTE} GREATER 59) - message(STATUS "WARNING: Extracted ${GD_PREFIX}MINUTE='${${GD_PREFIX}MINUTE}' is greater than 59!") - endif() - - # Expecting second to be <= 59: - # - if(${${GD_PREFIX}SECOND} GREATER 59) - message(STATUS "WARNING: Extracted ${GD_PREFIX}SECOND='${${GD_PREFIX}SECOND}' is greater than 59!") - endif() + # + # Extract six individual components by matching a regex with paren groupings. + # Use the replace functionality and \\1 thru \\6 to extract components. + # + set(${GD_PREFIX}REGEX "([^/]+)/([^/]+)/([^ ]+) +([^:]+):([^:]+):([^\\.]+)") - # If individual components are single digit, - # prepend a leading zero: - # - if("${${GD_PREFIX}YEAR}" MATCHES "^[0-9]$") - set(${GD_PREFIX}YEAR "0${${GD_PREFIX}YEAR}") - endif() - if("${${GD_PREFIX}MONTH}" MATCHES "^[0-9]$") - set(${GD_PREFIX}MONTH "0${${GD_PREFIX}MONTH}") - endif() - if("${${GD_PREFIX}DAY}" MATCHES "^[0-9]$") - set(${GD_PREFIX}DAY "0${${GD_PREFIX}DAY}") - endif() - if("${${GD_PREFIX}HOUR}" MATCHES "^[0-9]$") - set(${GD_PREFIX}HOUR "0${${GD_PREFIX}HOUR}") - endif() - if("${${GD_PREFIX}MINUTE}" MATCHES "^[0-9]$") - set(${GD_PREFIX}MINUTE "0${${GD_PREFIX}MINUTE}") - endif() - if("${${GD_PREFIX}SECOND}" MATCHES "^[0-9]$") - set(${GD_PREFIX}SECOND "0${${GD_PREFIX}SECOND}") - endif() + string(REGEX REPLACE "${${GD_PREFIX}REGEX}" "\\1" ${GD_PREFIX}MONTH "${${GD_PREFIX}OV}") + string(REGEX REPLACE "${${GD_PREFIX}REGEX}" "\\2" ${GD_PREFIX}DAY "${${GD_PREFIX}OV}") + string(REGEX REPLACE "${${GD_PREFIX}REGEX}" "\\3" ${GD_PREFIX}YEAR "${${GD_PREFIX}OV}") + string(REGEX REPLACE "${${GD_PREFIX}REGEX}" "\\4" ${GD_PREFIX}HOUR "${${GD_PREFIX}OV}") + string(REGEX REPLACE "${${GD_PREFIX}REGEX}" "\\5" ${GD_PREFIX}MINUTE "${${GD_PREFIX}OV}") + string(REGEX REPLACE "${${GD_PREFIX}REGEX}" "\\6" ${GD_PREFIX}SECOND "${${GD_PREFIX}OV}") - if(${GD_PREFIX}VERBOSE) - message(STATUS "${GD_PREFIX}REGEX='${${GD_PREFIX}REGEX}'") - message(STATUS "${GD_PREFIX}YEAR='${${GD_PREFIX}YEAR}'") - message(STATUS "${GD_PREFIX}MONTH='${${GD_PREFIX}MONTH}'") - message(STATUS "${GD_PREFIX}DAY='${${GD_PREFIX}DAY}'") - message(STATUS "${GD_PREFIX}HOUR='${${GD_PREFIX}HOUR}'") - message(STATUS "${GD_PREFIX}MINUTE='${${GD_PREFIX}MINUTE}'") - message(STATUS "${GD_PREFIX}SECOND='${${GD_PREFIX}SECOND}'") - message(STATUS "${GD_PREFIX}FRACTIONAL_SECOND='${${GD_PREFIX}FRACTIONAL_SECOND}'") - message(STATUS "${GD_PREFIX}DAY_OF_WEEK='${${GD_PREFIX}DAY_OF_WEEK}'") - message(STATUS "") - message(STATUS "Counters that change...") - message(STATUS "") - message(STATUS "...very very quickly : ${${GD_PREFIX}YEAR}${${GD_PREFIX}MONTH}${${GD_PREFIX}DAY}${${GD_PREFIX}HOUR}${${GD_PREFIX}MINUTE}${${GD_PREFIX}SECOND}${${GD_PREFIX}FRACTIONAL_SECOND}") - message(STATUS " every second : ${${GD_PREFIX}YEAR}${${GD_PREFIX}MONTH}${${GD_PREFIX}DAY}${${GD_PREFIX}HOUR}${${GD_PREFIX}MINUTE}${${GD_PREFIX}SECOND}") - message(STATUS " daily : ${${GD_PREFIX}YEAR}${${GD_PREFIX}MONTH}${${GD_PREFIX}DAY}") - message(STATUS " monthly : ${${GD_PREFIX}YEAR}${${GD_PREFIX}MONTH}") - message(STATUS " annually : ${${GD_PREFIX}YEAR}") - message(STATUS "") - endif() - else() - message(SEND_ERROR "ERROR: macro(GET_DATE) failed. ${GD_PREFIX}CMD='${${GD_PREFIX}CMD}' ${GD_PREFIX}ARGS='${${GD_PREFIX}ARGS}' ${GD_PREFIX}OV='${${GD_PREFIX}OV}' ${GD_PREFIX}RV='${${GD_PREFIX}RV}'") + if(${GD_PREFIX}VERBOSE) + message(STATUS "${GD_PREFIX}REGEX='${${GD_PREFIX}REGEX}'") + message(STATUS "${GD_PREFIX}YEAR='${${GD_PREFIX}YEAR}'") + message(STATUS "${GD_PREFIX}MONTH='${${GD_PREFIX}MONTH}'") + message(STATUS "${GD_PREFIX}DAY='${${GD_PREFIX}DAY}'") + message(STATUS "${GD_PREFIX}HOUR='${${GD_PREFIX}HOUR}'") + message(STATUS "${GD_PREFIX}MINUTE='${${GD_PREFIX}MINUTE}'") + message(STATUS "${GD_PREFIX}SECOND='${${GD_PREFIX}SECOND}'") + message(STATUS "") + message(STATUS "Counters that change...") + message(STATUS "") + message(STATUS " every second : ${${GD_PREFIX}YEAR}${${GD_PREFIX}MONTH}${${GD_PREFIX}DAY}${${GD_PREFIX}HOUR}${${GD_PREFIX}MINUTE}${${GD_PREFIX}SECOND}") + message(STATUS " daily : ${${GD_PREFIX}YEAR}${${GD_PREFIX}MONTH}${${GD_PREFIX}DAY}") + message(STATUS " monthly : ${${GD_PREFIX}YEAR}${${GD_PREFIX}MONTH}") + message(STATUS " annually : ${${GD_PREFIX}YEAR}") + message(STATUS "") endif() if(${GD_PREFIX}VERBOSE) diff --git a/Tests/CustomCommand/CMakeLists.txt b/Tests/CustomCommand/CMakeLists.txt index 30daa7d..ff96add 100644 --- a/Tests/CustomCommand/CMakeLists.txt +++ b/Tests/CustomCommand/CMakeLists.txt @@ -449,3 +449,10 @@ set_property(SOURCE perconfig.out PROPERTY SYMBOLIC 1) add_custom_target(perconfig_target ALL COMMAND ${CMAKE_COMMAND} -E echo "perconfig=$<TARGET_FILE:perconfig>" "config=$<CONFIGURATION>" DEPENDS perconfig.out) + +# Test SOURCES in add_custom_target() with COMPILE_DEFINITIONS +# which previously caused a crash in the makefile generators. +add_custom_target(source_in_custom_target SOURCES source_in_custom_target.cpp) +set_property(SOURCE source_in_custom_target + PROPERTY COMPILE_DEFINITIONS "TEST" +) diff --git a/Tests/CustomCommand/source_in_custom_target.cpp b/Tests/CustomCommand/source_in_custom_target.cpp new file mode 100644 index 0000000..e69de29 --- /dev/null +++ b/Tests/CustomCommand/source_in_custom_target.cpp diff --git a/Tests/QtAutomoc/Adir/CMakeLists.txt b/Tests/QtAutogen/Adir/CMakeLists.txt index a1c36ff..a1c36ff 100644 --- a/Tests/QtAutomoc/Adir/CMakeLists.txt +++ b/Tests/QtAutogen/Adir/CMakeLists.txt diff --git a/Tests/QtAutomoc/Adir/libA.cpp b/Tests/QtAutogen/Adir/libA.cpp index 3968c44..3968c44 100644 --- a/Tests/QtAutomoc/Adir/libA.cpp +++ b/Tests/QtAutogen/Adir/libA.cpp diff --git a/Tests/QtAutomoc/Adir/libA.h b/Tests/QtAutogen/Adir/libA.h index 03ad1e0..03ad1e0 100644 --- a/Tests/QtAutomoc/Adir/libA.h +++ b/Tests/QtAutogen/Adir/libA.h diff --git a/Tests/QtAutomoc/Bdir/CMakeLists.txt b/Tests/QtAutogen/Bdir/CMakeLists.txt index d9d4aa7..d9d4aa7 100644 --- a/Tests/QtAutomoc/Bdir/CMakeLists.txt +++ b/Tests/QtAutogen/Bdir/CMakeLists.txt diff --git a/Tests/QtAutomoc/Bdir/libB.cpp b/Tests/QtAutogen/Bdir/libB.cpp index 72f2cfa..72f2cfa 100644 --- a/Tests/QtAutomoc/Bdir/libB.cpp +++ b/Tests/QtAutogen/Bdir/libB.cpp diff --git a/Tests/QtAutomoc/Bdir/libB.h b/Tests/QtAutogen/Bdir/libB.h index 510c17f..510c17f 100644 --- a/Tests/QtAutomoc/Bdir/libB.h +++ b/Tests/QtAutogen/Bdir/libB.h diff --git a/Tests/QtAutomoc/CMakeLists.txt b/Tests/QtAutogen/CMakeLists.txt index 8ad693a..7991c4e 100644 --- a/Tests/QtAutomoc/CMakeLists.txt +++ b/Tests/QtAutogen/CMakeLists.txt @@ -1,6 +1,6 @@ -cmake_minimum_required(VERSION 2.8) +cmake_minimum_required(VERSION 2.8.11) -project(QtAutomoc) +project(QtAutogen) if (QT_TEST_VERSION STREQUAL 4) find_package(Qt4 REQUIRED) @@ -35,15 +35,20 @@ add_definitions(-DFOO -DSomeDefine="Barx") # enable relaxed mode so automoc can handle all the special cases: set(CMAKE_AUTOMOC_RELAXED_MODE TRUE) +set(CMAKE_AUTOUIC ON) +set(CMAKE_AUTORCC ON) + # create an executable and two library targets, each requiring automoc: add_library(codeeditorLib STATIC codeeditor.cpp) add_library(privateSlot OBJECT private_slot.cpp) -add_executable(foo main.cpp calwidget.cpp foo.cpp blub.cpp bar.cpp abc.cpp - xyz.cpp yaf.cpp gadget.cpp $<TARGET_OBJECTS:privateSlot>) +add_executable(QtAutogen main.cpp calwidget.cpp foo.cpp blub.cpp bar.cpp abc.cpp + xyz.cpp yaf.cpp gadget.cpp $<TARGET_OBJECTS:privateSlot> + test.qrc resourcetester.cpp +) -set_target_properties(foo codeeditorLib privateSlot PROPERTIES AUTOMOC TRUE) +set_target_properties(QtAutogen codeeditorLib privateSlot PROPERTIES AUTOMOC TRUE) include(GenerateExportHeader) # The order is relevant here. B depends on A, and B headers depend on A @@ -59,7 +64,7 @@ set_target_properties(libC PROPERTIES AUTOMOC TRUE) generate_export_header(libC) target_link_libraries(libC LINK_PUBLIC libB) -target_link_libraries(foo codeeditorLib ${QT_LIBRARIES} libC) +target_link_libraries(QtAutogen codeeditorLib ${QT_LIBRARIES} libC) add_library(empty STATIC empty.cpp) set_target_properties(empty PROPERTIES AUTOMOC TRUE) diff --git a/Tests/QtAutomoc/abc.cpp b/Tests/QtAutogen/abc.cpp index 4bbc769..4bbc769 100644 --- a/Tests/QtAutomoc/abc.cpp +++ b/Tests/QtAutogen/abc.cpp diff --git a/Tests/QtAutomoc/abc.h b/Tests/QtAutogen/abc.h index d1924b0..d1924b0 100644 --- a/Tests/QtAutomoc/abc.h +++ b/Tests/QtAutogen/abc.h diff --git a/Tests/QtAutomoc/abc_p.h b/Tests/QtAutogen/abc_p.h index 952fff3..952fff3 100644 --- a/Tests/QtAutomoc/abc_p.h +++ b/Tests/QtAutogen/abc_p.h diff --git a/Tests/QtAutomoc/bar.cpp b/Tests/QtAutogen/bar.cpp index 8be4815..8be4815 100644 --- a/Tests/QtAutomoc/bar.cpp +++ b/Tests/QtAutogen/bar.cpp diff --git a/Tests/QtAutomoc/blub.cpp b/Tests/QtAutogen/blub.cpp index bd53972..bd53972 100644 --- a/Tests/QtAutomoc/blub.cpp +++ b/Tests/QtAutogen/blub.cpp diff --git a/Tests/QtAutomoc/blub.h b/Tests/QtAutogen/blub.h index 1967bc1..1967bc1 100644 --- a/Tests/QtAutomoc/blub.h +++ b/Tests/QtAutogen/blub.h diff --git a/Tests/QtAutomoc/calwidget.cpp b/Tests/QtAutogen/calwidget.cpp index cbfa5a8..defde20 100644 --- a/Tests/QtAutomoc/calwidget.cpp +++ b/Tests/QtAutogen/calwidget.cpp @@ -49,7 +49,10 @@ #include "calwidget.h" + #include "ui_calwidget.h" + Window::Window() + : ui(new Ui::Window) { createPreviewGroupBox(); createGeneralOptionsGroupBox(); diff --git a/Tests/QtAutomoc/calwidget.h b/Tests/QtAutogen/calwidget.h index 8447389..d21a473 100644 --- a/Tests/QtAutomoc/calwidget.h +++ b/Tests/QtAutogen/calwidget.h @@ -52,6 +52,11 @@ class QGroupBox; class QLabel; + namespace Ui + { + class Window; + } + class Window : public QWidget { Q_OBJECT @@ -116,6 +121,8 @@ QCheckBox *firstFridayCheckBox; QCheckBox *mayFirstCheckBox; + + Ui::Window *ui; }; #endif diff --git a/Tests/QtAutogen/calwidget.ui b/Tests/QtAutogen/calwidget.ui new file mode 100644 index 0000000..1c245ca --- /dev/null +++ b/Tests/QtAutogen/calwidget.ui @@ -0,0 +1,32 @@ +<?xml version="1.0" encoding="UTF-8"?> +<ui version="4.0"> + <class>Window</class> + <widget class="QWidget" name="Window"> + <property name="geometry"> + <rect> + <x>0</x> + <y>0</y> + <width>400</width> + <height>300</height> + </rect> + </property> + <property name="windowTitle"> + <string>Form</string> + </property> + <widget class="QPushButton" name="pushButton"> + <property name="geometry"> + <rect> + <x>90</x> + <y>180</y> + <width>94</width> + <height>24</height> + </rect> + </property> + <property name="text"> + <string>PushButton</string> + </property> + </widget> + </widget> + <resources/> + <connections/> +</ui> diff --git a/Tests/QtAutomoc/codeeditor.cpp b/Tests/QtAutogen/codeeditor.cpp index 01da062..01da062 100644 --- a/Tests/QtAutomoc/codeeditor.cpp +++ b/Tests/QtAutogen/codeeditor.cpp diff --git a/Tests/QtAutomoc/codeeditor.h b/Tests/QtAutogen/codeeditor.h index 56e9e792..56e9e792 100644 --- a/Tests/QtAutomoc/codeeditor.h +++ b/Tests/QtAutogen/codeeditor.h diff --git a/Tests/QtAutomoc/defines_test/CMakeLists.txt b/Tests/QtAutogen/defines_test/CMakeLists.txt index ad4e684..ad4e684 100644 --- a/Tests/QtAutomoc/defines_test/CMakeLists.txt +++ b/Tests/QtAutogen/defines_test/CMakeLists.txt diff --git a/Tests/QtAutomoc/defines_test/defines_test.cpp b/Tests/QtAutogen/defines_test/defines_test.cpp index 2836d35..2836d35 100644 --- a/Tests/QtAutomoc/defines_test/defines_test.cpp +++ b/Tests/QtAutogen/defines_test/defines_test.cpp diff --git a/Tests/QtAutomoc/empty.cpp b/Tests/QtAutogen/empty.cpp index ab32cf6..ab32cf6 100644 --- a/Tests/QtAutomoc/empty.cpp +++ b/Tests/QtAutogen/empty.cpp diff --git a/Tests/QtAutomoc/empty.h b/Tests/QtAutogen/empty.h index 4566142..4566142 100644 --- a/Tests/QtAutomoc/empty.h +++ b/Tests/QtAutogen/empty.h diff --git a/Tests/QtAutomoc/foo.cpp b/Tests/QtAutogen/foo.cpp index 699ba09..699ba09 100644 --- a/Tests/QtAutomoc/foo.cpp +++ b/Tests/QtAutogen/foo.cpp diff --git a/Tests/QtAutomoc/foo.h b/Tests/QtAutogen/foo.h index 32d4c8d..32d4c8d 100644 --- a/Tests/QtAutomoc/foo.h +++ b/Tests/QtAutogen/foo.h diff --git a/Tests/QtAutomoc/gadget.cpp b/Tests/QtAutogen/gadget.cpp index 23d95fa..23d95fa 100644 --- a/Tests/QtAutomoc/gadget.cpp +++ b/Tests/QtAutogen/gadget.cpp diff --git a/Tests/QtAutomoc/gadget.h b/Tests/QtAutogen/gadget.h index 7c688ee..7c688ee 100644 --- a/Tests/QtAutomoc/gadget.h +++ b/Tests/QtAutogen/gadget.h diff --git a/Tests/QtAutomoc/libC.cpp b/Tests/QtAutogen/libC.cpp index 8d61cb1..8d61cb1 100644 --- a/Tests/QtAutomoc/libC.cpp +++ b/Tests/QtAutogen/libC.cpp diff --git a/Tests/QtAutomoc/libC.h b/Tests/QtAutogen/libC.h index 4fb4a2c..4fb4a2c 100644 --- a/Tests/QtAutomoc/libC.h +++ b/Tests/QtAutogen/libC.h diff --git a/Tests/QtAutomoc/main.cpp b/Tests/QtAutogen/main.cpp index bd80180..c8a036e 100644 --- a/Tests/QtAutomoc/main.cpp +++ b/Tests/QtAutogen/main.cpp @@ -38,7 +38,8 @@ ** ****************************************************************************/ -#include <QApplication> +#include <QCoreApplication> +#include <QTimer> #include "codeeditor.h" #include "calwidget.h" @@ -49,17 +50,11 @@ #include "xyz.h" #include "yaf.h" #include "libC.h" +#include "resourcetester.h" int main(int argv, char **args) { - QApplication app(argv, args); - - CodeEditor editor; - editor.setWindowTitle(QObject::tr("Code Editor Example")); - editor.show(); - - Window w; - w.show(); + QCoreApplication app(argv, args); Foo foo; foo.doFoo(); @@ -82,5 +77,9 @@ int main(int argv, char **args) LibC lc; lc.foo(); + ResourceTester rt; + + QTimer::singleShot(0, &rt, SLOT(doTest())); + return app.exec(); } diff --git a/Tests/QtAutomoc/private_slot.cpp b/Tests/QtAutogen/private_slot.cpp index 1387a70..1387a70 100644 --- a/Tests/QtAutomoc/private_slot.cpp +++ b/Tests/QtAutogen/private_slot.cpp diff --git a/Tests/QtAutomoc/private_slot.h b/Tests/QtAutogen/private_slot.h index 28e5448..28e5448 100644 --- a/Tests/QtAutomoc/private_slot.h +++ b/Tests/QtAutogen/private_slot.h diff --git a/Tests/QtAutogen/resourcetester.cpp b/Tests/QtAutogen/resourcetester.cpp new file mode 100644 index 0000000..43314e1 --- /dev/null +++ b/Tests/QtAutogen/resourcetester.cpp @@ -0,0 +1,21 @@ + +#include "resourcetester.h" + +#include <QDebug> +#include <QApplication> +#include <QFile> +#include <QTimer> + +ResourceTester::ResourceTester(QObject *parent) + : QObject(parent) +{ + +} + +void ResourceTester::doTest() +{ + if (!QFile::exists(":/CMakeLists.txt")) + qApp->exit(EXIT_FAILURE); + + QTimer::singleShot(0, qApp, SLOT(quit())); +} diff --git a/Tests/QtAutogen/resourcetester.h b/Tests/QtAutogen/resourcetester.h new file mode 100644 index 0000000..b02cb4e --- /dev/null +++ b/Tests/QtAutogen/resourcetester.h @@ -0,0 +1,17 @@ + +#ifndef RESOURCE_TESTER_H +#define RESOURCE_TESTER_H + +#include <QObject> + +class ResourceTester : public QObject +{ + Q_OBJECT +public: + explicit ResourceTester(QObject *parent = 0); + +private slots: + void doTest(); +}; + +#endif diff --git a/Tests/QtAutomoc/sub/bar.h b/Tests/QtAutogen/sub/bar.h index db56b8e..db56b8e 100644 --- a/Tests/QtAutomoc/sub/bar.h +++ b/Tests/QtAutogen/sub/bar.h diff --git a/Tests/QtAutogen/test.qrc b/Tests/QtAutogen/test.qrc new file mode 100644 index 0000000..c3d4e3c --- /dev/null +++ b/Tests/QtAutogen/test.qrc @@ -0,0 +1,5 @@ +<!DOCTYPE RCC><RCC version="1.0"> +<qresource> + <file>CMakeLists.txt</file> +</qresource> +</RCC> diff --git a/Tests/QtAutomoc/xyz.cpp b/Tests/QtAutogen/xyz.cpp index a3562a3..a3562a3 100644 --- a/Tests/QtAutomoc/xyz.cpp +++ b/Tests/QtAutogen/xyz.cpp diff --git a/Tests/QtAutomoc/xyz.h b/Tests/QtAutogen/xyz.h index 8175d37..8175d37 100644 --- a/Tests/QtAutomoc/xyz.h +++ b/Tests/QtAutogen/xyz.h diff --git a/Tests/QtAutomoc/yaf.cpp b/Tests/QtAutogen/yaf.cpp index d278ab4..d278ab4 100644 --- a/Tests/QtAutomoc/yaf.cpp +++ b/Tests/QtAutogen/yaf.cpp diff --git a/Tests/QtAutomoc/yaf.h b/Tests/QtAutogen/yaf.h index 8689f83..8689f83 100644 --- a/Tests/QtAutomoc/yaf.h +++ b/Tests/QtAutogen/yaf.h diff --git a/Tests/QtAutomoc/yaf_p.h b/Tests/QtAutogen/yaf_p.h index f0368ad..f0368ad 100644 --- a/Tests/QtAutomoc/yaf_p.h +++ b/Tests/QtAutogen/yaf_p.h diff --git a/Tests/RunCMake/CMakeLists.txt b/Tests/RunCMake/CMakeLists.txt index e84aba2..97bf14d 100644 --- a/Tests/RunCMake/CMakeLists.txt +++ b/Tests/RunCMake/CMakeLists.txt @@ -60,6 +60,7 @@ add_RunCMake_test(CTest) if(UNIX AND "${CMAKE_TEST_GENERATOR}" MATCHES "Unix Makefiles") add_RunCMake_test(CompilerChange) endif() +add_RunCMake_test(CompilerNotFound) add_RunCMake_test(Configure) add_RunCMake_test(DisallowedCommands) add_RunCMake_test(ExternalData) diff --git a/Tests/RunCMake/CompilerChange/EmptyCompiler-override.cmake b/Tests/RunCMake/CompilerChange/EmptyCompiler-override.cmake new file mode 100644 index 0000000..28d29e0 --- /dev/null +++ b/Tests/RunCMake/CompilerChange/EmptyCompiler-override.cmake @@ -0,0 +1,2 @@ +message(STATUS "CMAKE_C_COMPILER is \"${CMAKE_C_COMPILER}\"") +file(WRITE "${CMAKE_CURRENT_BINARY_DIR}/cc.cmake" "set(CMAKE_C_COMPILER \"${CMAKE_C_COMPILER}\")\n") diff --git a/Tests/RunCMake/CompilerChange/EmptyCompiler-stderr.txt b/Tests/RunCMake/CompilerChange/EmptyCompiler-stderr.txt index 4745b25..cf3b1b3 100644 --- a/Tests/RunCMake/CompilerChange/EmptyCompiler-stderr.txt +++ b/Tests/RunCMake/CompilerChange/EmptyCompiler-stderr.txt @@ -1,5 +1,13 @@ You have changed variables that require your cache to be deleted. Configure will be re-run and you may have to reset some variables. The following variables have changed: -CMAKE_C_COMPILER= *( -|$) +CMAKE_C_COMPILER= * ++ +CMake Error at EmptyCompiler.cmake:2 \(enable_language\): + No CMAKE_C_COMPILER could be found. + + Tell CMake where to find the compiler by setting either the environment + variable "CC" or the CMake cache entry CMAKE_C_COMPILER to the full path to + the compiler, or to the compiler name if it is in the PATH. +Call Stack \(most recent call first\): + CMakeLists.txt:6 \(include\)$ diff --git a/Tests/RunCMake/CompilerChange/EmptyCompiler.cmake b/Tests/RunCMake/CompilerChange/EmptyCompiler.cmake index c87ec49..06e9e03 100644 --- a/Tests/RunCMake/CompilerChange/EmptyCompiler.cmake +++ b/Tests/RunCMake/CompilerChange/EmptyCompiler.cmake @@ -1,3 +1,2 @@ +set(CMAKE_USER_MAKE_RULES_OVERRIDE_C ${CMAKE_CURRENT_LIST_DIR}/EmptyCompiler-override.cmake) enable_language(C) -message(STATUS "CMAKE_C_COMPILER is \"${CMAKE_C_COMPILER}\"") -file(WRITE "${CMAKE_CURRENT_BINARY_DIR}/cc.cmake" "set(CMAKE_C_COMPILER \"${CMAKE_C_COMPILER}\")\n") diff --git a/Tests/RunCMake/CompilerNotFound/BadCompilerC-result.txt b/Tests/RunCMake/CompilerNotFound/BadCompilerC-result.txt new file mode 100644 index 0000000..d00491f --- /dev/null +++ b/Tests/RunCMake/CompilerNotFound/BadCompilerC-result.txt @@ -0,0 +1 @@ +1 diff --git a/Tests/RunCMake/CompilerNotFound/BadCompilerC-stderr.txt b/Tests/RunCMake/CompilerNotFound/BadCompilerC-stderr.txt new file mode 100644 index 0000000..c98842d --- /dev/null +++ b/Tests/RunCMake/CompilerNotFound/BadCompilerC-stderr.txt @@ -0,0 +1,12 @@ +CMake Error at BadCompilerC.cmake:2 \(enable_language\): + The CMAKE_C_COMPILER: + + no-C-compiler + + is not a full path and was not found in the PATH. + + Tell CMake where to find the compiler by setting either the environment + variable "CC" or the CMake cache entry CMAKE_C_COMPILER to the full path to + the compiler, or to the compiler name if it is in the PATH. +Call Stack \(most recent call first\): + CMakeLists.txt:3 \(include\)$ diff --git a/Tests/RunCMake/CompilerNotFound/BadCompilerC.cmake b/Tests/RunCMake/CompilerNotFound/BadCompilerC.cmake new file mode 100644 index 0000000..10fe59a --- /dev/null +++ b/Tests/RunCMake/CompilerNotFound/BadCompilerC.cmake @@ -0,0 +1,3 @@ +set(CMAKE_C_COMPILER "no-C-compiler") +enable_language(C) +message(FATAL_ERROR "This error should not be reached.") diff --git a/Tests/RunCMake/CompilerNotFound/BadCompilerCXX-result.txt b/Tests/RunCMake/CompilerNotFound/BadCompilerCXX-result.txt new file mode 100644 index 0000000..d00491f --- /dev/null +++ b/Tests/RunCMake/CompilerNotFound/BadCompilerCXX-result.txt @@ -0,0 +1 @@ +1 diff --git a/Tests/RunCMake/CompilerNotFound/BadCompilerCXX-stderr.txt b/Tests/RunCMake/CompilerNotFound/BadCompilerCXX-stderr.txt new file mode 100644 index 0000000..7ef4f5e --- /dev/null +++ b/Tests/RunCMake/CompilerNotFound/BadCompilerCXX-stderr.txt @@ -0,0 +1,12 @@ +CMake Error at BadCompilerCXX.cmake:2 \(enable_language\): + The CMAKE_CXX_COMPILER: + + no-CXX-compiler + + is not a full path and was not found in the PATH. + + Tell CMake where to find the compiler by setting either the environment + variable "CXX" or the CMake cache entry CMAKE_CXX_COMPILER to the full path + to the compiler, or to the compiler name if it is in the PATH. +Call Stack \(most recent call first\): + CMakeLists.txt:3 \(include\)$ diff --git a/Tests/RunCMake/CompilerNotFound/BadCompilerCXX.cmake b/Tests/RunCMake/CompilerNotFound/BadCompilerCXX.cmake new file mode 100644 index 0000000..3b1e890 --- /dev/null +++ b/Tests/RunCMake/CompilerNotFound/BadCompilerCXX.cmake @@ -0,0 +1,3 @@ +set(CMAKE_CXX_COMPILER "no-CXX-compiler") +enable_language(CXX) +message(FATAL_ERROR "This error should not be reached.") diff --git a/Tests/RunCMake/CompilerNotFound/BadCompilerCandCXX-result.txt b/Tests/RunCMake/CompilerNotFound/BadCompilerCandCXX-result.txt new file mode 100644 index 0000000..d00491f --- /dev/null +++ b/Tests/RunCMake/CompilerNotFound/BadCompilerCandCXX-result.txt @@ -0,0 +1 @@ +1 diff --git a/Tests/RunCMake/CompilerNotFound/BadCompilerCandCXX-stderr.txt b/Tests/RunCMake/CompilerNotFound/BadCompilerCandCXX-stderr.txt new file mode 100644 index 0000000..eecff54 --- /dev/null +++ b/Tests/RunCMake/CompilerNotFound/BadCompilerCandCXX-stderr.txt @@ -0,0 +1,25 @@ +CMake Error at BadCompilerCandCXX.cmake:3 \(project\): + The CMAKE_C_COMPILER: + + no-C-compiler + + is not a full path and was not found in the PATH. + + Tell CMake where to find the compiler by setting either the environment + variable "CC" or the CMake cache entry CMAKE_C_COMPILER to the full path to + the compiler, or to the compiler name if it is in the PATH. +Call Stack \(most recent call first\): + CMakeLists.txt:3 \(include\) ++ +CMake Error at BadCompilerCandCXX.cmake:3 \(project\): + The CMAKE_CXX_COMPILER: + + no-CXX-compiler + + is not a full path and was not found in the PATH. + + Tell CMake where to find the compiler by setting either the environment + variable "CXX" or the CMake cache entry CMAKE_CXX_COMPILER to the full path + to the compiler, or to the compiler name if it is in the PATH. +Call Stack \(most recent call first\): + CMakeLists.txt:3 \(include\)$ diff --git a/Tests/RunCMake/CompilerNotFound/BadCompilerCandCXX.cmake b/Tests/RunCMake/CompilerNotFound/BadCompilerCandCXX.cmake new file mode 100644 index 0000000..2b6fa61 --- /dev/null +++ b/Tests/RunCMake/CompilerNotFound/BadCompilerCandCXX.cmake @@ -0,0 +1,4 @@ +set(CMAKE_C_COMPILER "no-C-compiler") +set(CMAKE_CXX_COMPILER "no-CXX-compiler") +project(BadCompilerCandCXXInner C CXX) +message(FATAL_ERROR "This error should not be reached.") diff --git a/Tests/RunCMake/CompilerNotFound/CMakeLists.txt b/Tests/RunCMake/CompilerNotFound/CMakeLists.txt new file mode 100644 index 0000000..12cd3c7 --- /dev/null +++ b/Tests/RunCMake/CompilerNotFound/CMakeLists.txt @@ -0,0 +1,3 @@ +cmake_minimum_required(VERSION 2.8.4) +project(${RunCMake_TEST} NONE) +include(${RunCMake_TEST}.cmake) diff --git a/Tests/RunCMake/CompilerNotFound/NoCompilerC-IDE-result.txt b/Tests/RunCMake/CompilerNotFound/NoCompilerC-IDE-result.txt new file mode 100644 index 0000000..d00491f --- /dev/null +++ b/Tests/RunCMake/CompilerNotFound/NoCompilerC-IDE-result.txt @@ -0,0 +1 @@ +1 diff --git a/Tests/RunCMake/CompilerNotFound/NoCompilerC-IDE-stderr.txt b/Tests/RunCMake/CompilerNotFound/NoCompilerC-IDE-stderr.txt new file mode 100644 index 0000000..88bb95e --- /dev/null +++ b/Tests/RunCMake/CompilerNotFound/NoCompilerC-IDE-stderr.txt @@ -0,0 +1,5 @@ +CMake Error at NoCompilerC-IDE.cmake:2 \(enable_language\): + No CMAKE_C_COMPILER could be found. + +Call Stack \(most recent call first\): + CMakeLists.txt:3 \(include\)$ diff --git a/Tests/RunCMake/CompilerNotFound/NoCompilerC-IDE.cmake b/Tests/RunCMake/CompilerNotFound/NoCompilerC-IDE.cmake new file mode 100644 index 0000000..45e1a68 --- /dev/null +++ b/Tests/RunCMake/CompilerNotFound/NoCompilerC-IDE.cmake @@ -0,0 +1,3 @@ +set(CMAKE_C_COMPILER_ID_ERROR_FOR_TEST "#error NoCompilerC-IDE") +enable_language(C) +message(FATAL_ERROR "This error should not be reached.") diff --git a/Tests/RunCMake/CompilerNotFound/NoCompilerCXX-IDE-result.txt b/Tests/RunCMake/CompilerNotFound/NoCompilerCXX-IDE-result.txt new file mode 100644 index 0000000..d00491f --- /dev/null +++ b/Tests/RunCMake/CompilerNotFound/NoCompilerCXX-IDE-result.txt @@ -0,0 +1 @@ +1 diff --git a/Tests/RunCMake/CompilerNotFound/NoCompilerCXX-IDE-stderr.txt b/Tests/RunCMake/CompilerNotFound/NoCompilerCXX-IDE-stderr.txt new file mode 100644 index 0000000..4c92323 --- /dev/null +++ b/Tests/RunCMake/CompilerNotFound/NoCompilerCXX-IDE-stderr.txt @@ -0,0 +1,5 @@ +CMake Error at NoCompilerCXX-IDE.cmake:2 \(enable_language\): + No CMAKE_CXX_COMPILER could be found. + +Call Stack \(most recent call first\): + CMakeLists.txt:3 \(include\)$ diff --git a/Tests/RunCMake/CompilerNotFound/NoCompilerCXX-IDE.cmake b/Tests/RunCMake/CompilerNotFound/NoCompilerCXX-IDE.cmake new file mode 100644 index 0000000..85025a0 --- /dev/null +++ b/Tests/RunCMake/CompilerNotFound/NoCompilerCXX-IDE.cmake @@ -0,0 +1,3 @@ +set(CMAKE_CXX_COMPILER_ID_ERROR_FOR_TEST "#error NoCompilerCXX-IDE") +enable_language(CXX) +message(FATAL_ERROR "This error should not be reached.") diff --git a/Tests/RunCMake/CompilerNotFound/NoCompilerCandCXX-IDE-result.txt b/Tests/RunCMake/CompilerNotFound/NoCompilerCandCXX-IDE-result.txt new file mode 100644 index 0000000..d00491f --- /dev/null +++ b/Tests/RunCMake/CompilerNotFound/NoCompilerCandCXX-IDE-result.txt @@ -0,0 +1 @@ +1 diff --git a/Tests/RunCMake/CompilerNotFound/NoCompilerCandCXX-IDE-stderr.txt b/Tests/RunCMake/CompilerNotFound/NoCompilerCandCXX-IDE-stderr.txt new file mode 100644 index 0000000..21c69f5 --- /dev/null +++ b/Tests/RunCMake/CompilerNotFound/NoCompilerCandCXX-IDE-stderr.txt @@ -0,0 +1,11 @@ +CMake Error at NoCompilerCandCXX-IDE.cmake:3 \(project\): + No CMAKE_C_COMPILER could be found. + +Call Stack \(most recent call first\): + CMakeLists.txt:3 \(include\) ++ +CMake Error at NoCompilerCandCXX-IDE.cmake:3 \(project\): + No CMAKE_CXX_COMPILER could be found. + +Call Stack \(most recent call first\): + CMakeLists.txt:3 \(include\)$ diff --git a/Tests/RunCMake/CompilerNotFound/NoCompilerCandCXX-IDE.cmake b/Tests/RunCMake/CompilerNotFound/NoCompilerCandCXX-IDE.cmake new file mode 100644 index 0000000..78256a9 --- /dev/null +++ b/Tests/RunCMake/CompilerNotFound/NoCompilerCandCXX-IDE.cmake @@ -0,0 +1,4 @@ +set(CMAKE_C_COMPILER_ID_ERROR_FOR_TEST "#error NoCompilerCandCXX-IDE") +set(CMAKE_CXX_COMPILER_ID_ERROR_FOR_TEST "#error NoCompilerCandCXX-IDE") +project(NoCompilerCandCXXInner C CXX) +message(FATAL_ERROR "This error should not be reached.") diff --git a/Tests/RunCMake/CompilerNotFound/RunCMakeTest.cmake b/Tests/RunCMake/CompilerNotFound/RunCMakeTest.cmake new file mode 100644 index 0000000..8b84f39 --- /dev/null +++ b/Tests/RunCMake/CompilerNotFound/RunCMakeTest.cmake @@ -0,0 +1,11 @@ +include(RunCMake) + +if("${RunCMake_GENERATOR}" MATCHES "Visual Studio|Xcode") + run_cmake(NoCompilerC-IDE) + run_cmake(NoCompilerCXX-IDE) + run_cmake(NoCompilerCandCXX-IDE) +else() + run_cmake(BadCompilerC) + run_cmake(BadCompilerCXX) + run_cmake(BadCompilerCandCXX) +endif() diff --git a/Tests/RunCMake/Syntax/BracketComment5.cmake b/Tests/RunCMake/Syntax/BracketComment5.cmake index bb6d9f3..dc9e6b4 100644 --- a/Tests/RunCMake/Syntax/BracketComment5.cmake +++ b/Tests/RunCMake/Syntax/BracketComment5.cmake @@ -2,5 +2,10 @@ message(FATAL_ERROR "This is commented out.") #]] #[[ message(FATAL_ERROR "This is commented out.") +#]]#[[ +message(FATAL_ERROR "This is commented out.") #]] #message(FATAL_ERROR "This is commented out.") +#[[ +message(FATAL_ERROR "This is commented out.") +#]]#message(FATAL_ERROR "This is commented out.") message(STATUS "The above FATAL_ERROR did not occur.") diff --git a/Tests/RunCMake/Syntax/Escape1-stderr.txt b/Tests/RunCMake/Syntax/Escape1-stderr.txt new file mode 100644 index 0000000..6601ce7 --- /dev/null +++ b/Tests/RunCMake/Syntax/Escape1-stderr.txt @@ -0,0 +1,3 @@ +^\\##\[\[#\]\]#\[\[\]\]x#\\" +\$\@\^\\; \(\)#\\" +\$\@\^; \(\)$ diff --git a/Tests/RunCMake/Syntax/Escape1.cmake b/Tests/RunCMake/Syntax/Escape1.cmake new file mode 100644 index 0000000..3bf801e --- /dev/null +++ b/Tests/RunCMake/Syntax/Escape1.cmake @@ -0,0 +1,3 @@ +message([[\#]] \#[[ \#]] "#[[]]" x#comment + "\#\\\"\n\$\@\^\;\ \t\(\)"#comment + \#\\\"\n\$\@\^\;\ \t\(\)) diff --git a/Tests/RunCMake/Syntax/RunCMakeTest.cmake b/Tests/RunCMake/Syntax/RunCMakeTest.cmake index 2d49f76..4f42a07 100644 --- a/Tests/RunCMake/Syntax/RunCMakeTest.cmake +++ b/Tests/RunCMake/Syntax/RunCMakeTest.cmake @@ -39,6 +39,7 @@ run_cmake(BracketNoSpace2) run_cmake(BracketNoSpace3) run_cmake(BracketNoSpace4) run_cmake(BracketNoSpace5) +run_cmake(Escape1) run_cmake(ParenNoSpace0) run_cmake(ParenNoSpace1) run_cmake(ParenNoSpace2) diff --git a/Utilities/Sphinx/CMakeLists.txt b/Utilities/Sphinx/CMakeLists.txt index 16d9aac..35c62fb 100644 --- a/Utilities/Sphinx/CMakeLists.txt +++ b/Utilities/Sphinx/CMakeLists.txt @@ -15,6 +15,7 @@ if(NOT CMake_SOURCE_DIR) set(CMAKE_LEGACY_CYGWIN_WIN32 0) # Remove when CMake >= 2.8.4 is required get_filename_component(tmp "${CMAKE_CURRENT_SOURCE_DIR}" PATH) get_filename_component(CMake_SOURCE_DIR "${tmp}" PATH) + include(${CMake_SOURCE_DIR}/Modules/CTestUseLaunchers.cmake) include(${CMake_SOURCE_DIR}/Source/CMakeVersionCompute.cmake) include(${CMake_SOURCE_DIR}/Source/CMakeInstallDestinations.cmake) unset(CMAKE_DATA_DIR) @@ -35,6 +36,7 @@ elseif(NOT SPHINX_EXECUTABLE) message(FATAL_ERROR "SPHINX_EXECUTABLE (sphinx-build) is not found!") endif() +set(conf_docs "${CMake_SOURCE_DIR}/Help") set(conf_path "${CMAKE_CURRENT_SOURCE_DIR}") set(conf_copyright "2000-2013 Kitware, Inc.") set(conf_version "${CMake_MAJOR_VERSION}.${CMake_MINOR_VERSION}.${CMake_PATCH_VERSION}") diff --git a/Utilities/Sphinx/conf.py.in b/Utilities/Sphinx/conf.py.in index 5dbdede..ea00b78 100644 --- a/Utilities/Sphinx/conf.py.in +++ b/Utilities/Sphinx/conf.py.in @@ -10,6 +10,9 @@ # See the License for more information. #============================================================================= import sys +import os +import re +import glob sys.path.insert(0, r'@conf_path@') @@ -27,21 +30,27 @@ exclude_patterns = [] extensions = ['cmake'] -man_pages = [ - ('manual/cmake.1', 'cmake', 'CMake Command-Line Reference', [], 1), - ('manual/ccmake.1', 'ccmake', 'CMake Curses Dialog Command-Line Reference', [], 1), - ('manual/cmake-gui.1', 'cmake-gui', 'CMake GUI Command-Line Reference', [], 1), - ('manual/cpack.1', 'cpack', 'CPack Command-Line Reference', [], 1), - ('manual/ctest.1', 'ctest', 'CTest Command-Line Reference', [], 1), - ('manual/cmake-commands.7', 'cmake-commands', 'CMake Language Command Reference', [], 7), - ('manual/cmake-generators.7', 'cmake-generators', 'CMake Generators Reference', [], 7), - ('manual/cmake-modules.7', 'cmake-modules', 'CMake Modules Reference', [], 7), - ('manual/cmake-policies.7', 'cmake-policies', 'CMake Policies Reference', [], 7), - ('manual/cmake-properties.7', 'cmake-properties', 'CMake Properties Reference', [], 7), - ('manual/cmake-variables.7', 'cmake-variables', 'CMake Variables Reference', [], 7), - ('manual/cmake-generator-expressions.7', 'cmake-generator-expressions', 'CMake Generator Expressions', [], 7), - ('manual/cmake-developer.7', 'cmake-developer', 'CMake Developer Reference', [], 7), -] +cmake_manuals = sorted(glob.glob(r'@conf_docs@/manual/*.rst')) +cmake_manual_description = re.compile('^\.\. cmake-manual-description:(.*)$') +man_pages = [] +for fpath in cmake_manuals: + try: + name, sec, rst = os.path.basename(fpath).split('.') + desc = None + f = open(fpath, 'r') + for l in f: + m = cmake_manual_description.match(l) + if m: + desc = m.group(1).strip() + break + f.close() + if desc: + man_pages.append(('manual/%s.%s' % (name, sec), + name, desc, [], int(sec))) + else: + sys.stderr.write("ERROR: No cmake-manual-description in '%s'\n" % fpath) + except Exception, e: + sys.stderr.write("ERROR: %s\n" % str(e)) man_show_urls = False html_show_sourcelink = True |