diff options
118 files changed, 1699 insertions, 693 deletions
diff --git a/Modules/CMakeDetermineASM-ATTCompiler.cmake b/Modules/CMakeDetermineASM-ATTCompiler.cmake index cec09e9..03c5668 100644 --- a/Modules/CMakeDetermineASM-ATTCompiler.cmake +++ b/Modules/CMakeDetermineASM-ATTCompiler.cmake @@ -15,6 +15,6 @@ # determine the compiler to use for ASM using AT&T syntax, e.g. GNU as set(ASM_DIALECT "-ATT") -set(CMAKE_ASM${ASM_DIALECT}_COMPILER_INIT ${_CMAKE_TOOLCHAIN_PREFIX}gas ${_CMAKE_TOOLCHAIN_PREFIX}as) +set(CMAKE_ASM${ASM_DIALECT}_COMPILER_LIST ${_CMAKE_TOOLCHAIN_PREFIX}gas ${_CMAKE_TOOLCHAIN_PREFIX}as) include(CMakeDetermineASMCompiler) set(ASM_DIALECT) diff --git a/Modules/CMakeDetermineASMCompiler.cmake b/Modules/CMakeDetermineASMCompiler.cmake index 3643b17..0fecb5d 100644 --- a/Modules/CMakeDetermineASMCompiler.cmake +++ b/Modules/CMakeDetermineASMCompiler.cmake @@ -39,8 +39,8 @@ if(NOT CMAKE_ASM${ASM_DIALECT}_COMPILER) endif() endif() else() # some specific assembler "dialect" - if(NOT CMAKE_ASM${ASM_DIALECT}_COMPILER_INIT) - message(FATAL_ERROR "CMAKE_ASM${ASM_DIALECT}_COMPILER_INIT must be preset !") + if(NOT CMAKE_ASM${ASM_DIALECT}_COMPILER_INIT AND NOT CMAKE_ASM${ASM_DIALECT}_COMPILER_LIST) + message(FATAL_ERROR "CMAKE_ASM${ASM_DIALECT}_COMPILER_INIT or CMAKE_ASM${ASM_DIALECT}_COMPILER_LIST must be preset !") endif() endif() diff --git a/Modules/CMakeDetermineASM_NASMCompiler.cmake b/Modules/CMakeDetermineASM_NASMCompiler.cmake index 50f71dd..5d783b1 100644 --- a/Modules/CMakeDetermineASM_NASMCompiler.cmake +++ b/Modules/CMakeDetermineASM_NASMCompiler.cmake @@ -14,7 +14,7 @@ # Find the nasm assembler. yasm (http://www.tortall.net/projects/yasm/) is nasm compatible -set(CMAKE_ASM_NASM_COMPILER_INIT nasm yasm) +set(CMAKE_ASM_NASM_COMPILER_LIST nasm yasm) if(NOT CMAKE_ASM_NASM_COMPILER) find_program(CMAKE_ASM_NASM_COMPILER nasm diff --git a/Modules/CMakeDetermineCompilerABI.cmake b/Modules/CMakeDetermineCompilerABI.cmake index 25d6bbe..44cc04a 100644 --- a/Modules/CMakeDetermineCompilerABI.cmake +++ b/Modules/CMakeDetermineCompilerABI.cmake @@ -28,6 +28,9 @@ function(CMAKE_DETERMINE_COMPILER_ABI lang src) if(DEFINED CMAKE_${lang}_VERBOSE_FLAG) set(CMAKE_FLAGS "-DCMAKE_EXE_LINKER_FLAGS=${CMAKE_${lang}_VERBOSE_FLAG}") endif() + if(CMAKE_${lang}_COMPILER_TARGET) + set(CMAKE_FLAGS "${CMAKE_FLAGS} -DCMAKE_${lang}_COMPILER_TARGET=${CMAKE_${lang}_COMPILER_TARGET}") + endif() try_compile(CMAKE_${lang}_ABI_COMPILED ${CMAKE_BINARY_DIR} ${src} CMAKE_FLAGS "${CMAKE_FLAGS}" diff --git a/Modules/CMakeDetermineVSServicePack.cmake b/Modules/CMakeDetermineVSServicePack.cmake index 98e5bb8..17b4bbf 100644 --- a/Modules/CMakeDetermineVSServicePack.cmake +++ b/Modules/CMakeDetermineVSServicePack.cmake @@ -1,32 +1,25 @@ -# - Includes a public function for assisting users in trying to determine the -# Visual Studio service pack in use. -# -# Sets the passed in variable to one of the following values or an empty -# string if unknown. -# vc80 -# vc80sp1 -# vc90 -# vc90sp1 -# vc100 -# vc100sp1 -# vc110 +# - Determine the Visual Studio service pack of the 'cl' in use. +# The functionality of this module has been superseded by the platform +# variable CMAKE_<LANG>_COMPILER_VERSION that contains the compiler version +# number. # # Usage: -# =========================== -# -# if(MSVC) -# include(CMakeDetermineVSServicePack) -# DetermineVSServicePack( my_service_pack ) -# -# if( my_service_pack ) -# message(STATUS "Detected: ${my_service_pack}") -# endif() +# if(MSVC) +# include(CMakeDetermineVSServicePack) +# DetermineVSServicePack( my_service_pack ) +# if( my_service_pack ) +# message(STATUS "Detected: ${my_service_pack}") # endif() -# -# =========================== +# endif() +# Function DetermineVSServicePack sets the given variable to one of the +# following values or an empty string if unknown: +# vc80, vc80sp1 +# vc90, vc90sp1 +# vc100, vc100sp1 +# vc110, vc110sp1, vc110sp2 #============================================================================= -# Copyright 2009-2011 Kitware, Inc. +# Copyright 2009-2013 Kitware, Inc. # Copyright 2009-2010 Philip Lowman <philip@yhbt.com> # Copyright 2010-2011 Aaron C. meadows <cmake@shadowguarddev.com> # @@ -57,6 +50,10 @@ function(_DetermineVSServicePackFromCompiler _OUT_VAR _cl_version) set(_version "vc100sp1") elseif(${_cl_version} VERSION_EQUAL "17.00.50727.1") set(_version "vc110") + elseif(${_cl_version} VERSION_EQUAL "17.00.51106.1") + set(_version "vc110sp1") + elseif(${_cl_version} VERSION_EQUAL "17.00.60315.1") + set(_version "vc110sp2") else() set(_version "") endif() diff --git a/Modules/Compiler/Clang.cmake b/Modules/Compiler/Clang.cmake index ec4562a..66b00bd 100644 --- a/Modules/Compiler/Clang.cmake +++ b/Modules/Compiler/Clang.cmake @@ -25,4 +25,5 @@ macro(__compiler_clang lang) set(CMAKE_${lang}_COMPILE_OPTIONS_PIE "-fPIE") set(CMAKE_INCLUDE_SYSTEM_FLAG_${lang} "-isystem ") set(CMAKE_${lang}_COMPILE_OPTIONS_VISIBILITY "-fvisibility=") + set(CMAKE_${lang}_COMPILE_OPTION_TARGET "-target ") endmacro() diff --git a/Modules/Compiler/GNU.cmake b/Modules/Compiler/GNU.cmake index 504704d..e5e10c3 100644 --- a/Modules/Compiler/GNU.cmake +++ b/Modules/Compiler/GNU.cmake @@ -30,6 +30,7 @@ macro(__compiler_gnu lang) endif() set(CMAKE_SHARED_LIBRARY_${lang}_FLAGS "-fPIC") set(CMAKE_SHARED_LIBRARY_CREATE_${lang}_FLAGS "-shared") + set(CMAKE_SYSROOT_FLAG "--sysroot=") # Older versions of gcc (< 4.5) contain a bug causing them to report a missing # header file as a warning if depfiles are enabled, causing check_header_file diff --git a/Modules/FindBoost.cmake b/Modules/FindBoost.cmake index d1ce2f4..4cc32be 100644 --- a/Modules/FindBoost.cmake +++ b/Modules/FindBoost.cmake @@ -1020,7 +1020,12 @@ if(Boost_FOUND) # We were unable to find some libraries, so generate a sensible # error message that lists the libraries we were unable to find. set(Boost_ERROR_REASON - "${Boost_ERROR_REASON}\nThe following Boost libraries could not be found:\n") + "${Boost_ERROR_REASON}\nCould not find the following") + if(Boost_USE_STATIC_LIBS) + set(Boost_ERROR_REASON "${Boost_ERROR_REASON} static") + endif() + set(Boost_ERROR_REASON + "${Boost_ERROR_REASON} Boost libraries:\n") foreach(COMPONENT ${_Boost_MISSING_COMPONENTS}) set(Boost_ERROR_REASON "${Boost_ERROR_REASON} boost_${COMPONENT}\n") diff --git a/Modules/FindFreetype.cmake b/Modules/FindFreetype.cmake index 1df2399..ccea991 100644 --- a/Modules/FindFreetype.cmake +++ b/Modules/FindFreetype.cmake @@ -50,6 +50,9 @@ find_path(FREETYPE_INCLUDE_DIR_ft2build ft2build.h /usr/local/X11R6 /usr/local/X11 /usr/freeware + ENV GTKMM_BASEPATH + [HKEY_CURRENT_USER\\SOFTWARE\\gtkmm\\2.4;Path] + [HKEY_LOCAL_MACHINE\\SOFTWARE\\gtkmm\\2.4;Path] PATH_SUFFIXES include/freetype2 include ) @@ -61,6 +64,9 @@ find_path(FREETYPE_INCLUDE_DIR_freetype2 freetype/config/ftheader.h /usr/local/X11R6 /usr/local/X11 /usr/freeware + ENV GTKMM_BASEPATH + [HKEY_CURRENT_USER\\SOFTWARE\\gtkmm\\2.4;Path] + [HKEY_LOCAL_MACHINE\\SOFTWARE\\gtkmm\\2.4;Path] PATH_SUFFIXES include/freetype2 include ) @@ -70,10 +76,13 @@ find_library(FREETYPE_LIBRARY ENV FREETYPE_DIR PATH_SUFFIXES lib PATHS - /usr/X11R6 - /usr/local/X11R6 - /usr/local/X11 - /usr/freeware + /usr/X11R6 + /usr/local/X11R6 + /usr/local/X11 + /usr/freeware + ENV GTKMM_BASEPATH + [HKEY_CURRENT_USER\\SOFTWARE\\gtkmm\\2.4;Path] + [HKEY_LOCAL_MACHINE\\SOFTWARE\\gtkmm\\2.4;Path] ) # set the user variables diff --git a/Modules/FindGTK2.cmake b/Modules/FindGTK2.cmake index 06cf962..f398c79 100644 --- a/Modules/FindGTK2.cmake +++ b/Modules/FindGTK2.cmake @@ -164,6 +164,7 @@ function(_GTK2_FIND_INCLUDE_DIR _var _hdr) cairo cairomm-1.0 gdk-pixbuf-2.0 + gthread-2.0 gdkmm-2.4 giomm-2.4 gtk-2.0 @@ -460,9 +461,13 @@ foreach(_GTK2_component ${GTK2_FIND_COMPONENTS}) _GTK2_FIND_INCLUDE_DIR(GTK2_PANGO_INCLUDE_DIR pango/pango.h) _GTK2_FIND_LIBRARY (GTK2_PANGO_LIBRARY pango false true) + _GTK2_FIND_LIBRARY (GTK2_PANGOCAIRO_LIBRARY pangocairo false true) + _GTK2_FIND_INCLUDE_DIR(GTK2_GDK_PIXBUF_INCLUDE_DIR gdk-pixbuf/gdk-pixbuf.h) _GTK2_FIND_LIBRARY (GTK2_GDK_PIXBUF_LIBRARY gdk_pixbuf false true) + _GTK2_FIND_LIBRARY (GTK2_GTHREAD_LIBRARY gthread false true) + _GTK2_FIND_LIBRARY (GTK2_GIO_LIBRARY gio false true) _GTK2_FIND_INCLUDE_DIR(GTK2_ATK_INCLUDE_DIR atk/atk.h) @@ -489,8 +494,6 @@ foreach(_GTK2_component ${GTK2_FIND_COMPONENTS}) _GTK2_FIND_INCLUDE_DIR(GTK2_PANGOMMCONFIG_INCLUDE_DIR pangommconfig.h) _GTK2_FIND_LIBRARY (GTK2_PANGOMM_LIBRARY pangomm true true) - _GTK2_FIND_LIBRARY (GTK2_PANGOCAIRO_LIBRARY pangocairo true true) - _GTK2_FIND_INCLUDE_DIR(GTK2_CAIROMM_INCLUDE_DIR cairomm/cairomm.h) _GTK2_FIND_INCLUDE_DIR(GTK2_CAIROMMCONFIG_INCLUDE_DIR cairommconfig.h) _GTK2_FIND_LIBRARY (GTK2_CAIROMM_LIBRARY cairomm true true) diff --git a/Modules/FindX11.cmake b/Modules/FindX11.cmake index 3cd3cef..131d979 100644 --- a/Modules/FindX11.cmake +++ b/Modules/FindX11.cmake @@ -68,6 +68,7 @@ if (UNIX) /usr/openwin/include /usr/openwin/share/include /opt/graphics/OpenGL/include + /opt/X11/include ) set(X11_LIB_SEARCH_PATH @@ -75,6 +76,7 @@ if (UNIX) /usr/X11R6/lib /usr/X11R7/lib /usr/openwin/lib + /opt/X11/lib ) find_path(X11_X11_INCLUDE_PATH X11/X.h ${X11_INC_SEARCH_PATH}) diff --git a/Modules/Platform/QNX.cmake b/Modules/Platform/QNX.cmake index 2598411..315f721 100644 --- a/Modules/Platform/QNX.cmake +++ b/Modules/Platform/QNX.cmake @@ -13,6 +13,9 @@ set(CMAKE_SHARED_LIBRARY_RUNTIME_C_FLAG_SEP ":") set(CMAKE_SHARED_LIBRARY_RPATH_LINK_C_FLAG "-Wl,-rpath-link,") set(CMAKE_SHARED_LIBRARY_SONAME_C_FLAG "-Wl,-soname,") set(CMAKE_EXE_EXPORTS_C_FLAG "-Wl,--export-dynamic") +# http://www.qnx.com/developers/docs/6.4.0/neutrino/utilities/q/qcc.html#examples +set(CMAKE_C_COMPILE_OPTION_TARGET "-V") +set(CMAKE_CXX_COMPILE_OPTION_TARGET "-V") # Shared libraries with no builtin soname may not be linked safely by # specifying the file path. diff --git a/Modules/Platform/Windows-Embarcadero.cmake b/Modules/Platform/Windows-Embarcadero.cmake index 307230e..26b3c0c 100644 --- a/Modules/Platform/Windows-Embarcadero.cmake +++ b/Modules/Platform/Windows-Embarcadero.cmake @@ -78,23 +78,24 @@ set (CMAKE_MODULE_LINKER_FLAGS_RELWITHDEBINFO_INIT ${CMAKE_SHARED_LINKER_FLAGS_R macro(__embarcadero_language lang) set(CMAKE_${lang}_COMPILE_OPTIONS_DLL "${_tD}") # Note: This variable is a ';' separated list set(CMAKE_SHARED_LIBRARY_${lang}_FLAGS "${_tD}") # ... while this is a space separated string. + set(CMAKE_${lang}_USE_RESPONSE_FILE_FOR_INCLUDES 1) # compile a source file into an object file # place <DEFINES> outside the response file because Borland refuses # to parse quotes from the response file. set(CMAKE_${lang}_COMPILE_OBJECT - "<CMAKE_${lang}_COMPILER> ${_tR} <DEFINES> ${CMAKE_START_TEMP_FILE}-DWIN32 -o<OBJECT> <FLAGS> ${_COMPILE_${lang}} <SOURCE>${CMAKE_END_TEMP_FILE}" + "<CMAKE_${lang}_COMPILER> ${_tR} <DEFINES> -DWIN32 -o<OBJECT> <FLAGS> ${_COMPILE_${lang}} <SOURCE>" ) set(CMAKE_${lang}_LINK_EXECUTABLE - "<CMAKE_${lang}_COMPILER> ${_tR} -e<TARGET> ${CMAKE_START_TEMP_FILE}<LINK_FLAGS> <FLAGS> <LINK_LIBRARIES> <OBJECTS>${CMAKE_END_TEMP_FILE}" + "<CMAKE_${lang}_COMPILER> ${_tR} -e<TARGET> <LINK_FLAGS> <FLAGS> ${CMAKE_START_TEMP_FILE} <LINK_LIBRARIES> <OBJECTS>${CMAKE_END_TEMP_FILE}" # "implib -c -w <TARGET_IMPLIB> <TARGET>" ) # place <DEFINES> outside the response file because Borland refuses # to parse quotes from the response file. set(CMAKE_${lang}_CREATE_PREPROCESSED_SOURCE - "cpp32 <DEFINES> ${CMAKE_START_TEMP_FILE}-DWIN32 <FLAGS> -o<PREPROCESSED_SOURCE> ${_COMPILE_${lang}} <SOURCE>${CMAKE_END_TEMP_FILE}" + "cpp32 <DEFINES> -DWIN32 <FLAGS> -o<PREPROCESSED_SOURCE> ${_COMPILE_${lang}} <SOURCE>" ) # Borland >= 5.6 allows -P option for cpp32, <= 5.5 does not diff --git a/Modules/UseJava.cmake b/Modules/UseJava.cmake index 9c23127..0242b24 100644 --- a/Modules/UseJava.cmake +++ b/Modules/UseJava.cmake @@ -221,6 +221,13 @@ set(_JAVA_SYMLINK_SCRIPT ${CMAKE_CURRENT_LIST_DIR}/UseJavaSymlinks.cmake) function(add_jar _TARGET_NAME) + # In CMake < 2.8.12, add_jar used variables which were set prior to calling + # add_jar for customizing the behavior of add_jar. In order to be backwards + # compatible, check if any of those variables are set, and use them to + # initialize values of the named arguments. (Giving the corresponding named + # argument will override the value set here.) + # + # New features should use named arguments only. if(DEFINED CMAKE_JAVA_TARGET_VERSION) set(_add_jar_VERSION "${CMAKE_JAVA_TARGET_VERSION}") endif() diff --git a/Source/CMakeLists.txt b/Source/CMakeLists.txt index 1893167..70d4b48 100644 --- a/Source/CMakeLists.txt +++ b/Source/CMakeLists.txt @@ -11,7 +11,11 @@ #============================================================================= include(CheckIncludeFile) # Check if we can build support for ELF parsing. -CHECK_INCLUDE_FILE("elf.h" HAVE_ELF_H) +if(CMAKE_CXX_PLATFORM_ID MATCHES "OpenBSD") + CHECK_INCLUDE_FILES("stdint.h;elf_abi.h" HAVE_ELF_H) +else() + CHECK_INCLUDE_FILE("elf.h" HAVE_ELF_H) +endif() if(HAVE_ELF_H) set(CMAKE_USE_ELF_PARSER 1) else() @@ -113,7 +117,8 @@ endif() set(SRCS cmStandardIncludes.cxx cmArchiveWrite.cxx - cmBootstrapCommands.cxx + cmBootstrapCommands1.cxx + cmBootstrapCommands2.cxx cmCacheManager.cxx cmCacheManager.h cmCommands.cxx diff --git a/Source/CMakeVersion.cmake b/Source/CMakeVersion.cmake index d06c9d8..ed7eafd 100644 --- a/Source/CMakeVersion.cmake +++ b/Source/CMakeVersion.cmake @@ -2,5 +2,5 @@ set(CMake_VERSION_MAJOR 2) set(CMake_VERSION_MINOR 8) set(CMake_VERSION_PATCH 11) -set(CMake_VERSION_TWEAK 20130610) +set(CMake_VERSION_TWEAK 20130701) #set(CMake_VERSION_RC 1) diff --git a/Source/cmBootstrapCommands1.cxx b/Source/cmBootstrapCommands1.cxx new file mode 100644 index 0000000..9093579 --- /dev/null +++ b/Source/cmBootstrapCommands1.cxx @@ -0,0 +1,91 @@ +/*============================================================================ + CMake - Cross Platform Makefile Generator + Copyright 2000-2009 Kitware, Inc., Insight Software Consortium + + 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. +============================================================================*/ +// This file is used to compile all the commands +// that CMake knows about at compile time. +// This is sort of a boot strapping approach since you would +// like to have CMake to build CMake. +#include "cmCommands.h" +#include "cmAddCustomCommandCommand.cxx" +#include "cmAddCustomTargetCommand.cxx" +#include "cmAddDefinitionsCommand.cxx" +#include "cmAddDependenciesCommand.cxx" +#include "cmAddExecutableCommand.cxx" +#include "cmAddLibraryCommand.cxx" +#include "cmAddSubDirectoryCommand.cxx" +#include "cmAddTestCommand.cxx" +#include "cmBreakCommand.cxx" +#include "cmBuildCommand.cxx" +#include "cmCMakeMinimumRequired.cxx" +#include "cmCMakePolicyCommand.cxx" +#include "cmCommandArgumentsHelper.cxx" +#include "cmConfigureFileCommand.cxx" +#include "cmCoreTryCompile.cxx" +#include "cmCreateTestSourceList.cxx" +#include "cmDefinePropertyCommand.cxx" +#include "cmElseCommand.cxx" +#include "cmEnableLanguageCommand.cxx" +#include "cmEnableTestingCommand.cxx" +#include "cmEndForEachCommand.cxx" +#include "cmEndFunctionCommand.cxx" +#include "cmEndIfCommand.cxx" +#include "cmEndMacroCommand.cxx" +#include "cmEndWhileCommand.cxx" +#include "cmExecProgramCommand.cxx" +#include "cmExecuteProcessCommand.cxx" +#include "cmExternalMakefileProjectGenerator.cxx" +#include "cmFindBase.cxx" +#include "cmFindCommon.cxx" +#include "cmFileCommand.cxx" +#include "cmFindFileCommand.cxx" +#include "cmFindLibraryCommand.cxx" +#include "cmFindPackageCommand.cxx" +#include "cmFindPathCommand.cxx" +#include "cmFindProgramCommand.cxx" +#include "cmForEachCommand.cxx" +#include "cmFunctionCommand.cxx" + +void GetBootstrapCommands1(std::list<cmCommand*>& commands) +{ + commands.push_back(new cmAddCustomCommandCommand); + commands.push_back(new cmAddCustomTargetCommand); + commands.push_back(new cmAddDefinitionsCommand); + commands.push_back(new cmAddDependenciesCommand); + commands.push_back(new cmAddExecutableCommand); + commands.push_back(new cmAddLibraryCommand); + commands.push_back(new cmAddSubDirectoryCommand); + commands.push_back(new cmAddTestCommand); + commands.push_back(new cmBreakCommand); + commands.push_back(new cmBuildCommand); + commands.push_back(new cmCMakeMinimumRequired); + commands.push_back(new cmCMakePolicyCommand); + commands.push_back(new cmConfigureFileCommand); + commands.push_back(new cmCreateTestSourceList); + commands.push_back(new cmDefinePropertyCommand); + commands.push_back(new cmElseCommand); + commands.push_back(new cmEnableLanguageCommand); + commands.push_back(new cmEnableTestingCommand); + commands.push_back(new cmEndForEachCommand); + commands.push_back(new cmEndFunctionCommand); + commands.push_back(new cmEndIfCommand); + commands.push_back(new cmEndMacroCommand); + commands.push_back(new cmEndWhileCommand); + commands.push_back(new cmExecProgramCommand); + commands.push_back(new cmExecuteProcessCommand); + commands.push_back(new cmFileCommand); + commands.push_back(new cmFindFileCommand); + commands.push_back(new cmFindLibraryCommand); + commands.push_back(new cmFindPackageCommand); + commands.push_back(new cmFindPathCommand); + commands.push_back(new cmFindProgramCommand); + commands.push_back(new cmForEachCommand); + commands.push_back(new cmFunctionCommand); +} diff --git a/Source/cmBootstrapCommands.cxx b/Source/cmBootstrapCommands2.cxx index 1b7a751..be72526 100644 --- a/Source/cmBootstrapCommands.cxx +++ b/Source/cmBootstrapCommands2.cxx @@ -14,44 +14,6 @@ // This is sort of a boot strapping approach since you would // like to have CMake to build CMake. #include "cmCommands.h" -#include "cmAddCustomCommandCommand.cxx" -#include "cmAddCustomTargetCommand.cxx" -#include "cmAddDefinitionsCommand.cxx" -#include "cmAddDependenciesCommand.cxx" -#include "cmAddExecutableCommand.cxx" -#include "cmAddLibraryCommand.cxx" -#include "cmAddSubDirectoryCommand.cxx" -#include "cmAddTestCommand.cxx" -#include "cmBreakCommand.cxx" -#include "cmBuildCommand.cxx" -#include "cmCMakeMinimumRequired.cxx" -#include "cmCMakePolicyCommand.cxx" -#include "cmCommandArgumentsHelper.cxx" -#include "cmConfigureFileCommand.cxx" -#include "cmCoreTryCompile.cxx" -#include "cmCreateTestSourceList.cxx" -#include "cmDefinePropertyCommand.cxx" -#include "cmElseCommand.cxx" -#include "cmEnableLanguageCommand.cxx" -#include "cmEnableTestingCommand.cxx" -#include "cmEndForEachCommand.cxx" -#include "cmEndFunctionCommand.cxx" -#include "cmEndIfCommand.cxx" -#include "cmEndMacroCommand.cxx" -#include "cmEndWhileCommand.cxx" -#include "cmExecProgramCommand.cxx" -#include "cmExecuteProcessCommand.cxx" -#include "cmExternalMakefileProjectGenerator.cxx" -#include "cmFindBase.cxx" -#include "cmFindCommon.cxx" -#include "cmFileCommand.cxx" -#include "cmFindFileCommand.cxx" -#include "cmFindLibraryCommand.cxx" -#include "cmFindPackageCommand.cxx" -#include "cmFindPathCommand.cxx" -#include "cmFindProgramCommand.cxx" -#include "cmForEachCommand.cxx" -#include "cmFunctionCommand.cxx" #include "cmGeneratorExpressionEvaluationFile.cxx" #include "cmGetCMakePropertyCommand.cxx" #include "cmGetDirectoryPropertyCommand.cxx" @@ -96,41 +58,8 @@ #include "cmUnsetCommand.cxx" #include "cmWhileCommand.cxx" -void GetBootstrapCommands(std::list<cmCommand*>& commands) +void GetBootstrapCommands2(std::list<cmCommand*>& commands) { - commands.push_back(new cmAddCustomCommandCommand); - commands.push_back(new cmAddCustomTargetCommand); - commands.push_back(new cmAddDefinitionsCommand); - commands.push_back(new cmAddDependenciesCommand); - commands.push_back(new cmAddExecutableCommand); - commands.push_back(new cmAddLibraryCommand); - commands.push_back(new cmAddSubDirectoryCommand); - commands.push_back(new cmAddTestCommand); - commands.push_back(new cmBreakCommand); - commands.push_back(new cmBuildCommand); - commands.push_back(new cmCMakeMinimumRequired); - commands.push_back(new cmCMakePolicyCommand); - commands.push_back(new cmConfigureFileCommand); - commands.push_back(new cmCreateTestSourceList); - commands.push_back(new cmDefinePropertyCommand); - commands.push_back(new cmElseCommand); - commands.push_back(new cmEnableLanguageCommand); - commands.push_back(new cmEnableTestingCommand); - commands.push_back(new cmEndForEachCommand); - commands.push_back(new cmEndFunctionCommand); - commands.push_back(new cmEndIfCommand); - commands.push_back(new cmEndMacroCommand); - commands.push_back(new cmEndWhileCommand); - commands.push_back(new cmExecProgramCommand); - commands.push_back(new cmExecuteProcessCommand); - commands.push_back(new cmFileCommand); - commands.push_back(new cmFindFileCommand); - commands.push_back(new cmFindLibraryCommand); - commands.push_back(new cmFindPackageCommand); - commands.push_back(new cmFindPathCommand); - commands.push_back(new cmFindProgramCommand); - commands.push_back(new cmForEachCommand); - commands.push_back(new cmFunctionCommand); commands.push_back(new cmGetCMakePropertyCommand); commands.push_back(new cmGetDirectoryPropertyCommand); commands.push_back(new cmGetFilenameComponentCommand); diff --git a/Source/cmCMakeHostSystemInformationCommand.cxx b/Source/cmCMakeHostSystemInformationCommand.cxx new file mode 100644 index 0000000..62f2383 --- /dev/null +++ b/Source/cmCMakeHostSystemInformationCommand.cxx @@ -0,0 +1,126 @@ +/*============================================================================ + CMake - Cross Platform Makefile Generator + Copyright 2013 Kitware, Inc., Insight Software Consortium + + 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. +============================================================================*/ +#include "cmCMakeHostSystemInformationCommand.h" + +#include <cmsys/ios/sstream> + +// cmCMakeHostSystemInformation +bool cmCMakeHostSystemInformationCommand +::InitialPass(std::vector<std::string> const &args, cmExecutionStatus &) +{ + size_t current_index = 0; + + if(args.size() < (current_index + 2) || args[current_index] != "RESULT") + { + this->SetError("missing RESULT specification."); + return false; + } + + std::string variable = args[current_index + 1]; + current_index += 2; + + if(args.size() < (current_index + 2) || args[current_index] != "QUERY") + { + this->SetError("missing QUERY specification"); + return false; + } + + cmsys::SystemInformation info; + info.RunCPUCheck(); + info.RunOSCheck(); + info.RunMemoryCheck(); + + std::string result_list; + for(size_t i = current_index + 1; i < args.size(); ++i) + { + std::string key = args[i]; + if(i != current_index + 1) + { + result_list += ";"; + } + std::string value; + if(!this->GetValue(info, key, value)) return false; + + result_list += value; + } + + this->Makefile->AddDefinition(variable.c_str(), result_list.c_str()); + + return true; +} + +bool cmCMakeHostSystemInformationCommand +::GetValue(cmsys::SystemInformation &info, + std::string const& key, std::string &value) +{ + if(key == "NUMBER_OF_LOGICAL_CORES") + { + value = this->ValueToString(info.GetNumberOfLogicalCPU()); + } + else if(key == "NUMBER_OF_PHYSICAL_CORES") + { + value = this->ValueToString(info.GetNumberOfPhysicalCPU()); + } + else if(key == "HOSTNAME") + { + value = this->ValueToString(info.GetHostname()); + } + else if(key == "FQDN") + { + value = this->ValueToString(info.GetFullyQualifiedDomainName()); + } + else if(key == "TOTAL_VIRTUAL_MEMORY") + { + value = this->ValueToString(info.GetTotalVirtualMemory()); + } + else if(key == "AVAILABLE_VIRTUAL_MEMORY") + { + value = this->ValueToString(info.GetAvailableVirtualMemory()); + } + else if(key == "TOTAL_PHYSICAL_MEMORY") + { + value = this->ValueToString(info.GetTotalPhysicalMemory()); + } + else if(key == "AVAILABLE_PHYSICAL_MEMORY") + { + value = this->ValueToString(info.GetAvailablePhysicalMemory()); + } + else + { + std::string e = "does not recognize <key> " + key; + this->SetError(e.c_str()); + return false; + } + + return true; +} + +std::string cmCMakeHostSystemInformationCommand +::ValueToString(size_t value) const +{ + cmsys_ios::stringstream tmp; + tmp << value; + return tmp.str(); +} + +std::string cmCMakeHostSystemInformationCommand +::ValueToString(const char *value) const +{ + std::string safe_string = value ? value : ""; + return safe_string; +} + +std::string cmCMakeHostSystemInformationCommand +::ValueToString(std::string const& value) const +{ + return value; +} diff --git a/Source/cmCMakeHostSystemInformationCommand.h b/Source/cmCMakeHostSystemInformationCommand.h new file mode 100644 index 0000000..d1b8700 --- /dev/null +++ b/Source/cmCMakeHostSystemInformationCommand.h @@ -0,0 +1,102 @@ +/*============================================================================ + CMake - Cross Platform Makefile Generator + Copyright 2013 Kitware, Inc., Insight Software Consortium + + 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. +============================================================================*/ +#ifndef cmCMakeHostSystemInformationCommand_h +#define cmCMakeHostSystemInformationCommand_h + +#include "cmCommand.h" + +#include <cmsys/SystemInformation.hxx> + +/** \class cmCMakeHostSystemInformationCommand + * \brief Query host system specific information + * + * cmCMakeHostSystemInformationCommand queries system information of + * the sytem on which CMake runs. + */ +class cmCMakeHostSystemInformationCommand : public cmCommand +{ +public: + /** + * This is a virtual constructor for the command. + */ + virtual cmCommand* Clone() + { + return new cmCMakeHostSystemInformationCommand; + } + + /** + * This is called when the command is first encountered in + * the CMakeLists.txt file. + */ + virtual bool InitialPass(std::vector<std::string> const& args, + cmExecutionStatus &status); + + /** + * This determines if the command is invoked when in script mode. + */ + virtual bool IsScriptable() const { return true; } + + /** + * The name of the command as specified in CMakeList.txt. + */ + virtual const char* GetName() const + { + return "cmake_host_system_information"; + } + + /** + * Succinct documentation. + */ + virtual const char* GetTerseDocumentation() const + { + return "Query host system specific information."; + } + + /** + * More documentation. + */ + virtual const char* GetFullDocumentation() const + { + return + " cmake_host_system_information(RESULT <variable> QUERY <key> ...)\n" + "Queries system information of the host system on which cmake runs. " + "One or more <key> can be provided to " + "select the information to be queried. " + "The list of queried values is stored in <variable>.\n" + "<key> can be one of the following values:\n" + " NUMBER_OF_LOGICAL_CORES = Number of logical cores.\n" + " NUMBER_OF_PHYSICAL_CORES = Number of physical cores.\n" + " HOSTNAME = Hostname.\n" + " FQDN = Fully qualified domain name.\n" + " TOTAL_VIRTUAL_MEMORY = " + "Total virtual memory in megabytes.\n" + " AVAILABLE_VIRTUAL_MEMORY = " + "Available virtual memory in megabytes.\n" + " TOTAL_PHYSICAL_MEMORY = " + "Total physical memory in megabytes.\n" + " AVAILABLE_PHYSICAL_MEMORY = " + "Available physical memory in megabytes.\n" + ; + } + + cmTypeMacro(cmCMakeHostSystemInformationCommand, cmCommand); + +private: + bool GetValue(cmsys::SystemInformation &info, + std::string const& key, std::string &value); + + std::string ValueToString(size_t value) const; + std::string ValueToString(const char *value) const; + std::string ValueToString(std::string const& value) const; +}; + +#endif diff --git a/Source/cmCommands.cxx b/Source/cmCommands.cxx index 3cfbf43..1e2a85c 100644 --- a/Source/cmCommands.cxx +++ b/Source/cmCommands.cxx @@ -14,6 +14,7 @@ #include "cmAddCompileOptionsCommand.cxx" #include "cmAuxSourceDirectoryCommand.cxx" #include "cmBuildNameCommand.cxx" +#include "cmCMakeHostSystemInformationCommand.cxx" #include "cmElseIfCommand.cxx" #include "cmExportCommand.cxx" #include "cmExportLibraryDependencies.cxx" @@ -56,6 +57,7 @@ void GetPredefinedCommands(std::list<cmCommand*>& commands.push_back(new cmAddCompileOptionsCommand); commands.push_back(new cmAuxSourceDirectoryCommand); commands.push_back(new cmBuildNameCommand); + commands.push_back(new cmCMakeHostSystemInformationCommand); commands.push_back(new cmElseIfCommand); commands.push_back(new cmExportCommand); commands.push_back(new cmExportLibraryDependenciesCommand); diff --git a/Source/cmCommands.h b/Source/cmCommands.h index 096fc20..c56673f 100644 --- a/Source/cmCommands.h +++ b/Source/cmCommands.h @@ -16,12 +16,13 @@ class cmCommand; /** * Global function to return all compiled in commands. - * To add a new command edit cmCommands.cxx or cmBootstrapCommands.cxx + * To add a new command edit cmCommands.cxx or cmBootstrapCommands[12].cxx * and add your command. * It is up to the caller to delete the commands created by this * call. */ -void GetBootstrapCommands(std::list<cmCommand*>& commands); +void GetBootstrapCommands1(std::list<cmCommand*>& commands); +void GetBootstrapCommands2(std::list<cmCommand*>& commands); void GetPredefinedCommands(std::list<cmCommand*>& commands); diff --git a/Source/cmComputeLinkInformation.cxx b/Source/cmComputeLinkInformation.cxx index 02495c4..0ba0139 100644 --- a/Source/cmComputeLinkInformation.cxx +++ b/Source/cmComputeLinkInformation.cxx @@ -499,7 +499,7 @@ bool cmComputeLinkInformation::Compute() if(!this->LinkLanguage) { cmSystemTools:: - Error("CMake can not determine linker language for target:", + Error("CMake can not determine linker language for target: ", this->Target->GetName()); return false; } @@ -1884,6 +1884,8 @@ void cmComputeLinkInformation::GetRPath(std::vector<std::string>& runtimeDirs, } if(use_build_rpath || use_link_rpath) { + std::string rootPath = this->Makefile->GetSafeDefinition("CMAKE_SYSROOT"); + cmSystemTools::ConvertToUnixSlashes(rootPath); std::vector<std::string> const& rdirs = this->GetRuntimeSearchPath(); for(std::vector<std::string>::const_iterator ri = rdirs.begin(); ri != rdirs.end(); ++ri) @@ -1907,9 +1909,14 @@ void cmComputeLinkInformation::GetRPath(std::vector<std::string>& runtimeDirs, !cmSystemTools::IsSubDirectory(ri->c_str(), topSourceDir) && !cmSystemTools::IsSubDirectory(ri->c_str(), topBinaryDir)) { - if(emitted.insert(*ri).second) + std::string d = *ri; + if (d.find(rootPath) == 0) { - runtimeDirs.push_back(*ri); + d = d.substr(rootPath.size()); + } + if(emitted.insert(d).second) + { + runtimeDirs.push_back(d); } } } diff --git a/Source/cmCoreTryCompile.cxx b/Source/cmCoreTryCompile.cxx index bf28428..860417f 100644 --- a/Source/cmCoreTryCompile.cxx +++ b/Source/cmCoreTryCompile.cxx @@ -38,10 +38,13 @@ int cmCoreTryCompile::TryCompileCode(std::vector<std::string> const& argv) char targetNameBuf[64]; bool didOutputVariable = false; bool didCopyFile = false; + bool useSources = argv[2] == "SOURCES"; + std::vector<std::string> sources; enum Doing { DoingNone, DoingCMakeFlags, DoingCompileDefinitions, - DoingLinkLibraries, DoingOutputVariable, DoingCopyFile }; - Doing doing = DoingNone; + DoingLinkLibraries, DoingOutputVariable, DoingCopyFile, + DoingSources }; + Doing doing = useSources? DoingSources : DoingNone; for(size_t i=3; i < argv.size(); ++i) { if(argv[i] == "CMAKE_FLAGS") @@ -118,6 +121,10 @@ int cmCoreTryCompile::TryCompileCode(std::vector<std::string> const& argv) copyFile = argv[i].c_str(); doing = DoingNone; } + else if(doing == DoingSources) + { + sources.push_back(argv[i]); + } else if(i == 3) { this->SrcFileSignature = false; @@ -149,6 +156,13 @@ int cmCoreTryCompile::TryCompileCode(std::vector<std::string> const& argv) return -1; } + if(useSources && sources.empty()) + { + this->Makefile->IssueMessage(cmake::FATAL_ERROR, + "SOURCES must be followed by at least one source file"); + return -1; + } + // compute the binary dir when TRY_COMPILE is called with a src file // signature if (this->SrcFileSignature) @@ -193,6 +207,44 @@ int cmCoreTryCompile::TryCompileCode(std::vector<std::string> const& argv) std::string ccFile = this->BinaryDirectory + "/CMakeCache.txt"; cmSystemTools::RemoveFile(ccFile.c_str()); + // Choose sources. + if(!useSources) + { + sources.push_back(argv[2]); + } + + // Detect languages to enable. + cmGlobalGenerator* gg = + this->Makefile->GetCMakeInstance()->GetGlobalGenerator(); + std::set<std::string> testLangs; + for(std::vector<std::string>::iterator si = sources.begin(); + si != sources.end(); ++si) + { + std::string ext = cmSystemTools::GetFilenameLastExtension(*si); + if(const char* lang = gg->GetLanguageFromExtension(ext.c_str())) + { + testLangs.insert(lang); + } + else + { + cmOStringStream err; + err << "Unknown extension \"" << ext << "\" for file\n" + << " " << *si << "\n" + << "try_compile() works only for enabled languages. " + << "Currently these are:\n "; + std::vector<std::string> langs; + gg->GetEnabledLanguages(langs); + for(std::vector<std::string>::iterator l = langs.begin(); + l != langs.end(); ++l) + { + err << " " << *l; + } + err << "\nSee project() command to enable other languages."; + this->Makefile->IssueMessage(cmake::FATAL_ERROR, err.str()); + return -1; + } + } + // we need to create a directory and CMakeLists file etc... // first create the directories sourceDirectory = this->BinaryDirectory.c_str(); @@ -209,10 +261,6 @@ int cmCoreTryCompile::TryCompileCode(std::vector<std::string> const& argv) return -1; } - std::string source = argv[2]; - std::string ext = cmSystemTools::GetFilenameLastExtension(source); - const char* lang =(this->Makefile->GetCMakeInstance()->GetGlobalGenerator() - ->GetLanguageFromExtension(ext.c_str())); const char* def = this->Makefile->GetDefinition("CMAKE_MODULE_PATH"); fprintf(fout, "cmake_minimum_required(VERSION %u.%u.%u.%u)\n", cmVersion::GetMajorVersion(), cmVersion::GetMinorVersion(), @@ -222,57 +270,39 @@ int cmCoreTryCompile::TryCompileCode(std::vector<std::string> const& argv) fprintf(fout, "SET(CMAKE_MODULE_PATH %s)\n", def); } - const char* rulesOverrideBase = "CMAKE_USER_MAKE_RULES_OVERRIDE"; - std::string rulesOverrideLang = - rulesOverrideBase + (lang ? std::string("_") + lang : std::string("")); - if(const char* rulesOverridePath = - this->Makefile->GetDefinition(rulesOverrideLang.c_str())) + std::string projectLangs; + for(std::set<std::string>::iterator li = testLangs.begin(); + li != testLangs.end(); ++li) { - fprintf(fout, "SET(%s \"%s\")\n", - rulesOverrideLang.c_str(), rulesOverridePath); - } - else if(const char* rulesOverridePath2 = - this->Makefile->GetDefinition(rulesOverrideBase)) - { - fprintf(fout, "SET(%s \"%s\")\n", - rulesOverrideBase, rulesOverridePath2); - } - - if(lang) - { - fprintf(fout, "PROJECT(CMAKE_TRY_COMPILE %s)\n", lang); - } - else - { - fclose(fout); - cmOStringStream err; - err << "Unknown extension \"" << ext << "\" for file\n" - << " " << source << "\n" - << "try_compile() works only for enabled languages. " - << "Currently these are:\n "; - std::vector<std::string> langs; - this->Makefile->GetCMakeInstance()->GetGlobalGenerator()-> - GetEnabledLanguages(langs); - for(std::vector<std::string>::iterator l = langs.begin(); - l != langs.end(); ++l) + projectLangs += " " + *li; + std::string rulesOverrideBase = "CMAKE_USER_MAKE_RULES_OVERRIDE"; + std::string rulesOverrideLang = rulesOverrideBase + "_" + *li; + if(const char* rulesOverridePath = + this->Makefile->GetDefinition(rulesOverrideLang.c_str())) { - err << " " << *l; + fprintf(fout, "SET(%s \"%s\")\n", + rulesOverrideLang.c_str(), rulesOverridePath); + } + else if(const char* rulesOverridePath2 = + this->Makefile->GetDefinition(rulesOverrideBase.c_str())) + { + fprintf(fout, "SET(%s \"%s\")\n", + rulesOverrideBase.c_str(), rulesOverridePath2); } - err << "\nSee project() command to enable other languages."; - this->Makefile->IssueMessage(cmake::FATAL_ERROR, err.str()); - return -1; } - std::string langFlags = "CMAKE_"; - langFlags += lang; - langFlags += "_FLAGS"; + fprintf(fout, "PROJECT(CMAKE_TRY_COMPILE%s)\n", projectLangs.c_str()); fprintf(fout, "SET(CMAKE_VERBOSE_MAKEFILE 1)\n"); - fprintf(fout, "SET(CMAKE_%s_FLAGS \"", lang); - const char* flags = this->Makefile->GetDefinition(langFlags.c_str()); - if(flags) + for(std::set<std::string>::iterator li = testLangs.begin(); + li != testLangs.end(); ++li) { - fprintf(fout, " %s ", flags); + fprintf(fout, "SET(CMAKE_%s_FLAGS \"", li->c_str()); + std::string langFlags = "CMAKE_" + *li + "_FLAGS"; + if(const char* flags = this->Makefile->GetDefinition(langFlags.c_str())) + { + fprintf(fout, " %s ", flags); + } + fprintf(fout, " ${COMPILE_DEFINITIONS}\")\n"); } - fprintf(fout, " ${COMPILE_DEFINITIONS}\")\n"); fprintf(fout, "INCLUDE_DIRECTORIES(${INCLUDE_DIRECTORIES})\n"); fprintf(fout, "SET(CMAKE_SUPPRESS_REGENERATION 1)\n"); fprintf(fout, "LINK_DIRECTORIES(${LINK_DIRECTORIES})\n"); @@ -357,7 +387,19 @@ int cmCoreTryCompile::TryCompileCode(std::vector<std::string> const& argv) fprintf(fout, "SET(CMAKE_RUNTIME_OUTPUT_DIRECTORY \"%s\")\n", this->BinaryDirectory.c_str()); /* Create the actual executable. */ - fprintf(fout, "ADD_EXECUTABLE(%s \"%s\")\n", targetName, source.c_str()); + fprintf(fout, "ADD_EXECUTABLE(%s", targetName); + for(std::vector<std::string>::iterator si = sources.begin(); + si != sources.end(); ++si) + { + fprintf(fout, " \"%s\"", si->c_str()); + + // Add dependencies on any non-temporary sources. + if(si->find("CMakeTmp") == si->npos) + { + this->Makefile->AddCMakeDependFile(*si); + } + } + fprintf(fout, ")\n"); if (useOldLinkLibs) { fprintf(fout, @@ -371,12 +413,6 @@ int cmCoreTryCompile::TryCompileCode(std::vector<std::string> const& argv) } fclose(fout); projectName = "CMAKE_TRY_COMPILE"; - // if the source is not in CMakeTmp - if(source.find("CMakeTmp") == source.npos) - { - this->Makefile->AddCMakeDependFile(source.c_str()); - } - } bool erroroc = cmSystemTools::GetErrorOccuredFlag(); diff --git a/Source/cmCryptoHash.cxx b/Source/cmCryptoHash.cxx index a1505bd..a4f6ac4 100644 --- a/Source/cmCryptoHash.cxx +++ b/Source/cmCryptoHash.cxx @@ -54,8 +54,8 @@ std::string cmCryptoHash::HashFile(const char* file) this->Initialize(); // Should be efficient enough on most system: - const int bufferSize = 4096; - char buffer[bufferSize]; + cm_sha2_uint64_t buffer[512]; + char* buffer_c = reinterpret_cast<char*>(buffer); unsigned char const* buffer_uc = reinterpret_cast<unsigned char const*>(buffer); // This copy loop is very sensitive on certain platforms with @@ -65,7 +65,7 @@ std::string cmCryptoHash::HashFile(const char* file) // error occurred. Therefore, the loop should be safe everywhere. while(fin) { - fin.read(buffer, bufferSize); + fin.read(buffer_c, sizeof(buffer)); if(int gcount = static_cast<int>(fin.gcount())) { this->Append(buffer_uc, gcount); diff --git a/Source/cmDocumentGeneratorExpressions.h b/Source/cmDocumentGeneratorExpressions.h index 84f4af5..841061c 100644 --- a/Source/cmDocumentGeneratorExpressions.h +++ b/Source/cmDocumentGeneratorExpressions.h @@ -44,9 +44,9 @@ "used.\n" \ " $<C_COMPILER_ID:comp> = '1' if the CMake-id of the C " \ "compiler matches comp, otherwise '0'.\n" \ - " $<CXX_COMPILER_ID> = The CMake-id of the CXX compiler " \ + " $<CXX_COMPILER_ID> = The CMake-id of the CXX compiler " \ "used.\n" \ - " $<CXX_COMPILER_ID:comp> = '1' if the CMake-id of the CXX " \ + " $<CXX_COMPILER_ID:comp> = '1' if the CMake-id of the CXX " \ "compiler matches comp, otherwise '0'.\n" \ " $<VERSION_GREATER:v1,v2> = '1' if v1 is a version greater than " \ "v2, else '0'.\n" \ @@ -54,6 +54,13 @@ "else '0'.\n" \ " $<VERSION_EQUAL:v1,v2> = '1' if v1 is the same version as v2, " \ "else '0'.\n" \ + " $<C_COMPILER_VERSION> = The version of the C compiler used.\n" \ + " $<C_COMPILER_VERSION:ver> = '1' if the version of the C " \ + "compiler matches ver, otherwise '0'.\n" \ + " $<CXX_COMPILER_VERSION> = The version of the CXX compiler " \ + "used.\n" \ + " $<CXX_COMPILER_VERSION:ver> = '1' if the version of the CXX " \ + "compiler matches ver, otherwise '0'.\n" \ " $<TARGET_FILE:tgt> = main file (.exe, .so.1.2, .a)\n" \ " $<TARGET_LINKER_FILE:tgt> = file used to link (.a, .lib, .so)\n" \ " $<TARGET_SONAME_FILE:tgt> = file with soname (.so.3)\n" \ diff --git a/Source/cmDocumentVariables.cxx b/Source/cmDocumentVariables.cxx index 689508f..7f5c8ad 100644 --- a/Source/cmDocumentVariables.cxx +++ b/Source/cmDocumentVariables.cxx @@ -561,6 +561,16 @@ void cmDocumentVariables::DefineVariables(cmake* cm) "Variables That Change Behavior"); cm->DefineProperty + ("CMAKE_SYSROOT", cmProperty::VARIABLE, + "Path to pass to the compiler in the --sysroot flag.", + "The CMAKE_SYSROOT content is passed to the compiler in the --sysroot " + "flag, if supported. The path is also stripped from the RPATH if " + "necessary on installation. The CMAKE_SYSROOT is also used to prefix " + "paths searched by the find_* commands.", + false, + "Variables That Change Behavior"); + + cm->DefineProperty ("CMAKE_FIND_LIBRARY_PREFIXES", cmProperty::VARIABLE, "Prefixes to prepend when looking for libraries.", "This specifies what prefixes to add to library names when " @@ -648,6 +658,10 @@ void cmDocumentVariables::DefineVariables(cmake* cm) "WARNING: DESTDIR may not be used on Windows because installation" " prefix usually contains a drive letter like in \"C:/Program Files\"" " which cannot be prepended with some other prefix." + "\n" + "The installation prefix is also added to CMAKE_SYSTEM_PREFIX_PATH " + "so that find_package, find_program, find_library, find_path, and " + "find_file will search the prefix for other software." ,false, "Variables That Change Behavior"); @@ -725,7 +739,8 @@ void cmDocumentVariables::DefineVariables(cmake* cm) "adds /bin to each of the directories in the path, FIND_LIBRARY() " "appends /lib to each of the directories, and FIND_PATH() and " "FIND_FILE() append /include . By default this contains the standard " - "directories for the current system. It is NOT intended " + "directories for the current system and the CMAKE_INSTALL_PREFIX. " + "It is NOT intended " "to be modified by the project, use CMAKE_PREFIX_PATH for this. See also " "CMAKE_SYSTEM_INCLUDE_PATH, CMAKE_SYSTEM_LIBRARY_PATH, " "CMAKE_SYSTEM_PROGRAM_PATH, and CMAKE_SYSTEM_IGNORE_PATH.", false, @@ -1165,6 +1180,14 @@ void cmDocumentVariables::DefineVariables(cmake* cm) "The value must be an integer no less than 128.",false, "Variables That Describe the System"); + cm->DefineProperty + ("ENV", cmProperty::VARIABLE, + "Access environment variables.", + "Use the syntax $ENV{VAR} to read environment variable VAR. " + "See also the set() command to set ENV{VAR}." + ,false, + "Variables That Describe the System"); + // Variables that affect the building of object files and // targets. // diff --git a/Source/cmELF.cxx b/Source/cmELF.cxx index 1158fc0..30de9a8 100644 --- a/Source/cmELF.cxx +++ b/Source/cmELF.cxx @@ -19,7 +19,12 @@ #include <cmsys/CPU.h> // Include the ELF format information system header. -#include <elf.h> +#if defined(__OpenBSD__) +# include <stdint.h> +# include <elf_abi.h> +#else +# include <elf.h> +#endif #if defined(__sun) # include <sys/link.h> // For dynamic section information #endif diff --git a/Source/cmEnableLanguageCommand.h b/Source/cmEnableLanguageCommand.h index ee963f9..747448b 100644 --- a/Source/cmEnableLanguageCommand.h +++ b/Source/cmEnableLanguageCommand.h @@ -59,18 +59,21 @@ public: virtual const char* GetFullDocumentation() const { return - " enable_language(languageName [OPTIONAL] )\n" + " enable_language(<lang> [OPTIONAL] )\n" "This command enables support for the named language in CMake. " "This is the same as the project command but does not create " "any of the extra variables that are created by the project command. " "Example languages are CXX, C, Fortran. " - "If OPTIONAL is used, use the CMAKE_<languageName>_COMPILER_WORKS " - "variable to check whether the language has been enabled successfully." "\n" - "This command must be called on file scope (not inside a function) and " - "the language enabled can only be used in the calling project or its " - "subdirectories added by add_subdirectory(). Also note that at present, " - "the OPTIONAL argument does not work."; + "This command must be called in file scope, not in a function call. " + "Furthermore, it must be called in the highest directory common to " + "all targets using the named language directly for compiling sources " + "or indirectly through link dependencies. " + "It is simplest to enable all needed languages in the top-level " + "directory of a project." + "\n" + "The OPTIONAL keyword is a placeholder for future implementation " + "and does not currently work."; } cmTypeMacro(cmEnableLanguageCommand, cmCommand); diff --git a/Source/cmExportBuildFileGenerator.cxx b/Source/cmExportBuildFileGenerator.cxx index 39184fb..326663c 100644 --- a/Source/cmExportBuildFileGenerator.cxx +++ b/Source/cmExportBuildFileGenerator.cxx @@ -72,6 +72,9 @@ bool cmExportBuildFileGenerator::GenerateMainFile(std::ostream& os) this->PopulateInterfaceProperty("INTERFACE_COMPILE_DEFINITIONS", te, cmGeneratorExpression::BuildInterface, properties, missingTargets); + this->PopulateInterfaceProperty("INTERFACE_COMPILE_OPTIONS", te, + cmGeneratorExpression::BuildInterface, + properties, missingTargets); this->PopulateInterfaceProperty("INTERFACE_POSITION_INDEPENDENT_CODE", te, properties); this->PopulateCompatibleInterfaceProperties(te, properties); diff --git a/Source/cmExportInstallFileGenerator.cxx b/Source/cmExportInstallFileGenerator.cxx index ea671cc..a966b16 100644 --- a/Source/cmExportInstallFileGenerator.cxx +++ b/Source/cmExportInstallFileGenerator.cxx @@ -130,6 +130,10 @@ bool cmExportInstallFileGenerator::GenerateMainFile(std::ostream& os) te, cmGeneratorExpression::InstallInterface, properties, missingTargets); + this->PopulateInterfaceProperty("INTERFACE_COMPILE_OPTIONS", + te, + cmGeneratorExpression::InstallInterface, + properties, missingTargets); this->PopulateInterfaceProperty("INTERFACE_POSITION_INDEPENDENT_CODE", te, properties); this->PopulateCompatibleInterfaceProperties(te, properties); diff --git a/Source/cmExportTryCompileFileGenerator.cxx b/Source/cmExportTryCompileFileGenerator.cxx index 948508b..e7b185a 100644 --- a/Source/cmExportTryCompileFileGenerator.cxx +++ b/Source/cmExportTryCompileFileGenerator.cxx @@ -31,8 +31,10 @@ bool cmExportTryCompileFileGenerator::GenerateMainFile(std::ostream& os) ImportPropertyMap properties; - this->FindTargets("INTERFACE_INCLUDE_DIRECTORIES", te, emittedDeps); - this->FindTargets("INTERFACE_COMPILE_DEFINITIONS", te, emittedDeps); +#define FIND_TARGETS(PROPERTY) \ + this->FindTargets(#PROPERTY, te, emittedDeps); + + CM_FOR_EACH_TRANSITIVE_PROPERTY_NAME(FIND_TARGETS) this->PopulateProperties(te, properties, emittedDeps); diff --git a/Source/cmExtraEclipseCDT4Generator.cxx b/Source/cmExtraEclipseCDT4Generator.cxx index 6b02e15..d80e775 100644 --- a/Source/cmExtraEclipseCDT4Generator.cxx +++ b/Source/cmExtraEclipseCDT4Generator.cxx @@ -554,12 +554,15 @@ void cmExtraEclipseCDT4Generator::CreateLinksForTargets( fileIt != sFiles.end(); ++fileIt) { - std::string linkName4 = linkName3; - linkName4 += "/"; - linkName4 += - cmSystemTools::GetFilenameName((*fileIt)->GetFullPath()); - this->AppendLinkedResource(fout, linkName4, - (*fileIt)->GetFullPath(), LinkToFile); + std::string fullPath = (*fileIt)->GetFullPath(); + if (!cmSystemTools::FileIsDirectory(fullPath.c_str())) + { + std::string linkName4 = linkName3; + linkName4 += "/"; + linkName4 += cmSystemTools::GetFilenameName(fullPath); + this->AppendLinkedResource(fout, linkName4, + fullPath, LinkToFile); + } } } } diff --git a/Source/cmExtraSublimeTextGenerator.cxx b/Source/cmExtraSublimeTextGenerator.cxx index 29d86a6..012013c 100644 --- a/Source/cmExtraSublimeTextGenerator.cxx +++ b/Source/cmExtraSublimeTextGenerator.cxx @@ -429,34 +429,7 @@ cmExtraSublimeTextGenerator::ComputeFlagsForObject(cmSourceFile* source, lg->AppendFlags(flags, makefile->GetDefineFlags()); // Add target-specific flags. - std::string targetFlags; - lg->GetCompileOptions(targetFlags, target, config); - if (!targetFlags.empty()) - { - std::string langIncludeExpr = "CMAKE_"; - langIncludeExpr += language; - langIncludeExpr += "_FLAG_REGEX"; - const char* regex = makefile->GetDefinition(langIncludeExpr.c_str()); - if(regex) - { - cmsys::RegularExpression r(regex); - std::vector<std::string> args; - cmSystemTools:: - ParseWindowsCommandLine(targetFlags.c_str(), args); - for(std::vector<std::string>::iterator i = args.begin(); - i != args.end(); ++i) - { - if(r.find(i->c_str())) - { - lg->AppendFlags(flags, i->c_str()); - } - } - } - else - { - lg->AppendFlags(flags, targetFlags.c_str()); - } - } + lg->AddCompileOptions(flags, target, config, language); // Add source file specific flags. lg->AppendFlags(flags, source->GetProperty("COMPILE_FLAGS")); diff --git a/Source/cmFindCommon.cxx b/Source/cmFindCommon.cxx index b44864e..5daa47d 100644 --- a/Source/cmFindCommon.cxx +++ b/Source/cmFindCommon.cxx @@ -62,10 +62,15 @@ void cmFindCommon::GenerateDocumentation() "The CMake variable CMAKE_FIND_ROOT_PATH specifies one or more " "directories to be prepended to all other search directories. " "This effectively \"re-roots\" the entire search under given locations. " - "By default it is empty. It is especially useful when " + "By default it is empty. " + "The variable CMAKE_SYSROOT can also be used to specify exactly one " + "directory to use as a prefix. Setting CMAKE_SYSROOT also has other " + "effects. See the documentation for that variable for more. " + "These are especially useful when " "cross-compiling to point to the root directory of the " "target environment and CMake will search there too. By default at first " - "the directories listed in CMAKE_FIND_ROOT_PATH and then the non-rooted " + "the CMAKE_SYSROOT directory is searched, then the directories listed in " + "CMAKE_FIND_ROOT_PATH and then the non-rooted " "directories will be searched. " "The default behavior can be adjusted by setting " "CMAKE_FIND_ROOT_PATH_MODE_XXX. This behavior can be manually " @@ -187,16 +192,27 @@ void cmFindCommon::RerootPaths(std::vector<std::string>& paths) { return; } + const char* sysroot = + this->Makefile->GetDefinition("CMAKE_SYSROOT"); const char* rootPath = this->Makefile->GetDefinition("CMAKE_FIND_ROOT_PATH"); - if((rootPath == 0) || (strlen(rootPath) == 0)) + const bool noSysroot = !sysroot || !*sysroot; + const bool noRootPath = !rootPath || !*rootPath; + if(noSysroot && noRootPath) { return; } // Construct the list of path roots with no trailing slashes. std::vector<std::string> roots; - cmSystemTools::ExpandListArgument(rootPath, roots); + if (sysroot) + { + roots.push_back(sysroot); + } + if (rootPath) + { + cmSystemTools::ExpandListArgument(rootPath, roots); + } for(std::vector<std::string>::iterator ri = roots.begin(); ri != roots.end(); ++ri) { diff --git a/Source/cmGeneratorExpressionDAGChecker.cxx b/Source/cmGeneratorExpressionDAGChecker.cxx index e5ffb0c..5b79e35 100644 --- a/Source/cmGeneratorExpressionDAGChecker.cxx +++ b/Source/cmGeneratorExpressionDAGChecker.cxx @@ -33,8 +33,13 @@ cmGeneratorExpressionDAGChecker::cmGeneratorExpressionDAGChecker( } this->CheckResult = this->checkGraph(); - if (CheckResult == DAG && (top->EvaluatingIncludeDirectories() - || top->EvaluatingCompileDefinitions())) +#define TEST_TRANSITIVE_PROPERTY_METHOD(METHOD) \ + top->METHOD () || + + if (CheckResult == DAG && ( + CM_FOR_EACH_TRANSITIVE_PROPERTY_METHOD(TEST_TRANSITIVE_PROPERTY_METHOD) + false) + ) { std::map<cmStdString, std::set<cmStdString> >::const_iterator it = top->Seen.find(target); @@ -134,7 +139,7 @@ cmGeneratorExpressionDAGChecker::checkGraph() const } //---------------------------------------------------------------------------- -bool cmGeneratorExpressionDAGChecker::EvaluatingLinkLibraries() +bool cmGeneratorExpressionDAGChecker::EvaluatingLinkLibraries(const char *tgt) { const cmGeneratorExpressionDAGChecker *top = this; const cmGeneratorExpressionDAGChecker *parent = this->Parent; @@ -145,6 +150,12 @@ bool cmGeneratorExpressionDAGChecker::EvaluatingLinkLibraries() } const char *prop = top->Property.c_str(); + + if (tgt) + { + return top->Target == tgt && strcmp(prop, "LINK_LIBRARIES") == 0; + } + return (strcmp(prop, "LINK_LIBRARIES") == 0 || strcmp(prop, "LINK_INTERFACE_LIBRARIES") == 0 || strcmp(prop, "IMPORTED_LINK_INTERFACE_LIBRARIES") == 0 diff --git a/Source/cmGeneratorExpressionDAGChecker.h b/Source/cmGeneratorExpressionDAGChecker.h index 8d9fd76..95d466a 100644 --- a/Source/cmGeneratorExpressionDAGChecker.h +++ b/Source/cmGeneratorExpressionDAGChecker.h @@ -16,6 +16,16 @@ #include "cmGeneratorExpressionEvaluator.h" +#define CM_FOR_EACH_TRANSITIVE_PROPERTY_METHOD(F) \ + F(EvaluatingIncludeDirectories) \ + F(EvaluatingCompileDefinitions) \ + F(EvaluatingCompileOptions) + +#define CM_FOR_EACH_TRANSITIVE_PROPERTY_NAME(F) \ + F(INTERFACE_INCLUDE_DIRECTORIES) \ + F(INTERFACE_COMPILE_DEFINITIONS) \ + F(INTERFACE_COMPILE_OPTIONS) + //---------------------------------------------------------------------------- struct cmGeneratorExpressionDAGChecker { @@ -37,10 +47,12 @@ struct cmGeneratorExpressionDAGChecker void reportError(cmGeneratorExpressionContext *context, const std::string &expr); - bool EvaluatingLinkLibraries(); - bool EvaluatingIncludeDirectories() const; - bool EvaluatingCompileDefinitions() const; - bool EvaluatingCompileOptions() const; + bool EvaluatingLinkLibraries(const char *tgt = 0); + +#define DECLARE_TRANSITIVE_PROPERTY_METHOD(METHOD) \ + bool METHOD () const; + +CM_FOR_EACH_TRANSITIVE_PROPERTY_METHOD(DECLARE_TRANSITIVE_PROPERTY_METHOD) private: Result checkGraph() const; diff --git a/Source/cmGeneratorExpressionEvaluator.cxx b/Source/cmGeneratorExpressionEvaluator.cxx index 1804691..05bbc1c 100644 --- a/Source/cmGeneratorExpressionEvaluator.cxx +++ b/Source/cmGeneratorExpressionEvaluator.cxx @@ -266,8 +266,6 @@ struct CompilerIdNode : public cmGeneratorExpressionNode { return compilerId ? compilerId : ""; } - else - { cmsys::RegularExpression compilerIdValidator; compilerIdValidator.compile("^[A-Za-z0-9_]*$"); if (!compilerIdValidator.find(parameters.begin()->c_str())) @@ -286,7 +284,6 @@ struct CompilerIdNode : public cmGeneratorExpressionNode return "1"; } return "0"; - } } }; @@ -345,6 +342,102 @@ static const struct CXXCompilerIdNode : public CompilerIdNode } cxxCompilerIdNode; //---------------------------------------------------------------------------- +struct CompilerVersionNode : public cmGeneratorExpressionNode +{ + CompilerVersionNode() {} + + virtual int NumExpectedParameters() const { return ZeroOrMoreParameters; } + + std::string EvaluateWithLanguage(const std::vector<std::string> ¶meters, + cmGeneratorExpressionContext *context, + const GeneratorExpressionContent *content, + cmGeneratorExpressionDAGChecker *, + const std::string &lang) const + { + const char *compilerVersion = context->Makefile ? + context->Makefile->GetSafeDefinition(( + "CMAKE_" + lang + "_COMPILER_VERSION").c_str()) : ""; + if (parameters.size() == 0) + { + return compilerVersion ? compilerVersion : ""; + } + + cmsys::RegularExpression compilerIdValidator; + compilerIdValidator.compile("^[0-9\\.]*$"); + if (!compilerIdValidator.find(parameters.begin()->c_str())) + { + reportError(context, content->GetOriginalExpression(), + "Expression syntax not recognized."); + return std::string(); + } + if (!compilerVersion) + { + return parameters.front().empty() ? "1" : "0"; + } + + return cmSystemTools::VersionCompare(cmSystemTools::OP_EQUAL, + parameters.begin()->c_str(), + compilerVersion) ? "1" : "0"; + } +}; + +//---------------------------------------------------------------------------- +static const struct CCompilerVersionNode : public CompilerVersionNode +{ + CCompilerVersionNode() {} + + std::string Evaluate(const std::vector<std::string> ¶meters, + cmGeneratorExpressionContext *context, + const GeneratorExpressionContent *content, + cmGeneratorExpressionDAGChecker *dagChecker) const + { + if (parameters.size() != 0 && parameters.size() != 1) + { + reportError(context, content->GetOriginalExpression(), + "$<C_COMPILER_VERSION> expression requires one or two parameters"); + return std::string(); + } + if (!context->HeadTarget) + { + reportError(context, content->GetOriginalExpression(), + "$<C_COMPILER_VERSION> may only be used with targets. It may not " + "be used with add_custom_command."); + } + return this->EvaluateWithLanguage(parameters, context, content, + dagChecker, "C"); + } +} cCompilerVersionNode; + +//---------------------------------------------------------------------------- +static const struct CxxCompilerVersionNode : public CompilerVersionNode +{ + CxxCompilerVersionNode() {} + + std::string Evaluate(const std::vector<std::string> ¶meters, + cmGeneratorExpressionContext *context, + const GeneratorExpressionContent *content, + cmGeneratorExpressionDAGChecker *dagChecker) const + { + if (parameters.size() != 0 && parameters.size() != 1) + { + reportError(context, content->GetOriginalExpression(), + "$<CXX_COMPILER_VERSION> expression requires one or two " + "parameters"); + return std::string(); + } + if (!context->HeadTarget) + { + reportError(context, content->GetOriginalExpression(), + "$<CXX_COMPILER_VERSION> may only be used with targets. It may " + "not be used with add_custom_command."); + } + return this->EvaluateWithLanguage(parameters, context, content, + dagChecker, "CXX"); + } +} cxxCompilerVersionNode; + + +//---------------------------------------------------------------------------- static const struct VersionGreaterNode : public cmGeneratorExpressionNode { VersionGreaterNode() {} @@ -472,8 +565,15 @@ static const struct LinkLanguageNode : public cmGeneratorExpressionNode std::string Evaluate(const std::vector<std::string> ¶meters, cmGeneratorExpressionContext *context, const GeneratorExpressionContent *content, - cmGeneratorExpressionDAGChecker *) const + cmGeneratorExpressionDAGChecker *dagChecker) const { + if (dagChecker && dagChecker->EvaluatingLinkLibraries()) + { + reportError(context, content->GetOriginalExpression(), + "$<LINK_LANGUAGE> expression can not be used while evaluating " + "link libraries"); + return std::string(); + } if (parameters.size() != 0 && parameters.size() != 1) { reportError(context, content->GetOriginalExpression(), @@ -486,6 +586,7 @@ static const struct LinkLanguageNode : public cmGeneratorExpressionNode reportError(context, content->GetOriginalExpression(), "$<LINK_LANGUAGE> may only be used with targets. It may not " "be used with add_custom_command."); + return std::string(); } const char *lang = target->GetLinkerLanguage(context->Config); @@ -545,11 +646,13 @@ static const struct JoinNode : public cmGeneratorExpressionNode } } joinNode; +#define TRANSITIVE_PROPERTY_NAME(PROPERTY) \ + , #PROPERTY + //---------------------------------------------------------------------------- static const char* targetPropertyTransitiveWhitelist[] = { - "INTERFACE_INCLUDE_DIRECTORIES" - , "INTERFACE_COMPILE_DEFINITIONS" - , "INTERFACE_COMPILE_OPTIONS" + 0 + CM_FOR_EACH_TRANSITIVE_PROPERTY_NAME(TRANSITIVE_PROPERTY_NAME) }; std::string getLinkedTargetsContent(const std::vector<std::string> &libraries, @@ -729,7 +832,7 @@ static const struct TargetPropertyNode : public cmGeneratorExpressionNode // No error. We just skip cyclic references. return std::string(); case cmGeneratorExpressionDAGChecker::ALREADY_SEEN: - for (size_t i = 0; + for (size_t i = 1; i < (sizeof(targetPropertyTransitiveWhitelist) / sizeof(*targetPropertyTransitiveWhitelist)); ++i) @@ -757,9 +860,13 @@ static const struct TargetPropertyNode : public cmGeneratorExpressionNode } else { - assert(dagCheckerParent->EvaluatingIncludeDirectories() - || dagCheckerParent->EvaluatingCompileDefinitions() - || dagCheckerParent->EvaluatingCompileOptions()); +#define ASSERT_TRANSITIVE_PROPERTY_METHOD(METHOD) \ + dagCheckerParent->METHOD () || + + assert( + CM_FOR_EACH_TRANSITIVE_PROPERTY_METHOD( + ASSERT_TRANSITIVE_PROPERTY_METHOD) + false); } } @@ -786,7 +893,7 @@ static const struct TargetPropertyNode : public cmGeneratorExpressionNode cmTarget *headTarget = context->HeadTarget ? context->HeadTarget : target; - const char **transBegin = targetPropertyTransitiveWhitelist; + const char **transBegin = targetPropertyTransitiveWhitelist + 1; const char **transEnd = targetPropertyTransitiveWhitelist + (sizeof(targetPropertyTransitiveWhitelist) / sizeof(*targetPropertyTransitiveWhitelist)); @@ -852,7 +959,7 @@ static const struct TargetPropertyNode : public cmGeneratorExpressionNode return linkedTargetsContent; } - for (size_t i = 0; + for (size_t i = 1; i < (sizeof(targetPropertyTransitiveWhitelist) / sizeof(*targetPropertyTransitiveWhitelist)); ++i) @@ -1143,7 +1250,7 @@ struct TargetFilesystemArtifact : public cmGeneratorExpressionNode std::string Evaluate(const std::vector<std::string> ¶meters, cmGeneratorExpressionContext *context, const GeneratorExpressionContent *content, - cmGeneratorExpressionDAGChecker *) const + cmGeneratorExpressionDAGChecker *dagChecker) const { // Lookup the referenced target. std::string name = *parameters.begin(); @@ -1168,6 +1275,13 @@ struct TargetFilesystemArtifact : public cmGeneratorExpressionNode "Target \"" + name + "\" is not an executable or library."); return std::string(); } + if (dagChecker && dagChecker->EvaluatingLinkLibraries(name.c_str())) + { + ::reportError(context, content->GetOriginalExpression(), + "Expressions which require the linker language may not " + "be used while evaluating link libraries"); + return std::string(); + } context->DependTargets.insert(target); context->AllTargets.insert(target); @@ -1229,6 +1343,10 @@ cmGeneratorExpressionNode* GetNode(const std::string &identifier) return &versionLessNode; else if (identifier == "VERSION_EQUAL") return &versionEqualNode; + else if (identifier == "C_COMPILER_VERSION") + return &cCompilerVersionNode; + else if (identifier == "CXX_COMPILER_VERSION") + return &cxxCompilerVersionNode; else if (identifier == "CONFIGURATION") return &configurationNode; else if (identifier == "CONFIG") diff --git a/Source/cmGetCMakePropertyCommand.cxx b/Source/cmGetCMakePropertyCommand.cxx index 8bb5487..e7ad91a 100644 --- a/Source/cmGetCMakePropertyCommand.cxx +++ b/Source/cmGetCMakePropertyCommand.cxx @@ -11,6 +11,8 @@ ============================================================================*/ #include "cmGetCMakePropertyCommand.h" +#include "cmGlobalGenerator.h" +#include "cmLocalGenerator.h" #include "cmake.h" // cmGetCMakePropertyCommand diff --git a/Source/cmGetPropertyCommand.cxx b/Source/cmGetPropertyCommand.cxx index 7d33358..985dc50 100644 --- a/Source/cmGetPropertyCommand.cxx +++ b/Source/cmGetPropertyCommand.cxx @@ -13,6 +13,9 @@ #include "cmake.h" #include "cmTest.h" +#include "cmGlobalGenerator.h" +#include "cmLocalGenerator.h" +#include "cmSourceFile.h" #include "cmPropertyDefinition.h" //---------------------------------------------------------------------------- diff --git a/Source/cmGlobalGenerator.cxx b/Source/cmGlobalGenerator.cxx index 3e3e5e4..ad74767 100644 --- a/Source/cmGlobalGenerator.cxx +++ b/Source/cmGlobalGenerator.cxx @@ -415,7 +415,7 @@ cmGlobalGenerator::EnableLanguage(std::vector<std::string>const& languages, { if(!mf->ReadListFile(0,fpath.c_str())) { - cmSystemTools::Error("Could not find cmake module file:", + cmSystemTools::Error("Could not find cmake module file: ", fpath.c_str()); } // if this file was found then the language was already determined @@ -445,7 +445,7 @@ cmGlobalGenerator::EnableLanguage(std::vector<std::string>const& languages, mf->GetModulesFile(determineCompiler.c_str()); if(!mf->ReadListFile(0,determineFile.c_str())) { - cmSystemTools::Error("Could not find cmake module file:", + cmSystemTools::Error("Could not find cmake module file: ", determineFile.c_str()); } needTestLanguage[lang] = true; @@ -479,7 +479,7 @@ cmGlobalGenerator::EnableLanguage(std::vector<std::string>const& languages, fpath += "Compiler.cmake"; if(!mf->ReadListFile(0,fpath.c_str())) { - cmSystemTools::Error("Could not find cmake module file:", + cmSystemTools::Error("Could not find cmake module file: ", fpath.c_str()); } this->SetLanguageEnabledFlag(lang, mf); @@ -498,7 +498,7 @@ cmGlobalGenerator::EnableLanguage(std::vector<std::string>const& languages, fpath = mf->GetModulesFile("CMakeSystemSpecificInformation.cmake"); if(!mf->ReadListFile(0,fpath.c_str())) { - cmSystemTools::Error("Could not find cmake module file:", + cmSystemTools::Error("Could not find cmake module file: ", fpath.c_str()); } } @@ -524,12 +524,12 @@ cmGlobalGenerator::EnableLanguage(std::vector<std::string>const& languages, std::string informationFile = mf->GetModulesFile(fpath.c_str()); if (informationFile.empty()) { - cmSystemTools::Error("Could not find cmake module file:", + cmSystemTools::Error("Could not find cmake module file: ", fpath.c_str()); } else if(!mf->ReadListFile(0, informationFile.c_str())) { - cmSystemTools::Error("Could not process cmake module file:", + cmSystemTools::Error("Could not process cmake module file: ", informationFile.c_str()); } } @@ -568,7 +568,7 @@ cmGlobalGenerator::EnableLanguage(std::vector<std::string>const& languages, std::string ifpath = mf->GetModulesFile(testLang.c_str()); if(!mf->ReadListFile(0,ifpath.c_str())) { - cmSystemTools::Error("Could not find cmake module file:", + cmSystemTools::Error("Could not find cmake module file: ", ifpath.c_str()); } std::string compilerWorks = "CMAKE_"; diff --git a/Source/cmGlobalNinjaGenerator.cxx b/Source/cmGlobalNinjaGenerator.cxx index fff972e..9596ebc 100644 --- a/Source/cmGlobalNinjaGenerator.cxx +++ b/Source/cmGlobalNinjaGenerator.cxx @@ -10,11 +10,12 @@ implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the License for more information. ============================================================================*/ +#include "cmGeneratedFileStream.h" +#include "cmGeneratorExpressionEvaluationFile.h" +#include "cmGeneratorTarget.h" #include "cmGlobalNinjaGenerator.h" #include "cmLocalNinjaGenerator.h" #include "cmMakefile.h" -#include "cmGeneratedFileStream.h" -#include "cmGeneratorTarget.h" #include "cmVersion.h" #include <algorithm> @@ -140,8 +141,15 @@ void cmGlobalNinjaGenerator::WriteBuild(std::ostream& os, for(cmNinjaDeps::const_iterator i = explicitDeps.begin(); i != explicitDeps.end(); ++i) + { arguments << " " << EncodeIdent(EncodePath(*i), os); + //we need to track every dependency that comes in, since we are trying + //to find dependencies that are side effects of build commands + // + this->CombinedBuildExplicitDependencies.insert(*i); + } + // Write implicit dependencies. if(!implicitDeps.empty()) { @@ -170,7 +178,10 @@ void cmGlobalNinjaGenerator::WriteBuild(std::ostream& os, build << "build"; for(cmNinjaDeps::const_iterator i = outputs.begin(); i != outputs.end(); ++i) + { build << " " << EncodeIdent(EncodePath(*i), os); + this->CombinedBuildOutputs.insert(*i); + } build << ":"; // Write the rule. @@ -208,14 +219,14 @@ void cmGlobalNinjaGenerator::WritePhonyBuild(std::ostream& os, const cmNinjaDeps& orderOnlyDeps, const cmNinjaVars& variables) { - cmGlobalNinjaGenerator::WriteBuild(os, - comment, - "phony", - outputs, - explicitDeps, - implicitDeps, - orderOnlyDeps, - variables); + this->WriteBuild(os, + comment, + "phony", + outputs, + explicitDeps, + implicitDeps, + orderOnlyDeps, + variables); } void cmGlobalNinjaGenerator::AddCustomCommandRule() @@ -251,14 +262,14 @@ cmGlobalNinjaGenerator::WriteCustomCommandBuild(const std::string& command, vars["COMMAND"] = cmd; vars["DESC"] = EncodeLiteral(description); - cmGlobalNinjaGenerator::WriteBuild(*this->BuildFileStream, - comment, - "CUSTOM_COMMAND", - outputs, - deps, - cmNinjaDeps(), - orderOnlyDeps, - vars); + this->WriteBuild(*this->BuildFileStream, + comment, + "CUSTOM_COMMAND", + outputs, + deps, + cmNinjaDeps(), + orderOnlyDeps, + vars); } void @@ -293,14 +304,14 @@ cmGlobalNinjaGenerator::WriteMacOSXContentBuild(const std::string& input, deps.push_back(input); cmNinjaVars vars; - cmGlobalNinjaGenerator::WriteBuild(*this->BuildFileStream, - "", - "COPY_OSX_CONTENT", - outputs, - deps, - cmNinjaDeps(), - cmNinjaDeps(), - cmNinjaVars()); + this->WriteBuild(*this->BuildFileStream, + "", + "COPY_OSX_CONTENT", + outputs, + deps, + cmNinjaDeps(), + cmNinjaDeps(), + cmNinjaVars()); } void cmGlobalNinjaGenerator::WriteRule(std::ostream& os, @@ -478,6 +489,7 @@ void cmGlobalNinjaGenerator::Generate() this->WriteAssumedSourceDependencies(); this->WriteTargetAliases(*this->BuildFileStream); + this->WriteUnknownExplicitDependencies(*this->BuildFileStream); this->WriteBuiltinTargets(*this->BuildFileStream); if (cmSystemTools::GetErrorOccuredFlag()) { @@ -887,7 +899,7 @@ void cmGlobalNinjaGenerator::WriteTargetAliases(std::ostream& os) cmGlobalNinjaGenerator::WriteDivider(os); os << "# Target aliases.\n\n"; - for (TargetAliasMap::iterator i = TargetAliases.begin(); + for (TargetAliasMap::const_iterator i = TargetAliases.begin(); i != TargetAliases.end(); ++i) { // Don't write ambiguous aliases. if (!i->second) @@ -896,13 +908,124 @@ void cmGlobalNinjaGenerator::WriteTargetAliases(std::ostream& os) cmNinjaDeps deps; this->AppendTargetOutputs(i->second, deps); - cmGlobalNinjaGenerator::WritePhonyBuild(os, - "", - cmNinjaDeps(1, i->first), - deps); + this->WritePhonyBuild(os, + "", + cmNinjaDeps(1, i->first), + deps); } } +void cmGlobalNinjaGenerator::WriteUnknownExplicitDependencies(std::ostream& os) +{ + //now write out the unknown explicit dependencies. + + //union the configured files, evaluations files and the CombinedBuildOutputs, + //and then difference with CombinedExplicitDependencies to find the explicit + //dependencies that we have no rule for + + cmGlobalNinjaGenerator::WriteDivider(os); + os << "# Unknown Build Time Dependencies.\n" + << "# Tell Ninja that they may appear as side effects of build rules\n" + << "# otherwise ordered by order-only dependencies.\n\n"; + + //get the list of files that cmake itself has generated as a + //product of configuration. + cmLocalNinjaGenerator *ng = + static_cast<cmLocalNinjaGenerator *>(this->LocalGenerators[0]); + + std::set<std::string> knownDependencies; + for (std::vector<cmLocalGenerator *>::const_iterator i = + this->LocalGenerators.begin(); i != this->LocalGenerators.end(); ++i) + { + //get the vector of files created by this makefile and convert them + //to ninja paths, which are all relative in respect to the build directory + const std::vector<std::string>& files = + (*i)->GetMakefile()->GetOutputFiles(); + typedef std::vector<std::string>::const_iterator vect_it; + for(vect_it j = files.begin(); j != files.end(); ++j) + { + knownDependencies.insert(ng->ConvertToNinjaPath( j->c_str() )); + } + } + + for(std::vector<cmGeneratorExpressionEvaluationFile*>::const_iterator + li = this->EvaluationFiles.begin(); + li != this->EvaluationFiles.end(); + ++li) + { + //get all the files created by generator expressions and convert them + //to ninja paths + std::vector<std::string> files = (*li)->GetFiles(); + typedef std::vector<std::string>::const_iterator vect_it; + for(vect_it j = files.begin(); j != files.end(); ++j) + { + knownDependencies.insert(ng->ConvertToNinjaPath( j->c_str() )); + } + } + + //insert outputs from all WirteBuild commands + for(std::set<std::string>::iterator i = this->CombinedBuildOutputs.begin(); + i != this->CombinedBuildOutputs.end(); ++i) + { + knownDependencies.insert(*i); + } + + //after we have combined the data into knownDependencies we have no need + //to keep this data around + this->CombinedBuildOutputs.clear(); + + for(TargetAliasMap::const_iterator i= this->TargetAliases.begin(); + i != this->TargetAliases.end(); + ++i) + { + knownDependencies.insert(i->first); + } + + //remove all source files we know will exist. + typedef std::map<std::string, std::set<std::string> >::const_iterator map_it; + for(map_it i = this->AssumedSourceDependencies.begin(); + i != this->AssumedSourceDependencies.end(); + ++i) + { + knownDependencies.insert(i->first); + } + + //now we difference with CombinedBuildExplicitDependencies to find + //the list of items we know nothing about + + std::vector<std::string> unkownExplicitDepends; + this->CombinedBuildExplicitDependencies.erase("all"); + + std::set_difference(this->CombinedBuildExplicitDependencies.begin(), + this->CombinedBuildExplicitDependencies.end(), + knownDependencies.begin(), + knownDependencies.end(), + std::back_inserter(unkownExplicitDepends)); + + + std::string const rootBuildDirectory = + this->GetCMakeInstance()->GetHomeOutputDirectory(); + for (std::vector<std::string>::const_iterator + i = unkownExplicitDepends.begin(); + i != unkownExplicitDepends.end(); + ++i) + { + //verify the file is in the build directory + std::string const absDepPath = cmSystemTools::CollapseFullPath( + i->c_str(), rootBuildDirectory.c_str()); + bool const inBuildDir = cmSystemTools::IsSubDirectory(absDepPath.c_str(), + rootBuildDirectory.c_str()); + if(inBuildDir) + { + cmNinjaDeps deps(1,*i); + this->WritePhonyBuild(os, + "", + deps, + deps); + } + } +} + void cmGlobalNinjaGenerator::WriteBuiltinTargets(std::ostream& os) { // Write headers. @@ -920,10 +1043,10 @@ void cmGlobalNinjaGenerator::WriteTargetAll(std::ostream& os) cmNinjaDeps outputs; outputs.push_back("all"); - cmGlobalNinjaGenerator::WritePhonyBuild(os, - "The main all target.", - outputs, - this->AllDependencies); + this->WritePhonyBuild(os, + "The main all target.", + outputs, + this->AllDependencies); cmGlobalNinjaGenerator::WriteDefault(os, outputs, @@ -961,25 +1084,28 @@ void cmGlobalNinjaGenerator::WriteTargetRebuildManifest(std::ostream& os) this->LocalGenerators.begin(); i != this->LocalGenerators.end(); ++i) { const std::vector<std::string>& lf = (*i)->GetMakefile()->GetListFiles(); implicitDeps.insert(implicitDeps.end(), lf.begin(), lf.end()); + + const std::vector<std::string>& of = (*i)->GetMakefile()->GetOutputFiles(); + implicitDeps.insert(implicitDeps.end(), of.begin(), of.end()); } std::sort(implicitDeps.begin(), implicitDeps.end()); implicitDeps.erase(std::unique(implicitDeps.begin(), implicitDeps.end()), implicitDeps.end()); implicitDeps.push_back("CMakeCache.txt"); - WriteBuild(os, - "Re-run CMake if any of its inputs changed.", - "RERUN_CMAKE", - /*outputs=*/ cmNinjaDeps(1, NINJA_BUILD_FILE), - /*explicitDeps=*/ cmNinjaDeps(), - implicitDeps, - /*orderOnlyDeps=*/ cmNinjaDeps(), - /*variables=*/ cmNinjaVars()); - - WritePhonyBuild(os, - "A missing CMake input file is not an error.", - implicitDeps, - cmNinjaDeps()); + this->WriteBuild(os, + "Re-run CMake if any of its inputs changed.", + "RERUN_CMAKE", + /*outputs=*/ cmNinjaDeps(1, NINJA_BUILD_FILE), + /*explicitDeps=*/ cmNinjaDeps(), + implicitDeps, + /*orderOnlyDeps=*/ cmNinjaDeps(), + /*variables=*/ cmNinjaVars()); + + this->WritePhonyBuild(os, + "A missing CMake input file is not an error.", + implicitDeps, + cmNinjaDeps()); } std::string cmGlobalNinjaGenerator::ninjaCmd() const diff --git a/Source/cmGlobalNinjaGenerator.h b/Source/cmGlobalNinjaGenerator.h index 6e93788..e046c7c 100644 --- a/Source/cmGlobalNinjaGenerator.h +++ b/Source/cmGlobalNinjaGenerator.h @@ -77,27 +77,27 @@ public: * It also writes the variables bound to this build statement. * @warning no escaping of any kind is done here. */ - static void WriteBuild(std::ostream& os, - const std::string& comment, - const std::string& rule, - const cmNinjaDeps& outputs, - const cmNinjaDeps& explicitDeps, - const cmNinjaDeps& implicitDeps, - const cmNinjaDeps& orderOnlyDeps, - const cmNinjaVars& variables, - const std::string& rspfile = std::string(), - int cmdLineLimit = -1); + void WriteBuild(std::ostream& os, + const std::string& comment, + const std::string& rule, + const cmNinjaDeps& outputs, + const cmNinjaDeps& explicitDeps, + const cmNinjaDeps& implicitDeps, + const cmNinjaDeps& orderOnlyDeps, + const cmNinjaVars& variables, + const std::string& rspfile = std::string(), + int cmdLineLimit = -1); /** * Helper to write a build statement with the special 'phony' rule. */ - static void WritePhonyBuild(std::ostream& os, - const std::string& comment, - const cmNinjaDeps& outputs, - const cmNinjaDeps& explicitDeps, - const cmNinjaDeps& implicitDeps = cmNinjaDeps(), - const cmNinjaDeps& orderOnlyDeps = cmNinjaDeps(), - const cmNinjaVars& variables = cmNinjaVars()); + void WritePhonyBuild(std::ostream& os, + const std::string& comment, + const cmNinjaDeps& outputs, + const cmNinjaDeps& explicitDeps, + const cmNinjaDeps& implicitDeps = cmNinjaDeps(), + const cmNinjaDeps& orderOnlyDeps = cmNinjaDeps(), + const cmNinjaVars& variables = cmNinjaVars()); void WriteCustomCommandBuild(const std::string& command, const std::string& description, @@ -321,6 +321,7 @@ private: void WriteAssumedSourceDependencies(); void WriteTargetAliases(std::ostream& os); + void WriteUnknownExplicitDependencies(std::ostream& os); void WriteBuiltinTargets(std::ostream& os); void WriteTargetAll(std::ostream& os); @@ -358,6 +359,12 @@ private: /// The set of custom command outputs we have seen. std::set<std::string> CustomCommandOutputs; + //The combined explicit dependencies of all build commands that the global + //generator has issued. When combined with CombinedBuildOutputs it allows + //us to detect the set of explicit dependencies that have + std::set<std::string> CombinedBuildExplicitDependencies; + std::set<std::string> CombinedBuildOutputs; + /// The mapping from source file to assumed dependencies. std::map<std::string, std::set<std::string> > AssumedSourceDependencies; diff --git a/Source/cmGlobalXCodeGenerator.cxx b/Source/cmGlobalXCodeGenerator.cxx index 5083cb3..9cfbe42 100644 --- a/Source/cmGlobalXCodeGenerator.cxx +++ b/Source/cmGlobalXCodeGenerator.cxx @@ -681,12 +681,6 @@ cmGlobalXCodeGenerator::CreateXCodeSourceFile(cmLocalGenerator* lg, { // Add flags from target and source file properties. std::string flags; - std::string targetFlags; - lg->GetCompileOptions(targetFlags, &cmtarget, 0); // TODO: Config? - if(!targetFlags.empty()) - { - lg->AppendFlags(flags, targetFlags.c_str()); - } const char* srcfmt = sf->GetProperty("Fortran_FORMAT"); switch(this->CurrentLocalGenerator->GetFortranFormat(srcfmt)) { @@ -1704,6 +1698,8 @@ void cmGlobalXCodeGenerator::CreateBuildSettings(cmTarget& target, this->CurrentLocalGenerator->AddLanguageFlags(cflags, "C", configName); this->CurrentLocalGenerator->AddCMP0018Flags(cflags, &target, "C", configName); + this->CurrentLocalGenerator-> + AddCompileOptions(cflags, &target, "C", configName); } // Add language-specific flags. @@ -1715,11 +1711,14 @@ void cmGlobalXCodeGenerator::CreateBuildSettings(cmTarget& target, this->CurrentLocalGenerator->AddVisibilityPresetFlags(flags, &target, lang); + + this->CurrentLocalGenerator-> + AddCompileOptions(flags, &target, lang, configName); } else if(binary) { cmSystemTools::Error - ("CMake can not determine linker language for target:", + ("CMake can not determine linker language for target: ", target.GetName()); return; } diff --git a/Source/cmGlobalXCodeGenerator.h b/Source/cmGlobalXCodeGenerator.h index fb897b2..c053943 100644 --- a/Source/cmGlobalXCodeGenerator.h +++ b/Source/cmGlobalXCodeGenerator.h @@ -85,6 +85,7 @@ public: virtual bool IsMultiConfig(); virtual bool SetGeneratorToolset(std::string const& ts); + void AppendFlag(std::string& flags, std::string const& flag); private: cmXCodeObject* CreateOrGetPBXGroup(cmTarget& cmtarget, cmSourceGroup* sg); @@ -198,7 +199,6 @@ private: void AppendDefines(BuildObjectListOrString& defs, std::vector<std::string> const& defines, bool dflag = false); - void AppendFlag(std::string& flags, std::string const& flag); protected: virtual const char* GetInstallTargetName() const { return "install"; } diff --git a/Source/cmLocalGenerator.cxx b/Source/cmLocalGenerator.cxx index c2da4a9..00846d5 100644 --- a/Source/cmLocalGenerator.cxx +++ b/Source/cmLocalGenerator.cxx @@ -761,7 +761,7 @@ void cmLocalGenerator if(!llang) { cmSystemTools::Error - ("CMake can not determine linker language for target:", + ("CMake can not determine linker language for target: ", target.Target->GetName()); return; } @@ -1044,11 +1044,20 @@ cmLocalGenerator::ExpandRuleVariable(std::string const& variable, // If this is the compiler then look for the extra variable // _COMPILER_ARG1 which must be the first argument to the compiler const char* compilerArg1 = 0; + const char* compilerTarget = 0; + const char* compilerOptionTarget = 0; if(actualReplace == "CMAKE_${LANG}_COMPILER") { std::string arg1 = actualReplace + "_ARG1"; cmSystemTools::ReplaceString(arg1, "${LANG}", lang); compilerArg1 = this->Makefile->GetDefinition(arg1.c_str()); + compilerTarget + = this->Makefile->GetDefinition( + (std::string("CMAKE_") + lang + "_COMPILER_TARGET").c_str()); + compilerOptionTarget + = this->Makefile->GetDefinition( + (std::string("CMAKE_") + lang + + "_COMPILE_OPTION_TARGET").c_str()); } if(actualReplace.find("${LANG}") != actualReplace.npos) { @@ -1069,6 +1078,11 @@ cmLocalGenerator::ExpandRuleVariable(std::string const& variable, ret += " "; ret += compilerArg1; } + if (compilerTarget && compilerOptionTarget) + { + ret += compilerOptionTarget; + ret += compilerTarget; + } return ret; } return replace; @@ -1325,22 +1339,50 @@ std::string cmLocalGenerator::GetIncludeFlags( } //---------------------------------------------------------------------------- -void cmLocalGenerator::GetCompileOptions(std::string& flags, - cmTarget* target, - const char *config) +void cmLocalGenerator::AddCompileOptions( + std::string& flags, cmTarget* target, + const char* lang, const char* config + ) { - // Add target-specific flags. - if(const char *prop = target->GetProperty("COMPILE_FLAGS")) + std::string langFlagRegexVar = std::string("CMAKE_")+lang+"_FLAG_REGEX"; + if(const char* langFlagRegexStr = + this->Makefile->GetDefinition(langFlagRegexVar.c_str())) { - this->AppendFlags(flags, prop); + // Filter flags acceptable to this language. + cmsys::RegularExpression r(langFlagRegexStr); + std::vector<std::string> opts; + if(const char* targetFlags = target->GetProperty("COMPILE_FLAGS")) + { + cmSystemTools::ParseWindowsCommandLine(targetFlags, opts); + } + target->GetCompileOptions(opts, config); + for(std::vector<std::string>::const_iterator i = opts.begin(); + i != opts.end(); ++i) + { + if(r.find(i->c_str())) + { + // (Re-)Escape this flag. COMPILE_FLAGS were already parsed + // as a command line above, and COMPILE_OPTIONS are escaped. + this->AppendFlagEscape(flags, i->c_str()); + } + } } - - std::vector<std::string> opts; // TODO: Emitted. - target->GetCompileOptions(opts, config); - for(std::vector<std::string>::const_iterator li = opts.begin(); - li != opts.end(); ++li) + else { - this->AppendFlags(flags, li->c_str()); + // Use all flags. + if(const char* targetFlags = target->GetProperty("COMPILE_FLAGS")) + { + // COMPILE_FLAGS are not escaped for historical reasons. + this->AppendFlags(flags, targetFlags); + } + std::vector<std::string> opts; // TODO: Emitted. + target->GetCompileOptions(opts, config); + for(std::vector<std::string>::const_iterator i = opts.begin(); + i != opts.end(); ++i) + { + // COMPILE_OPTIONS are escaped. + this->AppendFlagEscape(flags, i->c_str()); + } } } @@ -1425,6 +1467,8 @@ void cmLocalGenerator::GetIncludeDirectories(std::vector<std::string>& dirs, return; } + std::string rootPath = this->Makefile->GetSafeDefinition("CMAKE_SYSROOT"); + std::vector<std::string> implicitDirs; // Load implicit include directories for this language. std::string impDirVar = "CMAKE_"; @@ -1437,7 +1481,9 @@ void cmLocalGenerator::GetIncludeDirectories(std::vector<std::string>& dirs, for(std::vector<std::string>::const_iterator i = impDirVec.begin(); i != impDirVec.end(); ++i) { - emitted.insert(*i); + std::string d = rootPath + *i; + cmSystemTools::ConvertToUnixSlashes(d); + emitted.insert(d); if (!stripImplicitInclDirs) { implicitDirs.push_back(*i); @@ -1600,7 +1646,7 @@ void cmLocalGenerator::GetTargetFlags(std::string& linkLibs, if(!linkLanguage) { cmSystemTools::Error - ("CMake can not determine linker language for target:", + ("CMake can not determine linker language for target: ", target->Target->GetName()); return; } @@ -2198,7 +2244,7 @@ void cmLocalGenerator::AddPositionIndependentFlags(std::string& flags, for(std::vector<std::string>::const_iterator oi = options.begin(); oi != options.end(); ++oi) { - this->AppendFlags(flags, this->EscapeForShell(oi->c_str()).c_str()); + this->AppendFlagEscape(flags, oi->c_str()); } } } @@ -2236,6 +2282,13 @@ void cmLocalGenerator::AppendFlags(std::string& flags, } //---------------------------------------------------------------------------- +void cmLocalGenerator::AppendFlagEscape(std::string& flags, + const char* rawFlag) +{ + this->AppendFlags(flags, this->EscapeForShell(rawFlag).c_str()); +} + +//---------------------------------------------------------------------------- void cmLocalGenerator::AppendDefines(std::set<std::string>& defines, const char* defines_list) { @@ -2341,7 +2394,7 @@ void cmLocalGenerator::AppendFeatureOptions( for(std::vector<std::string>::const_iterator oi = options.begin(); oi != options.end(); ++oi) { - this->AppendFlags(flags, this->EscapeForShell(oi->c_str()).c_str()); + this->AppendFlagEscape(flags, oi->c_str()); } } } diff --git a/Source/cmLocalGenerator.h b/Source/cmLocalGenerator.h index 9a71b9b..f35ef8e 100644 --- a/Source/cmLocalGenerator.h +++ b/Source/cmLocalGenerator.h @@ -149,6 +149,7 @@ public: const char* config); ///! Append flags to a string. virtual void AppendFlags(std::string& flags, const char* newFlags); + virtual void AppendFlagEscape(std::string& flags, const char* rawFlag); ///! Get the include flags for the current makefile and language std::string GetIncludeFlags(const std::vector<std::string> &includes, const char* lang, bool forResponseFile = false, @@ -217,9 +218,8 @@ public: cmGeneratorTarget* target, const char* lang = "C", const char *config = 0, bool stripImplicitInclDirs = true); - void GetCompileOptions(std::string& flags, - cmTarget* target, - const char *config); + void AddCompileOptions(std::string& flags, cmTarget* target, + const char* lang, const char* config); /** Compute the language used to compile the given source file. */ const char* GetSourceFileLanguage(const cmSourceFile& source); diff --git a/Source/cmLocalNinjaGenerator.cxx b/Source/cmLocalNinjaGenerator.cxx index 294a539..bdc3d80 100644 --- a/Source/cmLocalNinjaGenerator.cxx +++ b/Source/cmLocalNinjaGenerator.cxx @@ -340,14 +340,15 @@ cmLocalNinjaGenerator::WriteCustomCommandBuildStatement( this->AppendCustomCommandLines(cc, cmdLines); if (cmdLines.empty()) { - cmGlobalNinjaGenerator::WritePhonyBuild(this->GetBuildFileStream(), - "Phony custom command for " + - ninjaOutputs[0], - ninjaOutputs, - ninjaDeps, - cmNinjaDeps(), - orderOnlyDeps, - cmNinjaVars()); + this->GetGlobalNinjaGenerator()->WritePhonyBuild( + this->GetBuildFileStream(), + "Phony custom command for " + + ninjaOutputs[0], + ninjaOutputs, + ninjaDeps, + cmNinjaDeps(), + orderOnlyDeps, + cmNinjaVars()); } else { this->GetGlobalNinjaGenerator()->WriteCustomCommandBuild( this->BuildCommandLine(cmdLines), diff --git a/Source/cmLocalVisualStudio6Generator.cxx b/Source/cmLocalVisualStudio6Generator.cxx index 4c78f7f..0b61e1d 100644 --- a/Source/cmLocalVisualStudio6Generator.cxx +++ b/Source/cmLocalVisualStudio6Generator.cxx @@ -1228,7 +1228,7 @@ void cmLocalVisualStudio6Generator if(!linkLanguage) { cmSystemTools::Error - ("CMake can not determine linker language for target:", + ("CMake can not determine linker language for target: ", target.GetName()); return; } @@ -1649,7 +1649,7 @@ void cmLocalVisualStudio6Generator if(!linkLanguage) { cmSystemTools::Error - ("CMake can not determine linker language for target:", + ("CMake can not determine linker language for target: ", target.GetName()); return; } @@ -1674,6 +1674,14 @@ void cmLocalVisualStudio6Generator flagVar = baseFlagVar + "_RELWITHDEBINFO"; flagsRelWithDebInfo = this->Makefile->GetSafeDefinition(flagVar.c_str()); flagsRelWithDebInfo += " -DCMAKE_INTDIR=\\\"RelWithDebInfo\\\" "; + + this->AddCompileOptions(flags, &target, linkLanguage, 0); + this->AddCompileOptions(flagsDebug, &target, linkLanguage, "Debug"); + this->AddCompileOptions(flagsRelease, &target, linkLanguage, "Release"); + this->AddCompileOptions(flagsMinSizeRel, &target, linkLanguage, + "MinSizeRel"); + this->AddCompileOptions(flagsRelWithDebInfo, &target, linkLanguage, + "RelWithDebInfo"); } // if _UNICODE and _SBCS are not found, then add -D_MBCS @@ -1686,32 +1694,6 @@ void cmLocalVisualStudio6Generator flags += " /D \"_MBCS\""; } - { - std::string targetFlags; - this->GetCompileOptions(targetFlags, &target, 0); - // Add per-target flags. - if(!targetFlags.empty()) - { - flags += " "; - flags += targetFlags; - } - } -#define ADD_FLAGS(CONFIG) \ - { \ - std::string targetFlags; \ - this->GetCompileOptions(targetFlags, &target, #CONFIG); \ - if(!targetFlags.empty()) \ - { \ - flags ## CONFIG += " "; \ - flags ## CONFIG += targetFlags; \ - } \ - } - - ADD_FLAGS(Debug) - ADD_FLAGS(Release) - ADD_FLAGS(MinSizeRel) - ADD_FLAGS(RelWithDebInfo) - // Add per-target and per-configuration preprocessor definitions. std::set<std::string> definesSet; std::set<std::string> debugDefinesSet; diff --git a/Source/cmLocalVisualStudio7Generator.cxx b/Source/cmLocalVisualStudio7Generator.cxx index e7badf0..1d2f709 100644 --- a/Source/cmLocalVisualStudio7Generator.cxx +++ b/Source/cmLocalVisualStudio7Generator.cxx @@ -686,7 +686,7 @@ void cmLocalVisualStudio7Generator::WriteConfiguration(std::ostream& fout, if(!linkLanguage) { cmSystemTools::Error - ("CMake can not determine linker language for target:", + ("CMake can not determine linker language for target: ", target.GetName()); return; } @@ -711,6 +711,9 @@ void cmLocalVisualStudio7Generator::WriteConfiguration(std::ostream& fout, { flags += " /TP "; } + + // Add the target-specific flags. + this->AddCompileOptions(flags, &target, linkLanguage, configName); } if(this->FortranProject) @@ -723,15 +726,6 @@ void cmLocalVisualStudio7Generator::WriteConfiguration(std::ostream& fout, } } - std::string targetFlags; - this->GetCompileOptions(targetFlags, &target, configName); - // Add the target-specific flags. - if(!targetFlags.empty()) - { - flags += " "; - flags += targetFlags; - } - // Get preprocessor definitions for this directory. std::string defineFlags = this->Makefile->GetDefineFlags(); Options::Tool t = Options::Compiler; diff --git a/Source/cmLocalXCodeGenerator.cxx b/Source/cmLocalXCodeGenerator.cxx index 551ebd3..7c5f69d 100644 --- a/Source/cmLocalXCodeGenerator.cxx +++ b/Source/cmLocalXCodeGenerator.cxx @@ -33,3 +33,12 @@ cmLocalXCodeGenerator::GetTargetDirectory(cmTarget const&) const // No per-target directory for this generator (yet). return ""; } + +//---------------------------------------------------------------------------- +void cmLocalXCodeGenerator::AppendFlagEscape(std::string& flags, + const char* rawFlag) +{ + cmGlobalXCodeGenerator* gg = + static_cast<cmGlobalXCodeGenerator*>(this->GlobalGenerator); + gg->AppendFlag(flags, rawFlag); +} diff --git a/Source/cmLocalXCodeGenerator.h b/Source/cmLocalXCodeGenerator.h index eab228f..d97a41c 100644 --- a/Source/cmLocalXCodeGenerator.h +++ b/Source/cmLocalXCodeGenerator.h @@ -28,6 +28,7 @@ public: virtual ~cmLocalXCodeGenerator(); virtual std::string GetTargetDirectory(cmTarget const& target) const; + virtual void AppendFlagEscape(std::string& flags, const char* rawFlag); private: }; diff --git a/Source/cmMakefile.cxx b/Source/cmMakefile.cxx index 7d58d68..f3a66ba 100644 --- a/Source/cmMakefile.cxx +++ b/Source/cmMakefile.cxx @@ -3369,8 +3369,9 @@ int cmMakefile::ConfigureFile(const char* infile, const char* outfile, } std::string soutfile = outfile; std::string sinfile = infile; - this->AddCMakeDependFile(infile); + this->AddCMakeDependFile(sinfile); cmSystemTools::ConvertToUnixSlashes(soutfile); + this->AddCMakeOutputFile(soutfile); mode_t perm = 0; cmSystemTools::GetPermissions(sinfile.c_str(), perm); std::string::size_type pos = soutfile.rfind('/'); diff --git a/Source/cmMakefile.h b/Source/cmMakefile.h index 0a87752..4297155 100644 --- a/Source/cmMakefile.h +++ b/Source/cmMakefile.h @@ -648,7 +648,7 @@ public: const std::vector<std::string>& GetListFiles() const { return this->ListFiles; } ///! When the file changes cmake will be re-run from the build system. - void AddCMakeDependFile(const char* file) + void AddCMakeDependFile(const std::string& file) { this->ListFiles.push_back(file);} /** @@ -666,7 +666,7 @@ public: */ const std::vector<std::string>& GetOutputFiles() const { return this->OutputFiles; } - void AddCMakeOutputFile(const char* file) + void AddCMakeOutputFile(const std::string& file) { this->OutputFiles.push_back(file);} /** diff --git a/Source/cmMakefileExecutableTargetGenerator.cxx b/Source/cmMakefileExecutableTargetGenerator.cxx index e4219a9..271183e 100644 --- a/Source/cmMakefileExecutableTargetGenerator.cxx +++ b/Source/cmMakefileExecutableTargetGenerator.cxx @@ -365,6 +365,22 @@ void cmMakefileExecutableTargetGenerator::WriteExecutableRule(bool relink) vars.TargetVersionMajor = targetVersionMajor.c_str(); vars.TargetVersionMinor = targetVersionMinor.c_str(); + if (const char *rootPath = + this->Makefile->GetDefinition("CMAKE_SYSROOT")) + { + if (*rootPath) + { + if (const char *sysrootFlag = + this->Makefile->GetDefinition("CMAKE_SYSROOT_FLAG")) + { + flags += " "; + flags += sysrootFlag; + flags += this->LocalGenerator->EscapeForShell(rootPath); + flags += " "; + } + } + } + vars.LinkLibraries = linkLibs.c_str(); vars.Flags = flags.c_str(); vars.LinkFlags = linkFlags.c_str(); diff --git a/Source/cmMakefileLibraryTargetGenerator.cxx b/Source/cmMakefileLibraryTargetGenerator.cxx index 347f26d..36d1a5a 100644 --- a/Source/cmMakefileLibraryTargetGenerator.cxx +++ b/Source/cmMakefileLibraryTargetGenerator.cxx @@ -589,6 +589,26 @@ void cmMakefileLibraryTargetGenerator::WriteLibraryRules cmLocalGenerator::SHELL); vars.ObjectDir = objdir.c_str(); vars.Target = targetOutPathReal.c_str(); + + if(this->Target->GetType() == cmTarget::SHARED_LIBRARY) + { + if (const char *rootPath = + this->Makefile->GetSafeDefinition("CMAKE_SYSROOT")) + { + if (*rootPath) + { + if (const char *sysrootFlag = + this->Makefile->GetDefinition("CMAKE_SYSROOT_FLAG")) + { + linkFlags += " "; + linkFlags += sysrootFlag; + linkFlags += this->LocalGenerator->EscapeForShell(rootPath); + linkFlags += " "; + } + } + } + } + vars.LinkLibraries = linkLibs.c_str(); vars.ObjectsQuoted = buildObjs.c_str(); if (this->Target->HasSOName(this->ConfigName)) diff --git a/Source/cmMakefileTargetGenerator.cxx b/Source/cmMakefileTargetGenerator.cxx index 10b7849..1492dfa 100644 --- a/Source/cmMakefileTargetGenerator.cxx +++ b/Source/cmMakefileTargetGenerator.cxx @@ -285,6 +285,10 @@ std::string cmMakefileTargetGenerator::GetFlags(const std::string &l) this->LocalGenerator-> AppendFlags(flags,this->GetFrameworkFlags().c_str()); + // Add target-specific flags. + this->LocalGenerator->AddCompileOptions(flags, this->Target, + lang, this->ConfigName); + ByLanguageMap::value_type entry(l, flags); i = this->FlagsByLanguage.insert(entry).first; } @@ -335,25 +339,12 @@ void cmMakefileTargetGenerator::WriteTargetLanguageFlags() this->Makefile->GetSafeDefinition(compiler.c_str()) << "\n"; } - std::string targetFlags; for(std::set<cmStdString>::const_iterator l = languages.begin(); l != languages.end(); ++l) { *this->FlagFileStream << *l << "_FLAGS = " << this->GetFlags(*l) << "\n\n"; *this->FlagFileStream << *l << "_DEFINES = " << this->GetDefines(*l) << "\n\n"; - std::string targetLangFlags; - this->LocalGenerator->GetCompileOptions(targetLangFlags, this->Target, - this->LocalGenerator->ConfigurationName.c_str()); - if (!targetFlags.empty() && targetFlags != targetLangFlags) - { - targetFlags += " " + targetLangFlags; - } - } - - if (!targetFlags.empty()) - { - *this->FlagFileStream << "# TARGET_FLAGS = " << targetFlags << "\n\n"; } } @@ -542,39 +533,6 @@ cmMakefileTargetGenerator std::string configUpper = cmSystemTools::UpperCase(this->LocalGenerator->ConfigurationName); - std::string targetFlags; - this->LocalGenerator->GetCompileOptions(targetFlags, this->Target, - configUpper.c_str()); - if (!targetFlags.empty()) - { - std::string langIncludeExpr = "CMAKE_"; - langIncludeExpr += lang; - langIncludeExpr += "_FLAG_REGEX"; - const char* regex = this->Makefile-> - GetDefinition(langIncludeExpr.c_str()); - if(regex) - { - cmsys::RegularExpression r(regex); - std::vector<std::string> args; - cmSystemTools::ParseWindowsCommandLine( - targetFlags.c_str(), - args); - for(std::vector<std::string>::iterator i = args.begin(); - i != args.end(); ++i) - { - if(r.find(i->c_str())) - { - this->LocalGenerator->AppendFlags - (flags, i->c_str()); - } - } - } - else - { - this->LocalGenerator->AppendFlags(flags, targetFlags.c_str()); - } - } - // Add Fortran format flags. if(strcmp(lang, "Fortran") == 0) { @@ -686,6 +644,23 @@ cmMakefileTargetGenerator cmLocalGenerator::START_OUTPUT, cmLocalGenerator::SHELL); vars.ObjectDir = objectDir.c_str(); + + if (const char *rootPath = + this->Makefile->GetSafeDefinition("CMAKE_SYSROOT")) + { + if (*rootPath) + { + if (const char *sysrootFlag = + this->Makefile->GetDefinition("CMAKE_SYSROOT_FLAG")) + { + flags += " "; + flags += sysrootFlag; + flags += this->LocalGenerator->EscapeForShell(rootPath); + flags += " "; + } + } + } + vars.Flags = flags.c_str(); std::string definesString = "$("; diff --git a/Source/cmNinjaNormalTargetGenerator.cxx b/Source/cmNinjaNormalTargetGenerator.cxx index 1bc4302..921ca92 100644 --- a/Source/cmNinjaNormalTargetGenerator.cxx +++ b/Source/cmNinjaNormalTargetGenerator.cxx @@ -71,7 +71,8 @@ cmNinjaNormalTargetGenerator::~cmNinjaNormalTargetGenerator() void cmNinjaNormalTargetGenerator::Generate() { if (!this->TargetLinkLanguage) { - cmSystemTools::Error("CMake can not determine linker language for target:", + cmSystemTools::Error("CMake can not determine linker language for " + "target: ", this->GetTarget()->GetName()); return; } @@ -223,7 +224,27 @@ cmNinjaNormalTargetGenerator vars.TargetVersionMajor = targetVersionMajor.c_str(); vars.TargetVersionMinor = targetVersionMinor.c_str(); - vars.Flags = "$FLAGS"; + + std::string flags = "$FLAGS"; + + if (const char *rootPath = + this->GetMakefile()->GetSafeDefinition("CMAKE_SYSROOT")) + { + if (*rootPath) + { + if (const char *sysrootFlag = + this->GetMakefile()->GetDefinition("CMAKE_SYSROOT_FLAG")) + { + flags += " "; + flags += sysrootFlag; + flags += this->GetLocalGenerator()->EscapeForShell(rootPath); + flags += " "; + } + } + } + + vars.Flags = flags.c_str(); + vars.LinkFlags = "$LINK_FLAGS"; std::string langFlags; @@ -577,32 +598,37 @@ void cmNinjaNormalTargetGenerator::WriteLinkStatement() #endif } + //Get the global generator as we are going to be call WriteBuild numerous + //times in the following section + cmGlobalNinjaGenerator* globalGenerator = this->GetGlobalGenerator(); + + const std::string rspfile = std::string (cmake::GetCMakeFilesDirectoryPostSlash()) + this->GetTarget()->GetName() + ".rsp"; // Write the build statement for this target. - cmGlobalNinjaGenerator::WriteBuild(this->GetBuildFileStream(), - comment.str(), - this->LanguageLinkerRule(), - outputs, - explicitDeps, - implicitDeps, - emptyDeps, - vars, - rspfile, - commandLineLengthLimit); + globalGenerator->WriteBuild(this->GetBuildFileStream(), + comment.str(), + this->LanguageLinkerRule(), + outputs, + explicitDeps, + implicitDeps, + emptyDeps, + vars, + rspfile, + commandLineLengthLimit); if (targetOutput != targetOutputReal) { if (targetType == cmTarget::EXECUTABLE) { - cmGlobalNinjaGenerator::WriteBuild(this->GetBuildFileStream(), + globalGenerator->WriteBuild(this->GetBuildFileStream(), "Create executable symlink " + targetOutput, - "CMAKE_SYMLINK_EXECUTABLE", - cmNinjaDeps(1, targetOutput), - cmNinjaDeps(1, targetOutputReal), - emptyDeps, - emptyDeps, - symlinkVars); + "CMAKE_SYMLINK_EXECUTABLE", + cmNinjaDeps(1, targetOutput), + cmNinjaDeps(1, targetOutputReal), + emptyDeps, + emptyDeps, + symlinkVars); } else { cmNinjaDeps symlinks; const std::string soName = this->GetTargetFilePath(this->TargetNameSO); @@ -614,30 +640,30 @@ void cmNinjaNormalTargetGenerator::WriteLinkStatement() symlinks.push_back(soName); } symlinks.push_back(targetOutput); - cmGlobalNinjaGenerator::WriteBuild(this->GetBuildFileStream(), - "Create library symlink " + targetOutput, - "CMAKE_SYMLINK_LIBRARY", - symlinks, - cmNinjaDeps(1, targetOutputReal), - emptyDeps, - emptyDeps, - symlinkVars); + globalGenerator->WriteBuild(this->GetBuildFileStream(), + "Create library symlink " + targetOutput, + "CMAKE_SYMLINK_LIBRARY", + symlinks, + cmNinjaDeps(1, targetOutputReal), + emptyDeps, + emptyDeps, + symlinkVars); } } if (!this->TargetNameImport.empty()) { // Since using multiple outputs would mess up the $out variable, use an // alias for the import library. - cmGlobalNinjaGenerator::WritePhonyBuild(this->GetBuildFileStream(), - "Alias for import library.", - cmNinjaDeps(1, targetOutputImplib), - cmNinjaDeps(1, targetOutputReal)); + globalGenerator->WritePhonyBuild(this->GetBuildFileStream(), + "Alias for import library.", + cmNinjaDeps(1, targetOutputImplib), + cmNinjaDeps(1, targetOutputReal)); } // Add aliases for the file name and the target name. - this->GetGlobalGenerator()->AddTargetAlias(this->TargetNameOut, + globalGenerator->AddTargetAlias(this->TargetNameOut, this->GetTarget()); - this->GetGlobalGenerator()->AddTargetAlias(this->GetTargetName(), + globalGenerator->AddTargetAlias(this->GetTargetName(), this->GetTarget()); } @@ -648,11 +674,11 @@ void cmNinjaNormalTargetGenerator::WriteObjectLibStatement() cmNinjaDeps outputs; this->GetLocalGenerator()->AppendTargetOutputs(this->GetTarget(), outputs); cmNinjaDeps depends = this->GetObjects(); - cmGlobalNinjaGenerator::WritePhonyBuild(this->GetBuildFileStream(), - "Object library " - + this->GetTargetName(), - outputs, - depends); + this->GetGlobalGenerator()->WritePhonyBuild(this->GetBuildFileStream(), + "Object library " + + this->GetTargetName(), + outputs, + depends); // Add aliases for the target name. this->GetGlobalGenerator()->AddTargetAlias(this->GetTargetName(), diff --git a/Source/cmNinjaTargetGenerator.cxx b/Source/cmNinjaTargetGenerator.cxx index ae18a48..65173ca 100644 --- a/Source/cmNinjaTargetGenerator.cxx +++ b/Source/cmNinjaTargetGenerator.cxx @@ -174,38 +174,8 @@ cmNinjaTargetGenerator::ComputeFlagsForObject(cmSourceFile *source, this->LocalGenerator->AppendFlags(flags, this->Makefile->GetDefineFlags()); // Add target-specific flags. - std::string targetFlags; - this->LocalGenerator->GetCompileOptions(targetFlags, this->Target, config); - if(!targetFlags.empty()) - { - std::string langIncludeExpr = "CMAKE_"; - langIncludeExpr += language; - langIncludeExpr += "_FLAG_REGEX"; - const char* regex = this->Makefile-> - GetDefinition(langIncludeExpr.c_str()); - if(regex) - { - cmsys::RegularExpression r(regex); - std::vector<std::string> args; - cmSystemTools::ParseWindowsCommandLine( - targetFlags.c_str(), - args); - for(std::vector<std::string>::iterator i = args.begin(); - i != args.end(); ++i) - { - if(r.find(i->c_str())) - { - this->LocalGenerator->AppendFlags - (flags, i->c_str()); - } - } - } - else - { - this->LocalGenerator->AppendFlags - (flags, targetFlags.c_str()); - } - } + this->LocalGenerator->AddCompileOptions(flags, this->Target, + language.c_str(), config); // Add source file specific flags. this->LocalGenerator->AppendFlags(flags, @@ -414,7 +384,23 @@ cmNinjaTargetGenerator cmSystemTools::ReplaceString(depFlagsStr, "<CMAKE_C_COMPILER>", mf->GetDefinition("CMAKE_C_COMPILER")); flags += " " + depFlagsStr; - } + + if (const char *rootPath = + this->Makefile->GetSafeDefinition("CMAKE_SYSROOT")) + { + if (*rootPath) + { + if (const char *sysrootFlag = + this->Makefile->GetDefinition("CMAKE_SYSROOT_FLAG")) + { + flags += " "; + flags += sysrootFlag; + flags += this->LocalGenerator->EscapeForShell(rootPath); + flags += " "; + } + } + } + } vars.Flags = flags.c_str(); @@ -626,24 +612,24 @@ cmNinjaTargetGenerator sourceFileName); } - cmGlobalNinjaGenerator::WriteBuild(this->GetBuildFileStream(), - comment, - rule, - outputs, - explicitDeps, - implicitDeps, - orderOnlyDeps, - vars); + this->GetGlobalGenerator()->WriteBuild(this->GetBuildFileStream(), + comment, + rule, + outputs, + explicitDeps, + implicitDeps, + orderOnlyDeps, + vars); if(const char* objectOutputs = source->GetProperty("OBJECT_OUTPUTS")) { std::vector<std::string> outputList; cmSystemTools::ExpandListArgument(objectOutputs, outputList); std::transform(outputList.begin(), outputList.end(), outputList.begin(), MapToNinjaPath()); - cmGlobalNinjaGenerator::WritePhonyBuild(this->GetBuildFileStream(), - "Additional output files.", - outputList, - outputs); + this->GetGlobalGenerator()->WritePhonyBuild(this->GetBuildFileStream(), + "Additional output files.", + outputList, + outputs); } } diff --git a/Source/cmNinjaUtilityTargetGenerator.cxx b/Source/cmNinjaUtilityTargetGenerator.cxx index 9c2fd13..755ce6e 100644 --- a/Source/cmNinjaUtilityTargetGenerator.cxx +++ b/Source/cmNinjaUtilityTargetGenerator.cxx @@ -61,11 +61,11 @@ void cmNinjaUtilityTargetGenerator::Generate() this->GetLocalGenerator()->AppendTargetDepends(this->GetTarget(), deps); if (commands.empty()) { - cmGlobalNinjaGenerator::WritePhonyBuild(this->GetBuildFileStream(), - "Utility command for " - + this->GetTargetName(), - outputs, - deps); + this->GetGlobalGenerator()->WritePhonyBuild(this->GetBuildFileStream(), + "Utility command for " + + this->GetTargetName(), + outputs, + deps); } else { std::string command = this->GetLocalGenerator()->BuildCommandLine(commands); @@ -105,10 +105,11 @@ void cmNinjaUtilityTargetGenerator::Generate() cmNinjaDeps(1, utilCommandName), deps); - cmGlobalNinjaGenerator::WritePhonyBuild(this->GetBuildFileStream(), - "", - outputs, - cmNinjaDeps(1, utilCommandName)); + this->GetGlobalGenerator()->WritePhonyBuild(this->GetBuildFileStream(), + "", + outputs, + cmNinjaDeps(1, utilCommandName) + ); } this->GetGlobalGenerator()->AddTargetAlias(this->GetTargetName(), diff --git a/Source/cmOSXBundleGenerator.cxx b/Source/cmOSXBundleGenerator.cxx index d3cdf85..a475c7c 100644 --- a/Source/cmOSXBundleGenerator.cxx +++ b/Source/cmOSXBundleGenerator.cxx @@ -49,7 +49,7 @@ void cmOSXBundleGenerator::CreateAppBundle(const std::string& targetName, out += "/"; out += this->Target->GetAppBundleDirectory(this->ConfigName, false); cmSystemTools::MakeDirectory(out.c_str()); - this->Makefile->AddCMakeOutputFile(out.c_str()); + this->Makefile->AddCMakeOutputFile(out); std::string newoutpath = out; @@ -62,7 +62,7 @@ void cmOSXBundleGenerator::CreateAppBundle(const std::string& targetName, this->LocalGenerator->GenerateAppleInfoPList(this->Target, targetName.c_str(), plist.c_str()); - this->Makefile->AddCMakeOutputFile(plist.c_str()); + this->Makefile->AddCMakeOutputFile(plist); outpath = newoutpath; } @@ -114,7 +114,7 @@ void cmOSXBundleGenerator::CreateFramework( newName += "/Current"; cmSystemTools::RemoveFile(newName.c_str()); cmSystemTools::CreateSymlink(oldName.c_str(), newName.c_str()); - this->Makefile->AddCMakeOutputFile(newName.c_str()); + this->Makefile->AddCMakeOutputFile(newName); // foo -> Versions/Current/foo oldName = "Versions/Current/"; @@ -123,7 +123,7 @@ void cmOSXBundleGenerator::CreateFramework( newName += name; cmSystemTools::RemoveFile(newName.c_str()); cmSystemTools::CreateSymlink(oldName.c_str(), newName.c_str()); - this->Makefile->AddCMakeOutputFile(newName.c_str()); + this->Makefile->AddCMakeOutputFile(newName); // Resources -> Versions/Current/Resources if(this->MacContentFolders->find("Resources") != @@ -134,7 +134,7 @@ void cmOSXBundleGenerator::CreateFramework( newName += "Resources"; cmSystemTools::RemoveFile(newName.c_str()); cmSystemTools::CreateSymlink(oldName.c_str(), newName.c_str()); - this->Makefile->AddCMakeOutputFile(newName.c_str()); + this->Makefile->AddCMakeOutputFile(newName); } // Headers -> Versions/Current/Headers @@ -146,7 +146,7 @@ void cmOSXBundleGenerator::CreateFramework( newName += "Headers"; cmSystemTools::RemoveFile(newName.c_str()); cmSystemTools::CreateSymlink(oldName.c_str(), newName.c_str()); - this->Makefile->AddCMakeOutputFile(newName.c_str()); + this->Makefile->AddCMakeOutputFile(newName); } // PrivateHeaders -> Versions/Current/PrivateHeaders @@ -158,7 +158,7 @@ void cmOSXBundleGenerator::CreateFramework( newName += "PrivateHeaders"; cmSystemTools::RemoveFile(newName.c_str()); cmSystemTools::CreateSymlink(oldName.c_str(), newName.c_str()); - this->Makefile->AddCMakeOutputFile(newName.c_str()); + this->Makefile->AddCMakeOutputFile(newName); } } @@ -174,7 +174,7 @@ void cmOSXBundleGenerator::CreateCFBundle(const std::string& targetName, out += "/"; out += this->Target->GetCFBundleDirectory(this->ConfigName, false); cmSystemTools::MakeDirectory(out.c_str()); - this->Makefile->AddCMakeOutputFile(out.c_str()); + this->Makefile->AddCMakeOutputFile(out); // Configure the Info.plist file. Note that it needs the executable name // to be set. @@ -184,7 +184,7 @@ void cmOSXBundleGenerator::CreateCFBundle(const std::string& targetName, this->LocalGenerator->GenerateAppleInfoPList(this->Target, targetName.c_str(), plist.c_str()); - this->Makefile->AddCMakeOutputFile(plist.c_str()); + this->Makefile->AddCMakeOutputFile(plist); } //---------------------------------------------------------------------------- diff --git a/Source/cmQtAutomoc.cxx b/Source/cmQtAutomoc.cxx index 350b462..05c43c4 100644 --- a/Source/cmQtAutomoc.cxx +++ b/Source/cmQtAutomoc.cxx @@ -152,10 +152,44 @@ bool cmQtAutomoc::InitializeMocSourceFile(cmTarget* target) return true; } -void cmQtAutomoc::SetupAutomocTarget(cmTarget* target) +static void GetCompileDefinitionsAndDirectories(cmTarget *target, + const char * config, + std::string &incs, + std::string &defs) { cmMakefile* makefile = target->GetMakefile(); cmLocalGenerator* localGen = makefile->GetLocalGenerator(); + std::vector<std::string> includeDirs; + cmGeneratorTarget gtgt(target); + // Get the include dirs for this target, without stripping the implicit + // include dirs off, see http://public.kitware.com/Bug/view.php?id=13667 + localGen->GetIncludeDirectories(includeDirs, >gt, "CXX", config, false); + const char* sep = ""; + incs = ""; + for(std::vector<std::string>::const_iterator incDirIt = includeDirs.begin(); + incDirIt != includeDirs.end(); + ++incDirIt) + { + incs += sep; + sep = ";"; + incs += *incDirIt; + } + + defs = target->GetCompileDefinitions(config); + + const char *tmp = makefile->GetProperty("COMPILE_DEFINITIONS"); + sep = ""; + if (tmp) + { + defs += sep; + sep = ";"; + defs += tmp; + } +} + +void cmQtAutomoc::SetupAutomocTarget(cmTarget* target) +{ + cmMakefile* makefile = target->GetMakefile(); const char* targetName = target->GetName(); bool relaxedMode = makefile->IsOn("CMAKE_AUTOMOC_RELAXED_MODE"); @@ -175,6 +209,7 @@ void cmQtAutomoc::SetupAutomocTarget(cmTarget* target) currentLine.push_back("-E"); currentLine.push_back("cmake_automoc"); currentLine.push_back(targetDir); + currentLine.push_back("$<CONFIGURATION>"); cmCustomCommandLines commandLines; commandLines.push_back(currentLine); @@ -188,6 +223,7 @@ void cmQtAutomoc::SetupAutomocTarget(cmTarget* target) #if defined(_WIN32) && !defined(__CYGWIN__) bool usePRE_BUILD = false; + cmLocalGenerator* localGen = makefile->GetLocalGenerator(); cmGlobalGenerator* gg = localGen->GetGlobalGenerator(); if(strstr(gg->GetName(), "Visual Studio")) { @@ -263,32 +299,7 @@ void cmQtAutomoc::SetupAutomocTarget(cmTarget* target) } } - - std::vector<std::string> includeDirs; - cmGeneratorTarget gtgt(target); - // Get the include dirs for this target, without stripping the implicit - // include dirs off, see http://public.kitware.com/Bug/view.php?id=13667 - localGen->GetIncludeDirectories(includeDirs, >gt, "CXX", 0, false); - std::string _moc_incs = ""; - const char* sep = ""; - for(std::vector<std::string>::const_iterator incDirIt = includeDirs.begin(); - incDirIt != includeDirs.end(); - ++incDirIt) - { - _moc_incs += sep; - sep = ";"; - _moc_incs += *incDirIt; - } - - std::string _moc_compile_defs = target->GetCompileDefinitions(0); - - const char* tmp = makefile->GetProperty("COMPILE_DEFINITIONS"); - if (tmp) - { - _moc_compile_defs += ";"; - _moc_compile_defs += tmp; - } - tmp = target->GetProperty("AUTOMOC_MOC_OPTIONS"); + const char* tmp = target->GetProperty("AUTOMOC_MOC_OPTIONS"); std::string _moc_options = (tmp!=0 ? tmp : ""); // forget the variables added here afterwards again: @@ -297,10 +308,6 @@ void cmQtAutomoc::SetupAutomocTarget(cmTarget* target) makefile->AddDefinition("_moc_target_name", cmLocalGenerator::EscapeForCMake(automocTargetName.c_str()).c_str()); - makefile->AddDefinition("_moc_incs", - cmLocalGenerator::EscapeForCMake(_moc_incs.c_str()).c_str()); - makefile->AddDefinition("_moc_compile_defs", - cmLocalGenerator::EscapeForCMake(_moc_compile_defs.c_str()).c_str()); makefile->AddDefinition("_moc_options", cmLocalGenerator::EscapeForCMake(_moc_options.c_str()).c_str()); makefile->AddDefinition("_moc_files", @@ -309,6 +316,49 @@ void cmQtAutomoc::SetupAutomocTarget(cmTarget* target) cmLocalGenerator::EscapeForCMake(_moc_headers.c_str()).c_str()); makefile->AddDefinition("_moc_relaxed_mode", relaxedMode ? "TRUE" : "FALSE"); + std::string _moc_incs; + std::string _moc_compile_defs; + std::vector<std::string> configs; + const char *config = makefile->GetConfigurations(configs); + GetCompileDefinitionsAndDirectories(target, config, + _moc_incs, _moc_compile_defs); + + makefile->AddDefinition("_moc_incs", + cmLocalGenerator::EscapeForCMake(_moc_incs.c_str()).c_str()); + makefile->AddDefinition("_moc_compile_defs", + cmLocalGenerator::EscapeForCMake(_moc_compile_defs.c_str()).c_str()); + + std::map<std::string, std::string> configIncludes; + std::map<std::string, std::string> configDefines; + + for (std::vector<std::string>::const_iterator li = configs.begin(); + li != configs.end(); ++li) + { + std::string config_moc_incs; + std::string config_moc_compile_defs; + GetCompileDefinitionsAndDirectories(target, li->c_str(), + config_moc_incs, + config_moc_compile_defs); + if (config_moc_incs != _moc_incs) + { + configIncludes["_moc_incs_" + *li] = + cmLocalGenerator::EscapeForCMake(config_moc_incs.c_str()); + if(_moc_incs.empty()) + { + _moc_incs = config_moc_incs; + } + } + if (config_moc_compile_defs != _moc_compile_defs) + { + configDefines["_moc_compile_defs_" + *li] = + cmLocalGenerator::EscapeForCMake(config_moc_compile_defs.c_str()); + if(_moc_compile_defs.empty()) + { + _moc_compile_defs = config_moc_compile_defs; + } + } + } + const char *qtVersion = makefile->GetDefinition("Qt5Core_VERSION_MAJOR"); if (!qtVersion) { @@ -356,17 +406,50 @@ void cmQtAutomoc::SetupAutomocTarget(cmTarget* target) outputFile += "/AutomocInfo.cmake"; makefile->ConfigureFile(inputFile.c_str(), outputFile.c_str(), false, true, false); + + if (!configDefines.empty() || !configIncludes.empty()) + { + std::ofstream infoFile(outputFile.c_str(), std::ios::app); + if ( !infoFile ) + { + std::string error = "Internal CMake error when trying to open file: "; + error += outputFile.c_str(); + error += " for writing."; + cmSystemTools::Error(error.c_str()); + return; + } + if (!configDefines.empty()) + { + for (std::map<std::string, std::string>::iterator + it = configDefines.begin(), end = configDefines.end(); + it != end; ++it) + { + infoFile << "SET(AM_MOC_COMPILE_DEFINITIONS_" << it->first << + " " << it->second << ")\n"; + } + } + if (!configIncludes.empty()) + { + for (std::map<std::string, std::string>::iterator + it = configIncludes.begin(), end = configIncludes.end(); + it != end; ++it) + { + infoFile << "SET(AM_MOC_INCLUDES_" << it->first << + " " << it->second << ")\n"; + } + } + } } -bool cmQtAutomoc::Run(const char* targetDirectory) +bool cmQtAutomoc::Run(const char* targetDirectory, const char *config) { bool success = true; cmake cm; cmGlobalGenerator* gg = this->CreateGlobalGenerator(&cm, targetDirectory); cmMakefile* makefile = gg->GetCurrentLocalGenerator()->GetMakefile(); - this->ReadAutomocInfoFile(makefile, targetDirectory); + this->ReadAutomocInfoFile(makefile, targetDirectory, config); this->ReadOldMocDefinitionsFile(makefile, targetDirectory); this->Init(); @@ -403,7 +486,8 @@ cmGlobalGenerator* cmQtAutomoc::CreateGlobalGenerator(cmake* cm, bool cmQtAutomoc::ReadAutomocInfoFile(cmMakefile* makefile, - const char* targetDirectory) + const char* targetDirectory, + const char *config) { std::string filename(cmSystemTools::CollapseFullPath(targetDirectory)); cmSystemTools::ConvertToUnixSlashes(filename); @@ -411,7 +495,7 @@ bool cmQtAutomoc::ReadAutomocInfoFile(cmMakefile* makefile, if (!makefile->ReadListFile(0, filename.c_str())) { - cmSystemTools::Error("Error processing file:", filename.c_str()); + cmSystemTools::Error("Error processing file: ", filename.c_str()); return false; } @@ -428,9 +512,26 @@ bool cmQtAutomoc::ReadAutomocInfoFile(cmMakefile* makefile, 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->MocIncludesStr = makefile->GetSafeDefinition("AM_MOC_INCLUDES"); + std::string compileDefsPropOrig = "AM_MOC_COMPILE_DEFINITIONS"; + std::string compileDefsProp = compileDefsPropOrig; + if(config) + { + compileDefsProp += "_"; + compileDefsProp += config; + } + const char *compileDefs = makefile->GetDefinition(compileDefsProp.c_str()); + this->MocCompileDefinitionsStr = compileDefs ? compileDefs + : makefile->GetSafeDefinition(compileDefsPropOrig.c_str()); + std::string includesPropOrig = "AM_MOC_INCLUDES"; + std::string includesProp = includesPropOrig; + if(config) + { + includesProp += "_"; + includesProp += config; + } + const char *includes = makefile->GetDefinition(includesProp.c_str()); + this->MocIncludesStr = includes ? includes + : makefile->GetSafeDefinition(includesPropOrig.c_str()); this->MocOptionsStr = makefile->GetSafeDefinition("AM_MOC_OPTIONS"); this->ProjectBinaryDir = makefile->GetSafeDefinition("AM_CMAKE_BINARY_DIR"); this->ProjectSourceDir = makefile->GetSafeDefinition("AM_CMAKE_SOURCE_DIR"); diff --git a/Source/cmQtAutomoc.h b/Source/cmQtAutomoc.h index 01b68fc..ebeeb0e 100644 --- a/Source/cmQtAutomoc.h +++ b/Source/cmQtAutomoc.h @@ -21,7 +21,7 @@ class cmQtAutomoc { public: cmQtAutomoc(); - bool Run(const char* targetDirectory); + bool Run(const char* targetDirectory, const char *config); bool InitializeMocSourceFile(cmTarget* target); void SetupAutomocTarget(cmTarget* target); @@ -31,7 +31,8 @@ private: const char* targetDirectory); bool ReadAutomocInfoFile(cmMakefile* makefile, - const char* targetDirectory); + const char* targetDirectory, + const char *config); bool ReadOldMocDefinitionsFile(cmMakefile* makefile, const char* targetDirectory); void WriteOldMocDefinitionsFile(const char* targetDirectory); diff --git a/Source/cmStringCommand.cxx b/Source/cmStringCommand.cxx index 1fbde01..68ba13f 100644 --- a/Source/cmStringCommand.cxx +++ b/Source/cmStringCommand.cxx @@ -534,8 +534,12 @@ void cmStringCommand::ClearMatches(cmMakefile* mf) { char name[128]; sprintf(name, "CMAKE_MATCH_%d", i); - mf->AddDefinition(name, ""); - mf->MarkVariableAsUsed(name); + const char* s = mf->GetDefinition(name); + if(s && *s != 0) + { + mf->AddDefinition(name, ""); + mf->MarkVariableAsUsed(name); + } } } @@ -544,10 +548,14 @@ void cmStringCommand::StoreMatches(cmMakefile* mf,cmsys::RegularExpression& re) { for (unsigned int i=0; i<10; i++) { - char name[128]; - sprintf(name, "CMAKE_MATCH_%d", i); - mf->AddDefinition(name, re.match(i).c_str()); - mf->MarkVariableAsUsed(name); + std::string m = re.match(i); + if(m.size() > 0) + { + char name[128]; + sprintf(name, "CMAKE_MATCH_%d", i); + mf->AddDefinition(name, re.match(i).c_str()); + mf->MarkVariableAsUsed(name); + } } } diff --git a/Source/cmSystemTools.cxx b/Source/cmSystemTools.cxx index 66b34ab..4ae16cc 100644 --- a/Source/cmSystemTools.cxx +++ b/Source/cmSystemTools.cxx @@ -1951,7 +1951,7 @@ bool extract_tar(const char* outFileName, bool verbose, { cmSystemTools::Error("Problem with archive_write_header(): ", archive_error_string(ext)); - cmSystemTools::Error("Current file:", + cmSystemTools::Error("Current file: ", archive_entry_pathname(entry)); break; } @@ -2425,7 +2425,10 @@ bool cmSystemTools::GuessLibraryInstallName(std::string const& fullPath, RunSingleCommand(cmds, &output, 0, 0, OUTPUT_NONE); std::vector<std::string> strs = cmSystemTools::tokenize(output, "\n"); - if(strs.size() == 2) + // otool returns extra lines reporting multiple install names + // in case the binary is multi-arch and none of the architectures + // is native (e.g. i386;ppc on x86_64) + if(strs.size() >= 2) { soname = strs[1]; return true; diff --git a/Source/cmSystemTools.h b/Source/cmSystemTools.h index f5be26b..ec53929 100644 --- a/Source/cmSystemTools.h +++ b/Source/cmSystemTools.h @@ -274,7 +274,7 @@ public: static bool GetRunCommandOutput() { return s_DisableRunCommandOutput; } /** - * Come constants for different file formats. + * Some constants for different file formats. */ enum FileFormat { NO_FILE_FORMAT = 0, diff --git a/Source/cmTarget.cxx b/Source/cmTarget.cxx index 7d25b91..b14db43 100644 --- a/Source/cmTarget.cxx +++ b/Source/cmTarget.cxx @@ -1403,6 +1403,11 @@ void cmTarget::DefineProperties(cmake *cm) "Sets the \"RootNamespace\" attribute for a generated Visual Studio " "project. The attribute will be generated only if this is set."); cm->DefineProperty + ("VS_DOTNET_TARGET_FRAMEWORK_VERSION", cmProperty::TARGET, + "Specify the .NET target framework version.", + "Used to specify the .NET target framework version for C++/CLI. " + "For example, \"v4.5\"."); + cm->DefineProperty ("VS_DOTNET_REFERENCES", cmProperty::TARGET, "Visual Studio managed project .NET references", "Adds one or more semicolon-delimited .NET references to a " diff --git a/Source/cmTryCompileCommand.h b/Source/cmTryCompileCommand.h index 6caa130..163756d 100644 --- a/Source/cmTryCompileCommand.h +++ b/Source/cmTryCompileCommand.h @@ -64,16 +64,16 @@ public: "Specify targetName to build a specific target instead of the 'all' or " "'ALL_BUILD' target." "\n" - " try_compile(RESULT_VAR <bindir> <srcfile>\n" + " try_compile(RESULT_VAR <bindir> <srcfile|SOURCES srcfile...>\n" " [CMAKE_FLAGS flags...]\n" " [COMPILE_DEFINITIONS flags...]\n" " [LINK_LIBRARIES libs...]\n" " [OUTPUT_VARIABLE <var>]\n" " [COPY_FILE <fileName>])\n" - "Try building a source file into an executable. " - "In this form the user need only supply a source file that defines " - "a 'main'. " - "CMake will create a CMakeLists.txt file to build the source " + "Try building an executable from one or more source files. " + "In this form the user need only supply one or more source files " + "that include a definition for 'main'. " + "CMake will create a CMakeLists.txt file to build the source(s) " "as an executable. " "Specify COPY_FILE to get a copy of the linked executable at the " "given fileName." diff --git a/Source/cmVisualStudio10TargetGenerator.cxx b/Source/cmVisualStudio10TargetGenerator.cxx index f8de3a8..479721a 100644 --- a/Source/cmVisualStudio10TargetGenerator.cxx +++ b/Source/cmVisualStudio10TargetGenerator.cxx @@ -280,6 +280,13 @@ void cmVisualStudio10TargetGenerator::Generate() } this->WriteString("<ProjectName>", 2); (*this->BuildFileStream) << projLabel << "</ProjectName>\n"; + if(const char* targetFrameworkVersion = this->Target->GetProperty( + "VS_DOTNET_TARGET_FRAMEWORK_VERSION")) + { + this->WriteString("<TargetFrameworkVersion>", 2); + (*this->BuildFileStream) << targetFrameworkVersion + << "</TargetFrameworkVersion>\n"; + } this->WriteString("</PropertyGroup>\n", 1); this->WriteString("<Import Project=" "\"$(VCTargetsPath)\\Microsoft.Cpp.Default.props\" />\n", @@ -1242,7 +1249,7 @@ bool cmVisualStudio10TargetGenerator::ComputeClOptions( if(!linkLanguage) { cmSystemTools::Error - ("CMake can not determine linker language for target:", + ("CMake can not determine linker language for target: ", this->Name.c_str()); return false; } @@ -1269,17 +1276,10 @@ bool cmVisualStudio10TargetGenerator::ComputeClOptions( { flags += " /TP "; } + this->LocalGenerator->AddCompileOptions(flags, this->Target, + linkLanguage, configName.c_str()); } - std::string targetFlags; - this->LocalGenerator->GetCompileOptions(targetFlags, this->Target, - configName.c_str()); - // Add the target-specific flags. - if(!targetFlags.empty()) - { - flags += " "; - flags += targetFlags; - } // Get preprocessor definitions for this directory. std::string defineFlags = this->Target->GetMakefile()->GetDefineFlags(); clOptions.FixExceptionHandlingDefault(); @@ -1422,7 +1422,7 @@ cmVisualStudio10TargetGenerator::ComputeLinkOptions(std::string const& config) if(!linkLanguage) { cmSystemTools::Error - ("CMake can not determine linker language for target:", + ("CMake can not determine linker language for target: ", this->Name.c_str()); return false; } @@ -1504,7 +1504,7 @@ cmVisualStudio10TargetGenerator::ComputeLinkOptions(std::string const& config) if(!pcli) { cmSystemTools::Error - ("CMake can not compute cmComputeLinkInformation for target:", + ("CMake can not compute cmComputeLinkInformation for target: ", this->Name.c_str()); return false; } diff --git a/Source/cmake.cxx b/Source/cmake.cxx index e757f3a..29d9bb3 100644 --- a/Source/cmake.cxx +++ b/Source/cmake.cxx @@ -549,7 +549,7 @@ void cmake::ReadListFile(const std::vector<std::string>& args, } if (!lg->GetMakefile()->ReadListFile(0, path)) { - cmSystemTools::Error("Error processing file:", path); + cmSystemTools::Error("Error processing file: ", path); } } @@ -1168,9 +1168,8 @@ void CMakeCommandUsage(const char* program) << " remove_directory dir - remove a directory and its contents\n" << " rename oldname newname - rename a file or directory " "(on one volume)\n" - << " tar [cxt][vfz][cvfj] file.tar " - "file/dir1 file/dir2 ... - create a tar " - "archive\n" + << " tar [cxt][vfz][cvfj] file.tar [file/dir1 file/dir2 ...]\n" + << " - create or extract a tar or zip archive\n" << " time command [args] ... - run command and return elapsed time\n" << " touch file - touch a file.\n" << " touch_nocreate file - touch a file but do not create it.\n" @@ -1737,7 +1736,8 @@ int cmake::ExecuteCMakeCommand(std::vector<std::string>& args) else if (args[1] == "cmake_automoc") { cmQtAutomoc automoc; - bool automocSuccess = automoc.Run(args[2].c_str()); + const char *config = args[3].empty() ? 0 : args[3].c_str(); + bool automocSuccess = automoc.Run(args[2].c_str(), config); return automocSuccess ? 0 : 1; } #endif @@ -2642,7 +2642,8 @@ const char* cmake::GetCacheDefinition(const char* name) const void cmake::AddDefaultCommands() { std::list<cmCommand*> commands; - GetBootstrapCommands(commands); + GetBootstrapCommands1(commands); + GetBootstrapCommands2(commands); GetPredefinedCommands(commands); for(std::list<cmCommand*>::iterator i = commands.begin(); i != commands.end(); ++i) diff --git a/Source/kwsys/SystemTools.cxx b/Source/kwsys/SystemTools.cxx index 7891708..4d5af5e 100644 --- a/Source/kwsys/SystemTools.cxx +++ b/Source/kwsys/SystemTools.cxx @@ -605,7 +605,7 @@ bool SystemTools::MakeDirectory(const char* path) } if(SystemTools::FileExists(path)) { - return true; + return SystemTools::FileIsDirectory(path); } kwsys_stl::string dir = path; if(dir.size() == 0) diff --git a/Tests/CMakeLists.txt b/Tests/CMakeLists.txt index b742dad..b660442 100644 --- a/Tests/CMakeLists.txt +++ b/Tests/CMakeLists.txt @@ -245,7 +245,7 @@ if(BUILD_TESTING) ADD_TEST_MACRO(CompileOptions CompileOptions) ADD_TEST_MACRO(CompatibleInterface CompatibleInterface) set_tests_properties(EmptyLibrary PROPERTIES - PASS_REGULAR_EXPRESSION "CMake Error: CMake can not determine linker language for target:test") + PASS_REGULAR_EXPRESSION "CMake Error: CMake can not determine linker language for target: test") ADD_TEST_MACRO(CrossCompile CrossCompile) set_tests_properties(CrossCompile PROPERTIES PASS_REGULAR_EXPRESSION "TRY_RUN.. invoked in cross-compiling mode") @@ -1640,7 +1640,7 @@ ${CMake_BINARY_DIR}/bin/cmake -DVERSION=master -P ${CMake_SOURCE_DIR}/Utilities/ FAIL_REGULAR_EXPRESSION "CMake Warning .*VariableUnusedViaUnset.CMakeLists.txt:5 \\(set\\):") list(APPEND TEST_BUILD_DIRS "${CMake_BINARY_DIR}/Tests/WarnUnusedUnusedViaUnset") - if("${CMAKE_TEST_GENERATOR}" MATCHES "Makefile") + if("${CMAKE_TEST_GENERATOR}" MATCHES "Makefile" AND NOT WIN32) # Ninja does not support ADDITIONAL_MAKE_CLEAN_FILES and therefore fails # this test. (See #13371) # Apparently Visual Studio does not support it either. As the MakeClean diff --git a/Tests/CMakeTests/CMakeHostSystemInformation-BadArg1.cmake b/Tests/CMakeTests/CMakeHostSystemInformation-BadArg1.cmake new file mode 100644 index 0000000..1655eb4 --- /dev/null +++ b/Tests/CMakeTests/CMakeHostSystemInformation-BadArg1.cmake @@ -0,0 +1 @@ +cmake_host_system_information(HOSTNAME) diff --git a/Tests/CMakeTests/CMakeHostSystemInformation-BadArg2.cmake b/Tests/CMakeTests/CMakeHostSystemInformation-BadArg2.cmake new file mode 100644 index 0000000..1f056d5 --- /dev/null +++ b/Tests/CMakeTests/CMakeHostSystemInformation-BadArg2.cmake @@ -0,0 +1 @@ +cmake_host_system_information(RESULT FQDN HOSTNAME) diff --git a/Tests/CMakeTests/CMakeHostSystemInformation-BadArg3.cmake b/Tests/CMakeTests/CMakeHostSystemInformation-BadArg3.cmake new file mode 100644 index 0000000..9c5a558 --- /dev/null +++ b/Tests/CMakeTests/CMakeHostSystemInformation-BadArg3.cmake @@ -0,0 +1 @@ +cmake_host_system_information(RESULT RESULT QUERY FOOBAR) diff --git a/Tests/CMakeTests/CMakeHostSystemInformation-QueryList.cmake b/Tests/CMakeTests/CMakeHostSystemInformation-QueryList.cmake new file mode 100644 index 0000000..1c3156d --- /dev/null +++ b/Tests/CMakeTests/CMakeHostSystemInformation-QueryList.cmake @@ -0,0 +1,5 @@ +cmake_host_system_information(RESULT RESULT + QUERY NUMBER_OF_LOGICAL_CORES NUMBER_OF_PHYSICAL_CORES +) + +message("[${RESULT}]") diff --git a/Tests/CMakeTests/CMakeHostSystemInformationTest.cmake.in b/Tests/CMakeTests/CMakeHostSystemInformationTest.cmake.in new file mode 100644 index 0000000..3294a2f --- /dev/null +++ b/Tests/CMakeTests/CMakeHostSystemInformationTest.cmake.in @@ -0,0 +1,33 @@ +set(BadArg1-RESULT 1) +set(BadArg1-STDERR "missing RESULT specification") +set(BadArg2-RESULT 1) +set(BadArg2-STDERR "missing QUERY specification") +set(BadArg3-RESULT 1) +set(BadArg3-STDERR "does not recognize <key> FOOBAR") +set(QueryList-RESULT 0) +set(QueryList-STDERR "\\[[0-9]+;[0-9]+\\]") + +function(try_and_print key) + cmake_host_system_information(RESULT RESULT QUERY ${key}) + message(STATUS "[${key}] [${RESULT}]") +endfunction() + +message("CTEST_FULL_OUTPUT (Avoid ctest truncation of output)") + +try_and_print(NUMBER_OF_LOGICAL_CORES) +try_and_print(NUMBER_OF_PHYSICAL_CORES) +try_and_print(HOSTNAME) +try_and_print(FQDN) +try_and_print(TOTAL_VIRTUAL_MEMORY) +try_and_print(AVAILABLE_VIRTUAL_MEMORY) +try_and_print(TOTAL_PHYSICAL_MEMORY) +try_and_print(AVAILABLE_PHYSICAL_MEMORY) + +include("@CMAKE_CURRENT_SOURCE_DIR@/CheckCMakeTest.cmake") + +check_cmake_test(CMakeHostSystemInformation + BadArg1 + BadArg2 + BadArg3 + QueryList +) diff --git a/Tests/CMakeTests/CMakeLists.txt b/Tests/CMakeTests/CMakeLists.txt index b049995..344b772 100644 --- a/Tests/CMakeTests/CMakeLists.txt +++ b/Tests/CMakeTests/CMakeLists.txt @@ -32,6 +32,7 @@ AddCMakeTest(CompilerIdVendor "") AddCMakeTest(ProcessorCount "-DKWSYS_TEST_EXE=$<TARGET_FILE:cmsysTestsCxx>") AddCMakeTest(PushCheckState "") AddCMakeTest(While "") +AddCMakeTest(CMakeHostSystemInformation "") AddCMakeTest(FileDownload "") set_property(TEST CMake.FileDownload PROPERTY diff --git a/Tests/CompileOptions/CMakeLists.txt b/Tests/CompileOptions/CMakeLists.txt index 6d8a96a..9b6c9c2 100644 --- a/Tests/CompileOptions/CMakeLists.txt +++ b/Tests/CompileOptions/CMakeLists.txt @@ -5,7 +5,23 @@ project(CompileOptions) add_library(testlib other.cpp) add_executable(CompileOptions main.cpp) -set_property(TARGET CompileOptions PROPERTY COMPILE_OPTIONS "$<$<CXX_COMPILER_ID:GNU>:-DTEST_DEFINE>") + +macro(get_compiler_test_genex lst lang) + list(APPEND ${lst} -DTEST_${lang}_COMPILER_VERSION="$<${lang}_COMPILER_VERSION>") + list(APPEND ${lst} -DTEST_${lang}_COMPILER_VERSION_EQUALITY=$<${lang}_COMPILER_VERSION:${CMAKE_${lang}_COMPILER_VERSION}>) +endmacro() + +get_compiler_test_genex(c_tests C) +get_compiler_test_genex(cxx_tests CXX) + +set_property(TARGET CompileOptions PROPERTY COMPILE_OPTIONS + "-DTEST_DEFINE" + "-DNEEDS_ESCAPE=\"E$CAPE\"" + "$<$<CXX_COMPILER_ID:GNU>:-DTEST_DEFINE_GNU>" + ${c_tests} + ${cxx_tests} + ) + target_link_libraries(CompileOptions testlib) if(CMAKE_CXX_COMPILER_ID MATCHES "GNU") @@ -14,3 +30,9 @@ if(CMAKE_CXX_COMPILER_ID MATCHES "GNU") "DO_GNU_TESTS" ) endif() + +target_compile_definitions(CompileOptions + PRIVATE + "EXPECTED_C_COMPILER_VERSION=\"${CMAKE_C_COMPILER_VERSION}\"" + "EXPECTED_CXX_COMPILER_VERSION=\"${CMAKE_CXX_COMPILER_VERSION}\"" +) diff --git a/Tests/CompileOptions/main.cpp b/Tests/CompileOptions/main.cpp index 0d39050..42f4cca 100644 --- a/Tests/CompileOptions/main.cpp +++ b/Tests/CompileOptions/main.cpp @@ -1,11 +1,24 @@ +#ifndef TEST_DEFINE +# error Expected definition TEST_DEFINE +#endif + +#ifndef NEEDS_ESCAPE +# error Expected definition NEEDS_ESCAPE +#endif #ifdef DO_GNU_TESTS -# ifndef TEST_DEFINE -# error Expected TEST_DEFINE -# endif +# ifndef TEST_DEFINE_GNU +# error Expected definition TEST_DEFINE_GNU +# endif #endif -int main(int argc, char **argv) +#include <string.h> + +int main() { - return 0; + return (strcmp(NEEDS_ESCAPE, "E$CAPE") == 0 + && strcmp(EXPECTED_C_COMPILER_VERSION, TEST_C_COMPILER_VERSION) == 0 + && strcmp(EXPECTED_CXX_COMPILER_VERSION, TEST_CXX_COMPILER_VERSION) == 0 + && TEST_C_COMPILER_VERSION_EQUALITY == 1 + && TEST_CXX_COMPILER_VERSION_EQUALITY == 1) ? 0 : 1; } diff --git a/Tests/CustomCommand/CMakeLists.txt b/Tests/CustomCommand/CMakeLists.txt index d3ced3f..30daa7d 100644 --- a/Tests/CustomCommand/CMakeLists.txt +++ b/Tests/CustomCommand/CMakeLists.txt @@ -123,6 +123,19 @@ add_custom_command( COMMENT "Running TDocument post-build commands" ) +# Setup a custom target that will fail if the POST_BUILD custom command +# isn't run before it. +add_custom_command( + OUTPUT doc3post.txt + DEPENDS ${PROJECT_BINARY_DIR}/doc2post.txt + COMMAND ${CMAKE_COMMAND} -E echo " Copying doc2pre.txt to doc3post.txt." + COMMAND ${CMAKE_COMMAND} -E copy ${PROJECT_BINARY_DIR}/doc2post.txt + ${PROJECT_BINARY_DIR}/doc3post.txt + COMMENT "Running TDocument post-build dependent custom command" + ) +add_custom_target(doc3Post ALL DEPENDS doc3post.txt) +add_dependencies(doc3Post TDocument) + ################################################################ # # Test using a multistep generated file diff --git a/Tests/ExportImport/Export/CMakeLists.txt b/Tests/ExportImport/Export/CMakeLists.txt index e3f23b8..efecd03 100644 --- a/Tests/ExportImport/Export/CMakeLists.txt +++ b/Tests/ExportImport/Export/CMakeLists.txt @@ -162,7 +162,6 @@ set_property(TARGET testLibRequired APPEND PROPERTY $<BUILD_INTERFACE:BuildOnly_DEFINE> $<INSTALL_INTERFACE:InstallOnly_DEFINE> ) - include(GenerateExportHeader) add_subdirectory(renamed) @@ -201,6 +200,11 @@ set_property(TARGET testSharedLibRequired PROPERTY INTERFACE_CUSTOM_STRING testcontent ) +set_property(TARGET testSharedLibRequired APPEND PROPERTY + INTERFACE_COMPILE_OPTIONS + $<$<CXX_COMPILER_ID:GNU>:-DCUSTOM_COMPILE_OPTION> +) + add_library(testSharedLibDepends SHARED testSharedLibDepends.cpp) set_property(TARGET testSharedLibDepends APPEND PROPERTY diff --git a/Tests/ExportImport/Import/A/CMakeLists.txt b/Tests/ExportImport/Import/A/CMakeLists.txt index 65b1a36..3bfbc46 100644 --- a/Tests/ExportImport/Import/A/CMakeLists.txt +++ b/Tests/ExportImport/Import/A/CMakeLists.txt @@ -169,6 +169,13 @@ target_compile_definitions(deps_shared_iface $<$<STREQUAL:$<TARGET_PROPERTY:CUSTOM_STRING>,testcontent>:CUSTOM_STRING_IS_MATCH> ) +if(CMAKE_CXX_COMPILER_ID MATCHES "GNU") + target_compile_definitions(deps_shared_iface + PRIVATE + "DO_GNU_TESTS" + ) +endif() + if (APPLE OR CMAKE_CXX_COMPILER_ID MATCHES "GNU") include(CheckCXXCompilerFlag) check_cxx_compiler_flag(-fPIE run_pic_test) @@ -199,6 +206,12 @@ endif() add_executable(deps_shared_iface2 deps_shared_iface.cpp) target_link_libraries(deps_shared_iface2 bld_testSharedLibDepends bld_subdirlib) +if(CMAKE_CXX_COMPILER_ID MATCHES "GNU") + target_compile_definitions(deps_shared_iface2 + PRIVATE + "DO_GNU_TESTS" + ) +endif() target_compile_definitions(deps_shared_iface2 PRIVATE TEST_SUBDIR_LIB $<$<BOOL:$<TARGET_PROPERTY:POSITION_INDEPENDENT_CODE>>:PIC_PROPERTY_IS_ON> diff --git a/Tests/ExportImport/Import/A/deps_shared_iface.cpp b/Tests/ExportImport/Import/A/deps_shared_iface.cpp index 32e04db..d5e4de3 100644 --- a/Tests/ExportImport/Import/A/deps_shared_iface.cpp +++ b/Tests/ExportImport/Import/A/deps_shared_iface.cpp @@ -25,6 +25,12 @@ #include "renamed.h" #endif +#ifdef DO_GNU_TESTS +#ifndef CUSTOM_COMPILE_OPTION +#error Expected CUSTOM_COMPILE_OPTION +#endif +#endif + int main(int,char **) { TestSharedLibDepends dep; diff --git a/Tests/RunCMake/Languages/LINK_LANGUAGE-genex-result.txt b/Tests/RunCMake/Languages/LINK_LANGUAGE-genex-result.txt new file mode 100644 index 0000000..d00491f --- /dev/null +++ b/Tests/RunCMake/Languages/LINK_LANGUAGE-genex-result.txt @@ -0,0 +1 @@ +1 diff --git a/Tests/RunCMake/Languages/LINK_LANGUAGE-genex-stderr.txt b/Tests/RunCMake/Languages/LINK_LANGUAGE-genex-stderr.txt new file mode 100644 index 0000000..8e0591d --- /dev/null +++ b/Tests/RunCMake/Languages/LINK_LANGUAGE-genex-stderr.txt @@ -0,0 +1,6 @@ +CMake Error: + Error evaluating generator expression: + + \$<LINK_LANGUAGE> + + \$<LINK_LANGUAGE> expression can not be used while evaluating link libraries diff --git a/Tests/RunCMake/Languages/LINK_LANGUAGE-genex.cmake b/Tests/RunCMake/Languages/LINK_LANGUAGE-genex.cmake new file mode 100644 index 0000000..e0f8c57 --- /dev/null +++ b/Tests/RunCMake/Languages/LINK_LANGUAGE-genex.cmake @@ -0,0 +1,4 @@ + +add_library(foo SHARED empty.cpp) +add_library(bar SHARED empty.cpp) +target_link_libraries(foo $<$<STREQUAL:$<LINK_LANGUAGE>,anything>:bar>) diff --git a/Tests/RunCMake/Languages/NoLangSHARED-stderr.txt b/Tests/RunCMake/Languages/NoLangSHARED-stderr.txt index 3f93cf8..983129a 100644 --- a/Tests/RunCMake/Languages/NoLangSHARED-stderr.txt +++ b/Tests/RunCMake/Languages/NoLangSHARED-stderr.txt @@ -1 +1 @@ -CMake Error: CMake can not determine linker language for target:NoLang +CMake Error: CMake can not determine linker language for target: NoLang diff --git a/Tests/RunCMake/Languages/RunCMakeTest.cmake b/Tests/RunCMake/Languages/RunCMakeTest.cmake index a99548f..6517a81 100644 --- a/Tests/RunCMake/Languages/RunCMakeTest.cmake +++ b/Tests/RunCMake/Languages/RunCMakeTest.cmake @@ -1,3 +1,6 @@ include(RunCMake) run_cmake(NoLangSHARED) +run_cmake(LINK_LANGUAGE-genex) +run_cmake(link-libraries-TARGET_FILE-genex) +run_cmake(link-libraries-TARGET_FILE-genex-ok) diff --git a/Tests/RunCMake/Languages/empty.cpp b/Tests/RunCMake/Languages/empty.cpp new file mode 100644 index 0000000..7279c5e --- /dev/null +++ b/Tests/RunCMake/Languages/empty.cpp @@ -0,0 +1,7 @@ +#ifdef _WIN32 +__declspec(dllexport) +#endif +int empty(void) +{ + return 0; +} diff --git a/Tests/RunCMake/Languages/link-libraries-TARGET_FILE-genex-ok-result.txt b/Tests/RunCMake/Languages/link-libraries-TARGET_FILE-genex-ok-result.txt new file mode 100644 index 0000000..573541a --- /dev/null +++ b/Tests/RunCMake/Languages/link-libraries-TARGET_FILE-genex-ok-result.txt @@ -0,0 +1 @@ +0 diff --git a/Tests/RunCMake/Languages/link-libraries-TARGET_FILE-genex-ok.cmake b/Tests/RunCMake/Languages/link-libraries-TARGET_FILE-genex-ok.cmake new file mode 100644 index 0000000..f0fd6e5 --- /dev/null +++ b/Tests/RunCMake/Languages/link-libraries-TARGET_FILE-genex-ok.cmake @@ -0,0 +1,6 @@ + +enable_language(CXX) + +add_library(foo SHARED empty.cpp) +add_library(bar SHARED empty.cpp) +target_link_libraries(foo $<$<STREQUAL:$<TARGET_FILE:bar>,anything>:bar>) diff --git a/Tests/RunCMake/Languages/link-libraries-TARGET_FILE-genex-result.txt b/Tests/RunCMake/Languages/link-libraries-TARGET_FILE-genex-result.txt new file mode 100644 index 0000000..d00491f --- /dev/null +++ b/Tests/RunCMake/Languages/link-libraries-TARGET_FILE-genex-result.txt @@ -0,0 +1 @@ +1 diff --git a/Tests/RunCMake/Languages/link-libraries-TARGET_FILE-genex-stderr.txt b/Tests/RunCMake/Languages/link-libraries-TARGET_FILE-genex-stderr.txt new file mode 100644 index 0000000..2d7a3c9 --- /dev/null +++ b/Tests/RunCMake/Languages/link-libraries-TARGET_FILE-genex-stderr.txt @@ -0,0 +1,7 @@ +CMake Error: + Error evaluating generator expression: + + \$<TARGET_FILE:foo> + + Expressions which require the linker language may not be used while + evaluating link libraries diff --git a/Tests/RunCMake/Languages/link-libraries-TARGET_FILE-genex.cmake b/Tests/RunCMake/Languages/link-libraries-TARGET_FILE-genex.cmake new file mode 100644 index 0000000..eca73e9 --- /dev/null +++ b/Tests/RunCMake/Languages/link-libraries-TARGET_FILE-genex.cmake @@ -0,0 +1,4 @@ + +add_library(foo SHARED empty.cpp) +add_library(bar SHARED empty.cpp) +target_link_libraries(foo $<$<STREQUAL:$<TARGET_FILE:foo>,anything>:bar>) diff --git a/Tests/RunCMake/try_compile/BadSources1-result.txt b/Tests/RunCMake/try_compile/BadSources1-result.txt new file mode 100644 index 0000000..d00491f --- /dev/null +++ b/Tests/RunCMake/try_compile/BadSources1-result.txt @@ -0,0 +1 @@ +1 diff --git a/Tests/RunCMake/try_compile/BadSources1-stderr.txt b/Tests/RunCMake/try_compile/BadSources1-stderr.txt new file mode 100644 index 0000000..864a294 --- /dev/null +++ b/Tests/RunCMake/try_compile/BadSources1-stderr.txt @@ -0,0 +1,12 @@ +CMake Error at BadSources1.cmake:1 \(try_compile\): + Unknown extension ".c" for file + + .*/Tests/RunCMake/try_compile/src.c + + try_compile\(\) works only for enabled languages. Currently these are: + + NONE + + See project\(\) command to enable other languages. +Call Stack \(most recent call first\): + CMakeLists.txt:3 \(include\) diff --git a/Tests/RunCMake/try_compile/BadSources1.cmake b/Tests/RunCMake/try_compile/BadSources1.cmake new file mode 100644 index 0000000..aa4dc5e --- /dev/null +++ b/Tests/RunCMake/try_compile/BadSources1.cmake @@ -0,0 +1 @@ +try_compile(RESULT ${CMAKE_CURRENT_BINARY_DIR} SOURCES ${CMAKE_CURRENT_SOURCE_DIR}/src.c) diff --git a/Tests/RunCMake/try_compile/BadSources2-result.txt b/Tests/RunCMake/try_compile/BadSources2-result.txt new file mode 100644 index 0000000..d00491f --- /dev/null +++ b/Tests/RunCMake/try_compile/BadSources2-result.txt @@ -0,0 +1 @@ +1 diff --git a/Tests/RunCMake/try_compile/BadSources2-stderr.txt b/Tests/RunCMake/try_compile/BadSources2-stderr.txt new file mode 100644 index 0000000..3313f99 --- /dev/null +++ b/Tests/RunCMake/try_compile/BadSources2-stderr.txt @@ -0,0 +1,12 @@ +CMake Error at BadSources2.cmake:2 \(try_compile\): + Unknown extension ".cxx" for file + + .*/Tests/RunCMake/try_compile/src.cxx + + try_compile\(\) works only for enabled languages. Currently these are: + + C NONE( RC)? + + See project\(\) command to enable other languages. +Call Stack \(most recent call first\): + CMakeLists.txt:3 \(include\) diff --git a/Tests/RunCMake/try_compile/BadSources2.cmake b/Tests/RunCMake/try_compile/BadSources2.cmake new file mode 100644 index 0000000..ed2b036 --- /dev/null +++ b/Tests/RunCMake/try_compile/BadSources2.cmake @@ -0,0 +1,5 @@ +enable_language(C) +try_compile(RESULT ${CMAKE_CURRENT_BINARY_DIR} + SOURCES ${CMAKE_CURRENT_SOURCE_DIR}/src.c + ${CMAKE_CURRENT_SOURCE_DIR}/src.cxx + ) diff --git a/Tests/RunCMake/try_compile/NoSources-result.txt b/Tests/RunCMake/try_compile/NoSources-result.txt new file mode 100644 index 0000000..d00491f --- /dev/null +++ b/Tests/RunCMake/try_compile/NoSources-result.txt @@ -0,0 +1 @@ +1 diff --git a/Tests/RunCMake/try_compile/NoSources-stderr.txt b/Tests/RunCMake/try_compile/NoSources-stderr.txt new file mode 100644 index 0000000..023032b --- /dev/null +++ b/Tests/RunCMake/try_compile/NoSources-stderr.txt @@ -0,0 +1,4 @@ +CMake Error at NoSources.cmake:1 \(try_compile\): + SOURCES must be followed by at least one source file +Call Stack \(most recent call first\): + CMakeLists.txt:3 \(include\) diff --git a/Tests/RunCMake/try_compile/NoSources.cmake b/Tests/RunCMake/try_compile/NoSources.cmake new file mode 100644 index 0000000..8a73af4 --- /dev/null +++ b/Tests/RunCMake/try_compile/NoSources.cmake @@ -0,0 +1 @@ +try_compile(RESULT ${CMAKE_CURRENT_BINARY_DIR} SOURCES) diff --git a/Tests/RunCMake/try_compile/RunCMakeTest.cmake b/Tests/RunCMake/try_compile/RunCMakeTest.cmake index 31643cf..3494695 100644 --- a/Tests/RunCMake/try_compile/RunCMakeTest.cmake +++ b/Tests/RunCMake/try_compile/RunCMakeTest.cmake @@ -7,6 +7,9 @@ run_cmake(NoCopyFile) run_cmake(NoCopyFile2) run_cmake(NoOutputVariable) run_cmake(NoOutputVariable2) +run_cmake(NoSources) run_cmake(BadLinkLibraries) +run_cmake(BadSources1) +run_cmake(BadSources2) run_cmake(NonSourceCopyFile) run_cmake(NonSourceCompileDefinitions) diff --git a/Tests/TryCompile/CMakeLists.txt b/Tests/TryCompile/CMakeLists.txt index b6b66d8..4540fd0 100644 --- a/Tests/TryCompile/CMakeLists.txt +++ b/Tests/TryCompile/CMakeLists.txt @@ -71,6 +71,24 @@ if(SHOULD_FAIL) message(SEND_ERROR "Should fail passed ${TRY_OUT}") endif() +# try to compile two files that should compile +try_compile(SHOULD_PASS + ${TryCompile_BINARY_DIR}${CMAKE_FILES_DIRECTORY}/CMakeTmp + SOURCES ${TryCompile_SOURCE_DIR}/pass2a.c ${TryCompile_SOURCE_DIR}/pass2b.cxx + OUTPUT_VARIABLE TRY_OUT) +if(NOT SHOULD_PASS) + message(SEND_ERROR "should pass failed ${TRY_OUT}") +endif() + +# try to compile two files that should not compile +try_compile(SHOULD_FAIL + ${TryCompile_BINARY_DIR}${CMAKE_FILES_DIRECTORY}/CMakeTmp + SOURCES ${TryCompile_SOURCE_DIR}/fail2a.c ${TryCompile_SOURCE_DIR}/fail2b.c + OUTPUT_VARIABLE TRY_OUT) +if(SHOULD_FAIL) + message(SEND_ERROR "Should fail passed ${TRY_OUT}") +endif() + if(NOT SHOULD_FAIL) if(SHOULD_PASS) message("All Tests passed, ignore all previous output.") diff --git a/Tests/TryCompile/fail2a.c b/Tests/TryCompile/fail2a.c new file mode 100644 index 0000000..78f2de1 --- /dev/null +++ b/Tests/TryCompile/fail2a.c @@ -0,0 +1 @@ +int main(void) { return 0; } diff --git a/Tests/TryCompile/fail2b.c b/Tests/TryCompile/fail2b.c new file mode 100644 index 0000000..5ee809c --- /dev/null +++ b/Tests/TryCompile/fail2b.c @@ -0,0 +1 @@ +does_not_compile diff --git a/Tests/TryCompile/pass2a.c b/Tests/TryCompile/pass2a.c new file mode 100644 index 0000000..bbfe6d5 --- /dev/null +++ b/Tests/TryCompile/pass2a.c @@ -0,0 +1,2 @@ +extern int pass2b(void); +int main() { return pass2b(); } diff --git a/Tests/TryCompile/pass2b.cxx b/Tests/TryCompile/pass2b.cxx new file mode 100644 index 0000000..4c539e2 --- /dev/null +++ b/Tests/TryCompile/pass2b.cxx @@ -0,0 +1 @@ +extern "C" int pass2b(void) { return 0; } diff --git a/Utilities/cmcurl/CMakeLists.txt b/Utilities/cmcurl/CMakeLists.txt index ef000a1..320612c 100644 --- a/Utilities/cmcurl/CMakeLists.txt +++ b/Utilities/cmcurl/CMakeLists.txt @@ -376,7 +376,6 @@ MARK_AS_ADVANCED(RANDOM_FILE) #sigaction \ #signal \ #getpass_r \ -#strlcat \ #getpwuid \ #geteuid \ #dlopen \ @@ -428,7 +427,6 @@ CHECK_SYMBOL_EXISTS(closesocket "${CURL_INCLUDES}" HAVE_CLOSESOCKET) CHECK_SYMBOL_EXISTS(setvbuf "${CURL_INCLUDES}" HAVE_SETVBUF) CHECK_SYMBOL_EXISTS(sigsetjmp "${CURL_INCLUDES}" HAVE_SIGSETJMP) CHECK_SYMBOL_EXISTS(getpass_r "${CURL_INCLUDES}" HAVE_GETPASS_R) -CHECK_SYMBOL_EXISTS(strlcat "${CURL_INCLUDES}" HAVE_STRLCAT) CHECK_SYMBOL_EXISTS(getpwuid "${CURL_INCLUDES}" HAVE_GETPWUID) CHECK_SYMBOL_EXISTS(geteuid "${CURL_INCLUDES}" HAVE_GETEUID) CHECK_SYMBOL_EXISTS(utime "${CURL_INCLUDES}" HAVE_UTIME) diff --git a/Utilities/cmcurl/Platforms/WindowsCache.cmake b/Utilities/cmcurl/Platforms/WindowsCache.cmake index b4515ce..57ab30b 100644 --- a/Utilities/cmcurl/Platforms/WindowsCache.cmake +++ b/Utilities/cmcurl/Platforms/WindowsCache.cmake @@ -76,7 +76,6 @@ IF(NOT UNIX) SET(HAVE_SETVBUF 0) SET(HAVE_SIGSETJMP 0) SET(HAVE_GETPASS_R 0) - SET(HAVE_STRLCAT 0) SET(HAVE_GETPWUID 0) SET(HAVE_GETEUID 0) SET(HAVE_UTIME 1) diff --git a/Utilities/cmcurl/Platforms/config-aix.h b/Utilities/cmcurl/Platforms/config-aix.h index 86d1093..c98b10f 100644 --- a/Utilities/cmcurl/Platforms/config-aix.h +++ b/Utilities/cmcurl/Platforms/config-aix.h @@ -343,9 +343,6 @@ /* Define to 1 if you have the <string.h> header file. */ #define HAVE_STRING_H 1 -/* Define to 1 if you have the `strlcat' function. */ -/* #undef HAVE_STRLCAT */ - /* Define to 1 if you have the `strlcpy' function. */ /* #undef HAVE_STRLCPY */ diff --git a/Utilities/cmcurl/config.h.in b/Utilities/cmcurl/config.h.in index e18af8f..148722b 100644 --- a/Utilities/cmcurl/config.h.in +++ b/Utilities/cmcurl/config.h.in @@ -441,9 +441,6 @@ /* Define to 1 if you have the <string.h> header file. */ #cmakedefine HAVE_STRING_H ${HAVE_STRING_H} -/* Define to 1 if you have the `strlcat' function. */ -#cmakedefine HAVE_STRLCAT ${HAVE_STRLCAT} - /* Define to 1 if you have the `strlcpy' function. */ #cmakedefine HAVE_STRLCPY ${HAVE_STRLCPY} diff --git a/Utilities/cmcurl/socks.c b/Utilities/cmcurl/socks.c index 3319e69..e0e947b 100644 --- a/Utilities/cmcurl/socks.c +++ b/Utilities/cmcurl/socks.c @@ -199,8 +199,15 @@ CURLcode Curl_SOCKS4(const char *proxy_name, * This is currently not supporting "Identification Protocol (RFC1413)". */ socksreq[8] = 0; /* ensure empty userid is NUL-terminated */ - if (proxy_name) - strlcat((char*)socksreq + 8, proxy_name, sizeof(socksreq) - 8); + if(proxy_name) { + size_t plen = strlen(proxy_name); + if(plen >= sizeof(socksreq) - 8) { + failf(data, "Too long SOCKS proxy name, can't use!\n"); + return CURLE_COULDNT_CONNECT; + } + /* copy the proxy name WITH trailing zero */ + memcpy(socksreq + 8, proxy_name, plen+1); + } /* * Make connection diff --git a/Utilities/cmcurl/strequal.c b/Utilities/cmcurl/strequal.c index 76ad524..83796f6 100644 --- a/Utilities/cmcurl/strequal.c +++ b/Utilities/cmcurl/strequal.c @@ -99,45 +99,3 @@ char *Curl_strcasestr(const char *haystack, const char *needle) } return NULL; } - -#ifndef HAVE_STRLCAT -/* - * The strlcat() function appends the NUL-terminated string src to the end - * of dst. It will append at most size - strlen(dst) - 1 bytes, NUL-termi- - * nating the result. - * - * The strlcpy() and strlcat() functions return the total length of the - * string they tried to create. For strlcpy() that means the length of src. - * For strlcat() that means the initial length of dst plus the length of - * src. While this may seem somewhat confusing it was done to make trunca- - * tion detection simple. - * - * - */ -size_t Curl_strlcat(char *dst, const char *src, size_t siz) -{ - char *d = dst; - const char *s = src; - size_t n = siz; - size_t dlen; - - /* Find the end of dst and adjust bytes left but don't go past end */ - while (n-- != 0 && *d != '\0') - d++; - dlen = d - dst; - n = siz - dlen; - - if (n == 0) - return(dlen + strlen(s)); - while (*s != '\0') { - if (n != 1) { - *d++ = *s; - n--; - } - s++; - } - *d = '\0'; - - return(dlen + (s - src)); /* count does not include NUL */ -} -#endif diff --git a/Utilities/cmcurl/strequal.h b/Utilities/cmcurl/strequal.h index b3caa73..6718c3c0 100644 --- a/Utilities/cmcurl/strequal.h +++ b/Utilities/cmcurl/strequal.h @@ -35,9 +35,4 @@ /* case insensitive strstr() */ char *Curl_strcasestr(const char *haystack, const char *needle); -#ifndef HAVE_STRLCAT -#define strlcat(x,y,z) Curl_strlcat(x,y,z) -#endif -size_t strlcat(char *dst, const char *src, size_t siz); - #endif @@ -247,7 +247,8 @@ CMAKE_CXX_SOURCES="\ cmMakefileUtilityTargetGenerator \ cmOSXBundleGenerator \ cmNewLineStyle \ - cmBootstrapCommands \ + cmBootstrapCommands1 \ + cmBootstrapCommands2 \ cmCommands \ cmTarget \ cmTest \ @@ -1449,11 +1450,15 @@ for a in ${CMAKE_CXX_SOURCES} ${CMAKE_C_SOURCES} ${KWSYS_CXX_SOURCES} ${KWSYS_C_ objs="${objs} ${a}.o" done -# Generate dependencies for cmBootstrapCommands.cxx -for file in `grep "#include.*cm[^.]*.cxx" "${cmake_source_dir}/Source/cmBootstrapCommands.cxx" | sed "s/.* \"\(.*\)\"/\1/"`; do - cmBootstrapCommandsDeps="${cmBootstrapCommandsDeps} `cmake_escape "${cmake_source_dir}/Source/$file"`" +# Generate dependencies for cmBootstrapCommands1.cxx +for file in `grep "#include.*cm[^.]*.cxx" "${cmake_source_dir}/Source/cmBootstrapCommands1.cxx" | sed "s/.* \"\(.*\)\"/\1/"`; do + cmBootstrapCommands1Deps="${cmBootstrapCommands1Deps} `cmake_escape "${cmake_source_dir}/Source/$file"`" done -cmBootstrapCommandsDeps=`echo $cmBootstrapCommandsDeps` +cmBootstrapCommands1Deps=`echo $cmBootstrapCommands1Deps` +for file in `grep "#include.*cm[^.]*.cxx" "${cmake_source_dir}/Source/cmBootstrapCommands2.cxx" | sed "s/.* \"\(.*\)\"/\1/"`; do + cmBootstrapCommands2Deps="${cmBootstrapCommands2Deps} `cmake_escape "${cmake_source_dir}/Source/$file"`" +done +cmBootstrapCommands2Deps=`echo $cmBootstrapCommands2Deps` if [ "x${cmake_ansi_cxx_flags}" != "x" ]; then cmake_cxx_flags="${cmake_ansi_cxx_flags} ${cmake_cxx_flags}" @@ -1486,7 +1491,8 @@ for a in ${CMAKE_CXX_SOURCES}; do echo "${a}.o : ${src} ${dep}" >> "${cmake_bootstrap_dir}/Makefile" echo " ${cmake_cxx_compiler} ${cmake_cxx_flags} -c ${src} -o ${a}.o" >> "${cmake_bootstrap_dir}/Makefile" done -echo "cmBootstrapCommands.o : $cmBootstrapCommandsDeps" >> "${cmake_bootstrap_dir}/Makefile" +echo "cmBootstrapCommands1.o : $cmBootstrapCommands1Deps" >> "${cmake_bootstrap_dir}/Makefile" +echo "cmBootstrapCommands2.o : $cmBootstrapCommands2Deps" >> "${cmake_bootstrap_dir}/Makefile" for a in ${CMAKE_C_SOURCES}; do src=`cmake_escape "${cmake_source_dir}/Source/${a}.c"` echo "${a}.o : ${src} ${dep}" >> "${cmake_bootstrap_dir}/Makefile" |