diff options
-rw-r--r-- | Copyright.txt | 1 | ||||
-rw-r--r-- | Help/manual/cmake-qt.7.rst | 8 | ||||
-rw-r--r-- | Help/prop_tgt/AUTOMOC.rst | 4 | ||||
-rw-r--r-- | Help/prop_tgt/AUTOUIC.rst | 4 | ||||
-rw-r--r-- | Help/release/dev/FindOpenGL-glvnd.rst | 4 | ||||
-rw-r--r-- | Help/variable/MSVC_VERSION.rst | 22 | ||||
-rw-r--r-- | Modules/AutogenInfo.cmake.in | 4 | ||||
-rw-r--r-- | Modules/FindOpenGL.cmake | 319 | ||||
-rw-r--r-- | Source/CMakeVersion.cmake | 2 | ||||
-rw-r--r-- | Source/cmMakefile.cxx | 50 | ||||
-rw-r--r-- | Source/cmMakefile.h | 11 | ||||
-rw-r--r-- | Source/cmNinjaTargetGenerator.cxx | 2 | ||||
-rw-r--r-- | Source/cmQtAutoGen.cxx | 95 | ||||
-rw-r--r-- | Source/cmQtAutoGen.h | 37 | ||||
-rw-r--r-- | Source/cmQtAutoGeneratorInitializer.cxx | 351 | ||||
-rw-r--r-- | Source/cmQtAutoGeneratorInitializer.h | 2 | ||||
-rw-r--r-- | Source/cmQtAutoGenerators.cxx | 106 | ||||
-rw-r--r-- | Source/cmQtAutoGenerators.h | 21 | ||||
-rw-r--r-- | Tests/FindOpenGL/CMakeLists.txt | 7 | ||||
-rw-r--r-- | Tests/FindOpenGL/Test/CMakeLists.txt | 58 | ||||
-rw-r--r-- | Tests/RunCMake/get_property/source_properties-stderr.txt | 8 | ||||
-rw-r--r-- | Tests/RunCMake/get_property/source_properties.cmake | 10 | ||||
-rw-r--r-- | Tests/VSResource/CMakeLists.txt | 7 |
23 files changed, 770 insertions, 363 deletions
diff --git a/Copyright.txt b/Copyright.txt index 978be0a..3c92a81 100644 --- a/Copyright.txt +++ b/Copyright.txt @@ -76,6 +76,7 @@ The following individuals and institutions are among the Contributors: * Nicolas Bock <nicolasbock@gmail.com> * Nicolas Despres <nicolas.despres@gmail.com> * Nikita Krupen'ko <krnekit@gmail.com> +* NVIDIA Corporation <www.nvidia.com> * OpenGamma Ltd. <opengamma.com> * Per Øyvind Karlsen <peroyvind@mandriva.org> * Peter Collingbourne <peter@pcc.me.uk> diff --git a/Help/manual/cmake-qt.7.rst b/Help/manual/cmake-qt.7.rst index 7052e0a..79e7e79 100644 --- a/Help/manual/cmake-qt.7.rst +++ b/Help/manual/cmake-qt.7.rst @@ -73,8 +73,8 @@ automatically added to the target's :prop_tgt:`INCLUDE_DIRECTORIES`. * This differs from CMake 3.7 and below; see their documentation for details. -* For multi configuration generators, the include directory is - ``<AUTOGEN_BUILD_DIR>/include_<CONFIG>``. +* For :prop_gbl:`multi configuration generators <GENERATOR_IS_MULTI_CONFIG>`, + the include directory is ``<AUTOGEN_BUILD_DIR>/include_<CONFIG>``. * See :prop_tgt:`AUTOGEN_BUILD_DIR`. @@ -133,8 +133,8 @@ automatically added to the target's :prop_tgt:`INCLUDE_DIRECTORIES`. * This differs from CMake 3.7 and below; see their documentation for details. -* For multi configuration generators, the include directory is - ``<AUTOGEN_BUILD_DIR>/include_<CONFIG>``. +* For :prop_gbl:`multi configuration generators <GENERATOR_IS_MULTI_CONFIG>`, + the include directory is ``<AUTOGEN_BUILD_DIR>/include_<CONFIG>``. * See :prop_tgt:`AUTOGEN_BUILD_DIR`. diff --git a/Help/prop_tgt/AUTOMOC.rst b/Help/prop_tgt/AUTOMOC.rst index 61813be68..4542401 100644 --- a/Help/prop_tgt/AUTOMOC.rst +++ b/Help/prop_tgt/AUTOMOC.rst @@ -20,8 +20,8 @@ source files at build time and invoke moc accordingly. This allows the compiler to find the included ``moc_<basename>.cpp`` file regardless of the location the original source. - * For multi configuration generators, the include directory is - ``<AUTOGEN_BUILD_DIR>/include_<CONFIG>``. + * For :prop_gbl:`multi configuration generators <GENERATOR_IS_MULTI_CONFIG>`, + the include directory is ``<AUTOGEN_BUILD_DIR>/include_<CONFIG>``. * See :prop_tgt:`AUTOGEN_BUILD_DIR`. diff --git a/Help/prop_tgt/AUTOUIC.rst b/Help/prop_tgt/AUTOUIC.rst index 2fc2167..1791384 100644 --- a/Help/prop_tgt/AUTOUIC.rst +++ b/Help/prop_tgt/AUTOUIC.rst @@ -17,8 +17,8 @@ optional :prop_tgt:`AUTOUIC_SEARCH_PATHS` of the target. ``<AUTOGEN_BUILD_DIR>/include``, which is automatically added to the target's :prop_tgt:`INCLUDE_DIRECTORIES`. -* For multi configuration generators, the include directory is - ``<AUTOGEN_BUILD_DIR>/include_<CONFIG>``. +* For :prop_gbl:`multi configuration generators <GENERATOR_IS_MULTI_CONFIG>`, + the include directory is ``<AUTOGEN_BUILD_DIR>/include_<CONFIG>``. * See :prop_tgt:`AUTOGEN_BUILD_DIR`. diff --git a/Help/release/dev/FindOpenGL-glvnd.rst b/Help/release/dev/FindOpenGL-glvnd.rst new file mode 100644 index 0000000..b3c8d53 --- /dev/null +++ b/Help/release/dev/FindOpenGL-glvnd.rst @@ -0,0 +1,4 @@ +FindOpenGL-glvnd +---------------- + +* The :module:`FindOpenGL` module gained support for GLVND on Linux. diff --git a/Help/variable/MSVC_VERSION.rst b/Help/variable/MSVC_VERSION.rst index 8932147..0a3a7a6 100644 --- a/Help/variable/MSVC_VERSION.rst +++ b/Help/variable/MSVC_VERSION.rst @@ -5,13 +5,15 @@ The version of Microsoft Visual C/C++ being used if any. Known version numbers are:: - 1200 = VS 6.0 - 1300 = VS 7.0 - 1310 = VS 7.1 - 1400 = VS 8.0 - 1500 = VS 9.0 - 1600 = VS 10.0 - 1700 = VS 11.0 - 1800 = VS 12.0 - 1900 = VS 14.0 - 1910 = VS 15.0 + 1200 = VS 6.0 + 1300 = VS 7.0 + 1310 = VS 7.1 + 1400 = VS 8.0 (v80 toolset) + 1500 = VS 9.0 (v90 toolset) + 1600 = VS 10.0 (v100 toolset) + 1700 = VS 11.0 (v110 toolset) + 1800 = VS 12.0 (v120 toolset) + 1900 = VS 14.0 (v140 toolset) + 1910-1919 = VS 15.0 (v141 toolset) + +See also the :variable:`CMAKE_<LANG>_COMPILER_VERSION` variable. diff --git a/Modules/AutogenInfo.cmake.in b/Modules/AutogenInfo.cmake.in index 484dc93..7f4b398 100644 --- a/Modules/AutogenInfo.cmake.in +++ b/Modules/AutogenInfo.cmake.in @@ -1,3 +1,5 @@ +# Meta +set(AM_MULTI_CONFIG @_multi_config@) # Directories and files set(AM_CMAKE_BINARY_DIR "@CMAKE_BINARY_DIR@/") set(AM_CMAKE_SOURCE_DIR "@CMAKE_SOURCE_DIR@/") @@ -16,7 +18,7 @@ set(AM_QT_RCC_EXECUTABLE @_qt_rcc_executable@) # MOC settings set(AM_MOC_SKIP @_moc_skip@) set(AM_MOC_DEFINITIONS @_moc_compile_defs@) -set(AM_MOC_INCLUDES @_moc_incs@) +set(AM_MOC_INCLUDES @_moc_include_dirs@) set(AM_MOC_OPTIONS @_moc_options@) set(AM_MOC_RELAXED_MODE @_moc_relaxed_mode@) set(AM_MOC_MACRO_NAMES @_moc_macro_names@) diff --git a/Modules/FindOpenGL.cmake b/Modules/FindOpenGL.cmake index af83fb7..59bee41 100644 --- a/Modules/FindOpenGL.cmake +++ b/Modules/FindOpenGL.cmake @@ -7,15 +7,28 @@ # # FindModule for OpenGL and GLU. # +# Optional COMPONENTS +# ^^^^^^^^^^^^^^^^^^^ +# +# This module respects several optional COMPONENTS: ``EGL``, ``GLX``, and +# ``OpenGL``. There are corresponding import targets for each of these flags. +# # IMPORTED Targets # ^^^^^^^^^^^^^^^^ # # This module defines the :prop_tgt:`IMPORTED` targets: # # ``OpenGL::GL`` -# Defined if the system has OpenGL. +# Defined to the platform-specific OpenGL libraries if the system has OpenGL. +# ``OpenGL::OpenGL`` +# Defined to libOpenGL if the system is GLVND-based. +# ``OpenGL::GL`` # ``OpenGL::GLU`` # Defined if the system has GLU. +# ``OpenGL::GLX`` +# Defined if the system has GLX. +# ``OpenGL::EGL`` +# Defined if the system has EGL. # # Result Variables # ^^^^^^^^^^^^^^^^ @@ -23,40 +36,87 @@ # This module sets the following variables: # # ``OPENGL_FOUND`` -# True, if the system has OpenGL. +# True, if the system has OpenGL and all components are found. # ``OPENGL_XMESA_FOUND`` # True, if the system has XMESA. # ``OPENGL_GLU_FOUND`` # True, if the system has GLU. +# ``OpenGL_OpenGL_FOUND`` +# True, if the system has an OpenGL library. +# ``OpenGL_GLX_FOUND`` +# True, if the system has GLX. +# ``OpenGL_EGL_FOUND`` +# True, if the system has EGL. # ``OPENGL_INCLUDE_DIR`` # Path to the OpenGL include directory. +# ``OPENGL_EGL_INCLUDE_DIRS`` +# Path to the EGL include directory. # ``OPENGL_LIBRARIES`` -# Paths to the OpenGL and GLU libraries. +# Paths to the OpenGL library, windowing system libraries, and GLU libraries. +# On Linux, this assumes glX and is never correct for EGL-based targets. +# Clients are encouraged to use the ``OpenGL::*`` import targets instead. # -# If you want to use just GL you can use these values: +# Cache variables +# ^^^^^^^^^^^^^^^ # -# ``OPENGL_gl_LIBRARY`` -# Path to the OpenGL library. +# The following cache variables may also be set: +# +# ``OPENGL_egl_LIBRARY`` +# Path to the EGL library. # ``OPENGL_glu_LIBRARY`` # Path to the GLU library. +# ``OPENGL_glx_LIBRARY`` +# Path to the GLVND 'GLX' library. +# ``OPENGL_opengl_LIBRARY`` +# Path to the GLVND 'OpenGL' library +# ``OPENGL_gl_LIBRARY`` +# Path to the OpenGL library. New code should prefer the ``OpenGL::*`` import +# targets. +# +# Linux-specific +# ^^^^^^^^^^^^^^ # -# OSX Specific -# ^^^^^^^^^^^^ +# Some Linux systems utilize GLVND as a new ABI for OpenGL. GLVND separates +# context libraries from OpenGL itself; OpenGL lives in "libOpenGL", and +# contexts are defined in "libGLX" or "libEGL". GLVND is currently the only way +# to get OpenGL 3+ functionality via EGL in a manner portable across vendors. # -# On OSX default to using the framework version of OpenGL. People will -# have to change the cache values of OPENGL_glu_LIBRARY and +# On Linux systems FindOpenGL defaults to using GLVND if available. Users can +# utilize GLVND explicitly with targets ``OpenGL::OpenGL``, ``OpenGL::GLX``, and +# ``OpenGL::EGL``. Additionally, when GLVND is available the ``OpenGL::GL`` +# target is equivalent to ``OpenGL::OpenGL OpenGL::GLX``. When the system is +# not GLVND-based, ``OpenGL::GL`` expands to libGL as it has historically done. +# Thus, for non-EGL-based Linux targets, the ``OpenGL::GL`` target is most +# portable. +# +# For EGL targets the client must rely on GLVND support on the user's system. +# Linking should use the ``OpenGL::OpenGL OpenGL::EGL`` targets. Using GLES* +# libraries is theoretically possible in place of ``OpenGL::OpenGL``, but this +# module does not currently support that; contributions welcome. +# +# ``OPENGL_egl_LIBRARY`` and ``OPENGL_EGL_INCLUDE_DIRS`` are defined in the case of +# GLVND. For non-GLVND Linux and other systems these are left undefined. +# +# macOS-Specific +# ^^^^^^^^^^^^^^ +# +# On OSX FindOpenGL defaults to using the framework version of OpenGL. People +# will have to change the cache values of OPENGL_glu_LIBRARY and # OPENGL_gl_LIBRARY to use OpenGL with X11 on OSX. - set(_OpenGL_REQUIRED_VARS OPENGL_gl_LIBRARY) -if (CYGWIN) +# Provide OPENGL_USE_<C> variables for each component. +foreach(component ${OpenGL_FIND_COMPONENTS}) + string(TOUPPER ${component} _COMPONENT) + set(OPENGL_USE_${_COMPONENT} 1) +endforeach() +if (CYGWIN) find_path(OPENGL_INCLUDE_DIR GL/gl.h ) list(APPEND _OpenGL_REQUIRED_VARS OPENGL_INCLUDE_DIR) find_library(OPENGL_gl_LIBRARY opengl32 ) - find_library(OPENGL_glu_LIBRARY glu32 ) elseif (WIN32) @@ -70,7 +130,6 @@ elseif (WIN32) endif() elseif (APPLE) - # The OpenGL.framework provides both gl and glu find_library(OPENGL_gl_LIBRARY OpenGL DOC "OpenGL library for OS X") find_library(OPENGL_glu_LIBRARY OpenGL DOC @@ -104,15 +163,14 @@ else() # fail since the compiler finds the Mesa headers but NVidia's library. # Make sure the NVIDIA directory comes BEFORE the others. # - Atanas Georgiev <atanas@cs.columbia.edu> - find_path(OPENGL_INCLUDE_DIR GL/gl.h /usr/share/doc/NVIDIA_GLX-1.0/include /usr/openwin/share/include /opt/graphics/OpenGL/include /usr/X11R6/include ${_OPENGL_INCLUDE_PATH} ) - list(APPEND _OpenGL_REQUIRED_VARS OPENGL_INCLUDE_DIR) - + find_path(OPENGL_GLX_INCLUDE_DIR GL/glx.h ${_OPENGL_INCLUDE_PATH}) + find_path(OPENGL_EGL_INCLUDE_DIR EGL/egl.h ${_OPENGL_INCLUDE_PATH}) find_path(OPENGL_xmesa_INCLUDE_DIR GL/xmesa.h /usr/share/doc/NVIDIA_GLX-1.0/include /usr/openwin/share/include @@ -126,6 +184,90 @@ else() /usr/shlib /usr/X11R6/lib ${_OPENGL_LIB_PATH} ) + # Search for the GLVND libraries. We do this regardless of COMPONENTS; we'll + # take into account the COMPONENTS logic later. + find_library(OPENGL_opengl_LIBRARY + NAMES OpenGL + PATHS /usr/X11R6/lib + ${_OPENGL_LIB_PATH} + ) + + find_library(OPENGL_glx_LIBRARY + NAMES GLX + PATHS /usr/X11R6/lib + ${_OPENGL_LIB_PATH} + ) + + find_library(OPENGL_egl_LIBRARY + NAMES EGL + PATHS ${_OPENGL_LIB_PATH} + ) + + find_library(OPENGL_glu_LIBRARY + NAMES GLU MesaGLU + PATHS ${OPENGL_gl_LIBRARY} + /opt/graphics/OpenGL/lib + /usr/openwin/lib + /usr/shlib /usr/X11R6/lib + ) + + # FPHSA cannot handle "this OR that is required", so we conditionally set what + # it must look for. First clear any previous config we might have done: + set(_OpenGL_REQUIRED_VARS) + + # now we append the libraries as appropriate. The complicated logic + # basically comes down to "use libOpenGL when we can, and add in specific + # context mechanisms when requested, or we need them to preserve the previous + # default where glx is always available." + if((NOT OPENGL_USE_EGL AND + NOT OPENGL_opengl_LIBRARY AND + OPENGL_glx_LIBRARY AND + NOT OPENGL_gl_LIBRARY) OR + (NOT OPENGL_USE_EGL AND + NOT OPENGL_glx_LIBRARY AND + NOT OPENGL_gl_LIBRARY) OR + (NOT OPENGL_USE_EGL AND + OPENGL_opengl_LIBRARY AND + OPENGL_glx_LIBRARY) OR + ( OPENGL_USE_EGL)) + list(APPEND _OpenGL_REQUIRED_VARS OPENGL_opengl_LIBRARY) + endif() + + # GLVND GLX library. Preferred when available. + if((NOT OPENGL_USE_OPENGL AND + NOT OPENGL_USE_GLX AND + NOT OPENGL_USE_EGL AND + NOT OPENGL_glx_LIBRARY AND + NOT OPENGL_gl_LIBRARY) OR + ( OPENGL_USE_GLX AND + NOT OPENGL_USE_EGL AND + NOT OPENGL_glx_LIBRARY AND + NOT OPENGL_gl_LIBRARY) OR + (NOT OPENGL_USE_EGL AND + OPENGL_opengl_LIBRARY AND + OPENGL_glx_LIBRARY) OR + (OPENGL_USE_GLX AND OPENGL_USE_EGL)) + list(APPEND _OpenGL_REQUIRED_VARS OPENGL_glx_LIBRARY) + endif() + + # GLVND EGL library. + if(OPENGL_USE_EGL) + list(APPEND _OpenGL_REQUIRED_VARS OPENGL_egl_LIBRARY) + endif() + + # Old-style "libGL" library: used as a fallback when GLVND isn't available. + if((NOT OPENGL_USE_EGL AND + NOT OPENGL_opengl_LIBRARY AND + OPENGL_glx_LIBRARY AND + OPENGL_gl_LIBRARY) OR + (NOT OPENGL_USE_EGL AND + NOT OPENGL_glx_LIBRARY AND + OPENGL_gl_LIBRARY)) + list(APPEND _OpenGL_REQUIRED_VARS OPENGL_gl_LIBRARY) + endif() + + # We always need the 'gl.h' include dir. + list(APPEND _OpenGL_REQUIRED_VARS OPENGL_INCLUDE_DIR) unset(_OPENGL_INCLUDE_PATH) unset(_OPENGL_LIB_PATH) @@ -137,42 +279,99 @@ else() /usr/openwin/lib /usr/shlib /usr/X11R6/lib ) - endif () -if(OPENGL_gl_LIBRARY) +if(OPENGL_xmesa_INCLUDE_DIR) + set( OPENGL_XMESA_FOUND "YES" ) +else() + set( OPENGL_XMESA_FOUND "NO" ) +endif() - if(OPENGL_xmesa_INCLUDE_DIR) - set( OPENGL_XMESA_FOUND "YES" ) - else() - set( OPENGL_XMESA_FOUND "NO" ) - endif() +if(OPENGL_glu_LIBRARY) + set( OPENGL_GLU_FOUND "YES" ) +else() + set( OPENGL_GLU_FOUND "NO" ) +endif() - set( OPENGL_LIBRARIES ${OPENGL_gl_LIBRARY} ${OPENGL_LIBRARIES}) - if(OPENGL_glu_LIBRARY) - set( OPENGL_GLU_FOUND "YES" ) - if(NOT "${OPENGL_glu_LIBRARY}" STREQUAL "${OPENGL_gl_LIBRARY}") - set( OPENGL_LIBRARIES ${OPENGL_glu_LIBRARY} ${OPENGL_LIBRARIES} ) - endif() - else() - set( OPENGL_GLU_FOUND "NO" ) - endif() +# OpenGL_OpenGL_FOUND is a bit unique in that it is okay if /either/ libOpenGL +# or libGL is found. +# Using libGL with libEGL is never okay, though; we handle that case later. +if(NOT OPENGL_opengl_LIBRARY AND NOT OPENGL_gl_LIBRARY) + set(OpenGL_OpenGL_FOUND FALSE) +else() + set(OpenGL_OpenGL_FOUND TRUE) +endif() - # This deprecated setting is for backward compatibility with CMake1.4 - set (OPENGL_LIBRARY ${OPENGL_LIBRARIES}) +if(OPENGL_glx_LIBRARY AND OPENGL_GLX_INCLUDE_DIR) + set(OpenGL_GLX_FOUND TRUE) +else() + set(OpenGL_GLX_FOUND FALSE) +endif() +if(OPENGL_egl_LIBRARY AND OPENGL_EGL_INCLUDE_DIR) + set(OpenGL_EGL_FOUND TRUE) +else() + set(OpenGL_EGL_FOUND FALSE) endif() -# This deprecated setting is for backward compatibility with CMake1.4 -set(OPENGL_INCLUDE_PATH ${OPENGL_INCLUDE_DIR}) +# User-visible names should be plural. +if(OPENGL_EGL_INCLUDE_DIR) + set(OPENGL_EGL_INCLUDE_DIRS ${OPENGL_EGL_INCLUDE_DIR}) +endif() include(${CMAKE_CURRENT_LIST_DIR}/FindPackageHandleStandardArgs.cmake) -FIND_PACKAGE_HANDLE_STANDARD_ARGS(OpenGL REQUIRED_VARS ${_OpenGL_REQUIRED_VARS}) +FIND_PACKAGE_HANDLE_STANDARD_ARGS(OpenGL REQUIRED_VARS ${_OpenGL_REQUIRED_VARS} + HANDLE_COMPONENTS) unset(_OpenGL_REQUIRED_VARS) # OpenGL:: targets if(OPENGL_FOUND) - if(NOT TARGET OpenGL::GL) + # ::OpenGL is a GLVND library, and thus Linux-only: we don't bother checking + # for a framework version of this library. + if(OPENGL_opengl_LIBRARY AND NOT TARGET OpenGL::OpenGL) + if(IS_ABSOLUTE "${OPENGL_opengl_LIBRARY}") + add_library(OpenGL::OpenGL UNKNOWN IMPORTED) + set_target_properties(OpenGL::OpenGL PROPERTIES IMPORTED_LOCATION + "${OPENGL_opengl_LIBRARY}") + else() + add_library(OpenGL::OpenGL INTERFACE IMPORTED) + set_target_properties(OpenGL::OpenGL PROPERTIES IMPORTED_LIBNAME + "${OPENGL_opengl_LIBRARY}") + endif() + set_target_properties(OpenGL::OpenGL PROPERTIES INTERFACE_INCLUDE_DIRECTORIES + "${OPENGL_INCLUDE_DIR}") + endif() + + # ::GLX is a GLVND library, and thus Linux-only: we don't bother checking + # for a framework version of this library. + if(OpenGL_GLX_FOUND AND NOT TARGET OpenGL::GLX) + if(IS_ABSOLUTE "${OPENGL_glx_LIBRARY}") + add_library(OpenGL::GLX UNKNOWN IMPORTED) + set_target_properties(OpenGL::GLX PROPERTIES IMPORTED_LOCATION + "${OPENGL_glx_LIBRARY}") + else() + add_library(OpenGL::GLX INTERFACE IMPORTED) + set_target_properties(OpenGL::GLX PROPERTIES IMPORTED_LIBNAME + "${OPENGL_glx_LIBRARY}") + endif() + set_target_properties(OpenGL::GLX PROPERTIES INTERFACE_LINK_LIBRARIES + OpenGL::OpenGL) + set_target_properties(OpenGL::GLX PROPERTIES INTERFACE_INCLUDE_DIRECTORIES + "${OPENGL_GLX_INCLUDE_DIR}") + endif() + + if(TARGET OpenGL::OpenGL AND TARGET OpenGL::GLX AND NOT TARGET OpenGL::GL) + # if GLVND with GLX is available, make ::GL a synonym for 'OpenGL::OpenGL + # OpenGL::GLX'. + add_library(OpenGL::GL INTERFACE IMPORTED) + set_target_properties(OpenGL::GL PROPERTIES INTERFACE_LINK_LIBRARIES + OpenGL::OpenGL) + set_property(TARGET OpenGL::GL APPEND PROPERTY INTERFACE_LINK_LIBRARIES + OpenGL::GLX) + set_target_properties(OpenGL::GL PROPERTIES INTERFACE_INCLUDE_DIRECTORIES + "${OPENGL_INCLUDE_DIR}") + + elseif(NOT TARGET OpenGL::GL) if(IS_ABSOLUTE "${OPENGL_gl_LIBRARY}") add_library(OpenGL::GL UNKNOWN IMPORTED) if(OPENGL_gl_LIBRARY MATCHES "/([^/]+)\\.framework$") @@ -195,6 +394,28 @@ if(OPENGL_FOUND) INTERFACE_INCLUDE_DIRECTORIES "${OPENGL_INCLUDE_DIR}") endif() + # ::EGL is a GLVND library, and thus Linux-only: we don't bother checking + # for a framework version of this library. + # Note we test for OpenGL::OpenGL as a target. When this module is updated to + # support GLES, we would additionally want to check for the hypothetical GLES + # target and enable EGL if either ::GLES or ::OpenGL is created. + if(TARGET OpenGL::OpenGL AND OpenGL_EGL_FOUND AND NOT TARGET OpenGL::EGL) + if(IS_ABSOLUTE "${OPENGL_egl_LIBRARY}") + add_library(OpenGL::EGL UNKNOWN IMPORTED) + set_target_properties(OpenGL::EGL PROPERTIES IMPORTED_LOCATION + "${OPENGL_egl_LIBRARY}") + else() + add_library(OpenGL::EGL INTERFACE IMPORTED) + set_target_properties(OpenGL::EGL PROPERTIES IMPORTED_LIBNAME + "${OPENGL_egl_LIBRARY}") + endif() + set_target_properties(OpenGL::EGL PROPERTIES INTERFACE_LINK_LIBRARIES + OpenGL::OpenGL) + # Note that EGL's include directory is different from OpenGL/GLX's! + set_target_properties(OpenGL::EGL PROPERTIES INTERFACE_INCLUDE_DIRECTORIES + "${OPENGL_EGL_INCLUDE_DIR}") + endif() + if(OPENGL_GLU_FOUND AND NOT TARGET OpenGL::GLU) if(IS_ABSOLUTE "${OPENGL_glu_LIBRARY}") add_library(OpenGL::GLU UNKNOWN IMPORTED) @@ -217,11 +438,31 @@ if(OPENGL_FOUND) set_target_properties(OpenGL::GLU PROPERTIES INTERFACE_LINK_LIBRARIES OpenGL::GL) endif() + + # OPENGL_LIBRARIES mirrors OpenGL::GL's logic ... + set(OPENGL_LIBRARIES ${OPENGL_gl_LIBRARY}) + if(TARGET OpenGL::GLX AND TARGET OpenGL::OpenGL) + set(OPENGL_LIBRARIES ${OPENGL_opengl_LIBRARY} ${OPENGL_glx_LIBRARY}) + endif() + # ... and also includes GLU, if available. + if(TARGET OpenGL::GLU) + list(APPEND OPENGL_LIBRARIES ${OPENGL_glu_LIBRARY}) + endif() endif() +# This deprecated setting is for backward compatibility with CMake1.4 +set(OPENGL_LIBRARY ${OPENGL_LIBRARIES}) +# This deprecated setting is for backward compatibility with CMake1.4 +set(OPENGL_INCLUDE_PATH ${OPENGL_INCLUDE_DIR}) + mark_as_advanced( OPENGL_INCLUDE_DIR OPENGL_xmesa_INCLUDE_DIR + OPENGL_egl_LIBRARY OPENGL_glu_LIBRARY + OPENGL_glx_LIBRARY OPENGL_gl_LIBRARY + OPENGL_opengl_LIBRARY + OPENGL_EGL_INCLUDE_DIR + OPENGL_GLX_INCLUDE_DIR ) diff --git a/Source/CMakeVersion.cmake b/Source/CMakeVersion.cmake index 10e0e85..d5dc2ba 100644 --- a/Source/CMakeVersion.cmake +++ b/Source/CMakeVersion.cmake @@ -1,5 +1,5 @@ # CMake version number components. set(CMake_VERSION_MAJOR 3) set(CMake_VERSION_MINOR 9) -set(CMake_VERSION_PATCH 20170925) +set(CMake_VERSION_PATCH 20170927) #set(CMake_VERSION_RC 1) diff --git a/Source/cmMakefile.cxx b/Source/cmMakefile.cxx index c96b892..e51cfcc 100644 --- a/Source/cmMakefile.cxx +++ b/Source/cmMakefile.cxx @@ -3082,18 +3082,9 @@ void cmMakefile::SetArgcArgv(const std::vector<std::string>& args) cmSourceFile* cmMakefile::GetSource(const std::string& sourceName) const { cmSourceFileLocation sfl(this, sourceName); - -#if defined(_WIN32) || defined(__APPLE__) - const auto& name = cmSystemTools::LowerCase(sfl.GetName()); -#else - const auto& name = sfl.GetName(); -#endif - auto sfsi = this->SourceFileSearchIndex.find(name); - if (sfsi != this->SourceFileSearchIndex.end()) { - for (auto sf : sfsi->second) { - if (sf->Matches(sfl)) { - return sf; - } + for (cmSourceFile* sf : this->SourceFiles) { + if (sf->Matches(sfl)) { + return sf; } } return nullptr; @@ -3107,41 +3098,6 @@ cmSourceFile* cmMakefile::CreateSource(const std::string& sourceName, sf->SetProperty("GENERATED", "1"); } this->SourceFiles.push_back(sf); - - auto name = sf->GetLocation().GetName(); -#if defined(_WIN32) || defined(__APPLE__) - name = cmSystemTools::LowerCase(name); -#endif - - // For a file in the form "a.b.c" add the cmSourceFile to the index - // at "a.b.c", "a.b" and "a". - auto partial = name; - while (true) { - this->SourceFileSearchIndex[partial].insert(sf); - auto i = partial.rfind('.'); - if (i == std::string::npos) { - break; - } - partial = partial.substr(0, i); - } - - if (sf->GetLocation().ExtensionIsAmbiguous()) { - // For an ambiguous extension also add the various "known" - // extensions to the original filename. - - const auto& srcExts = this->GetCMakeInstance()->GetSourceExtensions(); - for (const auto& ext : srcExts) { - auto name_ext = name + "." + cmSystemTools::LowerCase(ext); - this->SourceFileSearchIndex[name_ext].insert(sf); - } - - const auto& hdrExts = this->GetCMakeInstance()->GetHeaderExtensions(); - for (const auto& ext : hdrExts) { - auto name_ext = name + "." + cmSystemTools::LowerCase(ext); - this->SourceFileSearchIndex[name_ext].insert(sf); - } - } - return sf; } diff --git a/Source/cmMakefile.h b/Source/cmMakefile.h index 2cae659..272522c 100644 --- a/Source/cmMakefile.h +++ b/Source/cmMakefile.h @@ -13,7 +13,6 @@ #include <stddef.h> #include <string> #include <unordered_map> -#include <unordered_set> #include <vector> #include "cmAlgorithms.h" @@ -809,17 +808,7 @@ protected: // libraries, classes, and executables mutable cmTargets Targets; std::map<std::string, std::string> AliasTargets; - std::vector<cmSourceFile*> SourceFiles; - // Because cmSourceFile names are compared in a fuzzy way (see - // cmSourceFileLocation::Match()) we can't have a straight mapping from - // filename to cmSourceFile. To make lookups more efficient we store the - // Name portion of the cmSourceFileLocation and then compare on the list of - // cmSourceFiles that might match that name. Note that on platforms which - // have a case-insensitive filesystem we store the key in all lowercase. - typedef std::unordered_set<cmSourceFile*> SourceFileSet; - typedef std::unordered_map<std::string, SourceFileSet> SourceFileMap; - SourceFileMap SourceFileSearchIndex; // Tests std::map<std::string, cmTest*> Tests; diff --git a/Source/cmNinjaTargetGenerator.cxx b/Source/cmNinjaTargetGenerator.cxx index a464d6e..5fb4097 100644 --- a/Source/cmNinjaTargetGenerator.cxx +++ b/Source/cmNinjaTargetGenerator.cxx @@ -438,7 +438,7 @@ void cmNinjaTargetGenerator::WriteCompileRule(const std::string& lang) : mf->GetSafeDefinition("CMAKE_CXX_COMPILER"); cldeps = "\""; cldeps += cmSystemTools::GetCMClDepsCommand(); - cldeps += "\" " + lang + " " + vars.Source + " \"$DEP_FILE\" $out \""; + cldeps += "\" " + lang + " " + vars.Source + " $DEP_FILE $out \""; cldeps += mf->GetSafeDefinition("CMAKE_CL_SHOWINCLUDES_PREFIX"); cldeps += "\" \"" + cl + "\" "; } diff --git a/Source/cmQtAutoGen.cxx b/Source/cmQtAutoGen.cxx index d9b1fd3..5e89978 100644 --- a/Source/cmQtAutoGen.cxx +++ b/Source/cmQtAutoGen.cxx @@ -14,18 +14,22 @@ // - Static variables -const std::string genNameGen = "AutoGen"; -const std::string genNameMoc = "AutoMoc"; -const std::string genNameUic = "AutoUic"; -const std::string genNameRcc = "AutoRcc"; +std::string const genNameGen = "AutoGen"; +std::string const genNameMoc = "AutoMoc"; +std::string const genNameUic = "AutoUic"; +std::string const genNameRcc = "AutoRcc"; + +std::string const mcNameSingle = "SINGLE"; +std::string const mcNameWrap = "WRAP"; +std::string const mcNameFull = "FULL"; // - Static functions /// @brief Merges newOpts into baseOpts /// @arg valueOpts list of options that accept a value void MergeOptions(std::vector<std::string>& baseOpts, - const std::vector<std::string>& newOpts, - const std::vector<std::string>& valueOpts, bool isQt5) + std::vector<std::string> const& newOpts, + std::vector<std::string> const& valueOpts, bool isQt5) { typedef std::vector<std::string>::iterator Iter; typedef std::vector<std::string>::const_iterator CIter; @@ -40,7 +44,7 @@ void MergeOptions(std::vector<std::string>& baseOpts, std::vector<std::string> extraOpts; for (CIter fit = newOpts.begin(), fitEnd = newOpts.end(); fit != fitEnd; ++fit) { - const std::string& newOpt = *fit; + std::string const& newOpt = *fit; Iter existIt = std::find(baseOpts.begin(), baseOpts.end(), newOpt); if (existIt != baseOpts.end()) { if (newOpt.size() >= 2) { @@ -87,7 +91,7 @@ static std::string utilStripCR(std::string const& line) /// @brief Reads the resource files list from from a .qrc file - Qt4 version /// @return True if the .qrc file was successfully parsed -static bool RccListInputsQt4(const std::string& fileName, +static bool RccListInputsQt4(std::string const& fileName, std::vector<std::string>& files, std::string* errorMessage) { @@ -140,8 +144,8 @@ static bool RccListInputsQt4(const std::string& fileName, /// @brief Reads the resource files list from from a .qrc file - Qt5 version /// @return True if the .qrc file was successfully parsed -static bool RccListInputsQt5(const std::string& rccCommand, - const std::string& fileName, +static bool RccListInputsQt5(std::string const& rccCommand, + std::string const& fileName, std::vector<std::string>& files, std::string* errorMessage) { @@ -244,29 +248,53 @@ static bool RccListInputsQt5(const std::string& rccCommand, // - Class definitions -const std::string cmQtAutoGen::listSep = "@LSEP@"; +std::string const cmQtAutoGen::listSep = "@LSEP@"; -const std::string& cmQtAutoGen::GeneratorName(GeneratorType type) +std::string const& cmQtAutoGen::GeneratorName(Generator type) { switch (type) { - case GeneratorType::GEN: + case Generator::GEN: return genNameGen; - case GeneratorType::MOC: + case Generator::MOC: return genNameMoc; - case GeneratorType::UIC: + case Generator::UIC: return genNameUic; - case GeneratorType::RCC: + case Generator::RCC: return genNameRcc; } return genNameGen; } -std::string cmQtAutoGen::GeneratorNameUpper(GeneratorType genType) +std::string cmQtAutoGen::GeneratorNameUpper(Generator genType) { return cmSystemTools::UpperCase(cmQtAutoGen::GeneratorName(genType)); } -std::string cmQtAutoGen::Quoted(const std::string& text) +std::string const& cmQtAutoGen::MultiConfigName(MultiConfig config) +{ + switch (config) { + case MultiConfig::SINGLE: + return mcNameSingle; + case MultiConfig::WRAP: + return mcNameWrap; + case MultiConfig::FULL: + return mcNameFull; + } + return mcNameWrap; +} + +cmQtAutoGen::MultiConfig cmQtAutoGen::MultiConfigType(std::string const& name) +{ + if (name == mcNameSingle) { + return MultiConfig::SINGLE; + } + if (name == mcNameFull) { + return MultiConfig::FULL; + } + return MultiConfig::WRAP; +} + +std::string cmQtAutoGen::Quoted(std::string const& text) { static const char* rep[18] = { "\\", "\\\\", "\"", "\\\"", "\a", "\\a", "\b", "\\b", "\f", "\\f", "\n", "\\n", @@ -282,11 +310,28 @@ std::string cmQtAutoGen::Quoted(const std::string& text) return res; } +std::string cmQtAutoGen::AppendFilenameSuffix(std::string const& filename, + std::string const& suffix) +{ + std::string res; + auto pos = filename.rfind('.'); + if (pos != std::string::npos) { + const auto it_dot = filename.begin() + pos; + res.assign(filename.begin(), it_dot); + res.append(suffix); + res.append(it_dot, filename.end()); + } else { + res = filename; + res.append(suffix); + } + return res; +} + void cmQtAutoGen::UicMergeOptions(std::vector<std::string>& baseOpts, - const std::vector<std::string>& newOpts, + std::vector<std::string> const& newOpts, bool isQt5) { - static const std::vector<std::string> valueOpts = { + static std::vector<std::string> const valueOpts = { "tr", "translate", "postfix", "generator", "include", // Since Qt 5.3 "g" @@ -295,18 +340,18 @@ void cmQtAutoGen::UicMergeOptions(std::vector<std::string>& baseOpts, } void cmQtAutoGen::RccMergeOptions(std::vector<std::string>& baseOpts, - const std::vector<std::string>& newOpts, + std::vector<std::string> const& newOpts, bool isQt5) { - static const std::vector<std::string> valueOpts = { "name", "root", + static std::vector<std::string> const valueOpts = { "name", "root", "compress", "threshold" }; MergeOptions(baseOpts, newOpts, valueOpts, isQt5); } -bool cmQtAutoGen::RccListInputs(const std::string& qtMajorVersion, - const std::string& rccCommand, - const std::string& fileName, +bool cmQtAutoGen::RccListInputs(std::string const& qtMajorVersion, + std::string const& rccCommand, + std::string const& fileName, std::vector<std::string>& files, std::string* errorMessage) { diff --git a/Source/cmQtAutoGen.h b/Source/cmQtAutoGen.h index 4cd5e32..acc092f 100644 --- a/Source/cmQtAutoGen.h +++ b/Source/cmQtAutoGen.h @@ -14,9 +14,9 @@ class cmQtAutoGen { public: - static const std::string listSep; + static std::string const listSep; - enum GeneratorType + enum Generator { GEN, // General MOC, @@ -24,32 +24,47 @@ public: RCC }; + enum MultiConfig + { + SINGLE, // Single configuration + WRAP, // Multi configuration using wrapper files + FULL // Full multi configuration using per config sources + }; + public: /// @brief Returns the generator name - static const std::string& GeneratorName(GeneratorType genType); + static std::string const& GeneratorName(Generator genType); /// @brief Returns the generator name in upper case - static std::string GeneratorNameUpper(GeneratorType genType); + static std::string GeneratorNameUpper(Generator genType); + + /// @brief Returns the multi configuration name string + static std::string const& MultiConfigName(MultiConfig config); + /// @brief Returns the multi configuration type + static MultiConfig MultiConfigType(std::string const& name); /// @brief Returns a the string escaped and enclosed in quotes - /// - static std::string Quoted(const std::string& text); + static std::string Quoted(std::string const& text); + + /// @brief Appends the suffix to the filename before the last dot + static std::string AppendFilenameSuffix(std::string const& filename, + std::string const& suffix); /// @brief Merges newOpts into baseOpts static void UicMergeOptions(std::vector<std::string>& baseOpts, - const std::vector<std::string>& newOpts, + std::vector<std::string> const& newOpts, bool isQt5); /// @brief Merges newOpts into baseOpts static void RccMergeOptions(std::vector<std::string>& baseOpts, - const std::vector<std::string>& newOpts, + std::vector<std::string> const& newOpts, bool isQt5); /// @brief Reads the resource files list from from a .qrc file /// @arg fileName Must be the absolute path of the .qrc file /// @return True if the rcc file was successfully parsed - static bool RccListInputs(const std::string& qtMajorVersion, - const std::string& rccCommand, - const std::string& fileName, + static bool RccListInputs(std::string const& qtMajorVersion, + std::string const& rccCommand, + std::string const& fileName, std::vector<std::string>& files, std::string* errorMessage = nullptr); }; diff --git a/Source/cmQtAutoGeneratorInitializer.cxx b/Source/cmQtAutoGeneratorInitializer.cxx index 69f8b8f..9befd65 100644 --- a/Source/cmQtAutoGeneratorInitializer.cxx +++ b/Source/cmQtAutoGeneratorInitializer.cxx @@ -48,9 +48,26 @@ inline static std::string GetSafeProperty(cmSourceFile const* sf, return std::string(SafeString(sf->GetProperty(key))); } -inline static bool AutogenMultiConfig(cmGlobalGenerator* globalGen) +static cmQtAutoGen::MultiConfig AutogenMultiConfig( + cmGlobalGenerator* globalGen) { - return globalGen->IsMultiConfig(); + if (!globalGen->IsMultiConfig()) { + return cmQtAutoGen::SINGLE; + } + + // FIXME: Xcode does not support per-config sources, yet. + // (EXCLUDED_SOURCE_FILE_NAMES) + // if (globalGen->GetName().find("Xcode") != std::string::npos) { + // return cmQtAutoGen::FULL; + //} + + // FIXME: Visual Studio does not support per-config sources, yet. + // (EXCLUDED_SOURCE_FILE_NAMES) + // if (globalGen->GetName().find("Visual Studio") != std::string::npos) { + // return cmQtAutoGen::FULL; + //} + + return cmQtAutoGen::WRAP; } static std::string GetAutogenTargetName(cmGeneratorTarget const* target) @@ -100,7 +117,7 @@ std::string cmQtAutoGeneratorInitializer::GetQtMajorVersion( } std::string cmQtAutoGeneratorInitializer::GetQtMinorVersion( - cmGeneratorTarget const* target, const std::string& qtVersionMajor) + cmGeneratorTarget const* target, std::string const& qtVersionMajor) { cmMakefile* makefile = target->Target->GetMakefile(); std::string qtMinor; @@ -119,8 +136,8 @@ std::string cmQtAutoGeneratorInitializer::GetQtMinorVersion( return qtMinor; } -static bool QtVersionGreaterOrEqual(const std::string& major, - const std::string& minor, +static bool QtVersionGreaterOrEqual(std::string const& major, + std::string const& minor, unsigned long requestMajor, unsigned long requestMinor) { @@ -134,40 +151,17 @@ static bool QtVersionGreaterOrEqual(const std::string& major, return false; } -static std::vector<std::string> GetConfigurations( - cmMakefile* makefile, std::string* config = nullptr) -{ - std::vector<std::string> configs; - { - std::string cfg = makefile->GetConfigurations(configs); - if (config != nullptr) { - *config = cfg; - } - } - // Add empty configuration on demand - if (configs.empty()) { - configs.push_back(""); - } - return configs; -} - -static std::vector<std::string> GetConfigurationSuffixes(cmMakefile* makefile) +static void GetConfigs(cmMakefile* makefile, std::string& configDefault, + std::vector<std::string>& configsList) { - std::vector<std::string> suffixes; - if (AutogenMultiConfig(makefile->GetGlobalGenerator())) { - makefile->GetConfigurations(suffixes); - for (std::string& suffix : suffixes) { - suffix.insert(0, "_"); - } + configDefault = makefile->GetConfigurations(configsList); + if (configsList.empty()) { + configsList.push_back(""); } - if (suffixes.empty()) { - suffixes.push_back(""); - } - return suffixes; } static void AddDefinitionEscaped(cmMakefile* makefile, const char* key, - const std::string& value) + std::string const& value) { makefile->AddDefinition(key, cmOutputConverter::EscapeForCMake(value).c_str()); @@ -203,8 +197,8 @@ static void AddDefinitionEscaped( .c_str()); } -static bool AddToSourceGroup(cmMakefile* makefile, const std::string& fileName, - cmQtAutoGen::GeneratorType genType) +static bool AddToSourceGroup(cmMakefile* makefile, std::string const& fileName, + cmQtAutoGen::Generator genType) { cmSourceGroup* sourceGroup = nullptr; // Acquire source group @@ -255,25 +249,54 @@ static bool AddToSourceGroup(cmMakefile* makefile, const std::string& fileName, return true; } -static void AddCleanFile(cmMakefile* makefile, const std::string& fileName) +static void AddCleanFile(cmMakefile* makefile, std::string const& fileName) { makefile->AppendProperty("ADDITIONAL_MAKE_CLEAN_FILES", fileName.c_str(), false); } -static void AddGeneratedSource(cmGeneratorTarget* target, - const std::string& filename, - cmQtAutoGen::GeneratorType genType) +static std::vector<std::string> AddGeneratedSource( + cmGeneratorTarget* target, std::string const& filename, + cmQtAutoGen::MultiConfig multiConfig, + const std::vector<std::string>& configsList, cmQtAutoGen::Generator genType) { - cmMakefile* makefile = target->Target->GetMakefile(); + std::vector<std::string> genFiles; + // Register source file in makefile and source group + if (multiConfig != cmQtAutoGen::FULL) { + genFiles.push_back(filename); + } else { + for (std::string const& cfg : configsList) { + genFiles.push_back( + cmQtAutoGen::AppendFilenameSuffix(filename, "_" + cfg)); + } + } { - cmSourceFile* gFile = makefile->GetOrCreateSource(filename, true); - gFile->SetProperty("GENERATED", "1"); - gFile->SetProperty("SKIP_AUTOGEN", "On"); + cmMakefile* makefile = target->Target->GetMakefile(); + for (std::string const& genFile : genFiles) { + { + cmSourceFile* gFile = makefile->GetOrCreateSource(genFile, true); + gFile->SetProperty("GENERATED", "1"); + gFile->SetProperty("SKIP_AUTOGEN", "On"); + } + AddToSourceGroup(makefile, genFile, genType); + } } - target->AddSource(filename); - AddToSourceGroup(makefile, filename, genType); + // Add source file to target + if (multiConfig != cmQtAutoGen::FULL) { + target->AddSource(filename); + } else { + for (std::string const& cfg : configsList) { + std::string src = "$<$<CONFIG:"; + src += cfg; + src += ">:"; + src += cmQtAutoGen::AppendFilenameSuffix(filename, "_" + cfg); + src += ">"; + target->AddSource(src); + } + } + + return genFiles; } struct cmQtAutoGenSetup @@ -295,8 +318,8 @@ static void SetupAcquireSkipFiles(cmQtAutoGenDigest const& digest, digest.Target->Makefile->GetSourceFiles(); for (cmSourceFile* sf : allSources) { // sf->GetExtension() is only valid after sf->GetFullPath() ... - const std::string& fPath = sf->GetFullPath(); - const cmSystemTools::FileFormat fileType = + std::string const& fPath = sf->GetFullPath(); + cmSystemTools::FileFormat const fileType = cmSystemTools::GetFileFormat(sf->GetExtension().c_str()); if (!(fileType == cmSystemTools::CXX_FILE_FORMAT) && !(fileType == cmSystemTools::HEADER_FILE_FORMAT)) { @@ -308,7 +331,7 @@ static void SetupAcquireSkipFiles(cmQtAutoGenDigest const& digest, const bool uicSkip = digest.UicEnabled && (skipAll || sf->GetPropertyAsBool("SKIP_AUTOUIC")); if (mocSkip || uicSkip) { - const std::string absFile = cmSystemTools::GetRealPath(fPath); + std::string const absFile = cmSystemTools::GetRealPath(fPath); if (mocSkip) { setup.MocSkip.insert(absFile); } @@ -320,9 +343,9 @@ static void SetupAcquireSkipFiles(cmQtAutoGenDigest const& digest, } } -static void SetupAutoTargetMoc(const cmQtAutoGenDigest& digest, - std::string const& config, - std::vector<std::string> const& configs, +static void SetupAutoTargetMoc(cmQtAutoGenDigest const& digest, + std::string const& configDefault, + std::vector<std::string> const& configsList, cmQtAutoGenSetup& setup) { cmGeneratorTarget const* target = digest.Target; @@ -348,43 +371,42 @@ static void SetupAutoTargetMoc(const cmQtAutoGenDigest& digest, } // Moc includes and compile definitions { - auto GetCompileDefinitionsAndDirectories = [target, localGen]( - const std::string& cfg, std::string& incs, std::string& defs) { - { - std::vector<std::string> includeDirs; - // Get the include dirs for this target, without stripping the implicit - // include dirs off, see - // https://gitlab.kitware.com/cmake/cmake/issues/13667 - localGen->GetIncludeDirectories(includeDirs, target, "CXX", cfg, - false); - incs = cmJoin(includeDirs, ";"); - } - { - std::set<std::string> defines; - localGen->AddCompileDefinitions(defines, target, cfg, "CXX"); - defs += cmJoin(defines, ";"); - } + auto GetIncludeDirs = [target, + localGen](std::string const& cfg) -> std::string { + // Get the include dirs for this target, without stripping the implicit + // include dirs off, see + // https://gitlab.kitware.com/cmake/cmake/issues/13667 + std::vector<std::string> includeDirs; + localGen->GetIncludeDirectories(includeDirs, target, "CXX", cfg, false); + return cmJoin(includeDirs, ";"); + }; + auto GetCompileDefinitions = + [target, localGen](std::string const& cfg) -> std::string { + std::set<std::string> defines; + localGen->AddCompileDefinitions(defines, target, cfg, "CXX"); + return cmJoin(defines, ";"); }; - // Default settings - std::string incs; - std::string compileDefs; - GetCompileDefinitionsAndDirectories(config, incs, compileDefs); - AddDefinitionEscaped(makefile, "_moc_incs", incs); - AddDefinitionEscaped(makefile, "_moc_compile_defs", compileDefs); - - // Configuration specific settings - for (std::string const& cfg : configs) { - std::string configIncs; - std::string configCompileDefs; - GetCompileDefinitionsAndDirectories(cfg, configIncs, configCompileDefs); - if (configIncs != incs) { - setup.ConfigMocIncludes[cfg] = configIncs; + // Default configuration settings + std::string const includeDirs = GetIncludeDirs(configDefault); + std::string const compileDefs = GetCompileDefinitions(configDefault); + // Other configuration settings + for (std::string const& cfg : configsList) { + { + std::string const configIncludeDirs = GetIncludeDirs(cfg); + if (configIncludeDirs != includeDirs) { + setup.ConfigMocIncludes[cfg] = configIncludeDirs; + } } - if (configCompileDefs != compileDefs) { - setup.ConfigMocDefines[cfg] = configCompileDefs; + { + std::string const configCompileDefs = GetCompileDefinitions(cfg); + if (configCompileDefs != compileDefs) { + setup.ConfigMocDefines[cfg] = configCompileDefs; + } } } + AddDefinitionEscaped(makefile, "_moc_include_dirs", includeDirs); + AddDefinitionEscaped(makefile, "_moc_compile_defs", compileDefs); } // Moc executable @@ -419,7 +441,7 @@ static void SetupAutoTargetMoc(const cmQtAutoGenDigest& digest, } } -static void SetupAutoTargetUic(const cmQtAutoGenDigest& digest, +static void SetupAutoTargetUic(cmQtAutoGenDigest const& digest, std::string const& config, std::vector<std::string> const& configs, cmQtAutoGenSetup& setup) @@ -433,10 +455,10 @@ static void SetupAutoTargetUic(const cmQtAutoGenDigest& digest, { std::vector<std::string> uicSearchPaths; { - const std::string usp = GetSafeProperty(target, "AUTOUIC_SEARCH_PATHS"); + std::string const usp = GetSafeProperty(target, "AUTOUIC_SEARCH_PATHS"); if (!usp.empty()) { cmSystemTools::ExpandListArgument(usp, uicSearchPaths); - const std::string srcDir = makefile->GetCurrentSourceDirectory(); + std::string const srcDir = makefile->GetCurrentSourceDirectory(); for (std::string& path : uicSearchPaths) { path = cmSystemTools::CollapseFullPath(path, srcDir); } @@ -446,19 +468,19 @@ static void SetupAutoTargetUic(const cmQtAutoGenDigest& digest, } // Uic target options { - auto UicGetOpts = [target](const std::string& cfg) -> std::string { + auto UicGetOpts = [target](std::string const& cfg) -> std::string { std::vector<std::string> opts; target->GetAutoUicOptions(opts, cfg); return cmJoin(opts, ";"); }; // Default settings - const std::string uicOpts = UicGetOpts(config); + std::string const uicOpts = UicGetOpts(config); AddDefinitionEscaped(makefile, "_uic_target_options", uicOpts); // Configuration specific settings for (std::string const& cfg : configs) { - const std::string configUicOpts = UicGetOpts(cfg); + std::string const configUicOpts = UicGetOpts(cfg); if (configUicOpts != uicOpts) { setup.ConfigUicOptions[cfg] = configUicOpts; } @@ -469,16 +491,16 @@ static void SetupAutoTargetUic(const cmQtAutoGenDigest& digest, std::vector<std::string> uiFileFiles; std::vector<std::vector<std::string>> uiFileOptions; { - const std::string uiExt = "ui"; + std::string const uiExt = "ui"; const std::vector<cmSourceFile*>& srcFiles = makefile->GetSourceFiles(); for (cmSourceFile* sf : srcFiles) { // sf->GetExtension() is only valid after sf->GetFullPath() ... - const std::string& fPath = sf->GetFullPath(); + std::string const& fPath = sf->GetFullPath(); if (sf->GetExtension() == uiExt) { // Check if the files has uic options - const std::string uicOpts = GetSafeProperty(sf, "AUTOUIC_OPTIONS"); + std::string const uicOpts = GetSafeProperty(sf, "AUTOUIC_OPTIONS"); if (!uicOpts.empty()) { - const std::string absFile = cmSystemTools::GetRealPath(fPath); + std::string const absFile = cmSystemTools::GetRealPath(fPath); // Check if file isn't skipped if (setup.UicSkip.count(absFile) == 0) { uiFileFiles.push_back(absFile); @@ -528,7 +550,7 @@ static void SetupAutoTargetUic(const cmQtAutoGenDigest& digest, } static std::string RccGetExecutable(cmGeneratorTarget const* target, - const std::string& qtMajorVersion) + std::string const& qtMajorVersion) { std::string rccExec; std::string err; @@ -559,7 +581,7 @@ static std::string RccGetExecutable(cmGeneratorTarget const* target, return rccExec; } -static void SetupAutoTargetRcc(const cmQtAutoGenDigest& digest) +static void SetupAutoTargetRcc(cmQtAutoGenDigest const& digest) { std::vector<std::string> rccFiles; std::vector<std::string> rccBuilds; @@ -590,26 +612,36 @@ void cmQtAutoGeneratorInitializer::InitializeAutogenTarget( cmLocalGenerator* localGen = target->GetLocalGenerator(); cmGlobalGenerator* globalGen = localGen->GetGlobalGenerator(); - // Create a custom target for running generators at buildtime - const bool multiConfig = AutogenMultiConfig(globalGen); - const std::string autogenTargetName = GetAutogenTargetName(target); - const std::string autogenBuildDir = GetAutogenTargetBuildDir(target); - const std::string workingDirectory = + std::string const autogenTargetName = GetAutogenTargetName(target); + std::string const autogenBuildDir = GetAutogenTargetBuildDir(target); + std::string const workingDirectory = cmSystemTools::CollapseFullPath("", makefile->GetCurrentBinaryDirectory()); - const std::vector<std::string> suffixes = GetConfigurationSuffixes(makefile); + + cmQtAutoGen::MultiConfig const multiConfig = AutogenMultiConfig(globalGen); + std::string configDefault; + std::vector<std::string> configsList; + GetConfigs(makefile, configDefault, configsList); + std::set<std::string> autogenDependFiles; std::set<std::string> autogenDependTargets; std::vector<std::string> autogenProvides; // Remove build directories on cleanup AddCleanFile(makefile, autogenBuildDir); - // Remove old settings on cleanup { std::string base = GetAutogenTargetFilesDir(target); base += "/AutogenOldSettings"; - for (std::string const& suffix : suffixes) { - AddCleanFile(makefile, (base + suffix).append(".cmake")); + if (multiConfig == cmQtAutoGen::SINGLE) { + AddCleanFile(makefile, base.append(".cmake")); + } else { + for (std::string const& cfg : configsList) { + std::string filename = base; + filename += "_"; + filename += cfg; + filename += ".cmake"; + AddCleanFile(makefile, filename); + } } } @@ -653,15 +685,18 @@ void cmQtAutoGeneratorInitializer::InitializeAutogenTarget( // Add moc compilation to generated files list if (digest.MocEnabled) { - const std::string mocsComp = autogenBuildDir + "/mocs_compilation.cpp"; - AddGeneratedSource(target, mocsComp, cmQtAutoGen::MOC); - autogenProvides.push_back(mocsComp); + std::string const mocsComp = autogenBuildDir + "/mocs_compilation.cpp"; + auto files = AddGeneratedSource(target, mocsComp, multiConfig, configsList, + cmQtAutoGen::MOC); + for (std::string& file : files) { + autogenProvides.push_back(std::move(file)); + } } // Add autogen includes directory to the origin target INCLUDE_DIRECTORIES if (digest.MocEnabled || digest.UicEnabled) { std::string includeDir = autogenBuildDir + "/include"; - if (multiConfig) { + if (multiConfig != cmQtAutoGen::SINGLE) { includeDir += "_$<CONFIG>"; } target->AddIncludeDirectory(includeDir, true); @@ -671,7 +706,7 @@ void cmQtAutoGeneratorInitializer::InitializeAutogenTarget( std::vector<std::string> generatedSources; std::vector<std::string> generatedHeaders; { - const std::string qrcExt = "qrc"; + std::string const qrcExt = "qrc"; std::vector<cmSourceFile*> srcFiles; target->GetConfigCommonSourceFiles(srcFiles); for (cmSourceFile* sf : srcFiles) { @@ -679,15 +714,15 @@ void cmQtAutoGeneratorInitializer::InitializeAutogenTarget( continue; } // sf->GetExtension() is only valid after sf->GetFullPath() ... - const std::string& fPath = sf->GetFullPath(); - const std::string& ext = sf->GetExtension(); + std::string const& fPath = sf->GetFullPath(); + std::string const& ext = sf->GetExtension(); // Register generated files that will be scanned by moc or uic if (digest.MocEnabled || digest.UicEnabled) { - const cmSystemTools::FileFormat fileType = + cmSystemTools::FileFormat const fileType = cmSystemTools::GetFileFormat(ext.c_str()); if ((fileType == cmSystemTools::CXX_FILE_FORMAT) || (fileType == cmSystemTools::HEADER_FILE_FORMAT)) { - const std::string absPath = cmSystemTools::GetRealPath(fPath); + std::string const absPath = cmSystemTools::GetRealPath(fPath); if ((digest.MocEnabled && !sf->GetPropertyAsBool("SKIP_AUTOMOC")) || (digest.UicEnabled && !sf->GetPropertyAsBool("SKIP_AUTOUIC"))) { // Register source @@ -720,7 +755,7 @@ void cmQtAutoGeneratorInitializer::InitializeAutogenTarget( qrcDigest.Generated = sf->GetPropertyAsBool("GENERATED"); // RCC options { - const std::string opts = GetSafeProperty(sf, "AUTORCC_OPTIONS"); + std::string const opts = GetSafeProperty(sf, "AUTORCC_OPTIONS"); if (!opts.empty()) { cmSystemTools::ExpandListArgument(opts, qrcDigest.Options); } @@ -741,7 +776,7 @@ void cmQtAutoGeneratorInitializer::InitializeAutogenTarget( // Check status of policy CMP0071 bool policyAccept = false; bool policyWarn = false; - const cmPolicies::PolicyStatus CMP0071_status = + cmPolicies::PolicyStatus const CMP0071_status = target->Makefile->GetPolicyStatus(cmPolicies::CMP0071); switch (CMP0071_status) { case cmPolicies::WARN: @@ -785,13 +820,13 @@ void cmQtAutoGeneratorInitializer::InitializeAutogenTarget( } if (!generatedHeaders.empty()) { msg.append(tools).append(": Ignoring GENERATED header file(s):\n"); - for (const std::string& absFile : generatedHeaders) { + for (std::string const& absFile : generatedHeaders) { msg.append(" ").append(cmQtAutoGen::Quoted(absFile)).append("\n"); } } if (!generatedSources.empty()) { msg.append(tools).append(": Ignoring GENERATED source file(s):\n"); - for (const std::string& absFile : generatedSources) { + for (std::string const& absFile : generatedSources) { msg.append(" ").append(cmQtAutoGen::Quoted(absFile)).append("\n"); } } @@ -806,7 +841,7 @@ void cmQtAutoGeneratorInitializer::InitializeAutogenTarget( // Process qrc files if (!digest.Qrcs.empty()) { const bool QtV5 = (digest.QtVersionMajor == "5"); - const std::string rcc = RccGetExecutable(target, digest.QtVersionMajor); + std::string const rcc = RccGetExecutable(target, digest.QtVersionMajor); // Target rcc options std::vector<std::string> optionsTarget; cmSystemTools::ExpandListArgument( @@ -825,7 +860,7 @@ void cmQtAutoGeneratorInitializer::InitializeAutogenTarget( } // Path checksum { - const cmFilePathChecksum fpathCheckSum(makefile); + cmFilePathChecksum const fpathCheckSum(makefile); for (cmQtAutoGenDigestQrc& qrcDigest : digest.Qrcs) { qrcDigest.PathChecksum = fpathCheckSum.getPart(qrcDigest.QrcFile); // RCC output file name @@ -861,8 +896,13 @@ void cmQtAutoGeneratorInitializer::InitializeAutogenTarget( } for (cmQtAutoGenDigestQrc& qrcDigest : digest.Qrcs) { // Register file at target - AddGeneratedSource(target, qrcDigest.RccFile, cmQtAutoGen::RCC); - autogenProvides.push_back(qrcDigest.RccFile); + { + auto files = AddGeneratedSource(target, qrcDigest.RccFile, multiConfig, + configsList, cmQtAutoGen::RCC); + for (std::string& file : files) { + autogenProvides.push_back(std::move(file)); + } + } // Dependencies if (qrcDigest.Generated) { // Add the GENERATED .qrc file to the dependencies @@ -889,7 +929,7 @@ void cmQtAutoGeneratorInitializer::InitializeAutogenTarget( // Add user defined autogen target dependencies { - const std::string deps = GetSafeProperty(target, "AUTOGEN_TARGET_DEPENDS"); + std::string const deps = GetSafeProperty(target, "AUTOGEN_TARGET_DEPENDS"); if (!deps.empty()) { std::vector<std::string> extraDeps; cmSystemTools::ExpandListArgument(deps, extraDeps); @@ -924,7 +964,7 @@ void cmQtAutoGeneratorInitializer::InitializeAutogenTarget( // Create the autogen target/command if (usePRE_BUILD) { // Add additional autogen target dependencies to origin target - for (const std::string& depTarget : autogenDependTargets) { + for (std::string const& depTarget : autogenDependTargets) { target->Target->AddUtility(depTarget, makefile); } @@ -944,7 +984,7 @@ void cmQtAutoGeneratorInitializer::InitializeAutogenTarget( } else { // Add utility target dependencies to the autogen target dependencies - for (const std::string& depTarget : target->Target->GetUtilities()) { + for (std::string const& depTarget : target->Target->GetUtilities()) { autogenDependTargets.insert(depTarget); } // Add link library target dependencies to the autogen target dependencies @@ -967,7 +1007,7 @@ void cmQtAutoGeneratorInitializer::InitializeAutogenTarget( new cmGeneratorTarget(autogenTarget, localGen)); // Add additional autogen target dependencies to autogen target - for (const std::string& depTarget : autogenDependTargets) { + for (std::string const& depTarget : autogenDependTargets) { autogenTarget->AddUtility(depTarget, makefile); } @@ -994,45 +1034,51 @@ void cmQtAutoGeneratorInitializer::InitializeAutogenTarget( } void cmQtAutoGeneratorInitializer::SetupAutoGenerateTarget( - const cmQtAutoGenDigest& digest) + cmQtAutoGenDigest const& digest) { cmGeneratorTarget const* target = digest.Target; cmMakefile* makefile = target->Target->GetMakefile(); + cmQtAutoGen::MultiConfig const multiConfig = + AutogenMultiConfig(target->GetGlobalGenerator()); // forget the variables added here afterwards again: cmMakefile::ScopePushPop varScope(makefile); static_cast<void>(varScope); - // Get configurations - std::string config; - const std::vector<std::string> configs(GetConfigurations(makefile, &config)); - - // Configuration suffixes - std::map<std::string, std::string> configSuffix; - if (AutogenMultiConfig(target->GetGlobalGenerator())) { - for (std::string const& cfg : configs) { - configSuffix[cfg] = "_" + cfg; + // Configurations + std::string configDefault; + std::vector<std::string> configsList; + std::map<std::string, std::string> configSuffixes; + { + configDefault = makefile->GetConfigurations(configsList); + if (configsList.empty()) { + configsList.push_back(""); } } + for (std::string const& cfg : configsList) { + configSuffixes[cfg] = "_" + cfg; + } // Configurations settings buffers cmQtAutoGenSetup setup; // Basic setup + AddDefinitionEscaped(makefile, "_multi_config", + cmQtAutoGen::MultiConfigName(multiConfig)); AddDefinitionEscaped(makefile, "_build_dir", GetAutogenTargetBuildDir(target)); - AddDefinitionEscaped(makefile, "_qt_version_major", digest.QtVersionMajor); - AddDefinitionEscaped(makefile, "_qt_version_minor", digest.QtVersionMinor); AddDefinitionEscaped(makefile, "_sources", digest.Sources); AddDefinitionEscaped(makefile, "_headers", digest.Headers); + AddDefinitionEscaped(makefile, "_qt_version_major", digest.QtVersionMajor); + AddDefinitionEscaped(makefile, "_qt_version_minor", digest.QtVersionMinor); { if (digest.MocEnabled || digest.UicEnabled) { SetupAcquireSkipFiles(digest, setup); if (digest.MocEnabled) { - SetupAutoTargetMoc(digest, config, configs, setup); + SetupAutoTargetMoc(digest, configDefault, configsList, setup); } if (digest.UicEnabled) { - SetupAutoTargetUic(digest, config, configs, setup); + SetupAutoTargetUic(digest, configDefault, configsList, setup); } } if (digest.RccEnabled) { @@ -1041,17 +1087,18 @@ void cmQtAutoGeneratorInitializer::SetupAutoGenerateTarget( } // Generate info file - std::string infoFile = GetAutogenTargetFilesDir(target); - infoFile += "/AutogenInfo.cmake"; { - std::string inf = cmSystemTools::GetCMakeRoot(); - inf += "/Modules/AutogenInfo.cmake.in"; - makefile->ConfigureFile(inf.c_str(), infoFile.c_str(), false, true, false); - } + std::string infoFile = GetAutogenTargetFilesDir(target); + infoFile += "/AutogenInfo.cmake"; + { + std::string infoFileIn = cmSystemTools::GetCMakeRoot(); + infoFileIn += "/Modules/AutogenInfo.cmake.in"; + makefile->ConfigureFile(infoFileIn.c_str(), infoFile.c_str(), false, + true, false); + } - // Append custom definitions to info file on demand - if (!configSuffix.empty() || !setup.ConfigMocDefines.empty() || - !setup.ConfigMocIncludes.empty() || !setup.ConfigUicOptions.empty()) { + // Append custom definitions to info file + // -------------------------------------- // Ensure we have write permission in case .in was read-only. mode_t perm = 0; @@ -1069,14 +1116,14 @@ void cmQtAutoGeneratorInitializer::SetupAutoGenerateTarget( cmsys::ofstream ofs(infoFile.c_str(), std::ios::app); if (ofs) { auto OfsWriteMap = [&ofs]( - const char* key, const std::map<std::string, std::string>& map) { + const char* key, std::map<std::string, std::string> const& map) { for (auto const& item : map) { ofs << "set(" << key << "_" << item.first << " " << cmOutputConverter::EscapeForCMake(item.second) << ")\n"; } }; - ofs << "# Configuration specific options\n"; - OfsWriteMap("AM_CONFIG_SUFFIX", configSuffix); + ofs << "# Configurations options\n"; + OfsWriteMap("AM_CONFIG_SUFFIX", configSuffixes); OfsWriteMap("AM_MOC_DEFINITIONS", setup.ConfigMocDefines); OfsWriteMap("AM_MOC_INCLUDES", setup.ConfigMocIncludes); OfsWriteMap("AM_UIC_TARGET_OPTIONS", setup.ConfigUicOptions); diff --git a/Source/cmQtAutoGeneratorInitializer.h b/Source/cmQtAutoGeneratorInitializer.h index 1264ca5..b8a5ae4 100644 --- a/Source/cmQtAutoGeneratorInitializer.h +++ b/Source/cmQtAutoGeneratorInitializer.h @@ -15,7 +15,7 @@ class cmQtAutoGeneratorInitializer public: static std::string GetQtMajorVersion(cmGeneratorTarget const* target); static std::string GetQtMinorVersion(cmGeneratorTarget const* target, - const std::string& qtVersionMajor); + std::string const& qtVersionMajor); static void InitializeAutogenTarget(cmQtAutoGenDigest& digest); static void SetupAutoGenerateTarget(cmQtAutoGenDigest const& digest); diff --git a/Source/cmQtAutoGenerators.cxx b/Source/cmQtAutoGenerators.cxx index e8a9006..bd0fb9a 100644 --- a/Source/cmQtAutoGenerators.cxx +++ b/Source/cmQtAutoGenerators.cxx @@ -131,7 +131,8 @@ static bool ListContains(std::vector<std::string> const& list, // -- Class methods cmQtAutoGenerators::cmQtAutoGenerators() - : IncludeProjectDirsBefore(false) + : MultiConfig(cmQtAutoGen::WRAP) + , IncludeProjectDirsBefore(false) , Verbose(cmSystemTools::HasEnv("VERBOSE")) , ColorOutput(true) , MocSettingsChanged(false) @@ -196,6 +197,9 @@ bool cmQtAutoGenerators::InitInfoFile(cmMakefile* makefile, std::string const& targetDirectory, std::string const& config) { + // -- Meta + this->HeaderExtensions = makefile->GetCMakeInstance()->GetHeaderExtensions(); + // Utility lambdas auto InfoGet = [makefile](const char* key) { return makefile->GetSafeDefinition(key); @@ -239,10 +243,8 @@ bool cmQtAutoGenerators::InitInfoFile(cmMakefile* makefile, const char* valueConf = nullptr; { std::string keyConf = key; - if (!config.empty()) { - keyConf += '_'; - keyConf += config; - } + keyConf += '_'; + keyConf += config; valueConf = makefile->GetDefinition(keyConf); } if (valueConf == nullptr) { @@ -257,10 +259,10 @@ bool cmQtAutoGenerators::InitInfoFile(cmMakefile* makefile, return list; }; + // -- Read info file this->InfoFile = cmSystemTools::CollapseFullPath(targetDirectory); cmSystemTools::ConvertToUnixSlashes(this->InfoFile); this->InfoFile += "/AutogenInfo.cmake"; - if (!makefile->ReadListFile(this->InfoFile.c_str())) { this->LogFileError(cmQtAutoGen::GEN, this->InfoFile, "File processing failed"); @@ -268,16 +270,11 @@ bool cmQtAutoGenerators::InitInfoFile(cmMakefile* makefile, } // -- Meta - this->HeaderExtensions = makefile->GetCMakeInstance()->GetHeaderExtensions(); + this->MultiConfig = cmQtAutoGen::MultiConfigType(InfoGet("AM_MULTI_CONFIG")); this->ConfigSuffix = InfoGetConfig("AM_CONFIG_SUFFIX"); - - // - Old settings file - { - this->SettingsFile = cmSystemTools::CollapseFullPath(targetDirectory); - cmSystemTools::ConvertToUnixSlashes(this->SettingsFile); - this->SettingsFile += "/AutogenOldSettings"; - this->SettingsFile += this->ConfigSuffix; - this->SettingsFile += ".cmake"; + if (this->ConfigSuffix.empty()) { + this->ConfigSuffix = "_"; + this->ConfigSuffix += config; } // - Files and directories @@ -499,19 +496,28 @@ bool cmQtAutoGenerators::InitInfoFile(cmMakefile* makefile, // include directory this->AutogenIncludeDir = "include"; - this->AutogenIncludeDir += this->ConfigSuffix; + if (this->MultiConfig != cmQtAutoGen::SINGLE) { + this->AutogenIncludeDir += this->ConfigSuffix; + } this->AutogenIncludeDir += "/"; + // Moc variables if (this->MocEnabled()) { // Mocs compilation file - this->MocCompFileRel = "mocs_compilation.cpp"; + this->MocCompFileRel = "mocs_compilation"; + if (this->MultiConfig == cmQtAutoGen::FULL) { + this->MocCompFileRel += this->ConfigSuffix; + } + this->MocCompFileRel += ".cpp"; this->MocCompFileAbs = cmSystemTools::CollapseCombinedPath( this->AutogenBuildDir, this->MocCompFileRel); // Moc predefs file if (!this->MocPredefsCmd.empty()) { this->MocPredefsFileRel = "moc_predefs"; - this->MocPredefsFileRel += this->ConfigSuffix; + if (this->MultiConfig != cmQtAutoGen::SINGLE) { + this->MocPredefsFileRel += this->ConfigSuffix; + } this->MocPredefsFileRel += ".h"; this->MocPredefsFileAbs = cmSystemTools::CollapseCombinedPath( this->AutogenBuildDir, this->MocPredefsFileRel); @@ -585,6 +591,17 @@ bool cmQtAutoGenerators::InitInfoFile(cmMakefile* makefile, } } + // - Old settings file + { + this->SettingsFile = cmSystemTools::CollapseFullPath(targetDirectory); + cmSystemTools::ConvertToUnixSlashes(this->SettingsFile); + this->SettingsFile += "/AutogenOldSettings"; + if (this->MultiConfig != cmQtAutoGen::SINGLE) { + this->SettingsFile += this->ConfigSuffix; + } + this->SettingsFile += ".cmake"; + } + return true; } @@ -1299,18 +1316,18 @@ void cmQtAutoGenerators::MocParseHeaderContent(std::string const& absFilename, }); if (fit == this->MocJobsIncluded.cend()) { if (this->MocRequired(contentText)) { - static std::string const prefix = "moc_"; - static std::string const suffix = this->ConfigSuffix + ".cpp"; - auto job = cm::make_unique<MocJobAuto>(); job->SourceFile = absFilename; { std::string& bld = job->BuildFileRel; bld = this->FilePathChecksum.getPart(absFilename); - bld += "/"; - bld += prefix; + bld += '/'; + bld += "moc_"; bld += cmSystemTools::GetFilenameWithoutLastExtension(absFilename); - bld += suffix; + if (this->MultiConfig != cmQtAutoGen::SINGLE) { + bld += this->ConfigSuffix; + } + bld += ".cpp"; } this->MocFindDepends(absFilename, contentText, job->Depends); this->MocJobsAuto.push_back(std::move(job)); @@ -1437,9 +1454,12 @@ bool cmQtAutoGenerators::MocGenerateAll() // Compose mocs compilation file content { - std::string mocs = "/* This file is autogenerated, do not edit*/\n"; + std::string mocs = + "// This file is autogenerated. Changes will be overwritten.\n"; if (this->MocJobsAuto.empty()) { - // Dummy content + // Placeholder content + mocs += + "// No files found that require moc or the moc files are included\n"; mocs += "enum some_compilers { need_more_than_nothing };\n"; } else { // Valid content @@ -1917,14 +1937,11 @@ bool cmQtAutoGenerators::RccGenerateFile(const RccJob& rccJob) bool rccGenerated = false; std::string rccFileAbs; - if (this->ConfigSuffix.empty()) { + if (this->MultiConfig == cmQtAutoGen::SINGLE) { rccFileAbs = rccJob.RccFile; } else { - rccFileAbs = SubDirPrefix(rccJob.RccFile); - rccFileAbs += - cmSystemTools::GetFilenameWithoutLastExtension(rccJob.RccFile); - rccFileAbs += this->ConfigSuffix; - rccFileAbs += cmSystemTools::GetFilenameLastExtension(rccJob.RccFile); + rccFileAbs = + cmQtAutoGen::AppendFilenameSuffix(rccJob.RccFile, this->ConfigSuffix); } std::string const rccFileRel = cmSystemTools::RelativePath( this->AutogenBuildDir.c_str(), rccFileAbs.c_str()); @@ -2064,15 +2081,16 @@ bool cmQtAutoGenerators::RccGenerateFile(const RccJob& rccJob) success = false; } } - // For a multi configuration generator generate a wrapper file - if (success && !this->ConfigSuffix.empty()) { + + // Generate a wrapper source file on demand + if (success && (this->MultiConfig == cmQtAutoGen::WRAP)) { // Wrapper file name std::string const& wrapperFileAbs = rccJob.RccFile; std::string const wrapperFileRel = cmSystemTools::RelativePath( this->AutogenBuildDir.c_str(), wrapperFileAbs.c_str()); // Wrapper file content std::string content = "// This is an autogenerated configuration " - "wrapper file. Do not edit.\n" + "wrapper file. Changes will be overwritten.\n" "#include \""; content += cmSystemTools::GetFilenameName(rccFileRel); content += "\"\n"; @@ -2107,7 +2125,7 @@ void cmQtAutoGenerators::LogBold(std::string const& message) const message.c_str(), true, this->ColorOutput); } -void cmQtAutoGenerators::LogInfo(cmQtAutoGen::GeneratorType genType, +void cmQtAutoGenerators::LogInfo(cmQtAutoGen::Generator genType, std::string const& message) const { std::string msg = cmQtAutoGen::GeneratorName(genType); @@ -2119,7 +2137,7 @@ void cmQtAutoGenerators::LogInfo(cmQtAutoGen::GeneratorType genType, cmSystemTools::Stdout(msg.c_str(), msg.size()); } -void cmQtAutoGenerators::LogWarning(cmQtAutoGen::GeneratorType genType, +void cmQtAutoGenerators::LogWarning(cmQtAutoGen::Generator genType, std::string const& message) const { std::string msg = cmQtAutoGen::GeneratorName(genType); @@ -2140,7 +2158,7 @@ void cmQtAutoGenerators::LogWarning(cmQtAutoGen::GeneratorType genType, cmSystemTools::Stdout(msg.c_str(), msg.size()); } -void cmQtAutoGenerators::LogFileWarning(cmQtAutoGen::GeneratorType genType, +void cmQtAutoGenerators::LogFileWarning(cmQtAutoGen::Generator genType, std::string const& filename, std::string const& message) const { @@ -2152,7 +2170,7 @@ void cmQtAutoGenerators::LogFileWarning(cmQtAutoGen::GeneratorType genType, this->LogWarning(genType, msg); } -void cmQtAutoGenerators::LogError(cmQtAutoGen::GeneratorType genType, +void cmQtAutoGenerators::LogError(cmQtAutoGen::Generator genType, std::string const& message) const { std::string msg; @@ -2167,7 +2185,7 @@ void cmQtAutoGenerators::LogError(cmQtAutoGen::GeneratorType genType, cmSystemTools::Stderr(msg.c_str(), msg.size()); } -void cmQtAutoGenerators::LogFileError(cmQtAutoGen::GeneratorType genType, +void cmQtAutoGenerators::LogFileError(cmQtAutoGen::Generator genType, std::string const& filename, std::string const& message) const { @@ -2180,7 +2198,7 @@ void cmQtAutoGenerators::LogFileError(cmQtAutoGen::GeneratorType genType, } void cmQtAutoGenerators::LogCommandError( - cmQtAutoGen::GeneratorType genType, std::string const& message, + cmQtAutoGen::Generator genType, std::string const& message, std::vector<std::string> const& command, std::string const& output) const { std::string msg; @@ -2210,8 +2228,8 @@ void cmQtAutoGenerators::LogCommandError( * @brief Generates the parent directory of the given file on demand * @return True on success */ -bool cmQtAutoGenerators::MakeParentDirectory( - cmQtAutoGen::GeneratorType genType, std::string const& filename) const +bool cmQtAutoGenerators::MakeParentDirectory(cmQtAutoGen::Generator genType, + std::string const& filename) const { bool success = true; std::string const dirName = cmSystemTools::GetFilenamePath(filename); @@ -2238,7 +2256,7 @@ bool cmQtAutoGenerators::FileDiffers(std::string const& filename, return differs; } -bool cmQtAutoGenerators::FileWrite(cmQtAutoGen::GeneratorType genType, +bool cmQtAutoGenerators::FileWrite(cmQtAutoGen::Generator genType, std::string const& filename, std::string const& content) { diff --git a/Source/cmQtAutoGenerators.h b/Source/cmQtAutoGenerators.h index 0b502de..a7bb538 100644 --- a/Source/cmQtAutoGenerators.h +++ b/Source/cmQtAutoGenerators.h @@ -153,38 +153,39 @@ private: // -- Log info void LogBold(std::string const& message) const; - void LogInfo(cmQtAutoGen::GeneratorType genType, + void LogInfo(cmQtAutoGen::Generator genType, std::string const& message) const; // -- Log warning - void LogWarning(cmQtAutoGen::GeneratorType genType, + void LogWarning(cmQtAutoGen::Generator genType, std::string const& message) const; - void LogFileWarning(cmQtAutoGen::GeneratorType genType, + void LogFileWarning(cmQtAutoGen::Generator genType, std::string const& filename, std::string const& message) const; // -- Log error - void LogError(cmQtAutoGen::GeneratorType genType, + void LogError(cmQtAutoGen::Generator genType, std::string const& message) const; - void LogFileError(cmQtAutoGen::GeneratorType genType, + void LogFileError(cmQtAutoGen::Generator genType, std::string const& filename, std::string const& message) const; - void LogCommandError(cmQtAutoGen::GeneratorType genType, + void LogCommandError(cmQtAutoGen::Generator genType, std::string const& message, std::vector<std::string> const& command, std::string const& output) const; // -- Utility - bool MakeParentDirectory(cmQtAutoGen::GeneratorType genType, + bool MakeParentDirectory(cmQtAutoGen::Generator genType, std::string const& filename) const; bool FileDiffers(std::string const& filename, std::string const& content); - bool FileWrite(cmQtAutoGen::GeneratorType genType, - std::string const& filename, std::string const& content); + bool FileWrite(cmQtAutoGen::Generator genType, std::string const& filename, + std::string const& content); bool FindHeader(std::string& header, std::string const& testBasePath) const; bool RunCommand(std::vector<std::string> const& command, std::string& output) const; // -- Meta - std::string ConfigSuffix; std::string InfoFile; + std::string ConfigSuffix; + cmQtAutoGen::MultiConfig MultiConfig; // -- Settings bool IncludeProjectDirsBefore; bool Verbose; diff --git a/Tests/FindOpenGL/CMakeLists.txt b/Tests/FindOpenGL/CMakeLists.txt index 9aa3aba..97c9e60 100644 --- a/Tests/FindOpenGL/CMakeLists.txt +++ b/Tests/FindOpenGL/CMakeLists.txt @@ -1,3 +1,9 @@ +if(CMAKE_SYSTEM_NAME STREQUAL "Linux" AND CMake_TEST_FindOpenGL_VND) + set(_vnd_testing TRUE) +else() + set(_vnd_testing FALSE) +endif() + add_test(NAME FindOpenGL.Test COMMAND ${CMAKE_CTEST_COMMAND} -C $<CONFIGURATION> --build-and-test @@ -6,5 +12,6 @@ add_test(NAME FindOpenGL.Test COMMAND ${build_generator_args} --build-project TestFindOpenGL --build-options ${build_options} + -DOpenGL_TEST_VND=${_vnd_testing} --test-command ${CMAKE_CTEST_COMMAND} -V -C $<CONFIGURATION> ) diff --git a/Tests/FindOpenGL/Test/CMakeLists.txt b/Tests/FindOpenGL/Test/CMakeLists.txt index cac3424..3b5ffee 100644 --- a/Tests/FindOpenGL/Test/CMakeLists.txt +++ b/Tests/FindOpenGL/Test/CMakeLists.txt @@ -1,14 +1,70 @@ -cmake_minimum_required(VERSION 3.7) +cmake_minimum_required(VERSION 3.9) project(TestFindOpenGL C) include(CTest) find_package(OpenGL REQUIRED) +# import target for GLU add_executable(test_tgt main.c) target_link_libraries(test_tgt OpenGL::GLU) add_test(NAME test_tgt COMMAND test_tgt) +# OPENGL_LIBRARIES should be whatever libraries are needed to link. add_executable(test_var main.c) target_include_directories(test_var PRIVATE ${OPENGL_INGLUDE_DIRS}) target_link_libraries(test_var PRIVATE ${OPENGL_LIBRARIES}) add_test(NAME test_var COMMAND test_var) + +# VND support adds an ::OpenGL import target. This can be used for OpenGL-only +# code (code that does not manipulate contexts, like our 'main.c'). Without +# VND, ::GL can be used for both context and non-context OpenGL code. +if(OpenGL_TEST_VND) + add_executable(test_comp_none main.c) + target_link_libraries(test_comp_none PRIVATE OpenGL::OpenGL) + add_test(NAME test_comp_none COMMAND test_comp_none) +else() + add_executable(test_comp_none main.c) + target_link_libraries(test_comp_none PRIVATE OpenGL::GL) + add_test(NAME test_comp_none COMMAND test_comp_none) +endif() + +# GLX +if(OpenGL_TEST_VND) + find_package(OpenGL REQUIRED COMPONENTS OpenGL GLX) + add_executable(test_comp_glx main.c) + target_link_libraries(test_comp_glx PRIVATE OpenGL::OpenGL OpenGL::GLX) + add_test(NAME test_comp_glx COMMAND test_comp_glx) +else() + # non-VND systems won't have it, but an optional search for GLX should still + # be okay. + find_package(OpenGL COMPONENTS GLX) + add_executable(test_comp_glx_novnd main.c) + target_link_libraries(test_comp_glx_novnd PRIVATE OpenGL::GL) + add_test(NAME test_comp_glx_novnd COMMAND test_comp_glx_novnd) +endif() + +# EGL is only available on Linux+GLVND at present. +if(OpenGL_TEST_VND) + find_package(OpenGL COMPONENTS OpenGL EGL) + if(OpenGL_EGL_FOUND) + add_executable(test_comp_egl main.c) + target_link_libraries(test_comp_egl PRIVATE OpenGL::OpenGL OpenGL::EGL) + add_test(NAME test_comp_egl COMMAND test_comp_egl) + # EGL-only code should not link to GLX. + execute_process(COMMAND ldd test_comp_egl + OUTPUT_VARIABLE LDD_OUT + ERROR_VARIABLE LDD_ERR) + if("${LDD_OUT}" MATCHES "GLX") + message(FATAL_ERROR "EGL-only code links to GLX!") + endif() + endif() + + # all three COMPONENTS together. + find_package(OpenGL COMPONENTS OpenGL EGL GLX) + if(OpenGL_EGL_FOUND AND OpenGL_GLX_FOUND) + add_executable(test_comp_both main.c) + target_link_libraries(test_comp_both PRIVATE OpenGL::OpenGL OpenGL::EGL + OpenGL::GLX) + add_test(NAME test_comp_both COMMAND test_comp_both) + endif() +endif() diff --git a/Tests/RunCMake/get_property/source_properties-stderr.txt b/Tests/RunCMake/get_property/source_properties-stderr.txt index 0a46f96..00a9b82 100644 --- a/Tests/RunCMake/get_property/source_properties-stderr.txt +++ b/Tests/RunCMake/get_property/source_properties-stderr.txt @@ -3,4 +3,10 @@ get_property: --><-- get_source_file_property: -->value<-- get_property: -->value<-- get_source_file_property: -->NOTFOUND<-- -get_property: --><--$ +get_property: --><-- +get_source_file_property: -->value<-- +get_property: -->value<-- +get_source_file_property: -->NOTFOUND<-- +get_property: --><-- +get_source_file_property: -->value<-- +get_property: -->value<--$ diff --git a/Tests/RunCMake/get_property/source_properties.cmake b/Tests/RunCMake/get_property/source_properties.cmake index 263ffe1..12d2d07 100644 --- a/Tests/RunCMake/get_property/source_properties.cmake +++ b/Tests/RunCMake/get_property/source_properties.cmake @@ -13,3 +13,13 @@ set_source_files_properties(file.c PROPERTIES empty "" custom value) check_source_file_property(file.c empty) check_source_file_property(file.c custom) check_source_file_property(file.c noexist) + +# Test strange legacy behavior in which the order in which source files are +# first accessed affects how properties are applied without an extension. +# See also issue #15208. +get_property(lang SOURCE ${CMAKE_CURRENT_BINARY_DIR}/file2.c PROPERTY LANGUAGE) +get_property(lang SOURCE ${CMAKE_CURRENT_BINARY_DIR}/file2.h PROPERTY LANGUAGE) +set_property(SOURCE file2 PROPERTY custom value) # set property without extension +check_source_file_property(file2 custom) # should have property +check_source_file_property(file2.h custom) # should not have property +check_source_file_property(file2.c custom) # should have property diff --git a/Tests/VSResource/CMakeLists.txt b/Tests/VSResource/CMakeLists.txt index 718e624..fb47c7e 100644 --- a/Tests/VSResource/CMakeLists.txt +++ b/Tests/VSResource/CMakeLists.txt @@ -56,3 +56,10 @@ endif() set_property(TARGET VSResource PROPERTY VS_GLOBAL_CMakeTestVsGlobalVariable "test val") + +if(CMAKE_GENERATOR MATCHES "Ninja|Visual Studio") + cmake_policy(PUSH) + cmake_policy(SET CMP0037 OLD) + add_library("My ResourceLib" lib.cpp lib.rc) + cmake_policy(POP) +endif() |