diff options
52 files changed, 2701 insertions, 223 deletions
diff --git a/CTestCustom.cmake.in b/CTestCustom.cmake.in index 0047e68..e175d9f 100644 --- a/CTestCustom.cmake.in +++ b/CTestCustom.cmake.in @@ -42,6 +42,7 @@ SET(CTEST_CUSTOM_WARNING_EXCEPTION "warning:.*is.*misused, please use.*" "CMakeSetupManifest.xml.*manifest authoring warning.*Unrecognized Element" "cc-3968 CC: WARNING File.*" # "implicit" truncation by static_cast + "ld: warning: directory not found for option .-(F|L)" ) IF(NOT "@CMAKE_GENERATOR@" MATCHES "Xcode") diff --git a/Modules/AutomocInfo.cmake.in b/Modules/AutomocInfo.cmake.in new file mode 100644 index 0000000..2dc3aa2 --- /dev/null +++ b/Modules/AutomocInfo.cmake.in @@ -0,0 +1,13 @@ +set(AM_SOURCES "@_moc_files@" ) +set(AM_HEADERS "@_moc_headers@" ) +set(AM_MOC_COMPILE_DEFINITIONS "@_moc_compile_defs@") +set(AM_MOC_DEFINITIONS "@_moc_defs@") +set(AM_MOC_INCLUDES "@_moc_incs@") +set(AM_CMAKE_INCLUDE_DIRECTORIES_PROJECT_BEFORE "@CMAKE_INCLUDE_DIRECTORIES_PROJECT_BEFORE@") +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_CMAKE_CURRENT_SOURCE_DIR "@CMAKE_CURRENT_SOURCE_DIR@/") +set(AM_CMAKE_CURRENT_BINARY_DIR "@CMAKE_CURRENT_BINARY_DIR@/") +set(AM_QT_VERSION_MAJOR "@QT_VERSION_MAJOR@" ) +set(AM_TARGET_NAME "@_moc_target_name@") diff --git a/Modules/CMakeASMInformation.cmake b/Modules/CMakeASMInformation.cmake index d50f351..b5f2420 100644 --- a/Modules/CMakeASMInformation.cmake +++ b/Modules/CMakeASMInformation.cmake @@ -33,7 +33,7 @@ IF(CMAKE_ASM${ASM_DIALECT}_COMPILER_ID) ENDIF(CMAKE_ASM${ASM_DIALECT}_COMPILER_ID) IF(NOT _INCLUDED_FILE) IF("ASM${ASM_DIALECT}" STREQUAL "ASM") - MESSAGE(FATAL_ERROR "Did not find file Compiler/${CMAKE_ASM${ASM_DIALECT}_COMPILER_ID}-ASM${ASM_DIALECT}") + MESSAGE(STATUS "Warning: Did not find file Compiler/${CMAKE_ASM${ASM_DIALECT}_COMPILER_ID}-ASM${ASM_DIALECT}") ENDIF("ASM${ASM_DIALECT}" STREQUAL "ASM") INCLUDE(Platform/${CMAKE_BASE_NAME} OPTIONAL) ENDIF(NOT _INCLUDED_FILE) diff --git a/Modules/CMakeFindPackageMode.cmake b/Modules/CMakeFindPackageMode.cmake new file mode 100644 index 0000000..4296577 --- /dev/null +++ b/Modules/CMakeFindPackageMode.cmake @@ -0,0 +1,187 @@ +# This file is executed by cmake when invoked with --find-package. +# It expects that the following variables are set using -D: +# NAME = name of the package +# COMPILER_ID = the CMake compiler ID for which the result is, i.e. GNU/Intel/Clang/MSVC, etc. +# LANGUAGE = language for which the result will be used, i.e. C/CXX/Fortan/ASM +# MODE = EXIST : only check for existance of the given package +# COMPILE : print the flags needed for compiling an object file which uses the given package +# LINK : print the flags needed for linking when using the given package +# QUIET = if TRUE, don't print anything + +#============================================================================= +# Copyright 2006-2011 Alexander Neundorf, <neundorf@kde.org> +# +# Distributed under the OSI-approved BSD License (the "License"); +# see accompanying file Copyright.txt for details. +# +# This software is distributed WITHOUT ANY WARRANTY; without even the +# implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. +# See the License for more information. +#============================================================================= +# (To distribute this file outside of CMake, substitute the full +# License text for the above reference.) + +if(NOT NAME) + message(FATAL_ERROR "Name of the package to be searched not specified. Set the CMake variable NAME, e.g. -DNAME=JPEG .") +endif() + +if(NOT COMPILER_ID) + message(FATAL_ERROR "COMPILER_ID argument not specified. In doubt, use GNU.") +endif() + +if(NOT LANGUAGE) + message(FATAL_ERROR "LANGUAGE argument not specified. Use C, CXX or Fortran.") +endif() + +if(NOT MODE) + message(FATAL_ERROR "MODE argument not specified. Use either EXIST, COMPILE or LINK.") +endif() + +# require the current version. If we don't do this, Platforms/CYGWIN.cmake complains because +# it doesn't know whether it should set WIN32 or not: +cmake_minimum_required(VERSION ${CMAKE_MAJOR_VERSION}.${CMAKE_MINOR_VERSION}.${CMAKE_PATCH_VERSION} ) + +macro(ENABLE_LANGUAGE) + # disable the enable_language() command, otherwise --find-package breaks on Windows. + # On Windows, enable_language(RC) is called in the platform files unconditionally. + # But in --find-package mode, we don't want (and can't) enable any language. +endmacro() + +include(CMakeDetermineSystem) + +# short-cut some tests on Darwin, see Darwin-GNU.cmake: +if("${CMAKE_SYSTEM_NAME}" MATCHES Darwin AND "${COMPILER_ID}" MATCHES GNU) + set(${CMAKE_${LANGUAGE}_HAS_ISYSROOT} 0 ) + set(CMAKE_${lang}_OSX_DEPLOYMENT_TARGET_FLAG "") +endif() + +# Also load the system specific file, which sets up e.g. the search paths. +# This makes the FIND_XXX() calls work much better +include(CMakeSystemSpecificInformation) + +if(UNIX) + + # try to guess whether we have a 64bit system, if it has not been set + # from the outside + if(NOT CMAKE_SIZEOF_VOID_P) + set(CMAKE_SIZEOF_VOID_P 4) + if(EXISTS /usr/lib64) + set(CMAKE_SIZEOF_VOID_P 8) + else() + # use the file utility to check whether itself is 64 bit: + find_program(FILE_EXECUTABLE file) + if(FILE_EXECUTABLE) + execute_process(COMMAND "${FILE_EXECUTABLE}" "${FILE_EXECUTABLE}" OUTPUT_VARIABLE fileOutput ERROR_QUIET) + if("${fileOutput}" MATCHES "64-bit") + set(CMAKE_SIZEOF_VOID_P 8) + endif() + endif() + endif() + endif() + + # guess Debian multiarch if it has not been set: + if(EXISTS /etc/debian_version) + if(NOT CMAKE_${LANGUAGE}_LANGUAGE_ARCHITECTURE ) + file(GLOB filesInLib RELATIVE /lib /lib/*-linux-gnu* ) + foreach(file ${filesInLib}) + if("${file}" MATCHES "${CMAKE_LIBRARY_ARCHITECTURE_REGEX}") + set(CMAKE_${LANGUAGE}_LANGUAGE_ARCHITECTURE ${file}) + break() + endif() + endforeach() + endif() + endif() + +endif() + +set(CMAKE_${LANGUAGE}_COMPILER "dummy") +set(CMAKE_${LANGUAGE}_COMPILER_ID "${COMPILER_ID}") +include(CMake${LANGUAGE}Information) + + +function(set_compile_flags_var _packageName) + string(TOUPPER "${_packageName}" PACKAGE_NAME) + # Check the following variables: + # FOO_INCLUDE_DIRS + # Foo_INCLUDE_DIRS + # FOO_INCLUDES + # Foo_INCLUDES + # FOO_INCLUDE_DIR + # Foo_INCLUDE_DIR + set(includes) + if(DEFINED ${_packageName}_INCLUDE_DIRS) + set(includes ${_packageName}_INCLUDE_DIRS) + elseif(DEFINED ${PACKAGE_NAME}_INCLUDE_DIRS) + set(includes ${PACKAGE_NAME}_INCLUDE_DIRS) + elseif(DEFINED ${_packageName}_INCLUDES) + set(includes ${_packageName}_INCLUDES) + elseif(DEFINED ${PACKAGE_NAME}_INCLUDES) + set(includes ${PACKAGE_NAME}_INCLUDES) + elseif(DEFINED ${_packageName}_INCLUDE_DIR) + set(includes ${_packageName}_INCLUDE_DIR) + elseif(DEFINED ${PACKAGE_NAME}_INCLUDE_DIR) + set(includes ${PACKAGE_NAME}_INCLUDE_DIR) + endif() + + set(PACKAGE_INCLUDE_DIRS "${${includes}}" PARENT_SCOPE) + + # Check the following variables: + # FOO_DEFINITIONS + # Foo_DEFINITIONS + set(definitions) + if(DEFINED ${_packageName}_DEFINITIONS) + set(definitions ${_packageName}_DEFINITIONS) + elseif(DEFINED ${PACKAGE_NAME}_DEFINITIONS) + set(definitions ${PACKAGE_NAME}_DEFINITIONS) + endif() + + set(PACKAGE_DEFINITIONS "${${definitions}}" ) + +endfunction() + + +function(set_link_flags_var _packageName) + string(TOUPPER "${_packageName}" PACKAGE_NAME) + # Check the following variables: + # FOO_LIBRARIES + # Foo_LIBRARIES + # FOO_LIBS + # Foo_LIBS + set(libs) + if(DEFINED ${_packageName}_LIBRARIES) + set(libs ${_packageName}_LIBRARIES) + elseif(DEFINED ${PACKAGE_NAME}_LIBRARIES) + set(libs ${PACKAGE_NAME}_LIBRARIES) + elseif(DEFINED ${_packageName}_LIBS) + set(libs ${_packageName}_LIBS) + elseif(DEFINED ${PACKAGE_NAME}_LIBS) + set(libs ${PACKAGE_NAME}_LIBS) + endif() + + set(PACKAGE_LIBRARIES "${${libs}}" PARENT_SCOPE ) + +endfunction() + + +find_package("${NAME}" QUIET) + +set(PACKAGE_FOUND FALSE) + +string(TOUPPER "${NAME}" UPPERCASE_NAME) + +if(${NAME}_FOUND OR ${UPPERCASE_NAME}_FOUND) + set(PACKAGE_FOUND TRUE) + + if("${MODE}" STREQUAL "EXIST") + # do nothing + elseif("${MODE}" STREQUAL "COMPILE") + set_compile_flags_var(${NAME}) + elseif("${MODE}" STREQUAL "LINK") + set_link_flags_var(${NAME}) + else("${MODE}" STREQUAL "LINK") + message(FATAL_ERROR "Invalid mode argument ${MODE} given.") + endif() + +endif() + +set(PACKAGE_QUIET ${SILENT} ) diff --git a/Modules/CMakeTestASMCompiler.cmake b/Modules/CMakeTestASMCompiler.cmake index 56cf332..294511d 100644 --- a/Modules/CMakeTestASMCompiler.cmake +++ b/Modules/CMakeTestASMCompiler.cmake @@ -18,8 +18,18 @@ # because otherwise there would have to be a separate assembler source file # for each assembler on every architecture. + +SET(_ASM_COMPILER_WORKS 0) + IF(CMAKE_ASM${ASM_DIALECT}_COMPILER) - SET(CMAKE_ASM${ASM_DIALECT}_COMPILER_WORKS 1 CACHE INTERNAL "") -ELSE(CMAKE_ASM${ASM_DIALECT}_COMPILER) - SET(CMAKE_ASM${ASM_DIALECT}_COMPILER_WORKS 0 CACHE INTERNAL "") -ENDIF(CMAKE_ASM${ASM_DIALECT}_COMPILER) + SET(_ASM_COMPILER_WORKS 1) +ENDIF() + +# when using generic "ASM" support, we must have detected the compiler ID, fail otherwise: +IF("ASM${ASM_DIALECT}" STREQUAL "ASM") + IF(NOT CMAKE_ASM${ASM_DIALECT}_COMPILER_ID) + SET(_ASM_COMPILER_WORKS 0) + ENDIF() +ENDIF() + +SET(CMAKE_ASM${ASM_DIALECT}_COMPILER_WORKS ${_ASM_COMPILER_WORKS} CACHE INTERNAL "") diff --git a/Modules/CMakeVS10FindMake.cmake b/Modules/CMakeVS10FindMake.cmake index 388203c..695e92f 100644 --- a/Modules/CMakeVS10FindMake.cmake +++ b/Modules/CMakeVS10FindMake.cmake @@ -12,14 +12,11 @@ # (To distribute this file outside of CMake, substitute the full # License text for the above reference.) -# VCExpress does not support cross compiling, which is necessary for Win CE -SET( _CMAKE_MAKE_PROGRAM_NAMES devenv) -IF(NOT CMAKE_CROSSCOMPILING) - SET( _CMAKE_MAKE_PROGRAM_NAMES ${_CMAKE_MAKE_PROGRAM_NAMES} VCExpress) -ENDIF(NOT CMAKE_CROSSCOMPILING) - +# Look for devenv as a build program. We need to use this to support +# Intel Fortran integration into VS. MSBuild can not be used for that case +# since Intel Fortran uses the older devenv file format. FIND_PROGRAM(CMAKE_MAKE_PROGRAM - NAMES ${_CMAKE_MAKE_PROGRAM_NAMES} + NAMES devenv HINTS [HKEY_LOCAL_MACHINE\\SOFTWARE\\Microsoft\\VisualStudio\\10.0\\Setup\\VS;EnvironmentDirectory] [HKEY_LOCAL_MACHINE\\SOFTWARE\\Microsoft\\VisualStudio\\10.0\\Setup;Dbghelp_path] @@ -34,6 +31,24 @@ FIND_PROGRAM(CMAKE_MAKE_PROGRAM "/Program Files/Microsoft Visual Studio 10.0/Common7/IDE/" "/Program Files/Microsoft Visual Studio 10/Common7/IDE/" ) + +# if devenv is not found, then use MSBuild. +# it is expected that if devenv is not found, then we are +# dealing with Visual Studio Express. VCExpress has random +# failures when being run as a command line build tool which +# causes the compiler checks and try-compile stuff to fail. MSbuild +# is a better choice for this. However, VCExpress does not support +# cross compiling needed for Win CE. +IF(NOT CMAKE_CROSSCOMPILING) + FIND_PROGRAM(CMAKE_MAKE_PROGRAM + NAMES MSBuild + HINTS + [HKEY_LOCAL_MACHINE\\SOFTWARE\\Microsoft\\VisualStudio\\10.0\\Setup\\VS;ProductDir] + "$ENV{SYSTEMROOT}/Microsoft.NET/Framework/[HKEY_LOCAL_MACHINE\\SOFTWARE\\Microsoft\\VisualStudio\\10.0;CLR Version]/" + "c:/WINDOWS/Microsoft.NET/Framework/[HKEY_LOCAL_MACHINE\\SOFTWARE\\Microsoft\\VisualStudio\\10.0;CLR Version]/" + "$ENV{SYSTEMROOT}/Microsoft.NET/Framework/[HKEY_LOCAL_MACHINE\\SOFTWARE\\Microsoft\\VCExpress\\10.0;CLR Version]/") +ENDIF() + MARK_AS_ADVANCED(CMAKE_MAKE_PROGRAM) SET(MSVC10 1) SET(MSVC_VERSION 1600) diff --git a/Modules/CheckSymbolExists.cmake b/Modules/CheckSymbolExists.cmake index be7d658..183b2bb 100644 --- a/Modules/CheckSymbolExists.cmake +++ b/Modules/CheckSymbolExists.cmake @@ -63,7 +63,7 @@ MACRO(_CHECK_SYMBOL_EXISTS SOURCEFILE SYMBOL FILES VARIABLE) "${CMAKE_CONFIGURABLE_FILE_CONTENT}\nvoid cmakeRequireSymbol(int dummy,...){(void)dummy;}\nint main()\n{\n#ifndef ${SYMBOL}\n cmakeRequireSymbol(0,&${SYMBOL});\n#endif\n return 0;\n}\n") CONFIGURE_FILE("${CMAKE_ROOT}/Modules/CMakeConfigurableFile.in" - "${SOURCEFILE}" @ONLY) + "${SOURCEFILE}" @ONLY IMMEDIATE) MESSAGE(STATUS "Looking for ${SYMBOL}") TRY_COMPILE(${VARIABLE} diff --git a/Modules/FindBLAS.cmake b/Modules/FindBLAS.cmake index ae4a13f..dc9ab37 100644 --- a/Modules/FindBLAS.cmake +++ b/Modules/FindBLAS.cmake @@ -22,8 +22,8 @@ # BLA_F95 if set on tries to find the f95 interfaces for BLAS/LAPACK ########## ### List of vendors (BLA_VENDOR) valid in this module -## ATLAS, PhiPACK,CXML,DXML,SunPerf,SCSL,SGIMATH,IBMESSL,Intel10_32 (intel mkl v10 32 bit),Intel10_64lp (intel mkl v10 64 bit,lp thread model, lp64 model), -## Intel( older versions of mkl 32 and 64 bit), ACML,ACML_MP,Apple, NAS, Generic +## Goto,ATLAS PhiPACK,CXML,DXML,SunPerf,SCSL,SGIMATH,IBMESSL,Intel10_32 (intel mkl v10 32 bit),Intel10_64lp (intel mkl v10 64 bit,lp thread model, lp64 model), +## Intel( older versions of mkl 32 and 64 bit), ACML,ACML_MP,ACML_GPU,Apple, NAS, Generic # C/CXX should be enabled to use Intel mkl #============================================================================= @@ -57,7 +57,7 @@ else() endif(BLAS_FIND_REQUIRED) endif( ) -macro(Check_Fortran_Libraries LIBRARIES _prefix _name _flags _list _threads) +macro(Check_Fortran_Libraries LIBRARIES _prefix _name _flags _list _thread) # This macro checks for the existence of the combination of fortran libraries # given by _list. If the combination is found, this macro checks (using the # Check_Fortran_Function_Exists macro) whether can link against that library @@ -69,41 +69,38 @@ macro(Check_Fortran_Libraries LIBRARIES _prefix _name _flags _list _threads) # N.B. _prefix is the prefix applied to the names of all cached variables that # are generated internally and marked advanced by this macro. +set(_libdir ${ARGN}) + set(_libraries_work TRUE) set(${LIBRARIES}) set(_combined_name) +if (NOT _libdir) + if (WIN32) + set(_libdir ENV LIB) + elseif (APPLE) + set(_libdir /usr/local/lib /usr/lib /usr/local/lib64 /usr/lib64 ENV DYLD_LIBRARY_PATH) + else () + set(_libdir /usr/local/lib /usr/lib /usr/local/lib64 /usr/lib64 ENV LD_LIBRARY_PATH) + endif () +endif () foreach(_library ${_list}) set(_combined_name ${_combined_name}_${_library}) if(_libraries_work) - if ( WIN32 ) - if(BLA_STATIC) - set(CMAKE_FIND_LIBRARY_SUFFIXES ".lib;.dll") - endif(BLA_STATIC) - find_library(${_prefix}_${_library}_LIBRARY - NAMES ${_library} - PATHS ENV LIB - ) - endif ( WIN32 ) - - if ( APPLE ) - if(BLA_STATIC) - set(CMAKE_FIND_LIBRARY_SUFFIXES ".lib;.dll") - endif(BLA_STATIC) + if (BLA_STATIC) + if (WIN32) + set(CMAKE_FIND_LIBRARY_SUFFIXES ".lib;.dll") + endif ( WIN32 ) + if (APPLE) + set(CMAKE_FIND_LIBRARY_SUFFIXES ".lib;.dll") + else (APPLE) + set(CMAKE_FIND_LIBRARY_SUFFIXES ".a;.so") + endif (APPLE) + endif (BLA_STATIC) find_library(${_prefix}_${_library}_LIBRARY - NAMES ${_library} - PATHS /usr/local/lib /usr/lib /usr/local/lib64 /usr/lib64 ENV DYLD_LIBRARY_PATH - ) - - else ( APPLE ) - if(BLA_STATIC) - set(CMAKE_FIND_LIBRARY_SUFFIXES ".a;.so") - endif(BLA_STATIC) - find_library(${_prefix}_${_library}_LIBRARY - NAMES ${_library} - PATHS /usr/local/lib /usr/lib /usr/local/lib64 /usr/lib64 ENV LD_LIBRARY_PATH - ) - endif( APPLE ) + NAMES ${_library} + PATHS ${_libdir} + ) mark_as_advanced(${_prefix}_${_library}_LIBRARY) set(${LIBRARIES} ${${LIBRARIES}} ${${_prefix}_${_library}_LIBRARY}) set(_libraries_work ${${_prefix}_${_library}_LIBRARY}) @@ -139,15 +136,29 @@ else ($ENV{BLA_VENDOR} MATCHES ".+") endif(NOT BLA_VENDOR) endif ($ENV{BLA_VENDOR} MATCHES ".+") +if (BLA_VENDOR STREQUAL "Goto" OR BLA_VENDOR STREQUAL "All") + if(NOT BLAS_LIBRARIES) + # gotoblas (http://www.tacc.utexas.edu/tacc-projects/gotoblas2) + check_fortran_libraries( + BLAS_LIBRARIES + BLAS + sgemm + "" + "goto2" + "" + ) + endif(NOT BLAS_LIBRARIES) +endif (BLA_VENDOR STREQUAL "Goto" OR BLA_VENDOR STREQUAL "All") + if (BLA_VENDOR STREQUAL "ATLAS" OR BLA_VENDOR STREQUAL "All") if(NOT BLAS_LIBRARIES) # BLAS in ATLAS library? (http://math-atlas.sourceforge.net/) check_fortran_libraries( BLAS_LIBRARIES BLAS - cblas_dgemm + dgemm "" - "cblas;f77blas;atlas" + "f77blas;atlas" "" ) endif(NOT BLAS_LIBRARIES) @@ -255,15 +266,24 @@ if (BLA_VENDOR STREQUAL "IBMESSL" OR BLA_VENDOR STREQUAL "All") endif (BLA_VENDOR STREQUAL "IBMESSL" OR BLA_VENDOR STREQUAL "All") #BLAS in acml library? -if (BLA_VENDOR STREQUAL "ACML" OR BLA_VENDOR STREQUAL "ACML_MP" OR BLA_VENDOR STREQUAL "All") -# the patch from Chuck Atkins: - if( ((_BLAS_VENDOR STREQUAL "ACML") AND (NOT BLAS_ACML_LIB_DIRS)) OR - ((_BLAS_VENDOR STREQUAL "ACML_MP") AND (NOT BLAS_ACML_MP_LIB_DIRS)) ) +if (BLA_VENDOR MATCHES "ACML.*" OR BLA_VENDOR STREQUAL "All") + if( ((BLA_VENDOR STREQUAL "ACML") AND (NOT BLAS_ACML_LIB_DIRS)) OR + ((BLA_VENDOR STREQUAL "ACML_MP") AND (NOT BLAS_ACML_MP_LIB_DIRS)) OR + ((BLA_VENDOR STREQUAL "ACML_GPU") AND (NOT BLAS_ACML_GPU_LIB_DIRS)) + ) + # try to find acml in "standard" paths if( WIN32 ) file( GLOB _ACML_ROOT "C:/AMD/acml*/ACML-EULA.txt" ) else() file( GLOB _ACML_ROOT "/opt/acml*/ACML-EULA.txt" ) endif() + if( WIN32 ) + file( GLOB _ACML_GPU_ROOT "C:/AMD/acml*/GPGPUexamples" ) + else() + file( GLOB _ACML_GPU_ROOT "/opt/acml*/GPGPUexamples" ) + endif() + list(GET _ACML_ROOT 0 _ACML_ROOT) + list(GET _ACML_GPU_ROOT 0 _ACML_GPU_ROOT) if( _ACML_ROOT ) get_filename_component( _ACML_ROOT ${_ACML_ROOT} PATH ) if( SIZEOF_INTEGER EQUAL 8 ) @@ -297,7 +317,7 @@ if (BLA_VENDOR STREQUAL "ACML" OR BLA_VENDOR STREQUAL "ACML_MP" OR BLA_VENDOR ST set( _ACML_COMPILER64 "gfortran64" ) endif() - if( _BLAS_VENDOR STREQUAL "ACML_MP" ) + if( BLA_VENDOR STREQUAL "ACML_MP" ) set(_ACML_MP_LIB_DIRS "${_ACML_ROOT}/${_ACML_COMPILER32}_mp${_ACML_PATH_SUFFIX}/lib" "${_ACML_ROOT}/${_ACML_COMPILER64}_mp${_ACML_PATH_SUFFIX}/lib" ) @@ -307,19 +327,43 @@ if (BLA_VENDOR STREQUAL "ACML" OR BLA_VENDOR STREQUAL "ACML_MP" OR BLA_VENDOR ST "${_ACML_ROOT}/${_ACML_COMPILER64}${_ACML_PATH_SUFFIX}/lib" ) endif() endif() + elseif(BLAS_${BLA_VENDOR}_LIB_DIRS) + set(_${BLA_VENDOR}_LIB_DIRS ${BLAS_${BLA_VENDOR}_LIB_DIRS}) endif() - if( _BLAS_VENDOR STREQUAL "ACML_MP" ) - foreach( BLAS_ACML_MP_LIB_DIRS ${_ACML_MP_LIB_DIRS} ) - _BLAS_LOCATE_AND_TEST( ${_BLAS_VENDOR} "acml_mp;acml_mv" "" ) - if( BLAS_${_BLAS_VENDOR}_FOUND ) + if( BLA_VENDOR STREQUAL "ACML_MP" ) + foreach( BLAS_ACML_MP_LIB_DIRS ${_ACML_MP_LIB_DIRS}) + check_fortran_libraries ( + BLAS_LIBRARIES + BLAS + sgemm + "" "acml_mp;acml_mv" "" ${BLAS_ACML_MP_LIB_DIRS} + ) + if( BLAS_LIBRARIES ) + break() + endif() + endforeach() + elseif( BLA_VENDOR STREQUAL "ACML_GPU" ) + foreach( BLAS_ACML_GPU_LIB_DIRS ${_ACML_GPU_LIB_DIRS}) + check_fortran_libraries ( + BLAS_LIBRARIES + BLAS + sgemm + "" "acml_mp;acml_mv;CALBLAS" "" ${BLAS_ACML_GPU_LIB_DIRS} + ) + if( BLAS_LIBRARIES ) break() endif() endforeach() else() #if( _BLAS_VENDOR STREQUAL "ACML" ) foreach( BLAS_ACML_LIB_DIRS ${_ACML_LIB_DIRS} ) - _BLAS_LOCATE_AND_TEST( ${_BLAS_VENDOR} "acml;acml_mv" "" ) - if( BLAS_${_BLAS_VENDOR}_FOUND ) + check_fortran_libraries ( + BLAS_LIBRARIES + BLAS + sgemm + "" "acml_mp;acml_mv" "" ${BLAS_ACML_LIB_DIRS} + ) + if( BLAS_LIBRARIES ) break() endif() endforeach() @@ -346,6 +390,16 @@ if (BLA_VENDOR STREQUAL "ACML" OR BLA_VENDOR STREQUAL "ACML_MP" OR BLA_VENDOR ST "" ) endif(NOT BLAS_LIBRARIES) + if(NOT BLAS_LIBRARIES) + check_fortran_libraries( + BLAS_LIBRARIES + BLAS + sgemm + "" + "acml;acml_mv;CALBLAS" + "" + ) + endif(NOT BLAS_LIBRARIES) endif () # ACML # Apple BLAS library? diff --git a/Modules/FindLAPACK.cmake b/Modules/FindLAPACK.cmake index bf45406..80fe867 100644 --- a/Modules/FindLAPACK.cmake +++ b/Modules/FindLAPACK.cmake @@ -148,31 +148,28 @@ if(BLAS_FOUND) set(BLA_VENDOR "All") endif(NOT BLA_VENDOR) endif ($ENV{BLA_VENDOR} MATCHES ".+") + +if (BLA_VENDOR STREQUAL "Goto" OR BLA_VENDOR STREQUAL "All") + if(NOT LAPACK_LIBRARIES) + check_lapack_libraries( + LAPACK_LIBRARIES + LAPACK + cheev + "" + "goto2" + "${BLAS_LIBRARIES}" + "" + ) + endif(NOT LAPACK_LIBRARIES) +endif (BLA_VENDOR STREQUAL "Goto" OR BLA_VENDOR STREQUAL "All") + + #acml lapack - if (BLA_VENDOR STREQUAL "ACML" OR BLA_VENDOR STREQUAL "All") - if(NOT LAPACK_LIBRARIES) - check_lapack_libraries( - LAPACK_LIBRARIES - LAPACK - cheev - "" - "acml;acml_mv" - "" - "" - ) - endif(NOT LAPACK_LIBRARIES) - if(NOT LAPACK_LIBRARIES) - check_lapack_libraries( - LAPACK_LIBRARIES - LAPACK - cheev - "" - "acml_mp;acml_mv" - "" - "" - ) - endif(NOT LAPACK_LIBRARIES) - endif (BLA_VENDOR STREQUAL "ACML" OR BLA_VENDOR STREQUAL "All") + if (BLA_VENDOR STREQUAL "ACML.*" OR BLA_VENDOR STREQUAL "All") + if (BLAS_LIBRARIES MATCHES ".+acml.+") + set (LAPACK_LIBRARIES ${BLAS_LIBRARIES}) + endif () + endif () # Apple LAPACK library? if (BLA_VENDOR STREQUAL "Apple" OR BLA_VENDOR STREQUAL "All") diff --git a/Modules/FindThreads.cmake b/Modules/FindThreads.cmake index a6c2df8..21614fb 100644 --- a/Modules/FindThreads.cmake +++ b/Modules/FindThreads.cmake @@ -23,6 +23,7 @@ INCLUDE (CheckIncludeFiles) INCLUDE (CheckLibraryExists) +INCLUDE (CheckSymbolExists) SET(Threads_FOUND FALSE) # Do we have sproc? @@ -44,33 +45,41 @@ ELSE() # SET(CMAKE_HAVE_THREADS_LIBRARY) IF(NOT THREADS_HAVE_PTHREAD_ARG) - - # Do we have -lpthreads - CHECK_LIBRARY_EXISTS(pthreads pthread_create "" CMAKE_HAVE_PTHREADS_CREATE) - IF(CMAKE_HAVE_PTHREADS_CREATE) - SET(CMAKE_THREAD_LIBS_INIT "-lpthreads") + # Check if pthread functions are in normal C library + CHECK_SYMBOL_EXISTS(pthread_create pthread.h CMAKE_HAVE_LIBC_CREATE) + IF(CMAKE_HAVE_LIBC_CREATE) + SET(CMAKE_THREAD_LIBS_INIT "") SET(CMAKE_HAVE_THREADS_LIBRARY 1) SET(Threads_FOUND TRUE) ENDIF() - # Ok, how about -lpthread - CHECK_LIBRARY_EXISTS(pthread pthread_create "" CMAKE_HAVE_PTHREAD_CREATE) - IF(CMAKE_HAVE_PTHREAD_CREATE) - SET(CMAKE_THREAD_LIBS_INIT "-lpthread") - SET(Threads_FOUND TRUE) - SET(CMAKE_HAVE_THREADS_LIBRARY 1) - ENDIF() + IF(NOT CMAKE_HAVE_THREADS_LIBRARY) + # Do we have -lpthreads + CHECK_LIBRARY_EXISTS(pthreads pthread_create "" CMAKE_HAVE_PTHREADS_CREATE) + IF(CMAKE_HAVE_PTHREADS_CREATE) + SET(CMAKE_THREAD_LIBS_INIT "-lpthreads") + SET(CMAKE_HAVE_THREADS_LIBRARY 1) + SET(Threads_FOUND TRUE) + ENDIF() - IF(CMAKE_SYSTEM MATCHES "SunOS.*") - # On sun also check for -lthread - CHECK_LIBRARY_EXISTS(thread thr_create "" CMAKE_HAVE_THR_CREATE) - IF(CMAKE_HAVE_THR_CREATE) - SET(CMAKE_THREAD_LIBS_INIT "-lthread") + # Ok, how about -lpthread + CHECK_LIBRARY_EXISTS(pthread pthread_create "" CMAKE_HAVE_PTHREAD_CREATE) + IF(CMAKE_HAVE_PTHREAD_CREATE) + SET(CMAKE_THREAD_LIBS_INIT "-lpthread") SET(CMAKE_HAVE_THREADS_LIBRARY 1) SET(Threads_FOUND TRUE) ENDIF() - ENDIF(CMAKE_SYSTEM MATCHES "SunOS.*") + IF(CMAKE_SYSTEM MATCHES "SunOS.*") + # On sun also check for -lthread + CHECK_LIBRARY_EXISTS(thread thr_create "" CMAKE_HAVE_THR_CREATE) + IF(CMAKE_HAVE_THR_CREATE) + SET(CMAKE_THREAD_LIBS_INIT "-lthread") + SET(CMAKE_HAVE_THREADS_LIBRARY 1) + SET(Threads_FOUND TRUE) + ENDIF() + ENDIF(CMAKE_SYSTEM MATCHES "SunOS.*") + ENDIF(NOT CMAKE_HAVE_THREADS_LIBRARY) ENDIF(NOT THREADS_HAVE_PTHREAD_ARG) IF(NOT CMAKE_HAVE_THREADS_LIBRARY) @@ -111,7 +120,7 @@ ELSE() ENDIF(CMAKE_HAVE_PTHREAD_H) ENDIF() -IF(CMAKE_THREAD_LIBS_INIT) +IF(CMAKE_THREAD_LIBS_INIT OR CMAKE_HAVE_LIBC_CREATE) SET(CMAKE_USE_PTHREADS_INIT 1) SET(Threads_FOUND TRUE) ENDIF() diff --git a/Source/CMakeLists.txt b/Source/CMakeLists.txt index 1c942ba..96b3ea0 100644 --- a/Source/CMakeLists.txt +++ b/Source/CMakeLists.txt @@ -228,6 +228,8 @@ SET(SRCS cmPropertyDefinitionMap.h cmPropertyMap.cxx cmPropertyMap.h + cmQtAutomoc.cxx + cmQtAutomoc.h cmScriptGenerator.h cmScriptGenerator.cxx cmSourceFile.cxx diff --git a/Source/cmAddExecutableCommand.cxx b/Source/cmAddExecutableCommand.cxx index a625c47..bac2430 100644 --- a/Source/cmAddExecutableCommand.cxx +++ b/Source/cmAddExecutableCommand.cxx @@ -58,7 +58,8 @@ bool cmAddExecutableCommand } // Special modifiers are not allowed with IMPORTED signature. - if(importTarget && (use_win32 || use_macbundle || excludeFromAll)) + if(importTarget + && (use_win32 || use_macbundle || excludeFromAll)) { if(use_win32) { diff --git a/Source/cmAddLibraryCommand.cxx b/Source/cmAddLibraryCommand.cxx index f522cee..efa29e6 100644 --- a/Source/cmAddLibraryCommand.cxx +++ b/Source/cmAddLibraryCommand.cxx @@ -31,13 +31,13 @@ bool cmAddLibraryCommand } bool excludeFromAll = false; bool importTarget = false; - + std::vector<std::string>::const_iterator s = args.begin(); std::string libName = *s; ++s; - + // If the second argument is "SHARED" or "STATIC", then it controls // the type of library. Otherwise, it is treated as a source or // source list name. There may be two keyword arguments, check for them @@ -85,11 +85,11 @@ bool cmAddLibraryCommand } } - /* ideally we should check whether for the linker language of the target + /* ideally we should check whether for the linker language of the target CMAKE_${LANG}_CREATE_SHARED_LIBRARY is defined and if not default to - STATIC. But at this point we know only the name of the target, but not + STATIC. But at this point we know only the name of the target, but not yet its linker language. */ - if ((type != cmTarget::STATIC_LIBRARY) && + if ((type != cmTarget::STATIC_LIBRARY) && (this->Makefile->GetCMakeInstance()->GetPropertyAsBool( "TARGET_SUPPORTS_SHARED_LIBS") == false)) { @@ -103,16 +103,16 @@ bool cmAddLibraryCommand type = cmTarget::STATIC_LIBRARY; } - // The IMPORTED signature requires a type to be specified explicitly. - if(importTarget && !haveSpecifiedType) - { - this->SetError("called with IMPORTED argument but no library type."); - return false; - } - // Handle imported target creation. if(importTarget) { + // The IMPORTED signature requires a type to be specified explicitly. + if (!haveSpecifiedType) + { + this->SetError("called with IMPORTED argument but no library type."); + return false; + } + // Make sure the target does not already exist. if(this->Makefile->FindTargetToUse(libName.c_str())) { @@ -158,15 +158,14 @@ bool cmAddLibraryCommand } std::vector<std::string> srclists; - while (s != args.end()) + while (s != args.end()) { - srclists.push_back(*s); + srclists.push_back(*s); ++s; } - this->Makefile->AddLibrary(libName.c_str(), type, srclists, - excludeFromAll); - + this->Makefile->AddLibrary(libName.c_str(), type, srclists, excludeFromAll); + return true; } diff --git a/Source/cmDocumentVariables.cxx b/Source/cmDocumentVariables.cxx index ebe2988..26125d9 100644 --- a/Source/cmDocumentVariables.cxx +++ b/Source/cmDocumentVariables.cxx @@ -1085,6 +1085,15 @@ void cmDocumentVariables::DefineVariables(cmake* cm) "Variables that Control the Build"); cm->DefineProperty + ("CMAKE_AUTOMOC", cmProperty::VARIABLE, + "Whether to handle moc automatically for Qt targets.", + "This variable is used to initialize the " + "AUTOMOC property on all the targets. " + "See that target property for additional information.", + false, + "Variables that Control the Build"); + + cm->DefineProperty ("CMAKE_DEBUG_POSTFIX", cmProperty::VARIABLE, "See variable CMAKE_<CONFIG>_POSTFIX.", "This variable is a special case of the more-general " diff --git a/Source/cmGlobalGenerator.cxx b/Source/cmGlobalGenerator.cxx index 2eae01e..d62fb44 100644 --- a/Source/cmGlobalGenerator.cxx +++ b/Source/cmGlobalGenerator.cxx @@ -18,6 +18,7 @@ #include "cmExternalMakefileProjectGenerator.h" #include "cmake.h" #include "cmMakefile.h" +#include "cmQtAutomoc.h" #include "cmSourceFile.h" #include "cmVersion.h" #include "cmExportInstallFileGenerator.h" @@ -269,7 +270,7 @@ cmGlobalGenerator::EnableLanguage(std::vector<std::string>const& languages, cmOStringStream windowsVersionString; windowsVersionString << osvi.dwMajorVersion << "." << osvi.dwMinorVersion; windowsVersionString.str(); - mf->AddDefinition("CMAKE_HOST_SYSTEM_VERSION", + mf->AddDefinition("CMAKE_HOST_SYSTEM_VERSION", windowsVersionString.str().c_str()); #endif // Read the DetermineSystem file @@ -618,8 +619,8 @@ void cmGlobalGenerator::SetLanguageEnabledMaps(const char* l, cmMakefile* mf) if (sscanf(linkerPref, "%d", &preference)!=1) { // backward compatibility: before 2.6 LINKER_PREFERENCE - // was either "None" or "Prefered", and only the first character was - // tested. So if there is a custom language out there and it is + // was either "None" or "Prefered", and only the first character was + // tested. So if there is a custom language out there and it is // "Prefered", set its preference high if (linkerPref[0]=='P') { @@ -782,7 +783,7 @@ void cmGlobalGenerator::Configure() // so create the map from project name to vector of local generators this->FillProjectMap(); - if ( !this->CMakeInstance->GetScriptMode() ) + if ( this->CMakeInstance->GetWorkingMode() == cmake::NORMAL_MODE) { const char* msg = "Configuring done"; if(cmSystemTools::GetErrorOccuredFlag()) @@ -832,6 +833,10 @@ void cmGlobalGenerator::Generate() return; } + // Iterate through all targets and set up automoc for those which have + // the AUTOMOC property set + this->CreateAutomocTargets(); + // For each existing cmLocalGenerator unsigned int i; @@ -950,6 +955,35 @@ bool cmGlobalGenerator::CheckTargets() return true; } +//---------------------------------------------------------------------------- +void cmGlobalGenerator::CreateAutomocTargets() +{ +#ifdef CMAKE_BUILD_WITH_CMAKE + for(unsigned int i=0; i < this->LocalGenerators.size(); ++i) + { + cmTargets& targets = + this->LocalGenerators[i]->GetMakefile()->GetTargets(); + for(cmTargets::iterator ti = targets.begin(); + ti != targets.end(); ++ti) + { + cmTarget& target = ti->second; + if(target.GetType() == cmTarget::EXECUTABLE || + target.GetType() == cmTarget::STATIC_LIBRARY || + target.GetType() == cmTarget::SHARED_LIBRARY || + target.GetType() == cmTarget::MODULE_LIBRARY) + { + if(target.GetPropertyAsBool("AUTOMOC") && !target.IsImported()) + { + cmQtAutomoc automoc; + automoc.SetupAutomocTarget(&target); + } + } + } + } +#endif +} + + void cmGlobalGenerator::CheckLocalGenerators() { std::map<cmStdString, cmStdString> notFoundMap; @@ -1019,9 +1053,9 @@ void cmGlobalGenerator::CheckLocalGenerators() if(notFoundMap.size()) { std::string notFoundVars; - for(std::map<cmStdString, cmStdString>::const_iterator + for(std::map<cmStdString, cmStdString>::const_iterator ii = notFoundMap.begin(); - ii != notFoundMap.end(); + ii != notFoundMap.end(); ++ii) { notFoundVars += ii->first; @@ -1057,7 +1091,7 @@ int cmGlobalGenerator::TryCompile(const char *srcdir, const char *bindir, { this->FirstTimeProgress = 0.95f; } - this->CMakeInstance->UpdateProgress("Configuring", + this->CMakeInstance->UpdateProgress("Configuring", this->FirstTimeProgress); } @@ -1161,7 +1195,7 @@ int cmGlobalGenerator::Build( { outputPtr = &outputBuffer; } - + // should we do a clean first? if (clean) { @@ -1199,7 +1233,7 @@ int cmGlobalGenerator::Build( // now build std::string makeCommand = this->GenerateBuildCommand(makeCommandCSTR, projectName, - extraOptions, target, + extraOptions, target, config, false, fast); if(output) { @@ -1272,8 +1306,8 @@ void cmGlobalGenerator::AddLocalGenerator(cmLocalGenerator *lg) if(this->FirstTimeProgress > 0.95f) { this->FirstTimeProgress = 0.95f; - } - this->CMakeInstance->UpdateProgress("Configuring", + } + this->CMakeInstance->UpdateProgress("Configuring", this->FirstTimeProgress); return; } @@ -1296,8 +1330,8 @@ void cmGlobalGenerator::AddInstallComponent(const char* component) } } -void cmGlobalGenerator::AddTargetToExports(const char* exportSetName, - cmTarget* target, +void cmGlobalGenerator::AddTargetToExports(const char* exportSetName, + cmTarget* target, cmInstallTargetGenerator* archive, cmInstallTargetGenerator* runTime, cmInstallTargetGenerator* library, @@ -1331,7 +1365,7 @@ void cmGlobalGenerator::ClearExportSets() const std::vector<cmTargetExport*>* cmGlobalGenerator::GetExportSet( const char* name) const { - std::map<cmStdString, std::vector<cmTargetExport*> >::const_iterator + std::map<cmStdString, std::vector<cmTargetExport*> >::const_iterator exportSetIt = this->ExportSets.find(name); if (exportSetIt != this->ExportSets.end()) { @@ -1443,7 +1477,7 @@ void cmGlobalGenerator::GetEnabledLanguages(std::vector<std::string>& lang) int cmGlobalGenerator::GetLinkerPreference(const char* lang) { - std::map<cmStdString, int>::const_iterator it = + std::map<cmStdString, int>::const_iterator it = this->LanguageToLinkerPreference.find(lang); if (it != this->LanguageToLinkerPreference.end()) { diff --git a/Source/cmGlobalGenerator.h b/Source/cmGlobalGenerator.h index b7b1bff..88eb8b6 100644 --- a/Source/cmGlobalGenerator.h +++ b/Source/cmGlobalGenerator.h @@ -282,6 +282,8 @@ protected: virtual bool CheckALLOW_DUPLICATE_CUSTOM_TARGETS(); bool CheckTargets(); + void CreateAutomocTargets(); + // Fill the ProjectMap, this must be called after LocalGenerators // has been populated. diff --git a/Source/cmGlobalVisualStudio7Generator.cxx b/Source/cmGlobalVisualStudio7Generator.cxx index 51b8918..84e7f1b 100644 --- a/Source/cmGlobalVisualStudio7Generator.cxx +++ b/Source/cmGlobalVisualStudio7Generator.cxx @@ -739,18 +739,6 @@ void cmGlobalVisualStudio7Generator entry.Full = ""; } -// make sure "special" targets have GUID's -void cmGlobalVisualStudio7Generator::Configure() -{ - cmGlobalGenerator::Configure(); - this->CreateGUID("ALL_BUILD"); - this->CreateGUID("INSTALL"); - this->CreateGUID("RUN_TESTS"); - this->CreateGUID("EDIT_CACHE"); - this->CreateGUID("REBUILD_CACHE"); - this->CreateGUID("PACKAGE"); -} - //---------------------------------------------------------------------------- void cmGlobalVisualStudio7Generator diff --git a/Source/cmGlobalVisualStudio7Generator.h b/Source/cmGlobalVisualStudio7Generator.h index b6c84e8..7f19d83 100644 --- a/Source/cmGlobalVisualStudio7Generator.h +++ b/Source/cmGlobalVisualStudio7Generator.h @@ -80,9 +80,6 @@ public: void CreateGUID(const char* name); std::string GetGUID(const char* name); - ///! do configure step - virtual void Configure(); - /** Append the subdirectory for the given configuration. */ virtual void AppendDirectoryForConfig(const char* prefix, const char* config, diff --git a/Source/cmGlobalXCodeGenerator.cxx b/Source/cmGlobalXCodeGenerator.cxx index 5f5c1c3..02a95fe 100644 --- a/Source/cmGlobalXCodeGenerator.cxx +++ b/Source/cmGlobalXCodeGenerator.cxx @@ -489,6 +489,7 @@ void cmGlobalXCodeGenerator::ClearXCodeObjects() delete this->XCodeObjects[i]; } this->XCodeObjects.clear(); + this->XCodeObjectIDs.clear(); this->GroupMap.clear(); this->GroupNameMap.clear(); this->TargetGroup.clear(); @@ -496,6 +497,27 @@ void cmGlobalXCodeGenerator::ClearXCodeObjects() } //---------------------------------------------------------------------------- +void cmGlobalXCodeGenerator::addObject(cmXCodeObject *obj) +{ + if(obj->GetType() == cmXCodeObject::OBJECT) + { + cmStdString id = obj->GetId(); + + // If this is a duplicate id, it's an error: + // + if(this->XCodeObjectIDs.count(id)) + { + cmSystemTools::Error( + "Xcode generator: duplicate object ids not allowed"); + } + + this->XCodeObjectIDs.insert(id); + } + + this->XCodeObjects.push_back(obj); +} + +//---------------------------------------------------------------------------- cmXCodeObject* cmGlobalXCodeGenerator::CreateObject(cmXCodeObject::PBXType ptype) { @@ -508,7 +530,7 @@ cmGlobalXCodeGenerator::CreateObject(cmXCodeObject::PBXType ptype) { obj = new cmXCode21Object(ptype, cmXCodeObject::OBJECT); } - this->XCodeObjects.push_back(obj); + this->addObject(obj); return obj; } @@ -517,7 +539,7 @@ cmXCodeObject* cmGlobalXCodeGenerator::CreateObject(cmXCodeObject::Type type) { cmXCodeObject* obj = new cmXCodeObject(cmXCodeObject::None, type); - this->XCodeObjects.push_back(obj); + this->addObject(obj); return obj; } @@ -1758,7 +1780,7 @@ void cmGlobalXCodeGenerator::CreateBuildSettings(cmTarget& target, default: break; } - if(this->XcodeVersion >= 22) + if(this->XcodeVersion >= 22 && this->XcodeVersion < 40) { buildSettings->AddAttribute("PREBINDING", this->CreateString("NO")); @@ -2040,6 +2062,9 @@ cmGlobalXCodeGenerator::CreateUtilityTarget(cmTarget& cmtarget) } } + target->SetId(this->GetOrCreateId( + cmtarget.GetName(), target->GetId()).c_str()); + return target; } @@ -2188,6 +2213,8 @@ cmGlobalXCodeGenerator::CreateXCodeTarget(cmTarget& cmtarget, target->AddAttribute("productType", this->CreateString(productType)); } target->SetTarget(&cmtarget); + target->SetId(this->GetOrCreateId( + cmtarget.GetName(), target->GetId()).c_str()); return target; } @@ -2211,6 +2238,26 @@ cmXCodeObject* cmGlobalXCodeGenerator::FindXCodeTarget(cmTarget* t) } //---------------------------------------------------------------------------- +std::string cmGlobalXCodeGenerator::GetOrCreateId(const char* name, + const char* id) +{ + std::string guidStoreName = name; + guidStoreName += "_GUID_CMAKE"; + const char* storedGUID = + this->CMakeInstance->GetCacheDefinition(guidStoreName.c_str()); + + if(storedGUID) + { + return storedGUID; + } + + this->CMakeInstance->AddCacheEntry(guidStoreName.c_str(), + id, "Stored Xcode object GUID", cmCacheManager::INTERNAL); + + return id; +} + +//---------------------------------------------------------------------------- void cmGlobalXCodeGenerator::AddDependTarget(cmXCodeObject* target, cmXCodeObject* dependTarget) { @@ -2739,6 +2786,12 @@ void cmGlobalXCodeGenerator this->RootObject = this->CreateObject(cmXCodeObject::PBXProject); this->RootObject->SetComment("Project object"); + + std::string project_id = "PROJECT_"; + project_id += root->GetMakefile()->GetProjectName(); + this->RootObject->SetId(this->GetOrCreateId( + project_id.c_str(), this->RootObject->GetId()).c_str()); + group = this->CreateObject(cmXCodeObject::ATTRIBUTE_GROUP); this->RootObject->AddAttribute("mainGroup", this->CreateObjectReference(mainGroup)); @@ -3137,6 +3190,11 @@ cmGlobalXCodeGenerator::OutputXCodeProject(cmLocalGenerator* root, } this->WriteXCodePBXProj(fout, root, generators); this->ClearXCodeObjects(); + + // Since this call may have created new cache entries, save the cache: + // + root->GetMakefile()->GetCacheManager()->SaveCache( + root->GetMakefile()->GetHomeOutputDirectory()); } //---------------------------------------------------------------------------- diff --git a/Source/cmGlobalXCodeGenerator.h b/Source/cmGlobalXCodeGenerator.h index 39a5fd7..fa55ff0 100644 --- a/Source/cmGlobalXCodeGenerator.h +++ b/Source/cmGlobalXCodeGenerator.h @@ -123,6 +123,8 @@ private: ); cmXCodeObject* FindXCodeTarget(cmTarget*); + std::string GetOrCreateId(const char* name, const char* id); + // create cmXCodeObject from these functions so that memory can be managed // correctly. All objects created are stored in this->XCodeObjects. cmXCodeObject* CreateObject(cmXCodeObject::PBXType ptype); @@ -197,9 +199,11 @@ protected: unsigned int XcodeVersion; std::string VersionString; + std::set<cmStdString> XCodeObjectIDs; std::vector<cmXCodeObject*> XCodeObjects; cmXCodeObject* RootObject; private: + void addObject(cmXCodeObject *obj); std::string PostBuildMakeTarget(std::string const& tName, std::string const& configName); cmXCodeObject* MainGroupChildren; diff --git a/Source/cmLocalGenerator.h b/Source/cmLocalGenerator.h index aebf9f3..a204a73 100644 --- a/Source/cmLocalGenerator.h +++ b/Source/cmLocalGenerator.h @@ -307,7 +307,6 @@ public: std::string const& dir_max, bool* hasSourceExtension = 0); -protected: /** Fill out these strings for the given target. Libraries to link, * flags, and linkflags. */ void GetTargetFlags(std::string& linkLibs, @@ -315,6 +314,7 @@ protected: std::string& linkFlags, cmTarget&target); +protected: ///! put all the libraries for a target on into the given stream virtual void OutputLinkLibraries(std::ostream&, cmTarget&, bool relink); diff --git a/Source/cmLocalUnixMakefileGenerator3.cxx b/Source/cmLocalUnixMakefileGenerator3.cxx index 6ab5c2a..2eae9d0 100644 --- a/Source/cmLocalUnixMakefileGenerator3.cxx +++ b/Source/cmLocalUnixMakefileGenerator3.cxx @@ -1276,6 +1276,7 @@ cmLocalUnixMakefileGenerator3 // and there are no "." charactors in the string, then return the // unmodified combination. if((!this->MakefileVariableSize && unmodified.find('.') == s.npos) + && (!this->MakefileVariableSize && unmodified.find('+') == s.npos) && (!this->MakefileVariableSize && unmodified.find('-') == s.npos)) { return unmodified; @@ -1297,6 +1298,7 @@ cmLocalUnixMakefileGenerator3 { cmSystemTools::ReplaceString(ret, ".", "_"); cmSystemTools::ReplaceString(ret, "-", "__"); + cmSystemTools::ReplaceString(ret, "+", "___"); int ni = 0; char buffer[5]; // make sure the _ version is not already used, if diff --git a/Source/cmLocalVisualStudio7Generator.cxx b/Source/cmLocalVisualStudio7Generator.cxx index 2991a3a..1f99cba 100644 --- a/Source/cmLocalVisualStudio7Generator.cxx +++ b/Source/cmLocalVisualStudio7Generator.cxx @@ -68,6 +68,27 @@ void cmLocalVisualStudio7Generator::AddHelperCommands() lang.insert("DEF"); lang.insert("Fortran"); this->CreateCustomTargetsAndCommands(lang); + + // Now create GUIDs for targets + cmTargets &tgts = this->Makefile->GetTargets(); + + cmGlobalVisualStudio7Generator* gg = + static_cast<cmGlobalVisualStudio7Generator *>(this->GlobalGenerator); + for(cmTargets::iterator l = tgts.begin(); l != tgts.end(); l++) + { + const char* path = l->second.GetProperty("EXTERNAL_MSPROJECT"); + if(path) + { + this->ReadAndStoreExternalGUID( + l->second.GetName(), path); + } + else + { + gg->CreateGUID(l->first.c_str()); + } + } + + this->FixGlobalTargets(); } @@ -2032,29 +2053,6 @@ void cmLocalVisualStudio7Generator::ReadAndStoreExternalGUID( } -void cmLocalVisualStudio7Generator::ConfigureFinalPass() -{ - cmLocalGenerator::ConfigureFinalPass(); - cmTargets &tgts = this->Makefile->GetTargets(); - - cmGlobalVisualStudio7Generator* gg = - static_cast<cmGlobalVisualStudio7Generator *>(this->GlobalGenerator); - for(cmTargets::iterator l = tgts.begin(); l != tgts.end(); l++) - { - const char* path = l->second.GetProperty("EXTERNAL_MSPROJECT"); - if(path) - { - this->ReadAndStoreExternalGUID( - l->second.GetName(), path); - } - else - { - gg->CreateGUID(l->first.c_str()); - } - } - -} - //---------------------------------------------------------------------------- std::string cmLocalVisualStudio7Generator ::GetTargetDirectory(cmTarget const& target) const diff --git a/Source/cmLocalVisualStudio7Generator.h b/Source/cmLocalVisualStudio7Generator.h index 35f659f..cdd714e 100644 --- a/Source/cmLocalVisualStudio7Generator.h +++ b/Source/cmLocalVisualStudio7Generator.h @@ -57,7 +57,6 @@ public: void SetVersion8() {this->Version = 8;} void SetVersion9() {this->Version = 9;} void SetPlatformName(const char* n) { this->PlatformName = n;} - virtual void ConfigureFinalPass(); void GetTargetObjectFileDirectories(cmTarget* target, std::vector<std::string>& dirs); diff --git a/Source/cmMakefile.cxx b/Source/cmMakefile.cxx index a5cdee4..e5b5443 100644 --- a/Source/cmMakefile.cxx +++ b/Source/cmMakefile.cxx @@ -384,7 +384,9 @@ bool cmMakefile::ExecuteCommand(const cmListFileFunction& lff, // Decide whether to invoke the command. if(pcmd->GetEnabled() && !cmSystemTools::GetFatalErrorOccured() && - (!this->GetCMakeInstance()->GetScriptMode() || pcmd->IsScriptable())) + (this->GetCMakeInstance()->GetWorkingMode() != cmake::SCRIPT_MODE + || pcmd->IsScriptable())) + { // if trace is one, print out invoke information if(this->GetCMakeInstance()->GetTrace()) @@ -411,7 +413,7 @@ bool cmMakefile::ExecuteCommand(const cmListFileFunction& lff, this->IssueMessage(cmake::FATAL_ERROR, pcmd->GetError()); } result = false; - if ( this->GetCMakeInstance()->GetScriptMode() ) + if ( this->GetCMakeInstance()->GetWorkingMode() != cmake::NORMAL_MODE) { cmSystemTools::SetFatalErrorOccured(); } @@ -422,7 +424,7 @@ bool cmMakefile::ExecuteCommand(const cmListFileFunction& lff, this->UsedCommands.push_back(pcmd.release()); } } - else if ( this->GetCMakeInstance()->GetScriptMode() + else if ( this->GetCMakeInstance()->GetWorkingMode() == cmake::SCRIPT_MODE && !pcmd->IsScriptable() ) { std::string error = "Command "; @@ -1886,7 +1888,7 @@ void cmMakefile::AddGlobalLinkInformation(const char* name, cmTarget& target) } -void cmMakefile::AddLibrary(const char* lname, cmTarget::TargetType type, +cmTarget* cmMakefile::AddLibrary(const char* lname, cmTarget::TargetType type, const std::vector<std::string> &srcs, bool excludeFromAll) { @@ -1909,6 +1911,7 @@ void cmMakefile::AddLibrary(const char* lname, cmTarget::TargetType type, } target->AddSources(srcs); this->AddGlobalLinkInformation(lname, *target); + return target; } cmTarget* cmMakefile::AddExecutable(const char *exeName, @@ -3024,8 +3027,15 @@ cmCacheManager *cmMakefile::GetCacheManager() const void cmMakefile::DisplayStatus(const char* message, float s) { - this->GetLocalGenerator()->GetGlobalGenerator() - ->GetCMakeInstance()->UpdateProgress(message, s); + cmake* cm = this->GetLocalGenerator()->GetGlobalGenerator() + ->GetCMakeInstance(); + if (cm->GetWorkingMode() == cmake::FIND_PACKAGE_MODE) + { + // don't output any STATUS message in FIND_PACKAGE_MODE, since they will + // directly be fed to the compiler, which will be confused. + return; + } + cm->UpdateProgress(message, s); } std::string cmMakefile::GetModulesFile(const char* filename) diff --git a/Source/cmMakefile.h b/Source/cmMakefile.h index c01bb5d..618f4f3 100644 --- a/Source/cmMakefile.h +++ b/Source/cmMakefile.h @@ -325,7 +325,7 @@ public: /** * Set the name of the library. */ - void AddLibrary(const char *libname, cmTarget::TargetType type, + cmTarget* AddLibrary(const char *libname, cmTarget::TargetType type, const std::vector<std::string> &srcs, bool excludeFromAll = false); diff --git a/Source/cmQtAutomoc.cxx b/Source/cmQtAutomoc.cxx new file mode 100644 index 0000000..abda47e --- /dev/null +++ b/Source/cmQtAutomoc.cxx @@ -0,0 +1,782 @@ +#include "cmGlobalGenerator.h" +#include "cmLocalGenerator.h" +#include "cmMakefile.h" +#include "cmSourceFile.h" +#include "cmSystemTools.h" + +# include <cmsys/Terminal.h> + +#include "cmQtAutomoc.h" + + +cmQtAutomoc::cmQtAutomoc() +:Verbose(cmsys::SystemTools::GetEnv("VERBOSE") != 0) +,ColorOutput(true) +,RunMocFailed(false) +,GenerateAll(false) +{ + + std::string colorEnv = ""; + cmsys::SystemTools::GetEnv("COLOR", colorEnv); + if(!colorEnv.empty()) + { + if(cmSystemTools::IsOn(colorEnv.c_str())) + { + this->ColorOutput = true; + } + else + { + this->ColorOutput = false; + } + } +} + + +void cmQtAutomoc::SetupAutomocTarget(cmTarget* target) +{ + cmMakefile* makefile = target->GetMakefile(); + const char* targetName = target->GetName(); + // don't do anything if there is no Qt4: + std::string qtMajorVersion = makefile->GetSafeDefinition("QT_VERSION_MAJOR"); + if (qtMajorVersion != "4") + { + return; + } + + // create a custom target for running automoc at buildtime: + std::string automocTargetName = targetName; + automocTargetName += "_automoc"; + + std::string targetDir = makefile->GetCurrentOutputDirectory(); + targetDir += makefile->GetCMakeInstance()->GetCMakeFilesDirectory(); + targetDir += "/"; + targetDir += automocTargetName; + targetDir += ".dir/"; + + cmCustomCommandLine currentLine; + currentLine.push_back(makefile->GetCMakeInstance()->GetCMakeCommand()); + currentLine.push_back("-E"); + currentLine.push_back("cmake_automoc"); + currentLine.push_back(targetDir); + + cmCustomCommandLines commandLines; + commandLines.push_back(currentLine); + + std::string workingDirectory = cmSystemTools::CollapseFullPath( + "", makefile->GetCurrentOutputDirectory()); + + std::vector<std::string> depends; + std::string automocComment = "Automoc for target "; + automocComment += targetName; + + makefile->AddUtilityCommand(automocTargetName.c_str(), true, + workingDirectory.c_str(), depends, + commandLines, false, automocComment.c_str()); + target->AddUtility(automocTargetName.c_str()); + + // configure a file to get all information to automoc at buildtime: + std::string _moc_files; + std::string _moc_headers; + const char* sepFiles = ""; + const char* sepHeaders = ""; + + const std::vector<cmSourceFile*>& srcFiles = target->GetSourceFiles(); + + for(std::vector<cmSourceFile*>::const_iterator fileIt = srcFiles.begin(); + fileIt != srcFiles.end(); + ++fileIt) + { + cmSourceFile* sf = *fileIt; + std::string absFile = sf->GetFullPath(); + bool skip = cmSystemTools::IsOn(sf->GetPropertyForUser("SKIP_AUTOMOC")); + bool generated = cmSystemTools::IsOn(sf->GetPropertyForUser("GENERATED")); + + if ((skip==false) && (generated == false)) + { + 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 = ";"; + } + } + } + + std::string _moc_incs = makefile->GetProperty("INCLUDE_DIRECTORIES"); + std::string _moc_defs = makefile->GetProperty("DEFINITIONS"); + std::string _moc_compile_defs = makefile->GetProperty("COMPILE_DEFINITIONS"); + // forget the variables added here afterwards again: + cmMakefile::ScopePushPop varScope(makefile); + static_cast<void>(varScope); + + makefile->AddDefinition("_moc_target_name", automocTargetName.c_str()); + makefile->AddDefinition("_moc_incs", _moc_incs.c_str()); + makefile->AddDefinition("_moc_defs", _moc_defs.c_str()); + makefile->AddDefinition("_moc_compile_defs", _moc_compile_defs.c_str()); + makefile->AddDefinition("_moc_files", _moc_files.c_str()); + makefile->AddDefinition("_moc_headers", _moc_headers.c_str()); + + const char* cmakeRoot = makefile->GetDefinition("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); + + std::string mocCppFile = makefile->GetCurrentOutputDirectory(); + mocCppFile += "/"; + mocCppFile += automocTargetName; + mocCppFile += ".cpp"; + cmSourceFile* mocCppSource = makefile->GetOrCreateSource(mocCppFile.c_str(), + true); + target->AddSourceFile(mocCppSource); + + makefile->AppendProperty("ADDITIONAL_MAKE_CLEAN_FILES", + mocCppFile.c_str(), false); +} + + +bool cmQtAutomoc::Run(const char* targetDirectory) +{ + cmake cm; + cmGlobalGenerator* gg = this->CreateGlobalGenerator(&cm, targetDirectory); + cmMakefile* makefile = gg->GetCurrentLocalGenerator()->GetMakefile(); + + this->ReadAutomocInfoFile(makefile, targetDirectory); + this->ReadOldMocDefinitionsFile(makefile, targetDirectory); + + this->Init(); + + if (this->QtMajorVersion == "4") + { + this->RunAutomocQt4(); + } + + this->WriteOldMocDefinitionsFile(targetDirectory); + + delete gg; + gg = NULL; + makefile = NULL; + return true; +} + + +cmGlobalGenerator* cmQtAutomoc::CreateGlobalGenerator(cmake* cm, + const char* targetDirectory) +{ + cmGlobalGenerator* gg = new cmGlobalGenerator(); + gg->SetCMakeInstance(cm); + + cmLocalGenerator* lg = gg->CreateLocalGenerator(); + lg->GetMakefile()->SetHomeOutputDirectory(targetDirectory); + lg->GetMakefile()->SetStartOutputDirectory(targetDirectory); + lg->GetMakefile()->SetHomeDirectory(targetDirectory); + lg->GetMakefile()->SetStartDirectory(targetDirectory); + gg->SetCurrentLocalGenerator(lg); + + return gg; +} + + +bool cmQtAutomoc::ReadAutomocInfoFile(cmMakefile* makefile, + const char* targetDirectory) +{ + std::string filename(cmSystemTools::CollapseFullPath(targetDirectory)); + cmSystemTools::ConvertToUnixSlashes(filename); + filename += "/AutomocInfo.cmake"; + + if (!makefile->ReadListFile(0, filename.c_str())) + { + cmSystemTools::Error("Error processing file:", filename.c_str()); + return false; + } + + this->QtMajorVersion = makefile->GetSafeDefinition("AM_QT_VERSION_MAJOR"); + this->Sources = makefile->GetSafeDefinition("AM_SOURCES"); + 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->MocCompileDefinitionsStr = makefile->GetSafeDefinition( + "AM_MOC_COMPILE_DEFINITIONS"); + this->MocDefinitionsStr = makefile->GetSafeDefinition("AM_MOC_DEFINITIONS"); + this->MocIncludesStr = makefile->GetSafeDefinition("AM_MOC_INCLUDES"); + this->ProjectBinaryDir = makefile->GetSafeDefinition("AM_CMAKE_BINARY_DIR"); + this->ProjectSourceDir = makefile->GetSafeDefinition("AM_CMAKE_SOURCE_DIR"); + this->TargetName = makefile->GetSafeDefinition("AM_TARGET_NAME"); + + return true; +} + + +bool cmQtAutomoc::ReadOldMocDefinitionsFile(cmMakefile* makefile, + const char* targetDirectory) +{ + std::string filename(cmSystemTools::CollapseFullPath(targetDirectory)); + cmSystemTools::ConvertToUnixSlashes(filename); + filename += "/AutomocOldMocDefinitions.cmake"; + + if (makefile->ReadListFile(0, filename.c_str())) + { + this->OldMocDefinitionsStr = + makefile->GetSafeDefinition("AM_OLD_MOC_DEFINITIONS"); + } + return true; +} + + +void cmQtAutomoc::WriteOldMocDefinitionsFile(const char* targetDirectory) +{ + std::string filename(cmSystemTools::CollapseFullPath(targetDirectory)); + cmSystemTools::ConvertToUnixSlashes(filename); + filename += "/AutomocOldMocDefinitions.cmake"; + + std::fstream outfile; + outfile.open(filename.c_str(), + std::ios::out | std::ios::trunc); + outfile << "set(AM_OLD_MOC_DEFINITIONS \"" + << this->Join(this->MocDefinitions, ' ') << "\")\n"; + + outfile.close(); +} + + +void cmQtAutomoc::Init() +{ + this->OutMocCppFilename = this->Builddir; + this->OutMocCppFilename += this->TargetName; + this->OutMocCppFilename += ".cpp"; + + std::vector<std::string> cdefList; + cmSystemTools::ExpandListArgument(this->MocCompileDefinitionsStr, cdefList); + if (!cdefList.empty()) + { + for(std::vector<std::string>::const_iterator it = cdefList.begin(); + it != cdefList.end(); + ++it) + { + this->MocDefinitions.push_back("-D" + (*it)); + } + } + else + { + std::string tmpMocDefs = this->MocDefinitionsStr; + cmSystemTools::ReplaceString(tmpMocDefs, " ", ";"); + + std::vector<std::string> defList; + cmSystemTools::ExpandListArgument(tmpMocDefs, defList); + + for(std::vector<std::string>::const_iterator it = defList.begin(); + it != defList.end(); + ++it) + { + if (this->StartsWith(*it, "-D")) + { + this->MocDefinitions.push_back(*it); + } + } + } + + std::vector<std::string> incPaths; + cmSystemTools::ExpandListArgument(this->MocIncludesStr, incPaths); + + std::set<std::string> frameworkPaths; + for(std::vector<std::string>::const_iterator it = incPaths.begin(); + it != incPaths.end(); + ++it) + { + const std::string &path = *it; + this->MocIncludes.push_back("-I" + path); + if (this->EndsWith(path, ".framework/Headers")) + { + // Go up twice to get to the framework root + std::vector<std::string> pathComponents; + cmsys::SystemTools::SplitPath(path.c_str(), pathComponents); + std::string frameworkPath =cmsys::SystemTools::JoinPath( + pathComponents.begin(), pathComponents.end() - 2); + frameworkPaths.insert(frameworkPath); + } + } + + for (std::set<std::string>::const_iterator it = frameworkPaths.begin(); + it != frameworkPaths.end(); ++it) + { + this->MocIncludes.push_back("-F"); + this->MocIncludes.push_back(*it); + } + + + if (this->IncludeProjectDirsBefore) + { + const std::string &binDir = "-I" + this->ProjectBinaryDir; + + const std::string srcDir = "-I" + this->ProjectSourceDir; + + std::list<std::string> sortedMocIncludes; + std::list<std::string>::iterator it = this->MocIncludes.begin(); + while (it != this->MocIncludes.end()) + { + if (this->StartsWith(*it, binDir)) + { + sortedMocIncludes.push_back(*it); + it = this->MocIncludes.erase(it); + } + else + { + ++it; + } + } + it = this->MocIncludes.begin(); + while (it != this->MocIncludes.end()) + { + if (this->StartsWith(*it, srcDir)) + { + sortedMocIncludes.push_back(*it); + it = this->MocIncludes.erase(it); + } + else + { + ++it; + } + } + sortedMocIncludes.insert(sortedMocIncludes.end(), + this->MocIncludes.begin(), this->MocIncludes.end()); + this->MocIncludes = sortedMocIncludes; + } + +} + + +bool cmQtAutomoc::RunAutomocQt4() +{ + if (!cmsys::SystemTools::FileExists(this->OutMocCppFilename.c_str()) + || (this->OldMocDefinitionsStr != this->Join(this->MocDefinitions, ' '))) + { + this->GenerateAll = true; + } + + // the program goes through all .cpp files to see which moc files are + // included. It is not really interesting how the moc file is named, but + // what file the moc is created from. Once a moc is included the same moc + // may not be included in the _automoc.cpp file anymore. OTOH if there's a + // header containing Q_OBJECT where no corresponding moc file is included + // anywhere a moc_<filename>.cpp file is created and included in + // the _automoc.cpp file. + + // key = moc source filepath, value = moc output filepath + std::map<std::string, std::string> includedMocs; + // key = moc source filepath, value = moc output filename + std::map<std::string, std::string> notIncludedMocs; + + + std::vector<std::string> sourceFiles; + cmSystemTools::ExpandListArgument(this->Sources, sourceFiles); + + for (std::vector<std::string>::const_iterator it = sourceFiles.begin(); + it != sourceFiles.end(); + ++it) + { + const std::string &absFilename = *it; + if (this->Verbose) + { + std::cout << "AUTOMOC: Checking " << absFilename << std::endl; + } + this->ParseCppFile(absFilename, includedMocs, notIncludedMocs); + } + + std::vector<std::string> headerFiles; + cmSystemTools::ExpandListArgument(this->Headers, headerFiles); + for (std::vector<std::string>::const_iterator it = headerFiles.begin(); + it != headerFiles.end(); + ++it) + { + const std::string &absFilename = *it; + if (this->Verbose) + { + std::cout << "AUTOMOC: Checking " << absFilename << std::endl; + } + if (includedMocs.find(absFilename) == includedMocs.end() + && notIncludedMocs.find(absFilename) == notIncludedMocs.end()) + { + // if this header is not getting processed yet and is explicitly + // mentioned for the automoc the moc is run unconditionally on the + // header and the resulting file is included in the _automoc.cpp file + // (unless there's a .cpp file later on that includes the moc from + // this header) + const std::string currentMoc = "moc_" + cmsys::SystemTools:: + GetFilenameWithoutLastExtension(absFilename) + ".cpp"; + notIncludedMocs[absFilename] = currentMoc; + } + } + + // run moc on all the moc's that are #included in source files + for(std::map<std::string, std::string>::const_iterator + it = includedMocs.begin(); + it != includedMocs.end(); + ++it) + { + this->GenerateMoc(it->first, it->second); + } + + std::stringstream outStream(std::stringstream::out); + outStream << "/* This file is autogenerated, do not edit*/\n"; + + bool automocCppChanged = false; + if (notIncludedMocs.empty()) + { + outStream << "enum some_compilers { need_more_than_nothing };\n"; + } + else + { + // run moc on the remaining headers and include them in + // the _automoc.cpp file + for(std::map<std::string, std::string>::const_iterator + it = notIncludedMocs.begin(); + it != notIncludedMocs.end(); + ++it) + { + bool mocSuccess = this->GenerateMoc(it->first, it->second); + if (mocSuccess) + { + automocCppChanged = true; + } + outStream << "#include \"" << it->second << "\"\n"; + } + } + + if (this->RunMocFailed) + { + std::cerr << "returning failed.."<< std::endl; + return false; + } + outStream.flush(); + std::string automocSource = outStream.str(); + if (!automocCppChanged) + { + // compare contents of the _automoc.cpp file + const std::string oldContents = this->ReadAll(this->OutMocCppFilename); + if (oldContents == automocSource) + { + // nothing changed: don't touch the _automoc.cpp file + return true; + } + } + + // source file that includes all remaining moc files (_automoc.cpp file) + std::fstream outfile; + outfile.open(this->OutMocCppFilename.c_str(), + std::ios::out | std::ios::trunc); + outfile << automocSource; + outfile.close(); + + return true; +} + + +void cmQtAutomoc::ParseCppFile(const std::string& absFilename, + std::map<std::string, std::string>& includedMocs, + std::map<std::string, std::string>& notIncludedMocs) +{ + cmsys::RegularExpression mocIncludeRegExp( + "[\n][ \t]*#[ \t]*include[ \t]+" + "[\"<](([^ \">]+/)?moc_[^ \">/]+\\.cpp|[^ \">]+\\.moc)[\">]"); + cmsys::RegularExpression qObjectRegExp("[\n][ \t]*Q_OBJECT[^a-zA-Z0-9_]"); + std::list<std::string> headerExtensions; + headerExtensions.push_back(".h"); + headerExtensions.push_back(".hpp"); + headerExtensions.push_back(".hxx"); +#if defined(_WIN32) + // not case sensitive, don't add ".H" +#elif defined(__APPLE__) + // detect case-sensitive filesystem + long caseSensitive = pathconf(this->Srcdir.c_str(), _PC_CASE_SENSITIVE); + if (caseSensitive == 1) + { + headerExtensions.push_back(".H"); + } +#else + headerExtensions.push_back(".H"); +#endif + + const std::string contentsString = this->ReadAll(absFilename); + if (contentsString.empty()) + { + std::cerr << "AUTOMOC: empty source file: " << absFilename << std::endl; + return; + } + const std::string absPath = cmsys::SystemTools::GetFilenamePath( + cmsys::SystemTools::GetRealPath(absFilename.c_str())) + '/'; + + std::string::size_type matchOffset = 0; + if (!mocIncludeRegExp.find(contentsString.c_str())) + { + // no moc #include, look whether we need to create a moc from + // the .h nevertheless + const std::string basename = + cmsys::SystemTools::GetFilenameWithoutLastExtension(absFilename); + for(std::list<std::string>::const_iterator ext = headerExtensions.begin(); + ext != headerExtensions.end(); + ++ext) + { + const std::string headername = absPath + basename + (*ext); + if (cmsys::SystemTools::FileExists(headername.c_str()) + && includedMocs.find(headername) == includedMocs.end() + && notIncludedMocs.find(headername) == notIncludedMocs.end()) + { + const std::string currentMoc = "moc_" + basename + ".cpp"; + const std::string contents = this->ReadAll(headername); + if (qObjectRegExp.find(contents)) + { + //std::cout << "header contains Q_OBJECT macro"; + notIncludedMocs[headername] = currentMoc; + } + break; + } + } + for(std::list<std::string>::const_iterator ext = headerExtensions.begin(); + ext != headerExtensions.end(); + ++ext) + { + const std::string privateHeaderName = absPath+basename+"_p"+(*ext); + if (cmsys::SystemTools::FileExists(privateHeaderName.c_str()) + && includedMocs.find(privateHeaderName) == includedMocs.end() + && notIncludedMocs.find(privateHeaderName) == notIncludedMocs.end()) + { + const std::string currentMoc = "moc_" + basename + "_p.cpp"; + const std::string contents = this->ReadAll(privateHeaderName); + if (qObjectRegExp.find(contents)) + { + //std::cout << "header contains Q_OBJECT macro"; + notIncludedMocs[privateHeaderName] = currentMoc; + } + break; + } + } + } + else + { + // for every moc include in the file + do + { + const std::string currentMoc = mocIncludeRegExp.match(1); + //std::cout << "found moc include: " << currentMoc << std::endl; + + std::string basename = cmsys::SystemTools:: + GetFilenameWithoutLastExtension(currentMoc); + const bool moc_style = this->StartsWith(basename, "moc_"); + + // If the moc include is of the moc_foo.cpp style we expect + // the Q_OBJECT class declaration in a header file. + // If the moc include is of the foo.moc style we need to look for + // a Q_OBJECT macro in the current source file, if it contains the + // macro we generate the moc file from the source file, else from the + // header. + // Q_OBJECT + if (moc_style || !qObjectRegExp.find(contentsString)) + { + if (moc_style) + { + // basename should be the part of the moc filename used for + // finding the correct header, so we need to remove the moc_ part + basename = basename.substr(4); + } + + bool headerFound = false; + for(std::list<std::string>::const_iterator ext = + headerExtensions.begin(); + ext != headerExtensions.end(); + ++ext) + { + const std::string &sourceFilePath = absPath + basename + (*ext); + if (cmsys::SystemTools::FileExists(sourceFilePath.c_str())) + { + headerFound = true; + includedMocs[sourceFilePath] = currentMoc; + notIncludedMocs.erase(sourceFilePath); + break; + } + } + if (!headerFound) + { + // the moc file is in a subdir => look for the header in the + // same subdir + if (currentMoc.find_first_of('/') != std::string::npos) + { + const std::string &filepath = absPath + + cmsys::SystemTools::GetFilenamePath(currentMoc) + + '/' + basename; + + for(std::list<std::string>::const_iterator ext = + headerExtensions.begin(); + ext != headerExtensions.end(); + ++ext) + { + const std::string &sourceFilePath = filepath + (*ext); + if (cmsys::SystemTools::FileExists(sourceFilePath.c_str())) + { + headerFound = true; + includedMocs[sourceFilePath] = currentMoc; + notIncludedMocs.erase(sourceFilePath); + break; + } + } + if (!headerFound) + { + std::cerr << "AUTOMOC: The file \"" << absFilename + << "\" includes the moc file \"" << currentMoc + << "\", but neither \"" << absPath << basename + << '{' << this->Join(headerExtensions, ',') + << "}\" nor \"" << filepath << '{' + << this->Join(headerExtensions, ',') << '}' + << "\" exist." << std::endl; + ::exit(EXIT_FAILURE); + } + } + else + { + std::cerr << "AUTOMOC: The file \"" << absFilename + << "\" includes the moc file \"" << currentMoc + << "\", but \"" << absPath << basename << '{' + << this->Join(headerExtensions, ',') << '}' + << "\" does not exist." << std::endl; + ::exit(EXIT_FAILURE); + } + } + } + else + { + includedMocs[absFilename] = currentMoc; + notIncludedMocs.erase(absFilename); + } + matchOffset += mocIncludeRegExp.end(); + } while(mocIncludeRegExp.find(contentsString.c_str() + matchOffset)); + } +} + + +bool cmQtAutomoc::GenerateMoc(const std::string& sourceFile, + const std::string& mocFileName) +{ + const std::string mocFilePath = this->Builddir + mocFileName; + int sourceNewerThanMoc = 0; + bool success = cmsys::SystemTools::FileTimeCompare(sourceFile.c_str(), + mocFilePath.c_str(), + &sourceNewerThanMoc); + if (this->GenerateAll || !success || sourceNewerThanMoc >= 0) + { + // make sure the directory for the resulting moc file exists + std::string mocDir = mocFilePath.substr(0, mocFilePath.rfind('/')); + if (!cmsys::SystemTools::FileExists(mocDir.c_str(), false)) + { + cmsys::SystemTools::MakeDirectory(mocDir.c_str()); + } + + std::string msg = "Generating "; + msg += mocFileName; + cmSystemTools::MakefileColorEcho(cmsysTerminal_Color_ForegroundBlue + |cmsysTerminal_Color_ForegroundBold, + msg.c_str(), true, this->ColorOutput); + + std::vector<cmStdString> command; + command.push_back(this->MocExecutable); + for (std::list<std::string>::const_iterator it = this->MocIncludes.begin(); + it != this->MocIncludes.end(); + ++it) + { + command.push_back(*it); + } + for(std::list<std::string>::const_iterator it=this->MocDefinitions.begin(); + it != this->MocDefinitions.end(); + ++it) + { + command.push_back(*it); + } +#ifdef _WIN32 + command.push_back("-DWIN32"); +#endif + command.push_back("-o"); + command.push_back(mocFilePath); + command.push_back(sourceFile); + + 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 << "AUTOMOC: process for " << mocFilePath << " failed:\n" + << output << std::endl; + this->RunMocFailed = true; + cmSystemTools::RemoveFile(mocFilePath.c_str()); + } + return true; + } + return false; +} + + +std::string cmQtAutomoc::Join(const std::list<std::string>& lst,char separator) +{ + if (lst.empty()) + { + return ""; + } + + std::string result; + for (std::list<std::string>::const_iterator it = lst.begin(); + it != lst.end(); + ++it) + { + result += (*it) + separator; + } + result.erase(result.end() - 1); + return result; +} + + +bool cmQtAutomoc::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) +{ + if (with.length() > (str.length())) + { + return false; + } + return (str.substr(str.length() - with.length(), with.length()) == with); +} + + +std::string cmQtAutomoc::ReadAll(const std::string& filename) +{ + std::ifstream file(filename.c_str()); + std::stringstream stream; + stream << file.rdbuf(); + file.close(); + return stream.str(); +} diff --git a/Source/cmQtAutomoc.h b/Source/cmQtAutomoc.h new file mode 100644 index 0000000..4fd9041 --- /dev/null +++ b/Source/cmQtAutomoc.h @@ -0,0 +1,66 @@ +#ifndef cmQtAutomoc_h +#define cmQtAutomoc_h + +class cmGlobalGenerator; +class cmMakefile; + +class cmQtAutomoc +{ +public: + cmQtAutomoc(); + bool Run(const char* targetDirectory); + + void SetupAutomocTarget(cmTarget* target); + +private: + cmGlobalGenerator* CreateGlobalGenerator(cmake* cm, + const char* targetDirectory); + + bool ReadAutomocInfoFile(cmMakefile* makefile, + const char* targetDirectory); + bool ReadOldMocDefinitionsFile(cmMakefile* makefile, + const char* targetDirectory); + void WriteOldMocDefinitionsFile(const char* targetDirectory); + + bool RunAutomocQt4(); + bool GenerateMoc(const std::string& sourceFile, + const std::string& mocFileName); + void ParseCppFile(const std::string& absFilename, + std::map<std::string, std::string>& includedMocs, + std::map<std::string, std::string>& notIncludedMocs); + + void Init(); + + std::string Join(const std::list<std::string>& lst, char separator); + bool EndsWith(const std::string& str, const std::string& with); + bool StartsWith(const std::string& str, const std::string& with); + std::string ReadAll(const std::string& filename); + + std::string QtMajorVersion; + std::string Sources; + std::string Headers; + bool IncludeProjectDirsBefore; + std::string Srcdir; + std::string Builddir; + std::string MocExecutable; + std::string MocCompileDefinitionsStr; + std::string MocDefinitionsStr; + std::string MocIncludesStr; + std::string ProjectBinaryDir; + std::string ProjectSourceDir; + std::string TargetName; + + std::string OldMocDefinitionsStr; + + std::string OutMocCppFilename; + std::list<std::string> MocIncludes; + std::list<std::string> MocDefinitions; + + bool Verbose; + bool ColorOutput; + bool RunMocFailed; + bool GenerateAll; + +}; + +#endif diff --git a/Source/cmTarget.cxx b/Source/cmTarget.cxx index 17a26cc..4969b65 100644 --- a/Source/cmTarget.cxx +++ b/Source/cmTarget.cxx @@ -115,6 +115,28 @@ cmTarget::cmTarget() void cmTarget::DefineProperties(cmake *cm) { cm->DefineProperty + ("AUTOMOC", cmProperty::TARGET, + "Should the target be processed with automoc (for Qt projects).", + "AUTOMOC is a boolean specifying whether CMake will handle " + "the Qt moc preprocessor automatically, i.e. without having to use " + "the QT4_WRAP_CPP() macro. Currently Qt4 is supported. " + "When this property is set to TRUE, CMake will scan the source files " + "at build time and invoke moc accordingly. " + "If an #include statement like #include \"moc_foo.cpp\" is found, " + "the Q_OBJECT class declaration is expected in the header, and moc is " + "run on the header file. " + "If an #include statement like #include \"foo.moc\" is found, " + "then a Q_OBJECT is expected in the current source file and moc " + "is run on the file itself. " + "Additionally, all header files are parsed for Q_OBJECT macros, " + "and if found, moc is also executed on those files. The resulting " + "moc files, which are not included as shown above in any of the source " + "files are included in a generated <targetname>_automoc.cpp file, " + "which is compiled as part of the target." + "This property is initialized by the value of the variable " + "CMAKE_AUTOMOC if it is set when a target is created."); + + cm->DefineProperty ("BUILD_WITH_INSTALL_RPATH", cmProperty::TARGET, "Should build tree targets have install tree rpaths.", "BUILD_WITH_INSTALL_RPATH is a boolean specifying whether to link " @@ -1118,6 +1140,7 @@ void cmTarget::SetMakefile(cmMakefile* mf) this->SetPropertyDefault("RUNTIME_OUTPUT_DIRECTORY", 0); this->SetPropertyDefault("Fortran_MODULE_DIRECTORY", 0); this->SetPropertyDefault("OSX_ARCHITECTURES", 0); + this->SetPropertyDefault("AUTOMOC", 0); // Collect the set of configuration types. std::vector<std::string> configNames; @@ -1420,7 +1443,7 @@ bool cmTargetTraceDependencies::IsUtility(std::string const& dep) // the fact that the name matched a target was just a coincidence. if(cmSystemTools::FileIsFullPath(dep.c_str())) { - if(t->GetType() >= cmTarget::EXECUTABLE && + if(t->GetType() >= cmTarget::EXECUTABLE && t->GetType() <= cmTarget::MODULE_LIBRARY) { // This is really only for compatibility so we do not need to diff --git a/Source/cmVisualStudio10TargetGenerator.cxx b/Source/cmVisualStudio10TargetGenerator.cxx index 8cba84c..551b0ad 100644 --- a/Source/cmVisualStudio10TargetGenerator.cxx +++ b/Source/cmVisualStudio10TargetGenerator.cxx @@ -437,7 +437,7 @@ cmVisualStudio10TargetGenerator::WriteCustomRule(cmSourceFile* source, (*this->BuildFileStream ) << sep << out; sep = ";"; } - (*this->BuildFileStream ) << ";%(Outputs)</Outputs>\n"; + (*this->BuildFileStream ) << "</Outputs>\n"; } this->WriteString("</CustomBuild>\n", 2); } diff --git a/Source/cmXCodeObject.cxx b/Source/cmXCodeObject.cxx index 30e5076..30ade96 100644 --- a/Source/cmXCodeObject.cxx +++ b/Source/cmXCodeObject.cxx @@ -12,6 +12,8 @@ #include "cmXCodeObject.h" #include "cmSystemTools.h" +#include <CoreFoundation/CoreFoundation.h> // CFUUIDCreate + //---------------------------------------------------------------------------- const char* cmXCodeObject::PBXTypeNames[] = { "PBXGroup", "PBXBuildStyle", "PBXProject", "PBXHeadersBuildPhase", @@ -39,35 +41,35 @@ cmXCodeObject::cmXCodeObject(PBXType ptype, Type type) this->PBXTargetDependencyValue = 0; this->Target = 0; this->Object =0; - + this->IsA = ptype; + if(type == OBJECT) { - cmOStringStream str; - str << (void*)this; - str << (void*)this; - str << (void*)this; - this->Id = str.str(); + // Set the Id of an Xcode object to a unique string for each instance. + // However the Xcode user file references certain Ids: for those cases, + // override the generated Id using SetId(). + // + char cUuid[40] = {0}; + CFUUIDRef uuid = CFUUIDCreate(kCFAllocatorDefault); + CFStringRef s = CFUUIDCreateString(kCFAllocatorDefault, uuid); + CFStringGetCString(s, cUuid, sizeof(cUuid), kCFStringEncodingUTF8); + this->Id = cUuid; + CFRelease(s); + CFRelease(uuid); } else { - this->Id = - "Temporary cmake object, should not be refered to in xcode file"; - } - cmSystemTools::ReplaceString(this->Id, "0x", ""); - this->Id = cmSystemTools::UpperCase(this->Id); - if(this->Id.size() < 24) - { - int diff = 24 - this->Id.size(); - for(int i =0; i < diff; ++i) - { - this->Id += "0"; - } + this->Id = + "Temporary cmake object, should not be referred to in Xcode file"; } + + cmSystemTools::ReplaceString(this->Id, "-", ""); if(this->Id.size() > 24) { - this->Id = this->Id.substr(0,24); + this->Id = this->Id.substr(0, 24); } + this->TypeValue = type; if(this->TypeValue == OBJECT) { diff --git a/Source/cmXCodeObject.h b/Source/cmXCodeObject.h index 369fe66..2fb96f3 100644 --- a/Source/cmXCodeObject.h +++ b/Source/cmXCodeObject.h @@ -83,6 +83,10 @@ public: { return this->Id.c_str(); } + void SetId(const char* id) + { + this->Id = id; + } cmTarget* GetTarget() { return this->Target; diff --git a/Source/cmake.cxx b/Source/cmake.cxx index 51cc9d4..2b8c718 100644 --- a/Source/cmake.cxx +++ b/Source/cmake.cxx @@ -20,6 +20,7 @@ #include "cmCommand.h" #include "cmFileTimeComparison.h" #include "cmGeneratedFileStream.h" +#include "cmQtAutomoc.h" #include "cmSourceFile.h" #include "cmVersion.h" #include "cmTest.h" @@ -182,7 +183,7 @@ cmake::cmake() this->GlobalGenerator = 0; this->ProgressCallback = 0; this->ProgressCallbackClientData = 0; - this->ScriptMode = false; + this->CurrentWorkingMode = NORMAL_MODE; #ifdef CMAKE_BUILD_WITH_CMAKE this->VariableWatch = new cmVariableWatch; @@ -355,6 +356,7 @@ void cmake::RemoveUnscriptableCommands() // Parse the args bool cmake::SetCacheArgs(const std::vector<std::string>& args) { + bool findPackageMode = false; for(unsigned int i=1; i < args.size(); ++i) { std::string arg = args[i]; @@ -482,7 +484,17 @@ bool cmake::SetCacheArgs(const std::vector<std::string>& args) } this->ReadListFile(args, path.c_str()); } + else if (arg.find("--find-package",0) == 0) + { + findPackageMode = true; + } + } + + if (findPackageMode) + { + return this->FindPackage(args); } + return true; } @@ -513,7 +525,7 @@ void cmake::ReadListFile(const std::vector<std::string>& args, (cmSystemTools::GetCurrentWorkingDirectory().c_str()); lg->GetMakefile()->SetStartDirectory (cmSystemTools::GetCurrentWorkingDirectory().c_str()); - if (this->GetScriptMode()) + if (this->GetWorkingMode() != NORMAL_MODE) { std::string file(cmSystemTools::CollapseFullPath(path)); cmSystemTools::ConvertToUnixSlashes(file); @@ -534,6 +546,111 @@ void cmake::ReadListFile(const std::vector<std::string>& args, } } + +bool cmake::FindPackage(const std::vector<std::string>& args) +{ + // if a generator was not yet created, temporarily create one + cmGlobalGenerator *gg = new cmGlobalGenerator; + gg->SetCMakeInstance(this); + this->SetGlobalGenerator(gg); + + // read in the list file to fill the cache + std::auto_ptr<cmLocalGenerator> lg(gg->CreateLocalGenerator()); + cmMakefile* mf = lg->GetMakefile(); + mf->SetHomeOutputDirectory + (cmSystemTools::GetCurrentWorkingDirectory().c_str()); + mf->SetStartOutputDirectory + (cmSystemTools::GetCurrentWorkingDirectory().c_str()); + mf->SetHomeDirectory + (cmSystemTools::GetCurrentWorkingDirectory().c_str()); + mf->SetStartDirectory + (cmSystemTools::GetCurrentWorkingDirectory().c_str()); + + mf->SetArgcArgv(args); + + std::string systemFile = mf->GetModulesFile("CMakeFindPackageMode.cmake"); + mf->ReadListFile(0, systemFile.c_str()); + + std::string language = mf->GetSafeDefinition("LANGUAGE"); + std::string mode = mf->GetSafeDefinition("MODE"); + std::string packageName = mf->GetSafeDefinition("NAME"); + bool packageFound = mf->IsOn("PACKAGE_FOUND"); + bool quiet = mf->IsOn("PACKAGE_QUIET"); + + if (!packageFound) + { + if (!quiet) + { + printf("%s not found.\n", packageName.c_str()); + } + } + else if (mode == "EXIST") + { + if (!quiet) + { + printf("%s found.\n", packageName.c_str()); + } + } + else if (mode == "COMPILE") + { + std::string includes = mf->GetSafeDefinition("PACKAGE_INCLUDE_DIRS"); + std::vector<std::string> includeDirs; + cmSystemTools::ExpandListArgument(includes, includeDirs); + for(std::vector<std::string>::const_iterator dirIt=includeDirs.begin(); + dirIt != includeDirs.end(); + ++dirIt) + { + mf->AddIncludeDirectory(dirIt->c_str(), false); + } + + std::string includeFlags = lg->GetIncludeFlags(language.c_str(), false); + std::string definitions = mf->GetSafeDefinition("PACKAGE_DEFINITIONS"); + printf("%s %s\n", includeFlags.c_str(), definitions.c_str()); + } + else if (mode == "LINK") + { + const char* targetName = "dummy"; + std::vector<std::string> srcs; + cmTarget* tgt = mf->AddExecutable(targetName, srcs, true); + tgt->SetProperty("LINKER_LANGUAGE", language.c_str()); + + std::string libs = mf->GetSafeDefinition("PACKAGE_LIBRARIES"); + std::vector<std::string> libList; + cmSystemTools::ExpandListArgument(libs, libList); + for(std::vector<std::string>::const_iterator libIt=libList.begin(); + libIt != libList.end(); + ++libIt) + { + mf->AddLinkLibraryForTarget(targetName, libIt->c_str(), + cmTarget::GENERAL); + } + + + std::string linkLibs; + std::string flags; + std::string linkFlags; + lg->GetTargetFlags(linkLibs, flags, linkFlags, *tgt); + + printf("%s\n", linkLibs.c_str() ); + +/* if ( use_win32 ) + { + tgt->SetProperty("WIN32_EXECUTABLE", "ON"); + } + if ( use_macbundle) + { + tgt->SetProperty("MACOSX_BUNDLE", "ON"); + }*/ + } + + // free generic one if generated +// this->SetGlobalGenerator(0); // setting 0-pointer is not possible +// delete gg; // this crashes inside the cmake instance + + return packageFound; +} + + // Parse the args void cmake::SetArgs(const std::vector<std::string>& args, bool directoriesSetBefore) @@ -606,6 +723,11 @@ void cmake::SetArgs(const std::vector<std::string>& args, // skip for now i++; } + else if(arg.find("--find-package",0) == 0) + { + // skip for now + i++; + } else if(arg.find("-Wno-dev",0) == 0) { // skip for now @@ -1572,6 +1694,12 @@ int cmake::ExecuteCMakeCommand(std::vector<std::string>& args) { return cmake::ExecuteEchoColor(args); } + else if (args[1] == "cmake_automoc") + { + cmQtAutomoc automoc; + automoc.Run(args[2].c_str()); + return 0; + } #endif // Tar files @@ -2028,7 +2156,7 @@ int cmake::ActualConfigure() this->CleanupCommandsAndMacros(); int res = 0; - if ( !this->ScriptMode ) + if ( this->GetWorkingMode() == NORMAL_MODE ) { res = this->DoPreConfigureChecks(); } @@ -2216,7 +2344,7 @@ int cmake::ActualConfigure() this->CacheManager->RemoveCacheEntry("CMAKE_EXTRA_GENERATOR"); } // only save the cache if there were no fatal errors - if ( !this->ScriptMode ) + if ( this->GetWorkingMode() == NORMAL_MODE ) { this->CacheManager->SaveCache(this->GetHomeOutputDirectory()); } @@ -2282,7 +2410,7 @@ int cmake::Run(const std::vector<std::string>& args, bool noconfigure) // set the cmake command this->CMakeCommand = args[0]; - if ( !this->ScriptMode ) + if ( this->GetWorkingMode() == NORMAL_MODE ) { // load the cache if(this->LoadCache() < 0) @@ -2303,7 +2431,7 @@ int cmake::Run(const std::vector<std::string>& args, bool noconfigure) } // In script mode we terminate after running the script. - if(this->ScriptMode) + if(this->GetWorkingMode() != NORMAL_MODE) { if(cmSystemTools::GetErrorOccuredFlag()) { @@ -2349,7 +2477,7 @@ int cmake::Run(const std::vector<std::string>& args, bool noconfigure) this->SetStartDirectory(this->GetHomeDirectory()); this->SetStartOutputDirectory(this->GetHomeOutputDirectory()); int ret = this->Configure(); - if (ret || this->ScriptMode) + if (ret || this->GetWorkingMode() != NORMAL_MODE) { #if defined(CMAKE_HAVE_VS_GENERATORS) if(!this->VSSolutionFile.empty() && this->GlobalGenerator) @@ -2919,6 +3047,13 @@ const char* cmake::GetCPackCommand() return this->CPackCommand.c_str(); } + +const char* cmake::GetCMakeCommand() +{ + return this->CMakeCommand.c_str(); +} + + void cmake::MarkCliAsUsed(const std::string& variable) { this->UsedCliVariables[variable] = true; diff --git a/Source/cmake.h b/Source/cmake.h index f2a2ae3..ae56e85 100644 --- a/Source/cmake.h +++ b/Source/cmake.h @@ -64,6 +64,25 @@ class cmake WARNING, LOG }; + + + /** Describes the working modes of cmake. + * NORMAL_MODE: cmake runs to create project files + * SCRIPT_MODE: in script mode there is no generator and no cache. Also, + * language are not enabled, so add_executable and things do + * not do anything. Started by using -P + * FIND_PACKAGE_MODE: cmake runs in pkg-config like mode, i.e. it just + * searches for a package and prints the results to stdout. + * This is similar to SCRIPT_MODE, but commands like + * add_library() work too, since they may be used e.g. in + * exported target files. Started via --find-package + */ + enum WorkingMode + { + NORMAL_MODE, + SCRIPT_MODE, + FIND_PACKAGE_MODE + }; typedef std::map<cmStdString, cmCommand*> RegisteredCommandsMap; ///! construct an instance of cmake @@ -274,13 +293,8 @@ class cmake ///! Do all the checks before running configure int DoPreConfigureChecks(); - /** - * Set and get the script mode option. In script mode there is no - * generator and no cache. Also, language are not enabled, so - * add_executable and things do not do anything. - */ - void SetScriptMode(bool mode) { this->ScriptMode = mode; } - bool GetScriptMode() { return this->ScriptMode; } + void SetWorkingMode(WorkingMode mode) { this->CurrentWorkingMode = mode; } + WorkingMode GetWorkingMode() { return this->CurrentWorkingMode; } ///! Debug the try compile stuff by not delelting the files bool GetDebugTryCompile(){return this->DebugTryCompile;} @@ -301,6 +315,7 @@ class cmake */ const char* GetCTestCommand(); const char* GetCPackCommand(); + const char* GetCMakeCommand(); // Do we want debug output during the cmake run. bool GetDebugOutput() { return this->DebugOutput; } @@ -408,6 +423,7 @@ protected: ///! read in a cmake list file to initialize the cache void ReadListFile(const std::vector<std::string>& args, const char *path); + bool FindPackage(const std::vector<std::string>& args); ///! Check if CMAKE_CACHEFILE_DIR is set. If it is not, delete the log file. /// If it is set, truncate it to 50kb @@ -461,7 +477,7 @@ private: void* ProgressCallbackClientData; bool Verbose; bool InTryCompile; - bool ScriptMode; + WorkingMode CurrentWorkingMode; bool DebugOutput; bool Trace; bool WarnUninitialized; diff --git a/Source/cmakemain.cxx b/Source/cmakemain.cxx index 1fe9e82..9f213a5 100644 --- a/Source/cmakemain.cxx +++ b/Source/cmakemain.cxx @@ -103,6 +103,11 @@ static const char * cmDocumentationOptions[][3] = "No configure or generate step is performed and the cache is not" " modified. If variables are defined using -D, this must be done " "before the -P argument."}, + {"--find-package", "Run in pkg-config like mode.", + "Search a package using find_package() and print the resulting flags " + "to stdout. This can be used to use cmake instead of pkg-config to find " + "installed libraries in plain Makefile-based projects or in " + "autoconf-based projects (via share/aclocal/cmake.m4)."}, {"--graphviz=[file]", "Generate graphviz of dependencies.", "Generate a graphviz input file that will contain all the library and " "executable dependencies in the project."}, @@ -434,7 +439,7 @@ int do_cmake(int ac, char** av) bool list_all_cached = false; bool list_help = false; bool view_only = false; - bool script_mode = false; + cmake::WorkingMode workingMode = cmake::NORMAL_MODE; std::vector<std::string> args; for(int i =0; i < ac; ++i) { @@ -482,12 +487,18 @@ int do_cmake(int ac, char** av) } else { - script_mode = true; + workingMode = cmake::SCRIPT_MODE; args.push_back(av[i]); i++; args.push_back(av[i]); } } + else if (!command && strncmp(av[i], "--find-package", + strlen("--find-package")) == 0) + { + workingMode = cmake::FIND_PACKAGE_MODE; + args.push_back(av[i]); + } else { args.push_back(av[i]); @@ -512,7 +523,7 @@ int do_cmake(int ac, char** av) cmake cm; cmSystemTools::SetErrorCallback(cmakemainErrorCallback, (void *)&cm); cm.SetProgressCallback(cmakemainProgressCallback, (void *)&cm); - cm.SetScriptMode(script_mode); + cm.SetWorkingMode(workingMode); int res = cm.Run(args, view_only); if ( list_cached || list_all_cached ) diff --git a/Source/kwsys/hash_fun.hxx.in b/Source/kwsys/hash_fun.hxx.in index 926ec92..8c5eb6a 100644 --- a/Source/kwsys/hash_fun.hxx.in +++ b/Source/kwsys/hash_fun.hxx.in @@ -40,6 +40,7 @@ #include <@KWSYS_NAMESPACE@/Configure.hxx> #include <@KWSYS_NAMESPACE@/FundamentalType.h> #include <@KWSYS_NAMESPACE@/cstddef> // size_t +#include <@KWSYS_NAMESPACE@/stl/string> // string namespace @KWSYS_NAMESPACE@ { @@ -66,6 +67,18 @@ struct hash<const char*> { }; @KWSYS_NAMESPACE@_CXX_DEFINE_SPECIALIZATION + struct hash<@KWSYS_NAMESPACE@_stl::string> { + size_t operator()(const @KWSYS_NAMESPACE@_stl::string & __s) const { return _stl_hash_string(__s.c_str()); } +}; + +#if !defined(__BORLANDC__) +@KWSYS_NAMESPACE@_CXX_DEFINE_SPECIALIZATION + struct hash<const @KWSYS_NAMESPACE@_stl::string> { + size_t operator()(const @KWSYS_NAMESPACE@_stl::string & __s) const { return _stl_hash_string(__s.c_str()); } +}; +#endif + +@KWSYS_NAMESPACE@_CXX_DEFINE_SPECIALIZATION struct hash<char> { size_t operator()(char __x) const { return __x; } }; diff --git a/Source/kwsys/kwsysDateStamp.cmake b/Source/kwsys/kwsysDateStamp.cmake index fa2cab5..4558e2a 100644 --- a/Source/kwsys/kwsysDateStamp.cmake +++ b/Source/kwsys/kwsysDateStamp.cmake @@ -15,7 +15,7 @@ SET(KWSYS_DATE_STAMP_YEAR 2011) # KWSys version date month component. Format is MM. -SET(KWSYS_DATE_STAMP_MONTH 08) +SET(KWSYS_DATE_STAMP_MONTH 09) # KWSys version date day component. Format is DD. -SET(KWSYS_DATE_STAMP_DAY 24) +SET(KWSYS_DATE_STAMP_DAY 01) diff --git a/Tests/CMakeLists.txt b/Tests/CMakeLists.txt index 757947e..46b3c15 100644 --- a/Tests/CMakeLists.txt +++ b/Tests/CMakeLists.txt @@ -48,6 +48,8 @@ IF(BUILD_TESTING) ADD_SUBDIRECTORY(CMakeLib) + ADD_SUBDIRECTORY(FindPackageModeMakefileTest) + # Collect a list of all test build directories. SET(TEST_BUILD_DIRS) @@ -845,6 +847,45 @@ ${CMake_BINARY_DIR}/bin/cmake -DVERSION=master -P ${CMake_SOURCE_DIR}/Utilities/ ) LIST(APPEND TEST_BUILD_DIRS "${CMake_BINARY_DIR}/Tests/Environment") + IF(NOT QT4_FOUND) + FIND_PACKAGE(Qt4) + ENDIF(NOT QT4_FOUND) + + IF(QT4_FOUND) + # test whether the Qt4 which has been found works, on some machines + # which run nightly builds there were errors like "wrong file format" + # for libQtCore.so. So first check it works, and only if it does add + # the automoc test. + INCLUDE(CheckCXXSourceCompiles) + SET(_save_CMAKE_REQUIRED_INCLUDES "${CMAKE_REQUIRED_INCLUDES}") + SET(_save_CMAKE_REQUIRED_LIBRARIES "${CMAKE_REQUIRED_LIBRARIES}") + + SET(CMAKE_REQUIRED_INCLUDES ${QT_INCLUDES}) + SET(CMAKE_REQUIRED_LIBRARIES ${QT_QTCORE_LIBRARIES}) + + CHECK_CXX_SOURCE_COMPILES("#include <QCoreApplication>\n int main() {return (qApp == 0 ? 0 : 1); }\n" + QT4_WORKS_FOR_AUTOMOC_TEST) + + SET(CMAKE_REQUIRED_INCLUDES "${_save_CMAKE_REQUIRED_INCLUDES}") + SET(CMAKE_REQUIRED_LIBRARIES "${_save_CMAKE_REQUIRED_LIBRARIES}") + + IF(QT4_WORKS_FOR_AUTOMOC_TEST) + ADD_TEST(QtAutomoc ${CMAKE_CTEST_COMMAND} + --build-and-test + "${CMake_SOURCE_DIR}/Tests/QtAutomoc" + "${CMake_BINARY_DIR}/Tests/QtAutomoc" + --build-generator ${CMAKE_TEST_GENERATOR} + --build-project QtAutomoc + --build-makeprogram ${CMAKE_TEST_MAKEPROGRAM} + --build-exe-dir "${CMake_BINARY_DIR}/Tests/QtAutomoc" + --force-new-ctest-process + --build-options -DQT_QMAKE_EXECUTABLE:FILEPATH=${QT_QMAKE_EXECUTABLE} + --test-command ${CMAKE_CTEST_COMMAND} -V + ) + LIST(APPEND TEST_BUILD_DIRS "${CMake_BINARY_DIR}/Tests/QtAutomoc") + ENDIF() + ENDIF() + ADD_TEST(ExternalProject ${CMAKE_CTEST_COMMAND} --build-and-test "${CMake_SOURCE_DIR}/Tests/ExternalProject" diff --git a/Tests/FindPackageModeMakefileTest/CMakeLists.txt b/Tests/FindPackageModeMakefileTest/CMakeLists.txt new file mode 100644 index 0000000..def8d63 --- /dev/null +++ b/Tests/FindPackageModeMakefileTest/CMakeLists.txt @@ -0,0 +1,30 @@ + + +if(UNIX AND "${CMAKE_GENERATOR}" MATCHES "Makefile") + + # Test whether the make is GNU make, and only add the test in this case, + # since the configured makefile in this test uses $(shell ...), which + # is AFAIK a GNU make extension. Alex + execute_process(COMMAND ${CMAKE_MAKE_PROGRAM} -v + OUTPUT_VARIABLE makeVersionOutput + TIMEOUT 10) + string(TOUPPER "${makeVersionOutput}" MAKE_VERSION_OUTPUT) + if("${MAKE_VERSION_OUTPUT}" MATCHES ".*GNU MAKE.*") + + # build a library which we can search during the test + add_library(foo STATIC foo.cpp) + + # configure a FindFoo.cmake so it knows where the library can be found + configure_file(FindFoo.cmake.in ${CMAKE_CURRENT_BINARY_DIR}/FindFoo.cmake @ONLY) + + # now set up the test: + get_target_property(cmakeExecutable cmake LOCATION) + + configure_file(${CMAKE_CURRENT_SOURCE_DIR}/Makefile.in ${CMAKE_CURRENT_BINARY_DIR}/ConfMakefile @ONLY) + configure_file(${CMAKE_CURRENT_SOURCE_DIR}/main.cpp ${CMAKE_CURRENT_BINARY_DIR}/main.cpp COPYONLY) + + add_test(FindPackageModeMakefileTest ${CMAKE_MAKE_PROGRAM} -f ${CMAKE_CURRENT_BINARY_DIR}/ConfMakefile ) + + endif() + +endif() diff --git a/Tests/FindPackageModeMakefileTest/FindFoo.cmake.in b/Tests/FindPackageModeMakefileTest/FindFoo.cmake.in new file mode 100644 index 0000000..dc62bac --- /dev/null +++ b/Tests/FindPackageModeMakefileTest/FindFoo.cmake.in @@ -0,0 +1,9 @@ + +find_library(FOO_LIBRARY NAMES foo HINTS "@CMAKE_CURRENT_BINARY_DIR@" ) +find_path(FOO_INCLUDE_DIR NAMES foo.h HINTS "@CMAKE_CURRENT_SOURCE_DIR@" ) + +set(FOO_LIBRARIES ${FOO_LIBRARY}) +set(FOO_INCLUDE_DIRS "${FOO_INCLUDE_DIR}" "/some/path/with a space/include" ) + +include(FindPackageHandleStandardArgs) +find_package_handle_standard_args(Foo DEFAULT_MSG FOO_LIBRARY FOO_INCLUDE_DIR ) diff --git a/Tests/FindPackageModeMakefileTest/Makefile.in b/Tests/FindPackageModeMakefileTest/Makefile.in new file mode 100644 index 0000000..073d82e --- /dev/null +++ b/Tests/FindPackageModeMakefileTest/Makefile.in @@ -0,0 +1,10 @@ +all: clean pngtest + +main.o: main.cpp + "@CMAKE_CXX_COMPILER@" $(CXXFLAGS) -c $(shell "@cmakeExecutable@" --find-package -DCMAKE_MODULE_PATH="@CMAKE_CURRENT_BINARY_DIR@" -DNAME=Foo -DLANGUAGE=CXX -DCOMPILER_ID=@CMAKE_CXX_COMPILER_ID@ -DMODE=COMPILE) main.cpp + +pngtest: main.o + "@CMAKE_CXX_COMPILER@" $(LDFLAGS) -o pngtest main.o $(shell "@cmakeExecutable@" --find-package -DCMAKE_MODULE_PATH="@CMAKE_CURRENT_BINARY_DIR@" -DNAME=Foo -DLANGUAGE=CXX -DCOMPILER_ID=@CMAKE_CXX_COMPILER_ID@ -DMODE=LINK) + +clean: + rm -f *.o pngtest diff --git a/Tests/FindPackageModeMakefileTest/foo.cpp b/Tests/FindPackageModeMakefileTest/foo.cpp new file mode 100644 index 0000000..6aea226 --- /dev/null +++ b/Tests/FindPackageModeMakefileTest/foo.cpp @@ -0,0 +1,4 @@ +int foo() +{ + return 1477; +} diff --git a/Tests/FindPackageModeMakefileTest/foo.h b/Tests/FindPackageModeMakefileTest/foo.h new file mode 100644 index 0000000..4ec598a --- /dev/null +++ b/Tests/FindPackageModeMakefileTest/foo.h @@ -0,0 +1,6 @@ +#ifndef FOO_H +#define FOO_H + +int foo(); + +#endif diff --git a/Tests/FindPackageModeMakefileTest/main.cpp b/Tests/FindPackageModeMakefileTest/main.cpp new file mode 100644 index 0000000..e5f9134 --- /dev/null +++ b/Tests/FindPackageModeMakefileTest/main.cpp @@ -0,0 +1,8 @@ +#include <stdio.h> +#include <foo.h> + +int main() +{ + printf("foo is: %d\n", foo()); + return 0; +} diff --git a/Tests/QtAutomoc/CMakeLists.txt b/Tests/QtAutomoc/CMakeLists.txt new file mode 100644 index 0000000..4a5ff10 --- /dev/null +++ b/Tests/QtAutomoc/CMakeLists.txt @@ -0,0 +1,20 @@ +cmake_minimum_required(VERSION 2.8) + +project(QtAutomoc) + +find_package(Qt4 REQUIRED) + +include(UseQt4) + +include_directories(${CMAKE_CURRENT_BINARY_DIR}) + +add_definitions(-DFOO) + +# create an executable and a library target, both requiring automoc: +add_library(codeeditorLib STATIC codeeditor.cpp) + +add_executable(foo main.cpp calwidget.cpp ) + +set_target_properties(foo codeeditorLib PROPERTIES AUTOMOC TRUE) + +target_link_libraries(foo codeeditorLib ${QT_LIBRARIES} ) diff --git a/Tests/QtAutomoc/calwidget.cpp b/Tests/QtAutomoc/calwidget.cpp new file mode 100644 index 0000000..24f3b4e --- /dev/null +++ b/Tests/QtAutomoc/calwidget.cpp @@ -0,0 +1,424 @@ +/**************************************************************************** + ** + ** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies). + ** All rights reserved. + ** Contact: Nokia Corporation (qt-info@nokia.com) + ** + ** This file is part of the examples of the Qt Toolkit. + ** + ** $QT_BEGIN_LICENSE:BSD$ + ** You may use this file under the terms of the BSD license as follows: + ** + ** "Redistribution and use in source and binary forms, with or without + ** modification, are permitted provided that the following conditions are + ** met: + ** * Redistributions of source code must retain the above copyright + ** notice, this list of conditions and the following disclaimer. + ** * Redistributions in binary form must reproduce the above copyright + ** notice, this list of conditions and the following disclaimer in + ** the documentation and/or other materials provided with the + ** distribution. + ** * Neither the name of Nokia Corporation and its Subsidiary(-ies) nor + ** the names of its contributors may be used to endorse or promote + ** products derived from this software without specific prior written + ** permission. + ** + ** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + ** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + ** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + ** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + ** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + ** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + ** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + ** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + ** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + ** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + ** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." + ** $QT_END_LICENSE$ + ** + ****************************************************************************/ + + #include <QtGui> + + #include "calwidget.h" + + Window::Window() + { + createPreviewGroupBox(); + createGeneralOptionsGroupBox(); + createDatesGroupBox(); + createTextFormatsGroupBox(); + + QGridLayout *layout = new QGridLayout; + layout->addWidget(previewGroupBox, 0, 0); + layout->addWidget(generalOptionsGroupBox, 0, 1); + layout->addWidget(datesGroupBox, 1, 0); + layout->addWidget(textFormatsGroupBox, 1, 1); + layout->setSizeConstraint(QLayout::SetFixedSize); + setLayout(layout); + + previewLayout->setRowMinimumHeight(0, calendar->sizeHint().height()); + previewLayout->setColumnMinimumWidth(0, calendar->sizeHint().width()); + + setWindowTitle(tr("Calendar Widget")); + } + + void Window::localeChanged(int index) + { + calendar->setLocale(localeCombo->itemData(index).toLocale()); + } + + void Window::firstDayChanged(int index) + { + calendar->setFirstDayOfWeek(Qt::DayOfWeek( + firstDayCombo->itemData(index).toInt())); + } + + void Window::selectionModeChanged(int index) + { + calendar->setSelectionMode(QCalendarWidget::SelectionMode( + selectionModeCombo->itemData(index).toInt())); + } + + void Window::horizontalHeaderChanged(int index) + { + calendar->setHorizontalHeaderFormat(QCalendarWidget::HorizontalHeaderFormat( + horizontalHeaderCombo->itemData(index).toInt())); + } + + void Window::verticalHeaderChanged(int index) + { + calendar->setVerticalHeaderFormat(QCalendarWidget::VerticalHeaderFormat( + verticalHeaderCombo->itemData(index).toInt())); + } + + void Window::selectedDateChanged() + { + currentDateEdit->setDate(calendar->selectedDate()); + } + + void Window::minimumDateChanged(const QDate &date) + { + calendar->setMinimumDate(date); + maximumDateEdit->setDate(calendar->maximumDate()); + } + + void Window::maximumDateChanged(const QDate &date) + { + calendar->setMaximumDate(date); + minimumDateEdit->setDate(calendar->minimumDate()); + } + + void Window::weekdayFormatChanged() + { + QTextCharFormat format; + + format.setForeground(qvariant_cast<QColor>( + weekdayColorCombo->itemData(weekdayColorCombo->currentIndex()))); + calendar->setWeekdayTextFormat(Qt::Monday, format); + calendar->setWeekdayTextFormat(Qt::Tuesday, format); + calendar->setWeekdayTextFormat(Qt::Wednesday, format); + calendar->setWeekdayTextFormat(Qt::Thursday, format); + calendar->setWeekdayTextFormat(Qt::Friday, format); + } + + void Window::weekendFormatChanged() + { + QTextCharFormat format; + + format.setForeground(qvariant_cast<QColor>( + weekendColorCombo->itemData(weekendColorCombo->currentIndex()))); + calendar->setWeekdayTextFormat(Qt::Saturday, format); + calendar->setWeekdayTextFormat(Qt::Sunday, format); + } + + void Window::reformatHeaders() + { + QString text = headerTextFormatCombo->currentText(); + QTextCharFormat format; + + if (text == tr("Bold")) { + format.setFontWeight(QFont::Bold); + } else if (text == tr("Italic")) { + format.setFontItalic(true); + } else if (text == tr("Green")) { + format.setForeground(Qt::green); + } + calendar->setHeaderTextFormat(format); + } + + void Window::reformatCalendarPage() + { + if (firstFridayCheckBox->isChecked()) { + QDate firstFriday(calendar->yearShown(), calendar->monthShown(), 1); + while (firstFriday.dayOfWeek() != Qt::Friday) + firstFriday = firstFriday.addDays(1); + QTextCharFormat firstFridayFormat; + firstFridayFormat.setForeground(Qt::blue); + calendar->setDateTextFormat(firstFriday, firstFridayFormat); + } + + //May First in Red takes precedence + if (mayFirstCheckBox->isChecked()) { + const QDate mayFirst(calendar->yearShown(), 5, 1); + QTextCharFormat mayFirstFormat; + mayFirstFormat.setForeground(Qt::red); + calendar->setDateTextFormat(mayFirst, mayFirstFormat); + } + } + + void Window::createPreviewGroupBox() + { + previewGroupBox = new QGroupBox(tr("Preview")); + + calendar = new QCalendarWidget; + calendar->setMinimumDate(QDate(1900, 1, 1)); + calendar->setMaximumDate(QDate(3000, 1, 1)); + calendar->setGridVisible(true); + + connect(calendar, SIGNAL(currentPageChanged(int,int)), + this, SLOT(reformatCalendarPage())); + + previewLayout = new QGridLayout; + previewLayout->addWidget(calendar, 0, 0, Qt::AlignCenter); + previewGroupBox->setLayout(previewLayout); + } + + void Window::createGeneralOptionsGroupBox() + { + generalOptionsGroupBox = new QGroupBox(tr("General Options")); + + localeCombo = new QComboBox; + int curLocaleIndex = -1; + int index = 0; + for (int _lang = QLocale::C; _lang <= QLocale::LastLanguage; ++_lang) { + QLocale::Language lang = static_cast<QLocale::Language>(_lang); + QList<QLocale::Country> countries = QLocale::countriesForLanguage(lang); + for (int i = 0; i < countries.count(); ++i) { + QLocale::Country country = countries.at(i); + QString label = QLocale::languageToString(lang); + label += QLatin1Char('/'); + label += QLocale::countryToString(country); + QLocale locale(lang, country); + if (this->locale().language() == lang && this->locale().country() == country) + curLocaleIndex = index; + localeCombo->addItem(label, locale); + ++index; + } + } + if (curLocaleIndex != -1) + localeCombo->setCurrentIndex(curLocaleIndex); + localeLabel = new QLabel(tr("&Locale")); + localeLabel->setBuddy(localeCombo); + + firstDayCombo = new QComboBox; + firstDayCombo->addItem(tr("Sunday"), Qt::Sunday); + firstDayCombo->addItem(tr("Monday"), Qt::Monday); + firstDayCombo->addItem(tr("Tuesday"), Qt::Tuesday); + firstDayCombo->addItem(tr("Wednesday"), Qt::Wednesday); + firstDayCombo->addItem(tr("Thursday"), Qt::Thursday); + firstDayCombo->addItem(tr("Friday"), Qt::Friday); + firstDayCombo->addItem(tr("Saturday"), Qt::Saturday); + + firstDayLabel = new QLabel(tr("Wee&k starts on:")); + firstDayLabel->setBuddy(firstDayCombo); + + selectionModeCombo = new QComboBox; + selectionModeCombo->addItem(tr("Single selection"), + QCalendarWidget::SingleSelection); + selectionModeCombo->addItem(tr("None"), QCalendarWidget::NoSelection); + + selectionModeLabel = new QLabel(tr("&Selection mode:")); + selectionModeLabel->setBuddy(selectionModeCombo); + + gridCheckBox = new QCheckBox(tr("&Grid")); + gridCheckBox->setChecked(calendar->isGridVisible()); + + navigationCheckBox = new QCheckBox(tr("&Navigation bar")); + navigationCheckBox->setChecked(true); + + horizontalHeaderCombo = new QComboBox; + horizontalHeaderCombo->addItem(tr("Single letter day names"), + QCalendarWidget::SingleLetterDayNames); + horizontalHeaderCombo->addItem(tr("Short day names"), + QCalendarWidget::ShortDayNames); + horizontalHeaderCombo->addItem(tr("None"), + QCalendarWidget::NoHorizontalHeader); + horizontalHeaderCombo->setCurrentIndex(1); + + horizontalHeaderLabel = new QLabel(tr("&Horizontal header:")); + horizontalHeaderLabel->setBuddy(horizontalHeaderCombo); + + verticalHeaderCombo = new QComboBox; + verticalHeaderCombo->addItem(tr("ISO week numbers"), + QCalendarWidget::ISOWeekNumbers); + verticalHeaderCombo->addItem(tr("None"), QCalendarWidget::NoVerticalHeader); + + verticalHeaderLabel = new QLabel(tr("&Vertical header:")); + verticalHeaderLabel->setBuddy(verticalHeaderCombo); + + connect(localeCombo, SIGNAL(currentIndexChanged(int)), + this, SLOT(localeChanged(int))); + connect(firstDayCombo, SIGNAL(currentIndexChanged(int)), + this, SLOT(firstDayChanged(int))); + connect(selectionModeCombo, SIGNAL(currentIndexChanged(int)), + this, SLOT(selectionModeChanged(int))); + connect(gridCheckBox, SIGNAL(toggled(bool)), + calendar, SLOT(setGridVisible(bool))); + connect(navigationCheckBox, SIGNAL(toggled(bool)), + calendar, SLOT(setNavigationBarVisible(bool))); + connect(horizontalHeaderCombo, SIGNAL(currentIndexChanged(int)), + this, SLOT(horizontalHeaderChanged(int))); + connect(verticalHeaderCombo, SIGNAL(currentIndexChanged(int)), + this, SLOT(verticalHeaderChanged(int))); + + QHBoxLayout *checkBoxLayout = new QHBoxLayout; + checkBoxLayout->addWidget(gridCheckBox); + checkBoxLayout->addStretch(); + checkBoxLayout->addWidget(navigationCheckBox); + + QGridLayout *outerLayout = new QGridLayout; + outerLayout->addWidget(localeLabel, 0, 0); + outerLayout->addWidget(localeCombo, 0, 1); + outerLayout->addWidget(firstDayLabel, 1, 0); + outerLayout->addWidget(firstDayCombo, 1, 1); + outerLayout->addWidget(selectionModeLabel, 2, 0); + outerLayout->addWidget(selectionModeCombo, 2, 1); + outerLayout->addLayout(checkBoxLayout, 3, 0, 1, 2); + outerLayout->addWidget(horizontalHeaderLabel, 4, 0); + outerLayout->addWidget(horizontalHeaderCombo, 4, 1); + outerLayout->addWidget(verticalHeaderLabel, 5, 0); + outerLayout->addWidget(verticalHeaderCombo, 5, 1); + generalOptionsGroupBox->setLayout(outerLayout); + + firstDayChanged(firstDayCombo->currentIndex()); + selectionModeChanged(selectionModeCombo->currentIndex()); + horizontalHeaderChanged(horizontalHeaderCombo->currentIndex()); + verticalHeaderChanged(verticalHeaderCombo->currentIndex()); + } + + void Window::createDatesGroupBox() + { + datesGroupBox = new QGroupBox(tr("Dates")); + + minimumDateEdit = new QDateEdit; + minimumDateEdit->setDisplayFormat("MMM d yyyy"); + minimumDateEdit->setDateRange(calendar->minimumDate(), + calendar->maximumDate()); + minimumDateEdit->setDate(calendar->minimumDate()); + + minimumDateLabel = new QLabel(tr("&Minimum Date:")); + minimumDateLabel->setBuddy(minimumDateEdit); + + currentDateEdit = new QDateEdit; + currentDateEdit->setDisplayFormat("MMM d yyyy"); + currentDateEdit->setDate(calendar->selectedDate()); + currentDateEdit->setDateRange(calendar->minimumDate(), + calendar->maximumDate()); + + currentDateLabel = new QLabel(tr("&Current Date:")); + currentDateLabel->setBuddy(currentDateEdit); + + maximumDateEdit = new QDateEdit; + maximumDateEdit->setDisplayFormat("MMM d yyyy"); + maximumDateEdit->setDateRange(calendar->minimumDate(), + calendar->maximumDate()); + maximumDateEdit->setDate(calendar->maximumDate()); + + maximumDateLabel = new QLabel(tr("Ma&ximum Date:")); + maximumDateLabel->setBuddy(maximumDateEdit); + + connect(currentDateEdit, SIGNAL(dateChanged(QDate)), + calendar, SLOT(setSelectedDate(QDate))); + connect(calendar, SIGNAL(selectionChanged()), + this, SLOT(selectedDateChanged())); + connect(minimumDateEdit, SIGNAL(dateChanged(QDate)), + this, SLOT(minimumDateChanged(QDate))); + connect(maximumDateEdit, SIGNAL(dateChanged(QDate)), + this, SLOT(maximumDateChanged(QDate))); + + QGridLayout *dateBoxLayout = new QGridLayout; + dateBoxLayout->addWidget(currentDateLabel, 1, 0); + dateBoxLayout->addWidget(currentDateEdit, 1, 1); + dateBoxLayout->addWidget(minimumDateLabel, 0, 0); + dateBoxLayout->addWidget(minimumDateEdit, 0, 1); + dateBoxLayout->addWidget(maximumDateLabel, 2, 0); + dateBoxLayout->addWidget(maximumDateEdit, 2, 1); + dateBoxLayout->setRowStretch(3, 1); + + datesGroupBox->setLayout(dateBoxLayout); + } + + void Window::createTextFormatsGroupBox() + { + textFormatsGroupBox = new QGroupBox(tr("Text Formats")); + + weekdayColorCombo = createColorComboBox(); + weekdayColorCombo->setCurrentIndex( + weekdayColorCombo->findText(tr("Black"))); + + weekdayColorLabel = new QLabel(tr("&Weekday color:")); + weekdayColorLabel->setBuddy(weekdayColorCombo); + + weekendColorCombo = createColorComboBox(); + weekendColorCombo->setCurrentIndex( + weekendColorCombo->findText(tr("Red"))); + + weekendColorLabel = new QLabel(tr("Week&end color:")); + weekendColorLabel->setBuddy(weekendColorCombo); + + headerTextFormatCombo = new QComboBox; + headerTextFormatCombo->addItem(tr("Bold")); + headerTextFormatCombo->addItem(tr("Italic")); + headerTextFormatCombo->addItem(tr("Plain")); + + headerTextFormatLabel = new QLabel(tr("&Header text:")); + headerTextFormatLabel->setBuddy(headerTextFormatCombo); + + firstFridayCheckBox = new QCheckBox(tr("&First Friday in blue")); + + mayFirstCheckBox = new QCheckBox(tr("May &1 in red")); + + connect(weekdayColorCombo, SIGNAL(currentIndexChanged(int)), + this, SLOT(weekdayFormatChanged())); + connect(weekendColorCombo, SIGNAL(currentIndexChanged(int)), + this, SLOT(weekendFormatChanged())); + connect(headerTextFormatCombo, SIGNAL(currentIndexChanged(QString)), + this, SLOT(reformatHeaders())); + connect(firstFridayCheckBox, SIGNAL(toggled(bool)), + this, SLOT(reformatCalendarPage())); + connect(mayFirstCheckBox, SIGNAL(toggled(bool)), + this, SLOT(reformatCalendarPage())); + + QHBoxLayout *checkBoxLayout = new QHBoxLayout; + checkBoxLayout->addWidget(firstFridayCheckBox); + checkBoxLayout->addStretch(); + checkBoxLayout->addWidget(mayFirstCheckBox); + + QGridLayout *outerLayout = new QGridLayout; + outerLayout->addWidget(weekdayColorLabel, 0, 0); + outerLayout->addWidget(weekdayColorCombo, 0, 1); + outerLayout->addWidget(weekendColorLabel, 1, 0); + outerLayout->addWidget(weekendColorCombo, 1, 1); + outerLayout->addWidget(headerTextFormatLabel, 2, 0); + outerLayout->addWidget(headerTextFormatCombo, 2, 1); + outerLayout->addLayout(checkBoxLayout, 3, 0, 1, 2); + textFormatsGroupBox->setLayout(outerLayout); + + weekdayFormatChanged(); + weekendFormatChanged(); + reformatHeaders(); + reformatCalendarPage(); + } + +QComboBox *Window::createColorComboBox() + { + QComboBox *comboBox = new QComboBox; + comboBox->addItem(tr("Red"), Qt::red); + comboBox->addItem(tr("Blue"), Qt::blue); + comboBox->addItem(tr("Black"), Qt::black); + comboBox->addItem(tr("Magenta"), Qt::magenta); + return comboBox; + } + +//#include "moc_calwidget.cpp" diff --git a/Tests/QtAutomoc/calwidget.h b/Tests/QtAutomoc/calwidget.h new file mode 100644 index 0000000..8447389 --- /dev/null +++ b/Tests/QtAutomoc/calwidget.h @@ -0,0 +1,121 @@ + /**************************************************************************** + ** + ** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies). + ** All rights reserved. + ** Contact: Nokia Corporation (qt-info@nokia.com) + ** + ** This file is part of the examples of the Qt Toolkit. + ** + ** $QT_BEGIN_LICENSE:BSD$ + ** You may use this file under the terms of the BSD license as follows: + ** + ** "Redistribution and use in source and binary forms, with or without + ** modification, are permitted provided that the following conditions are + ** met: + ** * Redistributions of source code must retain the above copyright + ** notice, this list of conditions and the following disclaimer. + ** * Redistributions in binary form must reproduce the above copyright + ** notice, this list of conditions and the following disclaimer in + ** the documentation and/or other materials provided with the + ** distribution. + ** * Neither the name of Nokia Corporation and its Subsidiary(-ies) nor + ** the names of its contributors may be used to endorse or promote + ** products derived from this software without specific prior written + ** permission. + ** + ** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + ** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + ** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + ** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + ** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + ** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + ** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + ** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + ** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + ** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + ** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." + ** $QT_END_LICENSE$ + ** + ****************************************************************************/ + +#ifndef WINDOW_H +#define WINDOW_H + +#include <QWidget> + + class QCalendarWidget; + class QCheckBox; + class QComboBox; + class QDate; + class QDateEdit; + class QGridLayout; + class QGroupBox; + class QLabel; + + class Window : public QWidget + { + Q_OBJECT + + public: + Window(); + + private slots: + void localeChanged(int index); + void firstDayChanged(int index); + void selectionModeChanged(int index); + void horizontalHeaderChanged(int index); + void verticalHeaderChanged(int index); + void selectedDateChanged(); + void minimumDateChanged(const QDate &date); + void maximumDateChanged(const QDate &date); + void weekdayFormatChanged(); + void weekendFormatChanged(); + void reformatHeaders(); + void reformatCalendarPage(); + + private: + void createPreviewGroupBox(); + void createGeneralOptionsGroupBox(); + void createDatesGroupBox(); + void createTextFormatsGroupBox(); + QComboBox *createColorComboBox(); + + QGroupBox *previewGroupBox; + QGridLayout *previewLayout; + QCalendarWidget *calendar; + + QGroupBox *generalOptionsGroupBox; + QLabel *localeLabel; + QLabel *firstDayLabel; + QLabel *selectionModeLabel; + QLabel *horizontalHeaderLabel; + QLabel *verticalHeaderLabel; + QComboBox *localeCombo; + QComboBox *firstDayCombo; + QComboBox *selectionModeCombo; + QCheckBox *gridCheckBox; + QCheckBox *navigationCheckBox; + QComboBox *horizontalHeaderCombo; + QComboBox *verticalHeaderCombo; + + QGroupBox *datesGroupBox; + QLabel *currentDateLabel; + QLabel *minimumDateLabel; + QLabel *maximumDateLabel; + QDateEdit *currentDateEdit; + QDateEdit *minimumDateEdit; + QDateEdit *maximumDateEdit; + + QGroupBox *textFormatsGroupBox; + QLabel *weekdayColorLabel; + QLabel *weekendColorLabel; + QLabel *headerTextFormatLabel; + QComboBox *weekdayColorCombo; + QComboBox *weekendColorCombo; + QComboBox *headerTextFormatCombo; + + QCheckBox *firstFridayCheckBox; + QCheckBox *mayFirstCheckBox; + }; + + #endif diff --git a/Tests/QtAutomoc/codeeditor.cpp b/Tests/QtAutomoc/codeeditor.cpp new file mode 100644 index 0000000..01da062 --- /dev/null +++ b/Tests/QtAutomoc/codeeditor.cpp @@ -0,0 +1,153 @@ +/**************************************************************************** + ** + ** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies). + ** All rights reserved. + ** Contact: Nokia Corporation (qt-info@nokia.com) + ** + ** This file is part of the examples of the Qt Toolkit. + ** + ** $QT_BEGIN_LICENSE:BSD$ + ** You may use this file under the terms of the BSD license as follows: + ** + ** "Redistribution and use in source and binary forms, with or without + ** modification, are permitted provided that the following conditions are + ** met: + ** * Redistributions of source code must retain the above copyright + ** notice, this list of conditions and the following disclaimer. + ** * Redistributions in binary form must reproduce the above copyright + ** notice, this list of conditions and the following disclaimer in + ** the documentation and/or other materials provided with the + ** distribution. + ** * Neither the name of Nokia Corporation and its Subsidiary(-ies) nor + ** the names of its contributors may be used to endorse or promote + ** products derived from this software without specific prior written + ** permission. + ** + ** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + ** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + ** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + ** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + ** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + ** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + ** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + ** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + ** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + ** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + ** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." + ** $QT_END_LICENSE$ + ** + ****************************************************************************/ + + #include <QtGui> + + #include "codeeditor.h" + + + CodeEditor::CodeEditor(QWidget *parent) : QPlainTextEdit(parent) + { + lineNumberArea = new LineNumberArea(this); + + connect(this, SIGNAL(blockCountChanged(int)), this, SLOT(updateLineNumberAreaWidth(int))); + connect(this, SIGNAL(updateRequest(QRect,int)), this, SLOT(updateLineNumberArea(QRect,int))); + connect(this, SIGNAL(cursorPositionChanged()), this, SLOT(highlightCurrentLine())); + + updateLineNumberAreaWidth(0); + highlightCurrentLine(); + } + + + + int CodeEditor::lineNumberAreaWidth() + { + int digits = 1; + int max = qMax(1, blockCount()); + while (max >= 10) { + max /= 10; + ++digits; + } + + int space = 3 + fontMetrics().width(QLatin1Char('9')) * digits; + + return space; + } + + + + void CodeEditor::updateLineNumberAreaWidth(int /* newBlockCount */) + { + setViewportMargins(lineNumberAreaWidth(), 0, 0, 0); + } + + + + void CodeEditor::updateLineNumberArea(const QRect &rect, int dy) + { + if (dy) + lineNumberArea->scroll(0, dy); + else + lineNumberArea->update(0, rect.y(), lineNumberArea->width(), rect.height()); + + if (rect.contains(viewport()->rect())) + updateLineNumberAreaWidth(0); + } + + + + void CodeEditor::resizeEvent(QResizeEvent *e) + { + QPlainTextEdit::resizeEvent(e); + + QRect cr = contentsRect(); + lineNumberArea->setGeometry(QRect(cr.left(), cr.top(), lineNumberAreaWidth(), cr.height())); + } + + + + void CodeEditor::highlightCurrentLine() + { + QList<QTextEdit::ExtraSelection> extraSelections; + + if (!isReadOnly()) { + QTextEdit::ExtraSelection selection; + + QColor lineColor = QColor(Qt::yellow).lighter(160); + + selection.format.setBackground(lineColor); + selection.format.setProperty(QTextFormat::FullWidthSelection, true); + selection.cursor = textCursor(); + selection.cursor.clearSelection(); + extraSelections.append(selection); + } + + setExtraSelections(extraSelections); + } + + + + void CodeEditor::lineNumberAreaPaintEvent(QPaintEvent *event) + { + QPainter painter(lineNumberArea); + painter.fillRect(event->rect(), Qt::lightGray); + + + QTextBlock block = firstVisibleBlock(); + int blockNumber = block.blockNumber(); + int top = (int) blockBoundingGeometry(block).translated(contentOffset()).top(); + int bottom = top + (int) blockBoundingRect(block).height(); + + while (block.isValid() && top <= event->rect().bottom()) { + if (block.isVisible() && bottom >= event->rect().top()) { + QString number = QString::number(blockNumber + 1); + painter.setPen(Qt::black); + painter.drawText(0, top, lineNumberArea->width(), fontMetrics().height(), + Qt::AlignRight, number); + } + + block = block.next(); + top = bottom; + bottom = top + (int) blockBoundingRect(block).height(); + ++blockNumber; + } + } + +#include "codeeditor.moc" diff --git a/Tests/QtAutomoc/codeeditor.h b/Tests/QtAutomoc/codeeditor.h new file mode 100644 index 0000000..56e9e792 --- /dev/null +++ b/Tests/QtAutomoc/codeeditor.h @@ -0,0 +1,99 @@ + /**************************************************************************** + ** + ** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies). + ** All rights reserved. + ** Contact: Nokia Corporation (qt-info@nokia.com) + ** + ** This file is part of the examples of the Qt Toolkit. + ** + ** $QT_BEGIN_LICENSE:BSD$ + ** You may use this file under the terms of the BSD license as follows: + ** + ** "Redistribution and use in source and binary forms, with or without + ** modification, are permitted provided that the following conditions are + ** met: + ** * Redistributions of source code must retain the above copyright + ** notice, this list of conditions and the following disclaimer. + ** * Redistributions in binary form must reproduce the above copyright + ** notice, this list of conditions and the following disclaimer in + ** the documentation and/or other materials provided with the + ** distribution. + ** * Neither the name of Nokia Corporation and its Subsidiary(-ies) nor + ** the names of its contributors may be used to endorse or promote + ** products derived from this software without specific prior written + ** permission. + ** + ** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + ** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + ** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + ** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + ** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + ** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + ** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + ** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + ** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + ** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + ** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." + ** $QT_END_LICENSE$ + ** + ****************************************************************************/ + + #ifndef CODEEDITOR_H + #define CODEEDITOR_H + + #include <QPlainTextEdit> + #include <QObject> + + class QPaintEvent; + class QResizeEvent; + class QSize; + class QWidget; + + class LineNumberArea; + + + class CodeEditor : public QPlainTextEdit + { + Q_OBJECT + + public: + CodeEditor(QWidget *parent = 0); + + void lineNumberAreaPaintEvent(QPaintEvent *event); + int lineNumberAreaWidth(); + + protected: + void resizeEvent(QResizeEvent *event); + + private slots: + void updateLineNumberAreaWidth(int newBlockCount); + void highlightCurrentLine(); + void updateLineNumberArea(const QRect &, int); + + private: + QWidget *lineNumberArea; + }; + + + class LineNumberArea : public QWidget + { + public: + LineNumberArea(CodeEditor *editor) : QWidget(editor) { + codeEditor = editor; + } + + QSize sizeHint() const { + return QSize(codeEditor->lineNumberAreaWidth(), 0); + } + + protected: + void paintEvent(QPaintEvent *event) { + codeEditor->lineNumberAreaPaintEvent(event); + } + + private: + CodeEditor *codeEditor; + }; + + + #endif diff --git a/Tests/QtAutomoc/main.cpp b/Tests/QtAutomoc/main.cpp new file mode 100644 index 0000000..7bf4a5d --- /dev/null +++ b/Tests/QtAutomoc/main.cpp @@ -0,0 +1,58 @@ +/**************************************************************************** + ** + ** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies). + ** All rights reserved. + ** Contact: Nokia Corporation (qt-info@nokia.com) + ** + ** This file is part of the examples of the Qt Toolkit. + ** + ** $QT_BEGIN_LICENSE:BSD$ + ** You may use this file under the terms of the BSD license as follows: + ** + ** "Redistribution and use in source and binary forms, with or without + ** modification, are permitted provided that the following conditions are + ** met: + ** * Redistributions of source code must retain the above copyright + ** notice, this list of conditions and the following disclaimer. + ** * Redistributions in binary form must reproduce the above copyright + ** notice, this list of conditions and the following disclaimer in + ** the documentation and/or other materials provided with the + ** distribution. + ** * Neither the name of Nokia Corporation and its Subsidiary(-ies) nor + ** the names of its contributors may be used to endorse or promote + ** products derived from this software without specific prior written + ** permission. + ** + ** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + ** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + ** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + ** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + ** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + ** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + ** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + ** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + ** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + ** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + ** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." + ** $QT_END_LICENSE$ + ** + ****************************************************************************/ + +#include <QtGui> + +#include "codeeditor.h" +#include "calwidget.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(); + + return app.exec(); +} diff --git a/Utilities/CMakeLists.txt b/Utilities/CMakeLists.txt index 8b3e7f6..85db367 100644 --- a/Utilities/CMakeLists.txt +++ b/Utilities/CMakeLists.txt @@ -126,6 +126,7 @@ ADD_CUSTOM_COMMAND( INSTALL_FILES(${CMAKE_MAN_DIR}/man1 FILES ${MAN_FILES}) INSTALL_FILES(${CMAKE_DOC_DIR} FILES ${HTML_FILES} ${TEXT_FILES}) +INSTALL_FILES(share/aclocal FILES cmake.m4) # Drive documentation generation. ADD_CUSTOM_TARGET(documentation ALL DEPENDS ${DOC_FILES} ${CMake_BINARY_DIR}/Docs/cmake.txt ) diff --git a/Utilities/cmake.m4 b/Utilities/cmake.m4 new file mode 100644 index 0000000..a374a3b --- /dev/null +++ b/Utilities/cmake.m4 @@ -0,0 +1,53 @@ +dnl ============================================================================ +dnl CMake - Cross Platform Makefile Generator +dnl Copyright 2011 Matthias Kretz, kretz@kde.org +dnl +dnl Distributed under the OSI-approved BSD License (the "License"); +dnl see accompanying file Copyright.txt for details. +dnl +dnl This software is distributed WITHOUT ANY WARRANTY; without even the +dnl implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. +dnl See the License for more information. +dnl ============================================================================ + +AC_DEFUN([CMAKE_FIND_BINARY], +[AC_ARG_VAR([CMAKE_BINARY], [path to the cmake binary])dnl + +if test "x$ac_cv_env_CMAKE_BINARY_set" != "xset"; then + AC_PATH_TOOL([CMAKE_BINARY], [cmake])dnl +fi +])dnl + +# $1: package name +# $2: language (e.g. C/CXX/Fortran) +# $3: The compiler ID, defaults to GNU. +# Possible values are: GNU, Intel, Clang, SunPro, HP, XL, VisualAge, PGI, +# PathScale, Cray, SCO, MIPSpro, MSVC +# $4: optional extra arguments to cmake, e.g. "-DCMAKE_SIZEOF_VOID_P=8" +# $5: optional path to cmake binary +AC_DEFUN([CMAKE_FIND_PACKAGE], [ +AC_REQUIRE([CMAKE_FIND_BINARY])dnl + +AC_ARG_VAR([$1][_][$2][FLAGS], [$2 compiler flags for $1. This overrides the cmake output])dnl +AC_ARG_VAR([$1][_LIBS], [linker flags for $1. This overrides the cmake output])dnl + +failed=false +AC_MSG_CHECKING([for $1]) +if test -n "$1[]_$2[]FLAGS"; then + $1[]_$2[]FLAGS=`$CMAKE_BINARY --find-package "-DNAME=$1" "-DCOMPILER_ID=m4_default([$3], [GNU])" "-DLANGUAGE=$2" -DMODE=COMPILE $4` || failed=true +fi +if test -n "$1[]_LIBS"; then + $1[]_LIBS=`$CMAKE_BINARY --find-package "-DNAME=$1" "-DCOMPILER_ID=m4_default([$3], [GNU])" "-DLANGUAGE=$2" -DMODE=LINK $4` || failed=true +fi + +if $failed; then + unset $1[]_$2[]FLAGS + unset $1[]_LIBS + + AC_MSG_RESULT([no]) + $6 +else + AC_MSG_RESULT([yes]) + $5 +fi[]dnl +]) |