summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--Modules/CMakeFindEclipseCDT4.cmake4
-rw-r--r--Modules/CMakePackageConfigHelpers.cmake38
-rw-r--r--Modules/FindMPI.cmake14
-rw-r--r--Modules/FindPackageHandleStandardArgs.cmake42
-rw-r--r--Modules/Platform/Darwin.cmake33
-rw-r--r--Modules/Platform/eCos.cmake9
-rw-r--r--Modules/readme.txt30
-rw-r--r--Source/CMakeLists.txt2
-rw-r--r--Source/CPack/cmCPackArchiveGenerator.cxx2
-rw-r--r--Source/CPack/cmCPackDebGenerator.cxx2
-rw-r--r--Source/CPack/cmCPackDragNDropGenerator.cxx10
-rw-r--r--Source/CPack/cmCPackGenerator.cxx6
-rw-r--r--Source/CPack/cmCPackGenerator.h14
-rw-r--r--Source/CPack/cmCPackPackageMakerGenerator.cxx87
-rw-r--r--Source/CPack/cmCPackRPMGenerator.cxx2
-rw-r--r--Source/CPack/cmCPackSTGZGenerator.cxx25
-rw-r--r--Source/cmAddLibraryCommand.cxx14
-rw-r--r--Source/cmAddLibraryCommand.h20
-rw-r--r--Source/cmCacheManager.cxx11
-rw-r--r--Source/cmComputeLinkDepends.cxx13
-rw-r--r--Source/cmExportCommand.cxx8
-rw-r--r--Source/cmFindPackageCommand.cxx95
-rw-r--r--Source/cmGeneratorTarget.cxx179
-rw-r--r--Source/cmGeneratorTarget.h64
-rw-r--r--Source/cmGlobalGenerator.cxx57
-rw-r--r--Source/cmGlobalGenerator.h13
-rw-r--r--Source/cmGlobalNinjaGenerator.cxx30
-rw-r--r--Source/cmGlobalNinjaGenerator.h6
-rw-r--r--Source/cmGlobalUnixMakefileGenerator3.cxx38
-rw-r--r--Source/cmGlobalUnixMakefileGenerator3.h2
-rw-r--r--Source/cmGlobalVisualStudio10Generator.h2
-rw-r--r--Source/cmGlobalVisualStudio6Generator.h2
-rw-r--r--Source/cmGlobalVisualStudio7Generator.h2
-rw-r--r--Source/cmGlobalVisualStudioGenerator.cxx70
-rw-r--r--Source/cmGlobalVisualStudioGenerator.h2
-rw-r--r--Source/cmGlobalXCodeGenerator.cxx346
-rw-r--r--Source/cmGlobalXCodeGenerator.h15
-rw-r--r--Source/cmInstallCommand.cxx11
-rw-r--r--Source/cmInstallTargetGenerator.cxx1
-rw-r--r--Source/cmLocalGenerator.cxx4
-rw-r--r--Source/cmLocalNinjaGenerator.cxx31
-rw-r--r--Source/cmLocalNinjaGenerator.h3
-rw-r--r--Source/cmLocalUnixMakefileGenerator3.cxx40
-rw-r--r--Source/cmLocalUnixMakefileGenerator3.h5
-rw-r--r--Source/cmLocalVisualStudio6Generator.cxx141
-rw-r--r--Source/cmLocalVisualStudio6Generator.h3
-rw-r--r--Source/cmLocalVisualStudio7Generator.cxx126
-rw-r--r--Source/cmLocalVisualStudio7Generator.h6
-rw-r--r--Source/cmLocalVisualStudioGenerator.cxx63
-rw-r--r--Source/cmLocalVisualStudioGenerator.h8
-rw-r--r--Source/cmMakefile.cxx18
-rw-r--r--Source/cmMakefileLibraryTargetGenerator.cxx26
-rw-r--r--Source/cmMakefileLibraryTargetGenerator.h1
-rw-r--r--Source/cmMakefileTargetGenerator.cxx137
-rw-r--r--Source/cmMakefileTargetGenerator.h8
-rw-r--r--Source/cmNinjaNormalTargetGenerator.cxx40
-rw-r--r--Source/cmNinjaNormalTargetGenerator.h1
-rw-r--r--Source/cmNinjaTargetGenerator.cxx96
-rw-r--r--Source/cmNinjaTargetGenerator.h5
-rw-r--r--Source/cmSourceGroup.cxx6
-rw-r--r--Source/cmSourceGroup.h1
-rw-r--r--Source/cmTarget.cxx44
-rw-r--r--Source/cmTarget.h10
-rw-r--r--Source/cmTargetLinkLibrariesCommand.cxx10
-rw-r--r--Source/cmVisualStudio10TargetGenerator.cxx256
-rw-r--r--Source/cmVisualStudio10TargetGenerator.h9
-rw-r--r--Source/cmake.h10
-rw-r--r--Source/kwsys/kwsysDateStamp.cmake2
-rw-r--r--Tests/CMakeLists.txt1
-rw-r--r--Tests/CMakeOnly/AllFindModules/CMakeLists.txt16
-rw-r--r--Tests/CTestUpdateHG.cmake.in5
-rw-r--r--Tests/ExternalOBJ/CMakeLists.txt2
-rw-r--r--Tests/ExternalOBJ/Sub/CMakeLists.txt3
-rw-r--r--Tests/FindPackageTest/CMakeLists.txt28
-rw-r--r--Tests/FindPackageTest/FindLotsOfComponents.cmake10
-rw-r--r--Tests/FindPackageTest/RelocatableConfig.cmake.in6
-rw-r--r--Tests/FindPackageTest/cmake/SetFoundFALSEConfig.cmake1
-rw-r--r--Tests/FindPackageTest/cmake/SetFoundTRUEConfig.cmake1
-rw-r--r--Tests/ObjectLibrary/A/CMakeLists.txt17
-rw-r--r--Tests/ObjectLibrary/A/a.h6
-rw-r--r--Tests/ObjectLibrary/A/a1.c.in2
-rw-r--r--Tests/ObjectLibrary/A/a2.c2
-rw-r--r--Tests/ObjectLibrary/AB.def5
-rw-r--r--Tests/ObjectLibrary/B/CMakeLists.txt15
-rw-r--r--Tests/ObjectLibrary/B/b.h11
-rw-r--r--Tests/ObjectLibrary/B/b1.c2
-rw-r--r--Tests/ObjectLibrary/B/b1_vs6.c1
-rw-r--r--Tests/ObjectLibrary/B/b2.c2
-rw-r--r--Tests/ObjectLibrary/B/b2_vs6.c1
-rw-r--r--Tests/ObjectLibrary/CMakeLists.txt52
-rw-r--r--Tests/ObjectLibrary/c.c19
-rw-r--r--Tests/ObjectLibrary/dummy.c1
-rw-r--r--Tests/ObjectLibrary/dummy.objbin0 -> 498 bytes
-rw-r--r--Tests/ObjectLibrary/main.c16
-rw-r--r--Tests/ObjectLibrary/mainAB.c22
-rw-r--r--Tests/RunCMake/CMakeLists.txt2
-rw-r--r--Tests/RunCMake/ObjectLibrary/BadObjSource1-result.txt1
-rw-r--r--Tests/RunCMake/ObjectLibrary/BadObjSource1-stderr.txt8
-rw-r--r--Tests/RunCMake/ObjectLibrary/BadObjSource1.cmake1
-rw-r--r--Tests/RunCMake/ObjectLibrary/BadObjSource2-result.txt1
-rw-r--r--Tests/RunCMake/ObjectLibrary/BadObjSource2-stderr.txt8
-rw-r--r--Tests/RunCMake/ObjectLibrary/BadObjSource2.cmake1
-rw-r--r--Tests/RunCMake/ObjectLibrary/BadSourceExpression1-result.txt1
-rw-r--r--Tests/RunCMake/ObjectLibrary/BadSourceExpression1-stderr.txt6
-rw-r--r--Tests/RunCMake/ObjectLibrary/BadSourceExpression1.cmake1
-rw-r--r--Tests/RunCMake/ObjectLibrary/BadSourceExpression2-result.txt1
-rw-r--r--Tests/RunCMake/ObjectLibrary/BadSourceExpression2-stderr.txt4
-rw-r--r--Tests/RunCMake/ObjectLibrary/BadSourceExpression2.cmake1
-rw-r--r--Tests/RunCMake/ObjectLibrary/BadSourceExpression3-result.txt1
-rw-r--r--Tests/RunCMake/ObjectLibrary/BadSourceExpression3-stderr.txt4
-rw-r--r--Tests/RunCMake/ObjectLibrary/BadSourceExpression3.cmake2
-rw-r--r--Tests/RunCMake/ObjectLibrary/CMakeLists.txt3
-rw-r--r--Tests/RunCMake/ObjectLibrary/Export-result.txt1
-rw-r--r--Tests/RunCMake/ObjectLibrary/Export-stderr.txt4
-rw-r--r--Tests/RunCMake/ObjectLibrary/Export.cmake2
-rw-r--r--Tests/RunCMake/ObjectLibrary/ExportLanguages.cmake15
-rw-r--r--Tests/RunCMake/ObjectLibrary/Import-result.txt1
-rw-r--r--Tests/RunCMake/ObjectLibrary/Import-stderr.txt4
-rw-r--r--Tests/RunCMake/ObjectLibrary/Import.cmake1
-rw-r--r--Tests/RunCMake/ObjectLibrary/Install-result.txt1
-rw-r--r--Tests/RunCMake/ObjectLibrary/Install-stderr.txt4
-rw-r--r--Tests/RunCMake/ObjectLibrary/Install.cmake2
-rw-r--r--Tests/RunCMake/ObjectLibrary/LinkObjLHS-result.txt1
-rw-r--r--Tests/RunCMake/ObjectLibrary/LinkObjLHS-stderr.txt4
-rw-r--r--Tests/RunCMake/ObjectLibrary/LinkObjLHS.cmake2
-rw-r--r--Tests/RunCMake/ObjectLibrary/LinkObjRHS1-result.txt1
-rw-r--r--Tests/RunCMake/ObjectLibrary/LinkObjRHS1-stderr.txt6
-rw-r--r--Tests/RunCMake/ObjectLibrary/LinkObjRHS1.cmake3
-rw-r--r--Tests/RunCMake/ObjectLibrary/LinkObjRHS2-result.txt1
-rw-r--r--Tests/RunCMake/ObjectLibrary/LinkObjRHS2-stderr.txt6
-rw-r--r--Tests/RunCMake/ObjectLibrary/LinkObjRHS2.cmake3
-rw-r--r--Tests/RunCMake/ObjectLibrary/ObjWithObj-result.txt1
-rw-r--r--Tests/RunCMake/ObjectLibrary/ObjWithObj-stderr.txt4
-rw-r--r--Tests/RunCMake/ObjectLibrary/ObjWithObj.cmake2
-rw-r--r--Tests/RunCMake/ObjectLibrary/PostBuild-result.txt1
-rw-r--r--Tests/RunCMake/ObjectLibrary/PostBuild-stderr.txt5
-rw-r--r--Tests/RunCMake/ObjectLibrary/PostBuild.cmake4
-rw-r--r--Tests/RunCMake/ObjectLibrary/PreBuild-result.txt1
-rw-r--r--Tests/RunCMake/ObjectLibrary/PreBuild-stderr.txt5
-rw-r--r--Tests/RunCMake/ObjectLibrary/PreBuild.cmake4
-rw-r--r--Tests/RunCMake/ObjectLibrary/PreLink-result.txt1
-rw-r--r--Tests/RunCMake/ObjectLibrary/PreLink-stderr.txt5
-rw-r--r--Tests/RunCMake/ObjectLibrary/PreLink.cmake4
-rw-r--r--Tests/RunCMake/ObjectLibrary/RunCMakeTest.cmake18
-rw-r--r--Tests/RunCMake/ObjectLibrary/a.c1
-rw-r--r--Tests/RunCMake/ObjectLibrary/a.cxx1
-rw-r--r--Tests/RunCMake/ObjectLibrary/bad.def0
-rw-r--r--Tests/RunCMake/ObjectLibrary/bad.obj0
-rw-r--r--Tests/RunCMake/find_package/ComponentRequiredAndOptional-result.txt1
-rw-r--r--Tests/RunCMake/find_package/ComponentRequiredAndOptional-stderr.txt8
-rw-r--r--Tests/RunCMake/find_package/ComponentRequiredAndOptional.cmake1
-rw-r--r--Tests/RunCMake/find_package/RunCMakeTest.cmake2
-rw-r--r--Tests/RunCMake/find_package/SetFoundFALSE-stderr.txt9
-rw-r--r--Tests/RunCMake/find_package/SetFoundFALSE.cmake2
-rw-r--r--Tests/RunCMake/find_package/SetFoundFALSEConfig.cmake1
-rw-r--r--Utilities/KWIML/test/test_INT_format.h.in12
-rwxr-xr-xbootstrap1
157 files changed, 2212 insertions, 668 deletions
diff --git a/Modules/CMakeFindEclipseCDT4.cmake b/Modules/CMakeFindEclipseCDT4.cmake
index dd06128..a4264e7 100644
--- a/Modules/CMakeFindEclipseCDT4.cmake
+++ b/Modules/CMakeFindEclipseCDT4.cmake
@@ -20,7 +20,9 @@ FIND_PROGRAM(CMAKE_ECLIPSE_EXECUTABLE NAMES eclipse DOC "The Eclipse executable"
FUNCTION(_FIND_ECLIPSE_VERSION)
# This code is in a function so the variables used here have only local scope
IF(CMAKE_ECLIPSE_EXECUTABLE)
- GET_FILENAME_COMPONENT(_ECLIPSE_DIR "${CMAKE_ECLIPSE_EXECUTABLE}" PATH)
+ # use REALPATH to resolve symlinks (http://public.kitware.com/Bug/view.php?id=13036)
+ GET_FILENAME_COMPONENT(_REALPATH_CMAKE_ECLIPSE_EXECUTABLE "${CMAKE_ECLIPSE_EXECUTABLE}" REALPATH)
+ GET_FILENAME_COMPONENT(_ECLIPSE_DIR "${_REALPATH_CMAKE_ECLIPSE_EXECUTABLE}" PATH)
FILE(GLOB _ECLIPSE_FEATURE_DIR "${_ECLIPSE_DIR}/features/org.eclipse.platform*")
IF("${_ECLIPSE_FEATURE_DIR}" MATCHES ".+org.eclipse.platform_([0-9]+\\.[0-9]+).+")
SET(_ECLIPSE_VERSION ${CMAKE_MATCH_1})
diff --git a/Modules/CMakePackageConfigHelpers.cmake b/Modules/CMakePackageConfigHelpers.cmake
index 98cd560..48039e5 100644
--- a/Modules/CMakePackageConfigHelpers.cmake
+++ b/Modules/CMakePackageConfigHelpers.cmake
@@ -2,7 +2,8 @@
#
# CONFIGURE_PACKAGE_CONFIG_FILE(<input> <output> INSTALL_DESTINATION <path>
# [PATH_VARS <var1> <var2> ... <varN>]
-# [NO_SET_AND_CHECK_MACRO] )
+# [NO_SET_AND_CHECK_MACRO]
+# [NO_CHECK_REQUIRED_COMPONENTS_MACRO])
#
# CONFIGURE_PACKAGE_CONFIG_FILE() should be used instead of the plain
# CONFIGURE_FILE() command when creating the <Name>Config.cmake or <Name>-config.cmake
@@ -49,8 +50,10 @@
# For absolute locations it works only if the absolute location is a subdirectory
# of CMAKE_INSTALL_PREFIX.
#
-# By default configure_package_config_file() also generates a macro set_and_check()
-# into the FooConfig.cmake file. This should be used instead of the normal set()
+# By default configure_package_config_file() also generates two helper macros,
+# set_and_check() and check_required_components() into the FooConfig.cmake file.
+#
+# set_and_check() should be used instead of the normal set()
# command for setting directories and file locations. Additionally to setting the
# variable it also checks that the referenced file or directory actually exists
# and fails with a FATAL_ERROR otherwise. This makes sure that the created
@@ -58,6 +61,16 @@
# When using the NO_SET_AND_CHECK_MACRO, this macro is not generated into the
# FooConfig.cmake file.
#
+# check_required_components(<package_name>) should be called at the end of the
+# FooConfig.cmake file if the package supports components.
+# This macro checks whether all requested, non-optional components have been found,
+# and if this is not the case, sets the Foo_FOUND variable to FALSE, so that the package
+# is considered to be not found.
+# It does that by testing the Foo_<Component>_FOUND variables for all requested
+# required components.
+# When using the NO_CHECK_REQUIRED_COMPONENTS option, this macro is not generated
+# into the FooConfig.cmake file.
+#
# For an example see below the documentation for WRITE_BASIC_PACKAGE_VERSION_FILE().
#
#
@@ -114,6 +127,8 @@
# ...
# set_and_check(FOO_INCLUDE_DIR "@PACKAGE_INCLUDE_INSTALL_DIR@")
# set_and_check(FOO_SYSCONFIG_DIR "@PACKAGE_SYSCONFIG_INSTALL_DIR@")
+#
+# check_required_components(Foo)
#=============================================================================
@@ -139,7 +154,7 @@ endmacro()
function(CONFIGURE_PACKAGE_CONFIG_FILE _inputFile _outputFile)
- set(options NO_SET_AND_CHECK_MACRO)
+ set(options NO_SET_AND_CHECK_MACRO NO_CHECK_REQUIRED_COMPONENTS_MACRO)
set(oneValueArgs INSTALL_DESTINATION )
set(multiValueArgs PATH_VARS )
@@ -189,6 +204,21 @@ endmacro()
")
endif()
+
+ if(NOT CCF_NO_CHECK_REQUIRED_COMPONENTS_MACRO)
+ set(PACKAGE_INIT "${PACKAGE_INIT}
+macro(check_required_components _NAME)
+ foreach(comp \${\${_NAME}_FIND_COMPONENTS})
+ if(NOT \${_NAME}_\${comp}_FOUND)
+ if(\${_NAME}_FIND_REQUIRED_\${comp})
+ set(\${_NAME}_FOUND FALSE)
+ endif()
+ endif()
+ endforeach(comp)
+endmacro()
+")
+ endif()
+
set(PACKAGE_INIT "${PACKAGE_INIT}
####################################################################################")
diff --git a/Modules/FindMPI.cmake b/Modules/FindMPI.cmake
index 1be4ccf..ae50ca7 100644
--- a/Modules/FindMPI.cmake
+++ b/Modules/FindMPI.cmake
@@ -354,6 +354,20 @@ function (interrogate_mpi_compiler lang try_libs)
# Extract the set of libraries to link against from the link command
# line
string(REGEX MATCHALL "(^| )-l([^\" ]+|\"[^\"]+\")" MPI_LIBNAMES "${MPI_LINK_CMDLINE}")
+ # add the compiler implicit directories because some compilers
+ # such as the intel compiler have libraries that show up
+ # in the showme list that can only be found in the implicit
+ # link directories of the compiler. Do this for C++ and C
+ # compilers if the implicit link directories are defined.
+ if (DEFINED CMAKE_CXX_IMPLICIT_LINK_DIRECTORIES)
+ set(MPI_LINK_PATH
+ "${MPI_LINK_PATH};${CMAKE_CXX_IMPLICIT_LINK_DIRECTORIES}")
+ endif ()
+
+ if (DEFINED CMAKE_C_IMPLICIT_LINK_DIRECTORIES)
+ set(MPI_LINK_PATH
+ "${MPI_LINK_PATH};${CMAKE_C_IMPLICIT_LINK_DIRECTORIES}")
+ endif ()
# Determine full path names for all of the libraries that one needs
# to link against in an MPI program
diff --git a/Modules/FindPackageHandleStandardArgs.cmake b/Modules/FindPackageHandleStandardArgs.cmake
index b503357..cdcf9ca 100644
--- a/Modules/FindPackageHandleStandardArgs.cmake
+++ b/Modules/FindPackageHandleStandardArgs.cmake
@@ -19,7 +19,8 @@
#
# The second mode is more powerful and also supports version checking:
# FIND_PACKAGE_HANDLE_STANDARD_ARGS(NAME [REQUIRED_VARS <var1>...<varN>]
-# [VERSION_VAR <versionvar>
+# [VERSION_VAR <versionvar>]
+# [HANDLE_COMPONENTS]
# [CONFIG_MODE]
# [FAIL_MESSAGE "Custom failure message"] )
#
@@ -32,6 +33,11 @@
# in the find_package() call. The EXACT keyword is also handled. The default
# messages include information about the required version and the version
# which has been actually found, both if the version is ok or not.
+# If the package supports components, use the HANDLE_COMPONENTS option to enable
+# handling them. In this case, find_package_handle_standard_args() will report
+# which components have been found and which are missing, and the <NAME>_FOUND
+# variable will be set to FALSE if any of the required components (i.e. not the
+# ones listed after OPTIONAL_COMPONENTS) are missing.
# Use the option CONFIG_MODE if your FindXXX.cmake module is a wrapper for
# a find_package(... NO_MODULE) call. In this case VERSION_VAR will be set
# to <NAME>_VERSION and the macro will automatically check whether the
@@ -128,7 +134,7 @@ FUNCTION(FIND_PACKAGE_HANDLE_STANDARD_ARGS _NAME _FIRST_ARG)
# set up the arguments for CMAKE_PARSE_ARGUMENTS and check whether we are in
# new extended or in the "old" mode:
- SET(options CONFIG_MODE)
+ SET(options CONFIG_MODE HANDLE_COMPONENTS)
SET(oneValueArgs FAIL_MESSAGE VERSION_VAR)
SET(multiValueArgs REQUIRED_VARS)
SET(_KEYWORDS_FOR_EXTENDED_MODE ${options} ${oneValueArgs} ${multiValueArgs} )
@@ -189,6 +195,36 @@ FUNCTION(FIND_PACKAGE_HANDLE_STANDARD_ARGS _NAME _FIRST_ARG)
ENDIF(NOT ${_CURRENT_VAR})
ENDFOREACH(_CURRENT_VAR)
+ # component handling
+ UNSET(FOUND_COMPONENTS_MSG)
+ UNSET(MISSING_COMPONENTS_MSG)
+
+ IF(FPHSA_HANDLE_COMPONENTS)
+ FOREACH(comp ${${_NAME}_FIND_COMPONENTS})
+ IF(${_NAME}_${comp}_FOUND)
+
+ IF(NOT DEFINED FOUND_COMPONENTS_MSG)
+ SET(FOUND_COMPONENTS_MSG "found components: ")
+ ENDIF()
+ SET(FOUND_COMPONENTS_MSG "${FOUND_COMPONENTS_MSG} ${comp}")
+
+ ELSE()
+
+ IF(NOT DEFINED MISSING_COMPONENTS_MSG)
+ SET(MISSING_COMPONENTS_MSG "missing components: ")
+ ENDIF()
+ SET(MISSING_COMPONENTS_MSG "${MISSING_COMPONENTS_MSG} ${comp}")
+
+ IF(${_NAME}_FIND_REQUIRED_${comp})
+ SET(${_NAME_UPPER}_FOUND FALSE)
+ SET(MISSING_VARS "${MISSING_VARS} ${comp}")
+ ENDIF()
+
+ ENDIF()
+ ENDFOREACH(comp)
+ SET(COMPONENT_MSG "${FOUND_COMPONENTS_MSG} ${MISSING_COMPONENTS_MSG}")
+ SET(DETAILS "${DETAILS}[c${COMPONENT_MSG}]")
+ ENDIF(FPHSA_HANDLE_COMPONENTS)
# version handling:
SET(VERSION_MSG "")
@@ -240,7 +276,7 @@ FUNCTION(FIND_PACKAGE_HANDLE_STANDARD_ARGS _NAME _FIRST_ARG)
# print the result:
IF (${_NAME_UPPER}_FOUND)
- FIND_PACKAGE_MESSAGE(${_NAME} "Found ${_NAME}: ${${_FIRST_REQUIRED_VAR}} ${VERSION_MSG}" "${DETAILS}")
+ FIND_PACKAGE_MESSAGE(${_NAME} "Found ${_NAME}: ${${_FIRST_REQUIRED_VAR}} ${VERSION_MSG} ${COMPONENT_MSG}" "${DETAILS}")
ELSE (${_NAME_UPPER}_FOUND)
IF(FPHSA_CONFIG_MODE)
diff --git a/Modules/Platform/Darwin.cmake b/Modules/Platform/Darwin.cmake
index 867c788..c4b5635 100644
--- a/Modules/Platform/Darwin.cmake
+++ b/Modules/Platform/Darwin.cmake
@@ -6,6 +6,8 @@ SET(APPLE 1)
# 8.x == Mac OSX 10.4 (Tiger)
# 9.x == Mac OSX 10.5 (Leopard)
# 10.x == Mac OSX 10.6 (Snow Leopard)
+# 11.x == Mac OSX 10.7 (Lion)
+# 12.x == Mac OSX 10.8 (Mountain Lion)
STRING(REGEX REPLACE "^([0-9]+)\\.([0-9]+).*$" "\\1" DARWIN_MAJOR_VERSION "${CMAKE_SYSTEM_VERSION}")
STRING(REGEX REPLACE "^([0-9]+)\\.([0-9]+).*$" "\\2" DARWIN_MINOR_VERSION "${CMAKE_SYSTEM_VERSION}")
@@ -59,19 +61,24 @@ ENDIF(NOT DEFINED CMAKE_INSTALL_NAME_TOOL)
# Set the assumed (Pre 10.5 or Default) location of the developer tools
SET(OSX_DEVELOPER_ROOT "/Developer")
+# Use the xcode-select tool if it's available (Xcode >= 3.0 installations)
+FIND_PROGRAM(CMAKE_XCODE_SELECT xcode-select)
+IF(CMAKE_XCODE_SELECT)
+ EXECUTE_PROCESS(COMMAND ${CMAKE_XCODE_SELECT} "-print-path"
+ OUTPUT_VARIABLE OSX_DEVELOPER_ROOT
+ OUTPUT_STRIP_TRAILING_WHITESPACE)
+ENDIF(CMAKE_XCODE_SELECT)
+
# Find installed SDKs
-FILE(GLOB _CMAKE_OSX_SDKS "${OSX_DEVELOPER_ROOT}/SDKs/*")
+# Start with Xcode-4.3+ default SDKs directory
+SET(_CMAKE_OSX_SDKS_DIR
+ "${OSX_DEVELOPER_ROOT}/Platforms/MacOSX.platform/Developer/SDKs")
+FILE(GLOB _CMAKE_OSX_SDKS "${_CMAKE_OSX_SDKS_DIR}/*")
-# If nothing is found there, then try locating the dev tools based on the xcode-select tool
-# (available in Xcode >= 3.0 installations)
+# If not present, try pre-4.3 SDKs directory
IF(NOT _CMAKE_OSX_SDKS)
- FIND_PROGRAM(CMAKE_XCODE_SELECT xcode-select)
- IF(CMAKE_XCODE_SELECT)
- EXECUTE_PROCESS(COMMAND ${CMAKE_XCODE_SELECT} "-print-path"
- OUTPUT_VARIABLE OSX_DEVELOPER_ROOT
- OUTPUT_STRIP_TRAILING_WHITESPACE)
- FILE(GLOB _CMAKE_OSX_SDKS "${OSX_DEVELOPER_ROOT}/SDKs/*")
- ENDIF(CMAKE_XCODE_SELECT)
+SET(_CMAKE_OSX_SDKS_DIR "${OSX_DEVELOPER_ROOT}/SDKs")
+ FILE(GLOB _CMAKE_OSX_SDKS "${_CMAKE_OSX_SDKS_DIR}/*")
ENDIF(NOT _CMAKE_OSX_SDKS)
EXECUTE_PROCESS(COMMAND sw_vers -productVersion
@@ -103,16 +110,16 @@ SET(ENV_SDKROOT "$ENV{SDKROOT}")
# Set CMAKE_OSX_SYSROOT_DEFAULT based on _CURRENT_OSX_VERSION,
# accounting for the known specially named SDKs.
SET(CMAKE_OSX_SYSROOT_DEFAULT
- "${OSX_DEVELOPER_ROOT}/SDKs/MacOSX${_CURRENT_OSX_VERSION}.sdk")
+ "${_CMAKE_OSX_SDKS_DIR}/MacOSX${_CURRENT_OSX_VERSION}.sdk")
IF(_CURRENT_OSX_VERSION STREQUAL "10.4")
SET(CMAKE_OSX_SYSROOT_DEFAULT
- "${OSX_DEVELOPER_ROOT}/SDKs/MacOSX10.4u.sdk")
+ "${_CMAKE_OSX_SDKS_DIR}/MacOSX10.4u.sdk")
ENDIF(_CURRENT_OSX_VERSION STREQUAL "10.4")
IF(_CURRENT_OSX_VERSION STREQUAL "10.3")
SET(CMAKE_OSX_SYSROOT_DEFAULT
- "${OSX_DEVELOPER_ROOT}/SDKs/MacOSX10.3.9.sdk")
+ "${_CMAKE_OSX_SDKS_DIR}/MacOSX10.3.9.sdk")
ENDIF(_CURRENT_OSX_VERSION STREQUAL "10.3")
# Use environment or default as initial cache value:
diff --git a/Modules/Platform/eCos.cmake b/Modules/Platform/eCos.cmake
index f0881c0..b437c1a 100644
--- a/Modules/Platform/eCos.cmake
+++ b/Modules/Platform/eCos.cmake
@@ -1,5 +1,12 @@
# support for eCos http://ecos.sourceware.org
-SET(CMAKE_SHARED_LIBRARY_C_FLAGS "") # -pic
+
+# Guard against multiple inclusion, which e.g. leads to multiple calls to add_definition() #12987
+IF(__ECOS_CMAKE_INCLUDED)
+ RETURN()
+ENDIF()
+SET(__ECOS_CMAKE_INCLUDED TRUE)
+
+SET(CMAKE_SHARED_LIBRARY_C_FLAGS "") # -pic
SET(CMAKE_SHARED_LIBRARY_CREATE_C_FLAGS "") # -shared
SET(CMAKE_SHARED_LIBRARY_LINK_C_FLAGS "") # +s, flag for exe link to use shared lib
SET(CMAKE_SHARED_LIBRARY_RUNTIME_C_FLAG "") # -rpath
diff --git a/Modules/readme.txt b/Modules/readme.txt
index e2d7f06..7d61d8d 100644
--- a/Modules/readme.txt
+++ b/Modules/readme.txt
@@ -57,7 +57,7 @@ For example:
# - This is a cool module
# This module does really cool stuff.
# It can do even more than you think.
-#
+#
# It even needs to paragraphs to tell you about it.
# And it defines the following variables:
# VAR_COOL - this is great isn't it?
@@ -119,17 +119,31 @@ able to find the package. If the
REQUIRED option is given to the command it will set the variable
XXX_FIND_REQUIRED to true before loading the FindXXX.cmake module. If
this variable is set the module should issue a FATAL_ERROR if the
-package cannot be found. For each package-specific component, say
-YYY, listed after the REQUIRED option a variable XXX_FIND_REQUIRED_YYY
-to true. The set of components listed after either the REQUIRED
-option or the COMPONENTS option will be specified in a
-XXX_FIND_COMPONENTS variable. This can be used by the FindXXX.cmake
-module to determine which sub-components of the package must be found.
+package cannot be found.
If neither the QUIET nor REQUIRED options are given then the
FindXXX.cmake module should look for the package and complain without
error if the module is not found.
-To get this behaviour you can use the FIND_PACKAGE_HANDLE_STANDARD_ARGS()
+A package can be provide sub-components.
+Those components can be listed after the COMPONENTS (or REQUIRED)
+or OPTIONAL_COMPONENTS keywords. The set of all listed components will be
+specified in a XXX_FIND_COMPONENTS variable.
+For each package-specific component, say Yyy, a variable XXX_FIND_REQUIRED_Yyy
+will be set to true if it listed after COMPONENTS and it will be set to false
+if it was listed after OPTIONAL_COMPONENTS.
+Using those variables a FindXXX.cmake module and also a XXXConfig.cmake package
+configuration file can determine whether and which components have been requested,
+and whether they were requested as required or as optional.
+For each of the requested components a XXX_Yyy_FOUND variable should be set
+accordingly.
+The per-package XXX_FOUND variable should be only set to true if all requested
+required components have been found. A missing optional component should not
+keep the XXX_FOUND variable from being set to true.
+If the package provides XXX_INCLUDE_DIRS and XXX_LIBRARIES variables, the include
+dirs and libraries for all components which were requested and which have been
+found should be added to those two variables.
+
+To get this behaviour you can use the FIND_PACKAGE_HANDLE_STANDARD_ARGS()
macro, as an example see FindJPEG.cmake.
For internal implementation, it's a generally accepted convention that variables starting with
diff --git a/Source/CMakeLists.txt b/Source/CMakeLists.txt
index 18f9b8b..f9d1c03 100644
--- a/Source/CMakeLists.txt
+++ b/Source/CMakeLists.txt
@@ -185,6 +185,8 @@ SET(SRCS
cmGeneratedFileStream.cxx
cmGeneratorExpression.cxx
cmGeneratorExpression.h
+ cmGeneratorTarget.cxx
+ cmGeneratorTarget.h
cmGlobalGenerator.cxx
cmGlobalGenerator.h
cmGlobalUnixMakefileGenerator3.cxx
diff --git a/Source/CPack/cmCPackArchiveGenerator.cxx b/Source/CPack/cmCPackArchiveGenerator.cxx
index 0ff9050..6e7b8d7 100644
--- a/Source/CPack/cmCPackArchiveGenerator.cxx
+++ b/Source/CPack/cmCPackArchiveGenerator.cxx
@@ -247,7 +247,7 @@ int cmCPackArchiveGenerator::PackageFiles()
cmCPackLogger(cmCPackLog::LOG_DEBUG, "Toplevel: "
<< toplevel << std::endl);
- if (SupportsComponentInstallation()) {
+ if (WantsComponentInstallation()) {
// CASE 1 : COMPONENT ALL-IN-ONE package
// If ALL COMPONENTS in ONE package has been requested
// then the package file is unique and should be open here.
diff --git a/Source/CPack/cmCPackDebGenerator.cxx b/Source/CPack/cmCPackDebGenerator.cxx
index b707e96..178a18d 100644
--- a/Source/CPack/cmCPackDebGenerator.cxx
+++ b/Source/CPack/cmCPackDebGenerator.cxx
@@ -236,7 +236,7 @@ int cmCPackDebGenerator::PackageFiles()
int retval = -1;
/* Are we in the component packaging case */
- if (SupportsComponentInstallation()) {
+ if (WantsComponentInstallation()) {
// CASE 1 : COMPONENT ALL-IN-ONE package
// If ALL GROUPS or ALL COMPONENTS in ONE package has been requested
// then the package file is unique and should be open here.
diff --git a/Source/CPack/cmCPackDragNDropGenerator.cxx b/Source/CPack/cmCPackDragNDropGenerator.cxx
index 3b6135e..6aee401 100644
--- a/Source/CPack/cmCPackDragNDropGenerator.cxx
+++ b/Source/CPack/cmCPackDragNDropGenerator.cxx
@@ -63,6 +63,12 @@ cmCPackDragNDropGenerator::~cmCPackDragNDropGenerator()
//----------------------------------------------------------------------
int cmCPackDragNDropGenerator::InitializeInternal()
{
+ // Starting with Xcode 4.3, look in "/Applications/Xcode.app" first:
+ //
+ std::vector<std::string> paths;
+ paths.push_back("/Applications/Xcode.app/Contents/Developer/Tools");
+ paths.push_back("/Developer/Tools");
+
const std::string hdiutil_path = cmSystemTools::FindProgram("hdiutil",
std::vector<std::string>(), false);
if(hdiutil_path.empty())
@@ -75,7 +81,7 @@ int cmCPackDragNDropGenerator::InitializeInternal()
this->SetOptionIfNotSet("CPACK_COMMAND_HDIUTIL", hdiutil_path.c_str());
const std::string setfile_path = cmSystemTools::FindProgram("SetFile",
- std::vector<std::string>(1, "/Developer/Tools"), false);
+ paths, false);
if(setfile_path.empty())
{
cmCPackLogger(cmCPackLog::LOG_ERROR,
@@ -86,7 +92,7 @@ int cmCPackDragNDropGenerator::InitializeInternal()
this->SetOptionIfNotSet("CPACK_COMMAND_SETFILE", setfile_path.c_str());
const std::string rez_path = cmSystemTools::FindProgram("Rez",
- std::vector<std::string>(1, "/Developer/Tools"), false);
+ paths, false);
if(rez_path.empty())
{
cmCPackLogger(cmCPackLog::LOG_ERROR,
diff --git a/Source/CPack/cmCPackGenerator.cxx b/Source/CPack/cmCPackGenerator.cxx
index f7d8a4d..0f832b3 100644
--- a/Source/CPack/cmCPackGenerator.cxx
+++ b/Source/CPack/cmCPackGenerator.cxx
@@ -1437,6 +1437,12 @@ bool cmCPackGenerator::SupportsComponentInstallation() const
}
//----------------------------------------------------------------------
+bool cmCPackGenerator::WantsComponentInstallation() const
+{
+ return (!IsOn("CPACK_MONOLITHIC_INSTALL") & SupportsComponentInstallation());
+}
+
+//----------------------------------------------------------------------
cmCPackInstallationType*
cmCPackGenerator::GetInstallationType(const char *projectName,
const char *name)
diff --git a/Source/CPack/cmCPackGenerator.h b/Source/CPack/cmCPackGenerator.h
index 52def9d..55afb44 100644
--- a/Source/CPack/cmCPackGenerator.h
+++ b/Source/CPack/cmCPackGenerator.h
@@ -189,7 +189,21 @@ protected:
virtual int InstallProjectViaInstallCMakeProjects(
bool setDestDir, const char* tempInstallDirectory);
+ /**
+ * Does the CPack generator support component installation?.
+ * Some Generators requires the user to set
+ * CPACK_<GENNAME>_COMPONENT_INSTALL in order to make this
+ * method return true.
+ * @return true if supported, false otherwise
+ */
virtual bool SupportsComponentInstallation() const;
+ /**
+ * Does the currently running generator want a component installation.
+ * The generator may support component installation but he may
+ * be requiring monolithic install using CPACK_MONOLITHIC_INSTALL.
+ * @return true if component installation is supported and wanted.
+ */
+ virtual bool WantsComponentInstallation() const;
virtual cmCPackInstallationType* GetInstallationType(const char *projectName,
const char* name);
virtual cmCPackComponent* GetComponent(const char *projectName,
diff --git a/Source/CPack/cmCPackPackageMakerGenerator.cxx b/Source/CPack/cmCPackPackageMakerGenerator.cxx
index 327c4a6..3a0e89b 100644
--- a/Source/CPack/cmCPackPackageMakerGenerator.cxx
+++ b/Source/CPack/cmCPackPackageMakerGenerator.cxx
@@ -355,24 +355,73 @@ int cmCPackPackageMakerGenerator::InitializeInternal()
cmCPackLogger(cmCPackLog::LOG_DEBUG,
"cmCPackPackageMakerGenerator::Initialize()" << std::endl);
this->SetOptionIfNotSet("CPACK_PACKAGING_INSTALL_PREFIX", "/usr");
- std::vector<std::string> path;
- std::string pkgPath
- = "/Developer/Applications/Utilities/PackageMaker.app/Contents";
- std::string versionFile = pkgPath + "/version.plist";
- if ( !cmSystemTools::FileExists(versionFile.c_str()) )
+
+ // Starting with Xcode 4.3, PackageMaker is a separate app, and you
+ // can put it anywhere you want. So... use a variable for its location.
+ // People who put it in unexpected places can use the variable to tell
+ // us where it is.
+ //
+ // Use the following locations, in "most recent installation" order,
+ // to search for the PackageMaker app. Assume people who copy it into
+ // the new Xcode 4.3 app in "/Applications" will copy it into the nested
+ // Applications folder inside the Xcode bundle itself. Or directly in
+ // the "/Applications" directory.
+ //
+ // If found, save result in the CPACK_INSTALLER_PROGRAM variable.
+
+ std::vector<std::string> paths;
+ paths.push_back(
+ "/Applications/Xcode.app/Contents/Applications"
+ "/PackageMaker.app/Contents/MacOS");
+ paths.push_back(
+ "/Applications/Utilities"
+ "/PackageMaker.app/Contents/MacOS");
+ paths.push_back(
+ "/Applications"
+ "/PackageMaker.app/Contents/MacOS");
+ paths.push_back(
+ "/Developer/Applications/Utilities"
+ "/PackageMaker.app/Contents/MacOS");
+ paths.push_back(
+ "/Developer/Applications"
+ "/PackageMaker.app/Contents/MacOS");
+
+ std::string pkgPath;
+ const char *inst_program = this->GetOption("CPACK_INSTALLER_PROGRAM");
+ if (inst_program && *inst_program)
+ {
+ pkgPath = inst_program;
+ }
+ else
{
- pkgPath = "/Developer/Applications/PackageMaker.app/Contents";
- std::string newVersionFile = pkgPath + "/version.plist";
- if ( !cmSystemTools::FileExists(newVersionFile.c_str()) )
+ pkgPath = cmSystemTools::FindProgram("PackageMaker", paths, false);
+ if ( pkgPath.empty() )
{
- cmCPackLogger(cmCPackLog::LOG_ERROR,
- "Cannot find PackageMaker compiler version file: "
- << versionFile.c_str() << " or " << newVersionFile.c_str()
+ cmCPackLogger(cmCPackLog::LOG_ERROR, "Cannot find PackageMaker compiler"
<< std::endl);
return 0;
}
- versionFile = newVersionFile;
+ this->SetOptionIfNotSet("CPACK_INSTALLER_PROGRAM", pkgPath.c_str());
}
+
+ // Get path to the real PackageMaker, not a symlink:
+ pkgPath = cmSystemTools::GetRealPath(pkgPath.c_str());
+ // Up from there to find the version.plist file in the "Contents" dir:
+ std::string contents_dir;
+ contents_dir = cmSystemTools::GetFilenamePath(pkgPath);
+ contents_dir = cmSystemTools::GetFilenamePath(contents_dir);
+
+ std::string versionFile = contents_dir + "/version.plist";
+
+ if ( !cmSystemTools::FileExists(versionFile.c_str()) )
+ {
+ cmCPackLogger(cmCPackLog::LOG_ERROR,
+ "Cannot find PackageMaker compiler version file: "
+ << versionFile.c_str()
+ << std::endl);
+ return 0;
+ }
+
std::ifstream ifs(versionFile.c_str());
if ( !ifs )
{
@@ -380,6 +429,7 @@ int cmCPackPackageMakerGenerator::InitializeInternal()
"Cannot open PackageMaker compiler version file" << std::endl);
return 0;
}
+
// Check the PackageMaker version
cmsys::RegularExpression rexKey("<key>CFBundleShortVersionString</key>");
cmsys::RegularExpression rexVersion("<string>([0-9]+.[0-9.]+)</string>");
@@ -442,17 +492,8 @@ int cmCPackPackageMakerGenerator::InitializeInternal()
this->PackageCompatibilityVersion = 10.3;
}
- pkgPath += "/MacOS";
- path.push_back(pkgPath);
- pkgPath = cmSystemTools::FindProgram("PackageMaker", path, false);
- if ( pkgPath.empty() )
- {
- cmCPackLogger(cmCPackLog::LOG_ERROR, "Cannot find PackageMaker compiler"
- << std::endl);
- return 0;
- }
- this->SetOptionIfNotSet("CPACK_INSTALLER_PROGRAM", pkgPath.c_str());
- pkgPath = cmSystemTools::FindProgram("hdiutil", path, false);
+ std::vector<std::string> no_paths;
+ pkgPath = cmSystemTools::FindProgram("hdiutil", no_paths, false);
if ( pkgPath.empty() )
{
cmCPackLogger(cmCPackLog::LOG_ERROR, "Cannot find hdiutil compiler"
diff --git a/Source/CPack/cmCPackRPMGenerator.cxx b/Source/CPack/cmCPackRPMGenerator.cxx
index 1a6c3be..413572e 100644
--- a/Source/CPack/cmCPackRPMGenerator.cxx
+++ b/Source/CPack/cmCPackRPMGenerator.cxx
@@ -201,7 +201,7 @@ int cmCPackRPMGenerator::PackageFiles()
<< toplevel << std::endl);
/* Are we in the component packaging case */
- if (SupportsComponentInstallation()) {
+ if (WantsComponentInstallation()) {
// CASE 1 : COMPONENT ALL-IN-ONE package
// If ALL COMPONENTS in ONE package has been requested
// then the package file is unique and should be open here.
diff --git a/Source/CPack/cmCPackSTGZGenerator.cxx b/Source/CPack/cmCPackSTGZGenerator.cxx
index 184c557..966a231 100644
--- a/Source/CPack/cmCPackSTGZGenerator.cxx
+++ b/Source/CPack/cmCPackSTGZGenerator.cxx
@@ -54,21 +54,32 @@ int cmCPackSTGZGenerator::InitializeInternal()
//----------------------------------------------------------------------
int cmCPackSTGZGenerator::PackageFiles()
{
+ bool retval = true;
if ( !this->Superclass::PackageFiles() )
{
return 0;
}
- return cmSystemTools::SetPermissions(packageFileNames[0].c_str(),
+
+ /* TGZ generator (our Superclass) may
+ * have generated several packages (component packaging)
+ * so we must iterate over generated packages.
+ */
+ for (std::vector<std::string>::iterator it=packageFileNames.begin();
+ it != packageFileNames.end(); ++it)
+ {
+ retval &= cmSystemTools::SetPermissions((*it).c_str(),
#if defined( _MSC_VER ) || defined( __MINGW32__ )
- S_IREAD | S_IWRITE | S_IEXEC
+ S_IREAD | S_IWRITE | S_IEXEC
#elif defined( __BORLANDC__ )
- S_IRUSR | S_IWUSR | S_IXUSR
+ S_IRUSR | S_IWUSR | S_IXUSR
#else
- S_IRUSR | S_IWUSR | S_IXUSR |
- S_IRGRP | S_IWGRP | S_IXGRP |
- S_IROTH | S_IWOTH | S_IXOTH
+ S_IRUSR | S_IWUSR | S_IXUSR |
+ S_IRGRP | S_IWGRP | S_IXGRP |
+ S_IROTH | S_IWOTH | S_IXOTH
#endif
- );
+ );
+ }
+ return retval;
}
//----------------------------------------------------------------------
diff --git a/Source/cmAddLibraryCommand.cxx b/Source/cmAddLibraryCommand.cxx
index 9a776fb..c1d0e9d 100644
--- a/Source/cmAddLibraryCommand.cxx
+++ b/Source/cmAddLibraryCommand.cxx
@@ -64,6 +64,12 @@ bool cmAddLibraryCommand
type = cmTarget::MODULE_LIBRARY;
haveSpecifiedType = true;
}
+ else if(libType == "OBJECT")
+ {
+ ++s;
+ type = cmTarget::OBJECT_LIBRARY;
+ haveSpecifiedType = true;
+ }
else if(libType == "UNKNOWN")
{
++s;
@@ -118,6 +124,14 @@ bool cmAddLibraryCommand
this->SetError("called with IMPORTED argument but no library type.");
return false;
}
+ if(type == cmTarget::OBJECT_LIBRARY)
+ {
+ this->Makefile->IssueMessage(
+ cmake::FATAL_ERROR,
+ "The OBJECT library type may not be used for IMPORTED libraries."
+ );
+ return true;
+ }
// Make sure the target does not already exist.
if(this->Makefile->FindTargetToUse(libName.c_str()))
diff --git a/Source/cmAddLibraryCommand.h b/Source/cmAddLibraryCommand.h
index 9ca9cbe..b1ae202 100644
--- a/Source/cmAddLibraryCommand.h
+++ b/Source/cmAddLibraryCommand.h
@@ -112,6 +112,26 @@ public:
"(and its per-configuration version IMPORTED_LOCATION_<CONFIG>) "
"which specifies the location of the main library file on disk. "
"See documentation of the IMPORTED_* properties for more information."
+ "\n"
+ "The signature\n"
+ " add_library(<name> OBJECT <src>...)\n"
+ "creates a special \"object library\" target. "
+ "An object library compiles source files but does not archive or link "
+ "their object files into a library. "
+ "Instead other targets created by add_library or add_executable may "
+ "reference the objects using an expression of the form "
+ "$<TARGET_OBJECTS:objlib> as a source, where \"objlib\" is the "
+ "object library name. "
+ "For example:\n"
+ " add_library(... $<TARGET_OBJECTS:objlib> ...)\n"
+ " add_executable(... $<TARGET_OBJECTS:objlib> ...)\n"
+ "will include objlib's object files in a library and an executable "
+ "along with those compiled from their own sources. "
+ "Object libraries may contain only sources (and headers) that compile "
+ "to object files. "
+ "They may contain custom commands generating such sources, but not "
+ "PRE_BUILD, PRE_LINK, or POST_BUILD commands. "
+ "Object libraries cannot be imported, exported, installed, or linked."
;
}
diff --git a/Source/cmCacheManager.cxx b/Source/cmCacheManager.cxx
index ab0bb79..47a0e85 100644
--- a/Source/cmCacheManager.cxx
+++ b/Source/cmCacheManager.cxx
@@ -13,6 +13,7 @@
#include "cmCacheManager.h"
#include "cmSystemTools.h"
#include "cmCacheManager.h"
+#include "cmGeneratedFileStream.h"
#include "cmMakefile.h"
#include "cmake.h"
#include "cmVersion.h"
@@ -431,9 +432,8 @@ bool cmCacheManager::SaveCache(const char* path)
{
std::string cacheFile = path;
cacheFile += "/CMakeCache.txt";
- std::string tempFile = cacheFile;
- tempFile += ".tmp";
- std::ofstream fout(tempFile.c_str());
+ cmGeneratedFileStream fout(cacheFile.c_str());
+ fout.SetCopyIfDifferent(true);
if(!fout)
{
cmSystemTools::Error("Unable to open cache file for save. ",
@@ -561,10 +561,7 @@ bool cmCacheManager::SaveCache(const char* path)
}
}
fout << "\n";
- fout.close();
- cmSystemTools::CopyFileIfDifferent(tempFile.c_str(),
- cacheFile.c_str());
- cmSystemTools::RemoveFile(tempFile.c_str());
+ fout.Close();
std::string checkCacheFile = path;
checkCacheFile += cmake::GetCMakeFilesDirectory();
cmSystemTools::MakeDirectory(checkCacheFile.c_str());
diff --git a/Source/cmComputeLinkDepends.cxx b/Source/cmComputeLinkDepends.cxx
index ddff2d9..055aab0 100644
--- a/Source/cmComputeLinkDepends.cxx
+++ b/Source/cmComputeLinkDepends.cxx
@@ -633,6 +633,19 @@ cmTarget* cmComputeLinkDepends::FindTargetToLink(int depender_index,
tgt = 0;
}
+ if(tgt && tgt->GetType() == cmTarget::OBJECT_LIBRARY)
+ {
+ cmOStringStream e;
+ e << "Target \"" << this->Target->GetName() << "\" links to "
+ "OBJECT library \"" << tgt->GetName() << "\" but this is not "
+ "allowed. "
+ "One may link only to STATIC or SHARED libraries, or to executables "
+ "with the ENABLE_EXPORTS property set.";
+ this->CMakeInstance->IssueMessage(cmake::FATAL_ERROR, e.str(),
+ this->Target->GetBacktrace());
+ tgt = 0;
+ }
+
// Return the target found, if any.
return tgt;
}
diff --git a/Source/cmExportCommand.cxx b/Source/cmExportCommand.cxx
index cb614d4..1cc1754 100644
--- a/Source/cmExportCommand.cxx
+++ b/Source/cmExportCommand.cxx
@@ -124,6 +124,14 @@ bool cmExportCommand
{
targets.push_back(target);
}
+ else if(target->GetType() == cmTarget::OBJECT_LIBRARY)
+ {
+ cmOStringStream e;
+ e << "given OBJECT library \"" << *currentTarget
+ << "\" which may not be exported.";
+ this->SetError(e.str().c_str());
+ return false;
+ }
else
{
cmOStringStream e;
diff --git a/Source/cmFindPackageCommand.cxx b/Source/cmFindPackageCommand.cxx
index f17002e..ef16ce8 100644
--- a/Source/cmFindPackageCommand.cxx
+++ b/Source/cmFindPackageCommand.cxx
@@ -90,6 +90,7 @@ void cmFindPackageCommand::GenerateDocumentation()
this->CommandDocumentation =
" find_package(<package> [version] [EXACT] [QUIET] [MODULE]\n"
" [[REQUIRED|COMPONENTS] [components...]]\n"
+ " [OPTIONAL_COMPONENTS components...]\n"
" [NO_POLICY_SCOPE])\n"
"Finds and loads settings from an external project. "
"<package>_FOUND will be set to indicate whether the package was found. "
@@ -98,10 +99,14 @@ void cmFindPackageCommand::GenerateDocumentation()
"The QUIET option disables messages if the package cannot be found. "
"The MODULE option disables the second signature documented below. "
"The REQUIRED option stops processing with an error message if the "
- "package cannot be found. "
- "A package-specific list of components may be listed after the "
- "REQUIRED option or after the COMPONENTS option if no REQUIRED "
- "option is given. "
+ "package cannot be found."
+ "\n"
+ "A package-specific list of required components may be listed after the "
+ "COMPONENTS option or directly after the REQUIRED option. "
+ "Additional optional components may be listed after OPTIONAL_COMPONENTS. "
+ "Available components and their influence on whether a package is "
+ "considered to be found are defined by the target package."
+ "\n"
"The [version] argument requests a version with which the package found "
"should be compatible (format is major[.minor[.patch[.tweak]]]). "
"The EXACT option requests that the version be matched exactly. "
@@ -410,6 +415,8 @@ bool cmFindPackageCommand
this->Name = args[0];
std::string components;
const char* components_sep = "";
+ std::set<std::string> requiredComponents;
+ std::set<std::string> optionalComponents;
// Check ancient compatibility.
this->Compatibility_1_6 =
@@ -420,8 +427,8 @@ bool cmFindPackageCommand
this->SearchPathSuffixes.push_back("");
// Parse the arguments.
- enum Doing { DoingNone, DoingComponents, DoingNames, DoingPaths,
- DoingPathSuffixes, DoingConfigs, DoingHints };
+ enum Doing { DoingNone, DoingComponents, DoingOptionalComponents, DoingNames,
+ DoingPaths, DoingPathSuffixes, DoingConfigs, DoingHints };
Doing doing = DoingNone;
cmsys::RegularExpression version("^[0-9.]+$");
bool haveVersion = false;
@@ -465,6 +472,11 @@ bool cmFindPackageCommand
this->Compatibility_1_6 = false;
doing = DoingComponents;
}
+ else if(args[i] == "OPTIONAL_COMPONENTS")
+ {
+ this->Compatibility_1_6 = false;
+ doing = DoingOptionalComponents;
+ }
else if(args[i] == "NAMES")
{
configArgs.insert(i);
@@ -528,12 +540,23 @@ bool cmFindPackageCommand
this->Compatibility_1_6 = false;
doing = DoingNone;
}
- else if(doing == DoingComponents)
+ else if((doing == DoingComponents) || (doing == DoingOptionalComponents))
{
- // Set a variable telling the find script this component
+ // Set a variable telling the find script whether this component
// is required.
+ const char* isRequired = "1";
+ if (doing == DoingOptionalComponents)
+ {
+ isRequired = "0";
+ optionalComponents.insert(args[i]);
+ }
+ else
+ {
+ requiredComponents.insert(args[i]);
+ }
+
std::string req_var = this->Name + "_FIND_REQUIRED_" + args[i];
- this->AddFindDefinition(req_var.c_str(), "1");
+ this->AddFindDefinition(req_var.c_str(), isRequired);
// Append to the list of required components.
components += components_sep;
@@ -584,6 +607,22 @@ bool cmFindPackageCommand
}
}
+ std::vector<std::string> doubledComponents;
+ std::set_intersection(requiredComponents.begin(), requiredComponents.end(),
+ optionalComponents.begin(), optionalComponents.end(),
+ std::back_inserter(doubledComponents));
+ if(!doubledComponents.empty())
+ {
+ cmOStringStream e;
+ e << "called with components that are both required and optional:\n";
+ for(unsigned int i=0; i<doubledComponents.size(); ++i)
+ {
+ e << " " << doubledComponents[i] << "\n";
+ }
+ this->SetError(e.str().c_str());
+ return false;
+ }
+
// Maybe choose one mode exclusively.
this->UseFindModules = configArgs.empty();
this->UseConfigFiles = moduleArgs.empty();
@@ -952,11 +991,26 @@ bool cmFindPackageCommand::HandlePackageMode()
}
}
+ std::string foundVar = this->Name;
+ foundVar += "_FOUND";
+
// If the directory for the config file was found, try to read the file.
bool result = true;
bool found = false;
+ bool configFileSetFOUNDFalse = false;
+
if(fileFound)
{
+ if ((this->Makefile->IsDefinitionSet(foundVar.c_str()))
+ && (this->Makefile->IsOn(foundVar.c_str()) == false))
+ {
+ // by removing Foo_FOUND here if it is FALSE, we don't really change
+ // the situation for the Config file which is about to be included,
+ // but we make it possible to detect later on whether the Config file
+ // has set Foo_FOUND to FALSE itself:
+ this->Makefile->RemoveDefinition(foundVar.c_str());
+ }
+
// Set the version variables before loading the config file.
// It may override them.
this->StoreVersionFound();
@@ -966,6 +1020,15 @@ bool cmFindPackageCommand::HandlePackageMode()
{
// The package has been found.
found = true;
+
+ // Check whether the Config file has set Foo_FOUND to FALSE:
+ if ((this->Makefile->IsDefinitionSet(foundVar.c_str()))
+ && (this->Makefile->IsOn(foundVar.c_str()) == false))
+ {
+ // we get here if the Config file has set Foo_FOUND actively to FALSE
+ found = false;
+ configFileSetFOUNDFalse = true;
+ }
}
else
{
@@ -973,14 +1036,22 @@ bool cmFindPackageCommand::HandlePackageMode()
result = false;
}
}
- else if(!this->Quiet || this->Required)
+
+ if (result && !found && (!this->Quiet || this->Required))
{
// The variable is not set.
cmOStringStream e;
cmOStringStream aw;
+ if (configFileSetFOUNDFalse)
+ {
+ e << "Found package configuration file:\n"
+ " " << this->FileFound << "\n"
+ "but it set " << foundVar << " to FALSE so package \"" <<
+ this->Name << "\" is considered to be NOT FOUND.";
+ }
// If there are files in ConsideredConfigs, it means that FooConfig.cmake
// have been found, but they didn't have appropriate versions.
- if (this->ConsideredConfigs.size() > 0)
+ else if (this->ConsideredConfigs.size() > 0)
{
e << "Could not find a configuration file for package \""
<< this->Name << "\" that "
@@ -1074,8 +1145,6 @@ bool cmFindPackageCommand::HandlePackageMode()
}
// Set a variable marking whether the package was found.
- std::string foundVar = this->Name;
- foundVar += "_FOUND";
this->Makefile->AddDefinition(foundVar.c_str(), found? "1":"0");
// Set a variable naming the configuration file that was found.
diff --git a/Source/cmGeneratorTarget.cxx b/Source/cmGeneratorTarget.cxx
new file mode 100644
index 0000000..7979928
--- /dev/null
+++ b/Source/cmGeneratorTarget.cxx
@@ -0,0 +1,179 @@
+/*============================================================================
+ CMake - Cross Platform Makefile Generator
+ Copyright 2000-2012 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 "cmGeneratorTarget.h"
+
+#include "cmTarget.h"
+#include "cmMakefile.h"
+#include "cmLocalGenerator.h"
+#include "cmGlobalGenerator.h"
+#include "cmSourceFile.h"
+
+//----------------------------------------------------------------------------
+cmGeneratorTarget::cmGeneratorTarget(cmTarget* t): Target(t)
+{
+ this->Makefile = this->Target->GetMakefile();
+ this->LocalGenerator = this->Makefile->GetLocalGenerator();
+ this->GlobalGenerator = this->LocalGenerator->GetGlobalGenerator();
+ this->ClassifySources();
+ this->LookupObjectLibraries();
+}
+
+//----------------------------------------------------------------------------
+void cmGeneratorTarget::ClassifySources()
+{
+ bool isObjLib = this->Target->GetType() == cmTarget::OBJECT_LIBRARY;
+ std::vector<cmSourceFile*> badObjLib;
+ std::vector<cmSourceFile*> const& sources = this->Target->GetSourceFiles();
+ for(std::vector<cmSourceFile*>::const_iterator si = sources.begin();
+ si != sources.end(); ++si)
+ {
+ cmSourceFile* sf = *si;
+ std::string ext = cmSystemTools::LowerCase(sf->GetExtension());
+ cmTarget::SourceFileFlags tsFlags =
+ this->Target->GetTargetSourceFileFlags(sf);
+ if(sf->GetCustomCommand())
+ {
+ this->CustomCommands.push_back(sf);
+ }
+ else if(tsFlags.Type != cmTarget::SourceFileTypeNormal)
+ {
+ this->OSXContent.push_back(sf);
+ if(isObjLib) { badObjLib.push_back(sf); }
+ }
+ else if(sf->GetPropertyAsBool("HEADER_FILE_ONLY"))
+ {
+ this->HeaderSources.push_back(sf);
+ }
+ else if(sf->GetPropertyAsBool("EXTERNAL_OBJECT"))
+ {
+ this->ExternalObjects.push_back(sf);
+ if(isObjLib) { badObjLib.push_back(sf); }
+ }
+ else if(ext == "def")
+ {
+ this->ModuleDefinitionFile = sf->GetFullPath();
+ if(isObjLib) { badObjLib.push_back(sf); }
+ }
+ else if(ext == "idl")
+ {
+ this->IDLSources.push_back(sf);
+ if(isObjLib) { badObjLib.push_back(sf); }
+ }
+ else if(this->GlobalGenerator->IgnoreFile(sf->GetExtension().c_str()))
+ {
+ // We only get here if a source file is not an external object
+ // and has an extension that is listed as an ignored file type.
+ // No message or diagnosis should be given.
+ this->ExtraSources.push_back(sf);
+ }
+ else if(sf->GetLanguage())
+ {
+ this->ObjectSources.push_back(sf);
+ }
+ else
+ {
+ this->ExtraSources.push_back(sf);
+ if(isObjLib && ext != "txt")
+ {
+ badObjLib.push_back(sf);
+ }
+ }
+ }
+
+ if(!badObjLib.empty())
+ {
+ cmOStringStream e;
+ e << "OBJECT library \"" << this->Target->GetName() << "\" contains:\n";
+ for(std::vector<cmSourceFile*>::iterator i = badObjLib.begin();
+ i != badObjLib.end(); ++i)
+ {
+ e << " " << (*i)->GetLocation().GetName() << "\n";
+ }
+ e << "but may contain only headers and sources that compile.";
+ this->GlobalGenerator->GetCMakeInstance()
+ ->IssueMessage(cmake::FATAL_ERROR, e.str(),
+ this->Target->GetBacktrace());
+ }
+}
+
+//----------------------------------------------------------------------------
+void cmGeneratorTarget::LookupObjectLibraries()
+{
+ std::vector<std::string> const& objLibs =
+ this->Target->GetObjectLibraries();
+ for(std::vector<std::string>::const_iterator oli = objLibs.begin();
+ oli != objLibs.end(); ++oli)
+ {
+ std::string const& objLibName = *oli;
+ if(cmTarget* objLib = this->Makefile->FindTargetToUse(objLibName.c_str()))
+ {
+ if(objLib->GetType() == cmTarget::OBJECT_LIBRARY)
+ {
+ if(this->Target->GetType() != cmTarget::EXECUTABLE &&
+ this->Target->GetType() != cmTarget::STATIC_LIBRARY &&
+ this->Target->GetType() != cmTarget::SHARED_LIBRARY &&
+ this->Target->GetType() != cmTarget::MODULE_LIBRARY)
+ {
+ this->GlobalGenerator->GetCMakeInstance()
+ ->IssueMessage(cmake::FATAL_ERROR,
+ "Only executables and non-OBJECT libraries may "
+ "reference target objects.",
+ this->Target->GetBacktrace());
+ return;
+ }
+ this->Target->AddUtility(objLib->GetName());
+ this->ObjectLibraries.push_back(objLib);
+ }
+ else
+ {
+ cmOStringStream e;
+ e << "Objects of target \"" << objLibName
+ << "\" referenced but is not an OBJECT library.";
+ this->GlobalGenerator->GetCMakeInstance()
+ ->IssueMessage(cmake::FATAL_ERROR, e.str(),
+ this->Target->GetBacktrace());
+ return;
+ }
+ }
+ else
+ {
+ cmOStringStream e;
+ e << "Objects of target \"" << objLibName
+ << "\" referenced but no such target exists.";
+ this->GlobalGenerator->GetCMakeInstance()
+ ->IssueMessage(cmake::FATAL_ERROR, e.str(),
+ this->Target->GetBacktrace());
+ return;
+ }
+ }
+}
+
+//----------------------------------------------------------------------------
+void cmGeneratorTarget::UseObjectLibraries(std::vector<std::string>& objs)
+{
+ for(std::vector<cmTarget*>::const_iterator
+ ti = this->ObjectLibraries.begin();
+ ti != this->ObjectLibraries.end(); ++ti)
+ {
+ cmTarget* objLib = *ti;
+ cmGeneratorTarget* ogt =
+ this->GlobalGenerator->GetGeneratorTarget(objLib);
+ for(std::vector<cmSourceFile*>::const_iterator
+ si = ogt->ObjectSources.begin();
+ si != ogt->ObjectSources.end(); ++si)
+ {
+ std::string obj = ogt->ObjectDirectory;
+ obj += ogt->Objects[*si];
+ objs.push_back(obj);
+ }
+ }
+}
diff --git a/Source/cmGeneratorTarget.h b/Source/cmGeneratorTarget.h
new file mode 100644
index 0000000..3e50656
--- /dev/null
+++ b/Source/cmGeneratorTarget.h
@@ -0,0 +1,64 @@
+/*============================================================================
+ CMake - Cross Platform Makefile Generator
+ Copyright 2000-2012 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 cmGeneratorTarget_h
+#define cmGeneratorTarget_h
+
+#include "cmStandardIncludes.h"
+
+class cmCustomCommand;
+class cmGlobalGenerator;
+class cmLocalGenerator;
+class cmMakefile;
+class cmSourceFile;
+class cmTarget;
+
+class cmGeneratorTarget
+{
+public:
+ cmGeneratorTarget(cmTarget*);
+
+ cmTarget* Target;
+ cmMakefile* Makefile;
+ cmLocalGenerator* LocalGenerator;
+ cmGlobalGenerator* GlobalGenerator;
+
+ /** Sources classified by purpose. */
+ std::vector<cmSourceFile*> CustomCommands;
+ std::vector<cmSourceFile*> ExtraSources;
+ std::vector<cmSourceFile*> HeaderSources;
+ std::vector<cmSourceFile*> ObjectSources;
+ std::vector<cmSourceFile*> ExternalObjects;
+ std::vector<cmSourceFile*> OSXContent;
+ std::vector<cmSourceFile*> IDLSources;
+ std::string ModuleDefinitionFile;
+
+ std::map<cmSourceFile const*, std::string> Objects;
+ std::set<cmSourceFile const*> ExplicitObjectName;
+
+ /** Full path with trailing slash to the top-level directory
+ holding object files for this target. Includes the build
+ time config name placeholder if needed for the generator. */
+ std::string ObjectDirectory;
+
+ std::vector<cmTarget*> ObjectLibraries;
+
+ void UseObjectLibraries(std::vector<std::string>& objs);
+
+private:
+ void ClassifySources();
+ void LookupObjectLibraries();
+
+ cmGeneratorTarget(cmGeneratorTarget const&);
+ void operator=(cmGeneratorTarget const&);
+};
+
+#endif
diff --git a/Source/cmGlobalGenerator.cxx b/Source/cmGlobalGenerator.cxx
index a988844..545f9e8 100644
--- a/Source/cmGlobalGenerator.cxx
+++ b/Source/cmGlobalGenerator.cxx
@@ -24,6 +24,7 @@
#include "cmExportInstallFileGenerator.h"
#include "cmComputeTargetDepends.h"
#include "cmGeneratedFileStream.h"
+#include "cmGeneratorTarget.h"
#include <cmsys/Directory.hxx>
@@ -74,6 +75,7 @@ cmGlobalGenerator::~cmGlobalGenerator()
delete this->ExtraGenerator;
}
+ this->ClearGeneratorTargets();
this->ClearExportSets();
}
@@ -807,6 +809,7 @@ bool cmGlobalGenerator::IsDependedOn(const char* project,
void cmGlobalGenerator::Configure()
{
this->FirstTimeProgress = 0.0f;
+ this->ClearGeneratorTargets();
this->ClearExportSets();
// Delete any existing cmLocalGenerators
unsigned int i;
@@ -947,6 +950,9 @@ void cmGlobalGenerator::Generate()
this->LocalGenerators[i]->GenerateTargetManifest();
}
+ // Create per-target generator information.
+ this->CreateGeneratorTargets();
+
// Compute the inter-target dependencies.
if(!this->ComputeTargetDepends())
{
@@ -1056,6 +1062,55 @@ void cmGlobalGenerator::CreateAutomocTargets()
#endif
}
+//----------------------------------------------------------------------------
+void cmGlobalGenerator::CreateGeneratorTargets()
+{
+ // Construct per-target generator information.
+ for(unsigned int i=0; i < this->LocalGenerators.size(); ++i)
+ {
+ cmTargets& targets =
+ this->LocalGenerators[i]->GetMakefile()->GetTargets();
+ for(cmTargets::iterator ti = targets.begin();
+ ti != targets.end(); ++ti)
+ {
+ cmTarget* t = &ti->second;
+ cmGeneratorTarget* gt = new cmGeneratorTarget(t);
+ this->GeneratorTargets[t] = gt;
+ this->ComputeTargetObjects(gt);
+ }
+ }
+}
+
+//----------------------------------------------------------------------------
+void cmGlobalGenerator::ClearGeneratorTargets()
+{
+ for(GeneratorTargetsType::iterator i = this->GeneratorTargets.begin();
+ i != this->GeneratorTargets.end(); ++i)
+ {
+ delete i->second;
+ }
+ this->GeneratorTargets.clear();
+}
+
+//----------------------------------------------------------------------------
+cmGeneratorTarget* cmGlobalGenerator::GetGeneratorTarget(cmTarget* t) const
+{
+ GeneratorTargetsType::const_iterator ti = this->GeneratorTargets.find(t);
+ if(ti == this->GeneratorTargets.end())
+ {
+ this->CMakeInstance->IssueMessage(
+ cmake::INTERNAL_ERROR, "Missing cmGeneratorTarget instance!",
+ cmListFileBacktrace());
+ return 0;
+ }
+ return ti->second;
+}
+
+//----------------------------------------------------------------------------
+void cmGlobalGenerator::ComputeTargetObjects(cmGeneratorTarget*) const
+{
+ // Implemented in generator subclasses that need this.
+}
void cmGlobalGenerator::CheckLocalGenerators()
{
@@ -1714,7 +1769,7 @@ void cmGlobalGenerator::SetCMakeInstance(cmake* cm)
void cmGlobalGenerator::CreateDefaultGlobalTargets(cmTargets* targets)
{
cmMakefile* mf = this->LocalGenerators[0]->GetMakefile();
- const char* cmakeCfgIntDir = this->GetCMakeCFGInitDirectory();
+ const char* cmakeCfgIntDir = this->GetCMakeCFGIntDir();
const char* cmakeCommand = mf->GetRequiredDefinition("CMAKE_COMMAND");
// CPack
diff --git a/Source/cmGlobalGenerator.h b/Source/cmGlobalGenerator.h
index 1a0e41a..80b948b 100644
--- a/Source/cmGlobalGenerator.h
+++ b/Source/cmGlobalGenerator.h
@@ -19,6 +19,7 @@
#include "cmTargetDepend.h" // For cmTargetDependSet
#include "cmSystemTools.h" // for cmSystemTools::OutputOption
class cmake;
+class cmGeneratorTarget;
class cmMakefile;
class cmLocalGenerator;
class cmExternalMakefileProjectGenerator;
@@ -183,7 +184,7 @@ public:
const char* GetLanguageOutputExtension(cmSourceFile const&);
///! What is the configurations directory variable called?
- virtual const char* GetCMakeCFGInitDirectory() { return "."; }
+ virtual const char* GetCMakeCFGIntDir() const { return "."; }
/** Get whether the generator should use a script for link commands. */
bool GetUseLinkScript() const { return this->UseLinkScript; }
@@ -251,6 +252,9 @@ public:
// via a target_link_libraries or add_dependencies
TargetDependSet const& GetTargetDirectDepends(cmTarget & target);
+ /** Get per-target generator information. */
+ cmGeneratorTarget* GetGeneratorTarget(cmTarget*) const;
+
const std::map<cmStdString, std::vector<cmLocalGenerator*> >& GetProjectMap()
const {return this->ProjectMap;}
@@ -370,6 +374,13 @@ private:
typedef std::map<cmTarget *, TargetDependSet> TargetDependMap;
TargetDependMap TargetDependencies;
+ // Per-target generator information.
+ typedef std::map<cmTarget*, cmGeneratorTarget*> GeneratorTargetsType;
+ GeneratorTargetsType GeneratorTargets;
+ void CreateGeneratorTargets();
+ void ClearGeneratorTargets();
+ virtual void ComputeTargetObjects(cmGeneratorTarget* gt) const;
+
// Cache directory content and target files to be built.
struct DirectoryContent: public std::set<cmStdString>
{
diff --git a/Source/cmGlobalNinjaGenerator.cxx b/Source/cmGlobalNinjaGenerator.cxx
index 7c1529b..9cbd502 100644
--- a/Source/cmGlobalNinjaGenerator.cxx
+++ b/Source/cmGlobalNinjaGenerator.cxx
@@ -14,6 +14,7 @@
#include "cmLocalNinjaGenerator.h"
#include "cmMakefile.h"
#include "cmGeneratedFileStream.h"
+#include "cmGeneratorTarget.h"
#include "cmVersion.h"
const char* cmGlobalNinjaGenerator::NINJA_BUILD_FILE = "build.ninja";
@@ -500,6 +501,34 @@ bool cmGlobalNinjaGenerator::HasRule(const std::string &name)
}
//----------------------------------------------------------------------------
+// Private virtual overrides
+
+// TODO: Refactor to combine with cmGlobalUnixMakefileGenerator3 impl.
+void cmGlobalNinjaGenerator::ComputeTargetObjects(cmGeneratorTarget* gt) const
+{
+ cmTarget* target = gt->Target;
+
+ // Compute full path to object file directory for this target.
+ std::string dir_max;
+ dir_max += gt->Makefile->GetCurrentOutputDirectory();
+ dir_max += "/";
+ dir_max += gt->LocalGenerator->GetTargetDirectory(*target);
+ dir_max += "/";
+ gt->ObjectDirectory = dir_max;
+
+ // Compute the name of each object file.
+ for(std::vector<cmSourceFile*>::iterator
+ si = gt->ObjectSources.begin();
+ si != gt->ObjectSources.end(); ++si)
+ {
+ cmSourceFile* sf = *si;
+ std::string objectName = gt->LocalGenerator
+ ->GetObjectFileNameWithoutTarget(*sf, dir_max);
+ gt->Objects[sf] = objectName;
+ }
+}
+
+//----------------------------------------------------------------------------
// Private methods
void cmGlobalNinjaGenerator::OpenBuildFileStream()
@@ -635,6 +664,7 @@ cmGlobalNinjaGenerator
target->GetFullPath(configName).c_str()));
break;
+ case cmTarget::OBJECT_LIBRARY:
case cmTarget::UTILITY: {
std::string path = ng->ConvertToNinjaPath(
target->GetMakefile()->GetStartOutputDirectory());
diff --git a/Source/cmGlobalNinjaGenerator.h b/Source/cmGlobalNinjaGenerator.h
index 39df826..3217581 100644
--- a/Source/cmGlobalNinjaGenerator.h
+++ b/Source/cmGlobalNinjaGenerator.h
@@ -18,6 +18,7 @@
class cmLocalGenerator;
class cmGeneratedFileStream;
+class cmGeneratorTarget;
/**
* \class cmGlobalNinjaGenerator
@@ -236,6 +237,11 @@ protected:
virtual bool CheckALLOW_DUPLICATE_CUSTOM_TARGETS() { return true; }
private:
+
+ /// @see cmGlobalGenerator::ComputeTargetObjects
+ virtual void ComputeTargetObjects(cmGeneratorTarget* gt) const;
+
+private:
// In order to access the AddDependencyToAll() functions and co.
friend class cmLocalNinjaGenerator;
diff --git a/Source/cmGlobalUnixMakefileGenerator3.cxx b/Source/cmGlobalUnixMakefileGenerator3.cxx
index a23c0d8..e63de9c 100644
--- a/Source/cmGlobalUnixMakefileGenerator3.cxx
+++ b/Source/cmGlobalUnixMakefileGenerator3.cxx
@@ -17,6 +17,7 @@
#include "cmGeneratedFileStream.h"
#include "cmSourceFile.h"
#include "cmTarget.h"
+#include "cmGeneratorTarget.h"
cmGlobalUnixMakefileGenerator3::cmGlobalUnixMakefileGenerator3()
{
@@ -71,6 +72,38 @@ void cmGlobalUnixMakefileGenerator3
}
//----------------------------------------------------------------------------
+void
+cmGlobalUnixMakefileGenerator3
+::ComputeTargetObjects(cmGeneratorTarget* gt) const
+{
+ cmTarget* target = gt->Target;
+ cmLocalUnixMakefileGenerator3* lg =
+ static_cast<cmLocalUnixMakefileGenerator3*>(gt->LocalGenerator);
+
+ // Compute full path to object file directory for this target.
+ std::string dir_max;
+ dir_max += gt->Makefile->GetCurrentOutputDirectory();
+ dir_max += "/";
+ dir_max += gt->LocalGenerator->GetTargetDirectory(*target);
+ dir_max += "/";
+ gt->ObjectDirectory = dir_max;
+
+ // Compute the name of each object file.
+ for(std::vector<cmSourceFile*>::iterator
+ si = gt->ObjectSources.begin();
+ si != gt->ObjectSources.end(); ++si)
+ {
+ cmSourceFile* sf = *si;
+ bool hasSourceExtension = true;
+ std::string objectName = gt->LocalGenerator
+ ->GetObjectFileNameWithoutTarget(*sf, dir_max,
+ &hasSourceExtension);
+ gt->Objects[sf] = objectName;
+ lg->AddLocalObjectFile(target, sf, objectName, hasSourceExtension);
+ }
+}
+
+//----------------------------------------------------------------------------
std::string EscapeJSON(const std::string& s) {
std::string result;
for (std::string::size_type i = 0; i < s.size(); ++i) {
@@ -378,6 +411,7 @@ void cmGlobalUnixMakefileGenerator3
(l->second.GetType() == cmTarget::STATIC_LIBRARY) ||
(l->second.GetType() == cmTarget::SHARED_LIBRARY) ||
(l->second.GetType() == cmTarget::MODULE_LIBRARY) ||
+ (l->second.GetType() == cmTarget::OBJECT_LIBRARY) ||
(l->second.GetType() == cmTarget::UTILITY))
{
std::string tname = lg->GetRelativeTargetDirectory(l->second);
@@ -413,6 +447,7 @@ cmGlobalUnixMakefileGenerator3
(l->second.GetType() == cmTarget::STATIC_LIBRARY) ||
(l->second.GetType() == cmTarget::SHARED_LIBRARY) ||
(l->second.GetType() == cmTarget::MODULE_LIBRARY) ||
+ (l->second.GetType() == cmTarget::OBJECT_LIBRARY) ||
(l->second.GetType() == cmTarget::UTILITY))
{
// Add this to the list of depends rules in this directory.
@@ -587,6 +622,7 @@ cmGlobalUnixMakefileGenerator3
(t->second.GetType() == cmTarget::STATIC_LIBRARY) ||
(t->second.GetType() == cmTarget::SHARED_LIBRARY) ||
(t->second.GetType() == cmTarget::MODULE_LIBRARY) ||
+ (t->second.GetType() == cmTarget::OBJECT_LIBRARY) ||
(t->second.GetType() == cmTarget::UTILITY)))
{
// Add a rule to build the target by name.
@@ -673,6 +709,7 @@ cmGlobalUnixMakefileGenerator3
|| (t->second.GetType() == cmTarget::STATIC_LIBRARY)
|| (t->second.GetType() == cmTarget::SHARED_LIBRARY)
|| (t->second.GetType() == cmTarget::MODULE_LIBRARY)
+ || (t->second.GetType() == cmTarget::OBJECT_LIBRARY)
|| (t->second.GetType() == cmTarget::UTILITY)))
{
std::string makefileName;
@@ -982,6 +1019,7 @@ void cmGlobalUnixMakefileGenerator3::WriteHelpRule
(t->second.GetType() == cmTarget::STATIC_LIBRARY) ||
(t->second.GetType() == cmTarget::SHARED_LIBRARY) ||
(t->second.GetType() == cmTarget::MODULE_LIBRARY) ||
+ (t->second.GetType() == cmTarget::OBJECT_LIBRARY) ||
(t->second.GetType() == cmTarget::GLOBAL_TARGET) ||
(t->second.GetType() == cmTarget::UTILITY))
{
diff --git a/Source/cmGlobalUnixMakefileGenerator3.h b/Source/cmGlobalUnixMakefileGenerator3.h
index 9663b55..e6dd09d 100644
--- a/Source/cmGlobalUnixMakefileGenerator3.h
+++ b/Source/cmGlobalUnixMakefileGenerator3.h
@@ -182,6 +182,8 @@ protected:
size_t CountProgressMarksInAll(cmLocalUnixMakefileGenerator3* lg);
cmGeneratedFileStream *CommandDatabase;
+private:
+ virtual void ComputeTargetObjects(cmGeneratorTarget* gt) const;
};
#endif
diff --git a/Source/cmGlobalVisualStudio10Generator.h b/Source/cmGlobalVisualStudio10Generator.h
index 18b483d..750b89c 100644
--- a/Source/cmGlobalVisualStudio10Generator.h
+++ b/Source/cmGlobalVisualStudio10Generator.h
@@ -72,7 +72,7 @@ public:
* Studio?
*/
virtual std::string GetUserMacrosRegKeyBase();
- virtual const char* GetCMakeCFGInitDirectory()
+ virtual const char* GetCMakeCFGIntDir() const
{ return "$(Configuration)";}
bool Find64BitTools(cmMakefile* mf);
protected:
diff --git a/Source/cmGlobalVisualStudio6Generator.h b/Source/cmGlobalVisualStudio6Generator.h
index 77d5370..da08a12 100644
--- a/Source/cmGlobalVisualStudio6Generator.h
+++ b/Source/cmGlobalVisualStudio6Generator.h
@@ -82,7 +82,7 @@ public:
std::string& dir);
///! What is the configurations directory variable called?
- virtual const char* GetCMakeCFGInitDirectory() { return "$(IntDir)"; }
+ virtual const char* GetCMakeCFGIntDir() const { return "$(IntDir)"; }
protected:
virtual const char* GetIDEVersion() { return "6.0"; }
diff --git a/Source/cmGlobalVisualStudio7Generator.h b/Source/cmGlobalVisualStudio7Generator.h
index adfb757..c92998e 100644
--- a/Source/cmGlobalVisualStudio7Generator.h
+++ b/Source/cmGlobalVisualStudio7Generator.h
@@ -87,7 +87,7 @@ public:
std::string& dir);
///! What is the configurations directory variable called?
- virtual const char* GetCMakeCFGInitDirectory() { return "$(OutDir)"; }
+ virtual const char* GetCMakeCFGIntDir() const { return "$(OutDir)"; }
/** Return true if the target project file should have the option
LinkLibraryDependencies and link to .sln dependencies. */
diff --git a/Source/cmGlobalVisualStudioGenerator.cxx b/Source/cmGlobalVisualStudioGenerator.cxx
index 449d090..7da4f86 100644
--- a/Source/cmGlobalVisualStudioGenerator.cxx
+++ b/Source/cmGlobalVisualStudioGenerator.cxx
@@ -12,8 +12,10 @@
#include "cmGlobalVisualStudioGenerator.h"
#include "cmCallVisualStudioMacro.h"
-#include "cmLocalGenerator.h"
+#include "cmGeneratorTarget.h"
+#include "cmLocalVisualStudioGenerator.h"
#include "cmMakefile.h"
+#include "cmSourceFile.h"
#include "cmTarget.h"
//----------------------------------------------------------------------------
@@ -98,6 +100,64 @@ void cmGlobalVisualStudioGenerator::Generate()
}
//----------------------------------------------------------------------------
+void
+cmGlobalVisualStudioGenerator
+::ComputeTargetObjects(cmGeneratorTarget* gt) const
+{
+ cmLocalVisualStudioGenerator* lg =
+ static_cast<cmLocalVisualStudioGenerator*>(gt->LocalGenerator);
+ std::string dir_max = lg->ComputeLongestObjectDirectory(*gt->Target);
+
+ // Count the number of object files with each name. Note that
+ // windows file names are not case sensitive.
+ std::map<cmStdString, int> counts;
+ for(std::vector<cmSourceFile*>::const_iterator
+ si = gt->ObjectSources.begin();
+ si != gt->ObjectSources.end(); ++si)
+ {
+ cmSourceFile* sf = *si;
+ std::string objectNameLower = cmSystemTools::LowerCase(
+ cmSystemTools::GetFilenameWithoutLastExtension(sf->GetFullPath()));
+ objectNameLower += ".obj";
+ counts[objectNameLower] += 1;
+ }
+
+ // For all source files producing duplicate names we need unique
+ // object name computation.
+ for(std::vector<cmSourceFile*>::const_iterator
+ si = gt->ObjectSources.begin();
+ si != gt->ObjectSources.end(); ++si)
+ {
+ cmSourceFile* sf = *si;
+ std::string objectName =
+ cmSystemTools::GetFilenameWithoutLastExtension(sf->GetFullPath());
+ objectName += ".obj";
+ if(counts[cmSystemTools::LowerCase(objectName)] > 1)
+ {
+ gt->ExplicitObjectName.insert(sf);
+ objectName = lg->GetObjectFileNameWithoutTarget(*sf, dir_max);
+ }
+ gt->Objects[sf] = objectName;
+ }
+
+ std::string dir = gt->Makefile->GetCurrentOutputDirectory();
+ dir += "/";
+ std::string tgtDir = lg->GetTargetDirectory(*gt->Target);
+ if(!tgtDir.empty())
+ {
+ dir += tgtDir;
+ dir += "/";
+ }
+ const char* cd = this->GetCMakeCFGIntDir();
+ if(cd && *cd)
+ {
+ dir += cd;
+ dir += "/";
+ }
+ gt->ObjectDirectory = dir;
+}
+
+//----------------------------------------------------------------------------
bool IsVisualStudioMacrosFileRegistered(const std::string& macrosFile,
const std::string& regKeyBase,
std::string& nextAvailableSubKeyName);
@@ -315,6 +375,12 @@ bool cmGlobalVisualStudioGenerator::ComputeTargetDepends()
}
//----------------------------------------------------------------------------
+static bool VSLinkable(cmTarget* t)
+{
+ return t->IsLinkable() || t->GetType() == cmTarget::OBJECT_LIBRARY;
+}
+
+//----------------------------------------------------------------------------
void cmGlobalVisualStudioGenerator::ComputeVSTargetDepends(cmTarget& target)
{
if(this->VSTargetDepends.find(&target) != this->VSTargetDepends.end())
@@ -398,7 +464,7 @@ void cmGlobalVisualStudioGenerator::ComputeVSTargetDepends(cmTarget& target)
di != utilDepends.end(); ++di)
{
cmTarget* dep = *di;
- if(allowLinkable || !dep->IsLinkable() || linked.count(dep))
+ if(allowLinkable || !VSLinkable(dep) || linked.count(dep))
{
// Direct dependency allowed.
vsTargetDepend.insert(dep->GetName());
diff --git a/Source/cmGlobalVisualStudioGenerator.h b/Source/cmGlobalVisualStudioGenerator.h
index bc96f4e..b62ba22 100644
--- a/Source/cmGlobalVisualStudioGenerator.h
+++ b/Source/cmGlobalVisualStudioGenerator.h
@@ -97,6 +97,8 @@ protected:
typedef std::map<cmTarget*, cmStdString> UtilityDependsMap;
UtilityDependsMap UtilityDepends;
private:
+ void ComputeTargetObjects(cmGeneratorTarget* gt) const;
+
void FollowLinkDepends(cmTarget* target, std::set<cmTarget*>& linked);
class TargetSetMap: public std::map<cmTarget*, TargetSet> {};
diff --git a/Source/cmGlobalXCodeGenerator.cxx b/Source/cmGlobalXCodeGenerator.cxx
index e552928..56228f5 100644
--- a/Source/cmGlobalXCodeGenerator.cxx
+++ b/Source/cmGlobalXCodeGenerator.cxx
@@ -19,6 +19,7 @@
#include "cmComputeLinkInformation.h"
#include "cmSourceFile.h"
#include "cmCustomCommandGenerator.h"
+#include "cmGeneratorTarget.h"
#include <cmsys/auto_ptr.hxx>
@@ -135,8 +136,17 @@ cmGlobalGenerator* cmGlobalXCodeGenerator::New()
{
#if defined(CMAKE_BUILD_WITH_CMAKE)
cmXcodeVersionParser parser;
- parser.ParseFile
- ("/Developer/Applications/Xcode.app/Contents/version.plist");
+ if (cmSystemTools::FileExists(
+ "/Applications/Xcode.app/Contents/version.plist"))
+ {
+ parser.ParseFile
+ ("/Applications/Xcode.app/Contents/version.plist");
+ }
+ else
+ {
+ parser.ParseFile
+ ("/Developer/Applications/Xcode.app/Contents/version.plist");
+ }
cmsys::auto_ptr<cmGlobalXCodeGenerator>
gg(new cmGlobalXCodeGenerator(parser.Version));
if (gg->XcodeVersion == 20)
@@ -294,6 +304,10 @@ void cmGlobalXCodeGenerator::Generate()
}
this->ForceLinkerLanguages();
this->cmGlobalGenerator::Generate();
+ if(cmSystemTools::GetErrorOccuredFlag())
+ {
+ return;
+ }
for(it = this->ProjectMap.begin(); it!= this->ProjectMap.end(); ++it)
{
cmLocalGenerator* root = it->second[0];
@@ -408,6 +422,8 @@ cmGlobalXCodeGenerator::AddExtraTargets(cmLocalGenerator* root,
// this will make sure that when the next target is built
// things are up-to-date
if((target.GetType() == cmTarget::EXECUTABLE ||
+// Nope - no post-build for OBJECT_LIRBRARY
+// target.GetType() == cmTarget::OBJECT_LIBRARY ||
target.GetType() == cmTarget::STATIC_LIBRARY ||
target.GetType() == cmTarget::SHARED_LIBRARY ||
target.GetType() == cmTarget::MODULE_LIBRARY))
@@ -561,15 +577,43 @@ cmXCodeObject* cmGlobalXCodeGenerator
}
//----------------------------------------------------------------------------
-cmStdString GetGroupMapKey(cmTarget& cmtarget, cmSourceFile* sf)
+cmStdString
+GetGroupMapKeyFromPath(cmTarget& cmtarget, const std::string& fullpath)
{
cmStdString key(cmtarget.GetName());
key += "-";
- key += sf->GetFullPath();
+ key += fullpath;
return key;
}
//----------------------------------------------------------------------------
+cmStdString
+GetGroupMapKey(cmTarget& cmtarget, cmSourceFile* sf)
+{
+ return GetGroupMapKeyFromPath(cmtarget, sf->GetFullPath());
+}
+
+//----------------------------------------------------------------------------
+cmXCodeObject*
+cmGlobalXCodeGenerator::CreateXCodeSourceFileFromPath(
+ const std::string &fullpath,
+ cmTarget& cmtarget,
+ const std::string &lang)
+{
+ // Using a map and the full path guarantees that we will always get the same
+ // fileRef object for any given full path.
+ //
+ cmXCodeObject* fileRef =
+ this->CreateXCodeFileReferenceFromPath(fullpath, cmtarget, lang);
+
+ cmXCodeObject* buildFile = this->CreateObject(cmXCodeObject::PBXBuildFile);
+ buildFile->SetComment(fileRef->GetComment());
+ buildFile->AddAttribute("fileRef", this->CreateObjectReference(fileRef));
+
+ return buildFile;
+}
+
+//----------------------------------------------------------------------------
cmXCodeObject*
cmGlobalXCodeGenerator::CreateXCodeSourceFile(cmLocalGenerator* lg,
cmSourceFile* sf,
@@ -603,14 +647,16 @@ cmGlobalXCodeGenerator::CreateXCodeSourceFile(cmLocalGenerator* lg,
flags += flagsBuild.GetString();
}
- // Using a map and the full path guarantees that we will always get the same
- // fileRef object for any given full path.
- //
- cmXCodeObject* fileRef = this->CreateXCodeFileReference(sf, cmtarget);
+ const char* lang =
+ this->CurrentLocalGenerator->GetSourceFileLanguage(*sf);
+ if (!lang)
+ {
+ lang = "";
+ }
- cmXCodeObject* buildFile = this->CreateObject(cmXCodeObject::PBXBuildFile);
- buildFile->SetComment(fileRef->GetComment());
- buildFile->AddAttribute("fileRef", this->CreateObjectReference(fileRef));
+ cmXCodeObject* buildFile =
+ this->CreateXCodeSourceFileFromPath(sf->GetFullPath(), cmtarget, lang);
+ cmXCodeObject* fileRef = buildFile->GetObject("fileRef")->GetObject();
cmXCodeObject* settings =
this->CreateObject(cmXCodeObject::ATTRIBUTE_GROUP);
@@ -662,36 +708,12 @@ cmGlobalXCodeGenerator::CreateXCodeSourceFile(cmLocalGenerator* lg,
}
//----------------------------------------------------------------------------
-cmXCodeObject*
-cmGlobalXCodeGenerator::CreateXCodeFileReference(cmSourceFile* sf,
- cmTarget& cmtarget)
+std::string
+GetSourcecodeValueFromFileExtension(const std::string& _ext,
+ const std::string& lang)
{
- std::string fname = sf->GetFullPath();
- cmXCodeObject* fileRef = this->FileRefs[fname];
- if(!fileRef)
- {
- fileRef = this->CreateObject(cmXCodeObject::PBXFileReference);
- std::string comment = fname;
- //comment += " in ";
- //std::string gname = group->GetObject("name")->GetString();
- //comment += gname.substr(1, gname.size()-2);
- fileRef->SetComment(fname.c_str());
- this->FileRefs[fname] = fileRef;
- }
- cmStdString key = GetGroupMapKey(cmtarget, sf);
- cmXCodeObject* group = this->GroupMap[key];
- cmXCodeObject* children = group->GetObject("children");
- if (!children->HasObject(fileRef))
- {
- children->AddObject(fileRef);
- }
- fileRef->AddAttribute("fileEncoding", this->CreateString("4"));
-
- const char* lang =
- this->CurrentLocalGenerator->GetSourceFileLanguage(*sf);
+ std::string ext = cmSystemTools::LowerCase(_ext);
std::string sourcecode = "sourcecode";
- std::string ext = sf->GetExtension();
- ext = cmSystemTools::LowerCase(ext);
if(ext == "o")
{
@@ -726,25 +748,25 @@ cmGlobalXCodeGenerator::CreateXCodeFileReference(cmSourceFile* sf,
{
sourcecode += ".cpp.h";
}
- else if(lang && strcmp(lang, "CXX") == 0)
+ else if(ext == "png" || ext == "gif" || ext == "jpg")
{
- sourcecode += ".cpp.cpp";
+ sourcecode = "image";
}
- else if(lang && strcmp(lang, "C") == 0)
+ else if(ext == "txt")
{
- sourcecode += ".c.c";
+ sourcecode += ".text";
}
- else if(lang && strcmp(lang, "Fortran") == 0)
+ else if(lang == "CXX")
{
- sourcecode += ".fortran.f90";
+ sourcecode += ".cpp.cpp";
}
- else if(ext == "png" || ext == "gif" || ext == "jpg")
+ else if(lang == "C")
{
- sourcecode = "image";
+ sourcecode += ".c.c";
}
- else if(ext == "txt")
+ else if(lang == "Fortran")
{
- sourcecode += ".text";
+ sourcecode += ".fortran.f90";
}
//else
// {
@@ -754,11 +776,51 @@ cmGlobalXCodeGenerator::CreateXCodeFileReference(cmSourceFile* sf,
// // valid lastKnownFileType value.
// }
+ return sourcecode;
+}
+
+//----------------------------------------------------------------------------
+cmXCodeObject*
+cmGlobalXCodeGenerator::CreateXCodeFileReferenceFromPath(
+ const std::string &fullpath,
+ cmTarget& cmtarget,
+ const std::string &lang)
+{
+ std::string fname = fullpath;
+ cmXCodeObject* fileRef = this->FileRefs[fname];
+ if(!fileRef)
+ {
+ fileRef = this->CreateObject(cmXCodeObject::PBXFileReference);
+ std::string comment = fname;
+ fileRef->SetComment(fname.c_str());
+ this->FileRefs[fname] = fileRef;
+ }
+ cmStdString key = GetGroupMapKeyFromPath(cmtarget, fullpath);
+ cmXCodeObject* group = this->GroupMap[key];
+ cmXCodeObject* children = group->GetObject("children");
+ if (!children->HasObject(fileRef))
+ {
+ children->AddObject(fileRef);
+ }
+ fileRef->AddAttribute("fileEncoding", this->CreateString("4"));
+
+ // Compute the extension.
+ std::string ext;
+ std::string realExt =
+ cmSystemTools::GetFilenameLastExtension(fullpath);
+ if(!realExt.empty())
+ {
+ // Extension without the leading '.'.
+ ext = realExt.substr(1);
+ }
+
+ std::string sourcecode = GetSourcecodeValueFromFileExtension(ext, lang);
+
fileRef->AddAttribute("lastKnownFileType",
this->CreateString(sourcecode.c_str()));
// Store the file path relative to the top of the source tree.
- std::string path = this->RelativeToSource(sf->GetFullPath().c_str());
+ std::string path = this->RelativeToSource(fullpath.c_str());
std::string name = cmSystemTools::GetFilenameName(path.c_str());
const char* sourceTree = (cmSystemTools::FileIsFullPath(path.c_str())?
"<absolute>" : "SOURCE_ROOT");
@@ -773,6 +835,22 @@ cmGlobalXCodeGenerator::CreateXCodeFileReference(cmSourceFile* sf,
}
//----------------------------------------------------------------------------
+cmXCodeObject*
+cmGlobalXCodeGenerator::CreateXCodeFileReference(cmSourceFile* sf,
+ cmTarget& cmtarget)
+{
+ const char* lang =
+ this->CurrentLocalGenerator->GetSourceFileLanguage(*sf);
+ if (!lang)
+ {
+ lang = "";
+ }
+
+ return this->CreateXCodeFileReferenceFromPath(
+ sf->GetFullPath(), cmtarget, lang);
+}
+
+//----------------------------------------------------------------------------
bool cmGlobalXCodeGenerator::SpecialTargetEmitted(std::string const& tname)
{
if(tname == "ALL_BUILD" || tname == "XCODE_DEPEND_HELPER" ||
@@ -880,6 +958,20 @@ cmGlobalXCodeGenerator::CreateXCodeTargets(cmLocalGenerator* gen,
}
}
+ // Add object library contents as external objects. (Equivalent to
+ // the externalObjFiles above, except each one is not a cmSourceFile
+ // within the target.)
+ std::vector<std::string> objs;
+ this->GetGeneratorTarget(&cmtarget)->UseObjectLibraries(objs);
+ for(std::vector<std::string>::const_iterator
+ oi = objs.begin(); oi != objs.end(); ++oi)
+ {
+ std::string obj = *oi;
+ cmXCodeObject* xsf =
+ this->CreateXCodeSourceFileFromPath(obj, cmtarget, "");
+ externalObjFiles.push_back(xsf);
+ }
+
// some build phases only apply to bundles and/or frameworks
bool isFrameworkTarget = cmtarget.IsFrameworkOnApple();
bool isBundleTarget = cmtarget.GetPropertyAsBool("MACOSX_BUNDLE");
@@ -1485,7 +1577,8 @@ void cmGlobalXCodeGenerator::CreateBuildSettings(cmTarget& target,
std::string defFlags;
bool shared = ((target.GetType() == cmTarget::SHARED_LIBRARY) ||
(target.GetType() == cmTarget::MODULE_LIBRARY));
- bool binary = ((target.GetType() == cmTarget::STATIC_LIBRARY) ||
+ bool binary = ((target.GetType() == cmTarget::OBJECT_LIBRARY) ||
+ (target.GetType() == cmTarget::STATIC_LIBRARY) ||
(target.GetType() == cmTarget::EXECUTABLE) ||
shared);
@@ -1572,7 +1665,8 @@ void cmGlobalXCodeGenerator::CreateBuildSettings(cmTarget& target,
}
const char* linkFlagsProp = "LINK_FLAGS";
- if(target.GetType() == cmTarget::STATIC_LIBRARY)
+ if(target.GetType() == cmTarget::OBJECT_LIBRARY ||
+ target.GetType() == cmTarget::STATIC_LIBRARY)
{
linkFlagsProp = "STATIC_LIBRARY_FLAGS";
}
@@ -1626,11 +1720,8 @@ void cmGlobalXCodeGenerator::CreateBuildSettings(cmTarget& target,
std::string pnprefix;
std::string pnbase;
std::string pnsuffix;
- target.GetFullNameComponents(pnprefix, pnbase, pnsuffix, configName);
- // Store the product name for all target types.
- buildSettings->AddAttribute("PRODUCT_NAME",
- this->CreateString(pnbase.c_str()));
+ target.GetFullNameComponents(pnprefix, pnbase, pnsuffix, configName);
// Set attributes to specify the proper name for the target.
std::string pndir = this->CurrentMakefile->GetCurrentOutputDirectory();
@@ -1654,17 +1745,44 @@ void cmGlobalXCodeGenerator::CreateBuildSettings(cmTarget& target,
this->CreateString(pndir.c_str()));
pndir = target.GetDirectory(configName);
}
+
buildSettings->AddAttribute("EXECUTABLE_PREFIX",
this->CreateString(pnprefix.c_str()));
buildSettings->AddAttribute("EXECUTABLE_SUFFIX",
this->CreateString(pnsuffix.c_str()));
}
+ else if(target.GetType() == cmTarget::OBJECT_LIBRARY)
+ {
+ pnprefix = "lib";
+ pnbase = target.GetName();
+ pnsuffix = ".a";
+
+ if(this->XcodeVersion >= 21)
+ {
+ std::string pncdir = this->GetObjectsNormalDirectory(
+ this->CurrentProject, configName, &target);
+ buildSettings->AddAttribute("CONFIGURATION_BUILD_DIR",
+ this->CreateString(pncdir.c_str()));
+ }
+ else
+ {
+ buildSettings->AddAttribute("OBJROOT",
+ this->CreateString(pndir.c_str()));
+ pndir = this->GetObjectsNormalDirectory(
+ this->CurrentProject, configName, &target);
+ }
+ }
+
+ // Store the product name for all target types.
+ buildSettings->AddAttribute("PRODUCT_NAME",
+ this->CreateString(pnbase.c_str()));
buildSettings->AddAttribute("SYMROOT",
this->CreateString(pndir.c_str()));
// Handle settings for each target type.
switch(target.GetType())
{
+ case cmTarget::OBJECT_LIBRARY:
case cmTarget::STATIC_LIBRARY:
{
buildSettings->AddAttribute("LIBRARY_STYLE",
@@ -2168,6 +2286,7 @@ const char* cmGlobalXCodeGenerator::GetTargetFileType(cmTarget& cmtarget)
{
switch(cmtarget.GetType())
{
+ case cmTarget::OBJECT_LIBRARY:
case cmTarget::STATIC_LIBRARY:
return "archive.ar";
case cmTarget::MODULE_LIBRARY:
@@ -2191,6 +2310,7 @@ const char* cmGlobalXCodeGenerator::GetTargetProductType(cmTarget& cmtarget)
{
switch(cmtarget.GetType())
{
+ case cmTarget::OBJECT_LIBRARY:
case cmTarget::STATIC_LIBRARY:
return "com.apple.product-type.library.static";
case cmTarget::MODULE_LIBRARY:
@@ -2248,7 +2368,17 @@ cmGlobalXCodeGenerator::CreateXCodeTarget(cmTarget& cmtarget,
{
fileRef->AddAttribute("explicitFileType", this->CreateString(fileType));
}
- std::string fullName = cmtarget.GetFullName(defConfig.c_str());
+ std::string fullName;
+ if(cmtarget.GetType() == cmTarget::OBJECT_LIBRARY)
+ {
+ fullName = "lib";
+ fullName += cmtarget.GetName();
+ fullName += ".a";
+ }
+ else
+ {
+ fullName = cmtarget.GetFullName(defConfig.c_str());
+ }
fileRef->AddAttribute("path", this->CreateString(fullName.c_str()));
fileRef->AddAttribute("refType", this->CreateString("0"));
fileRef->AddAttribute("sourceTree",
@@ -2453,7 +2583,8 @@ void cmGlobalXCodeGenerator
}
// Skip link information for static libraries.
- if(cmtarget->GetType() == cmTarget::STATIC_LIBRARY)
+ if(cmtarget->GetType() == cmTarget::OBJECT_LIBRARY ||
+ cmtarget->GetType() == cmTarget::STATIC_LIBRARY)
{
return;
}
@@ -2601,6 +2732,7 @@ void cmGlobalXCodeGenerator::CreateGroups(cmLocalGenerator* root,
std::vector<cmSourceFile*> classes = cmtarget.GetSourceFiles();
+ // Put cmSourceFile instances in proper groups:
for(std::vector<cmSourceFile*>::const_iterator s = classes.begin();
s != classes.end(); s++)
{
@@ -2614,6 +2746,21 @@ void cmGlobalXCodeGenerator::CreateGroups(cmLocalGenerator* root,
cmStdString key = GetGroupMapKey(cmtarget, sf);
this->GroupMap[key] = pbxgroup;
}
+
+ // Put OBJECT_LIBRARY objects in proper groups:
+ std::vector<std::string> objs;
+ this->GetGeneratorTarget(&cmtarget)->UseObjectLibraries(objs);
+ for(std::vector<std::string>::const_iterator
+ oi = objs.begin(); oi != objs.end(); ++oi)
+ {
+ std::string const& source = *oi;
+ cmSourceGroup& sourceGroup =
+ mf->FindSourceGroup(source.c_str(), sourceGroups);
+ cmXCodeObject* pbxgroup =
+ this->CreateOrGetPBXGroup(cmtarget, &sourceGroup);
+ cmStdString key = GetGroupMapKeyFromPath(cmtarget, source);
+ this->GroupMap[key] = pbxgroup;
+ }
}
}
}
@@ -3046,6 +3193,26 @@ void cmGlobalXCodeGenerator
}
//----------------------------------------------------------------------------
+std::string
+cmGlobalXCodeGenerator::GetObjectsNormalDirectory(
+ const std::string &projName,
+ const std::string &configName,
+ const cmTarget *t) const
+{
+ std::string dir =
+ t->GetMakefile()->GetCurrentOutputDirectory();
+ dir += "/";
+ dir += projName;
+ dir += ".build/";
+ dir += configName;
+ dir += "/";
+ dir += t->GetName();
+ dir += ".build/Objects-normal/";
+
+ return dir;
+}
+
+//----------------------------------------------------------------------------
void
cmGlobalXCodeGenerator::CreateXCodeDependHackTarget(
std::vector<cmXCodeObject*>& targets)
@@ -3114,6 +3281,8 @@ cmGlobalXCodeGenerator::CreateXCodeDependHackTarget(
cmTarget* t =target->GetTarget();
if(t->GetType() == cmTarget::EXECUTABLE ||
+// Nope - no post-build for OBJECT_LIRBRARY
+// t->GetType() == cmTarget::OBJECT_LIBRARY ||
t->GetType() == cmTarget::STATIC_LIBRARY ||
t->GetType() == cmTarget::SHARED_LIBRARY ||
t->GetType() == cmTarget::MODULE_LIBRARY)
@@ -3169,15 +3338,8 @@ cmGlobalXCodeGenerator::CreateXCodeDependHackTarget(
// then remove those exectuables as well
if(this->Architectures.size() > 1)
{
- std::string universal =
- t->GetMakefile()->GetCurrentOutputDirectory();
- universal += "/";
- universal += this->CurrentProject;
- universal += ".build/";
- universal += configName;
- universal += "/";
- universal += t->GetName();
- universal += ".build/Objects-normal/";
+ std::string universal = this->GetObjectsNormalDirectory(
+ this->CurrentProject, configName, t);
for( std::vector<std::string>::iterator arch =
this->Architectures.begin();
arch != this->Architectures.end(); ++arch)
@@ -3283,7 +3445,7 @@ cmGlobalXCodeGenerator::WriteXCodePBXProj(std::ostream& fout,
}
//----------------------------------------------------------------------------
-const char* cmGlobalXCodeGenerator::GetCMakeCFGInitDirectory()
+const char* cmGlobalXCodeGenerator::GetCMakeCFGIntDir() const
{
return this->XcodeVersion >= 21 ?
"$(CONFIGURATION)$(EFFECTIVE_PLATFORM_NAME)" : ".";
@@ -3536,3 +3698,51 @@ bool cmGlobalXCodeGenerator::IsMultiConfig()
// Newer Xcode versions are multi config:
return true;
}
+
+ //----------------------------------------------------------------------------
+void
+cmGlobalXCodeGenerator
+::ComputeTargetObjects(cmGeneratorTarget* gt) const
+{
+ // Count the number of object files with each name. Warn about duplicate
+ // names since Xcode names them uniquely automatically with a numeric suffix
+ // to avoid exact duplicate file names. Note that Mac file names are not
+ // typically case sensitive, hence the LowerCase.
+ std::map<cmStdString, int> counts;
+ for(std::vector<cmSourceFile*>::const_iterator
+ si = gt->ObjectSources.begin();
+ si != gt->ObjectSources.end(); ++si)
+ {
+ cmSourceFile* sf = *si;
+ std::string objectName =
+ cmSystemTools::GetFilenameWithoutLastExtension(sf->GetFullPath());
+ objectName += ".o";
+
+ std::string objectNameLower = cmSystemTools::LowerCase(objectName);
+ counts[objectNameLower] += 1;
+ if (2 == counts[objectNameLower])
+ {
+ // TODO: emit warning about duplicate name?
+ }
+
+ gt->Objects[sf] = objectName;
+ }
+
+ const char* configName = this->GetCMakeCFGIntDir();
+ std::string dir = this->GetObjectsNormalDirectory(
+ this->CurrentProject, configName, gt->Target);
+ if(this->XcodeVersion >= 21)
+ {
+ dir += "$(CURRENT_ARCH)/";
+ }
+ else
+ {
+#ifdef __ppc__
+ dir += "ppc/";
+#endif
+#ifdef __i386
+ dir += "i386/";
+#endif
+ }
+ gt->ObjectDirectory = dir;
+}
diff --git a/Source/cmGlobalXCodeGenerator.h b/Source/cmGlobalXCodeGenerator.h
index 45f62eb..800963b 100644
--- a/Source/cmGlobalXCodeGenerator.h
+++ b/Source/cmGlobalXCodeGenerator.h
@@ -74,7 +74,7 @@ public:
std::string& dir);
///! What is the configurations directory variable called?
- virtual const char* GetCMakeCFGInitDirectory();
+ virtual const char* GetCMakeCFGIntDir() const;
void SetCurrentLocalGenerator(cmLocalGenerator*);
@@ -153,6 +153,12 @@ private:
std::vector<cmLocalGenerator*>& generators);
void WriteXCodePBXProj(std::ostream& fout, cmLocalGenerator* root,
std::vector<cmLocalGenerator*>& generators);
+ cmXCodeObject* CreateXCodeFileReferenceFromPath(const std::string &fullpath,
+ cmTarget& cmtarget,
+ const std::string &lang);
+ cmXCodeObject* CreateXCodeSourceFileFromPath(const std::string &fullpath,
+ cmTarget& cmtarget,
+ const std::string &lang);
cmXCodeObject* CreateXCodeFileReference(cmSourceFile* sf,
cmTarget& cmtarget);
cmXCodeObject* CreateXCodeSourceFile(cmLocalGenerator* gen,
@@ -200,6 +206,13 @@ protected:
std::vector<cmXCodeObject*> XCodeObjects;
cmXCodeObject* RootObject;
private:
+ void ComputeTargetObjects(cmGeneratorTarget* gt) const;
+
+ std::string GetObjectsNormalDirectory(
+ const std::string &projName,
+ const std::string &configName,
+ const cmTarget *t) const;
+
void addObject(cmXCodeObject *obj);
std::string PostBuildMakeTarget(std::string const& tName,
std::string const& configName);
diff --git a/Source/cmInstallCommand.cxx b/Source/cmInstallCommand.cxx
index dca528d..c656487 100644
--- a/Source/cmInstallCommand.cxx
+++ b/Source/cmInstallCommand.cxx
@@ -357,7 +357,8 @@ bool cmInstallCommand::HandleTargetsMode(std::vector<std::string> const& args)
if(target->GetType() != cmTarget::EXECUTABLE &&
target->GetType() != cmTarget::STATIC_LIBRARY &&
target->GetType() != cmTarget::SHARED_LIBRARY &&
- target->GetType() != cmTarget::MODULE_LIBRARY)
+ target->GetType() != cmTarget::MODULE_LIBRARY &&
+ target->GetType() != cmTarget::OBJECT_LIBRARY)
{
cmOStringStream e;
e << "TARGETS given target \"" << (*targetIt)
@@ -365,6 +366,14 @@ bool cmInstallCommand::HandleTargetsMode(std::vector<std::string> const& args)
this->SetError(e.str().c_str());
return false;
}
+ else if(target->GetType() == cmTarget::OBJECT_LIBRARY)
+ {
+ cmOStringStream e;
+ e << "TARGETS given OBJECT library \"" << (*targetIt)
+ << "\" which may not be installed.";
+ this->SetError(e.str().c_str());
+ return false;
+ }
// Store the target in the list to be installed.
targets.push_back(target);
}
diff --git a/Source/cmInstallTargetGenerator.cxx b/Source/cmInstallTargetGenerator.cxx
index c74dda0..5f9b658 100644
--- a/Source/cmInstallTargetGenerator.cxx
+++ b/Source/cmInstallTargetGenerator.cxx
@@ -90,6 +90,7 @@ void cmInstallTargetGenerator::GenerateScriptForConfig(std::ostream& os,
case cmTarget::STATIC_LIBRARY: type = cmInstallType_STATIC_LIBRARY; break;
case cmTarget::SHARED_LIBRARY: type = cmInstallType_SHARED_LIBRARY; break;
case cmTarget::MODULE_LIBRARY: type = cmInstallType_MODULE_LIBRARY; break;
+ case cmTarget::OBJECT_LIBRARY:
case cmTarget::UTILITY:
case cmTarget::GLOBAL_TARGET:
case cmTarget::UNKNOWN_LIBRARY:
diff --git a/Source/cmLocalGenerator.cxx b/Source/cmLocalGenerator.cxx
index a7f201c..13ede5d 100644
--- a/Source/cmLocalGenerator.cxx
+++ b/Source/cmLocalGenerator.cxx
@@ -1914,6 +1914,10 @@ bool cmLocalGenerator::GetRealDependency(const char* inName,
case cmTarget::UNKNOWN_LIBRARY:
dep = target->GetLocation(config);
return true;
+ case cmTarget::OBJECT_LIBRARY:
+ // An object library has no single file on which to depend.
+ // This was listed to get the target-level dependency.
+ return false;
case cmTarget::UTILITY:
case cmTarget::GLOBAL_TARGET:
// A utility target has no file on which to depend. This was listed
diff --git a/Source/cmLocalNinjaGenerator.cxx b/Source/cmLocalNinjaGenerator.cxx
index 78072b5..425b219 100644
--- a/Source/cmLocalNinjaGenerator.cxx
+++ b/Source/cmLocalNinjaGenerator.cxx
@@ -117,37 +117,6 @@ cmGlobalNinjaGenerator* cmLocalNinjaGenerator::GetGlobalNinjaGenerator()
return static_cast<cmGlobalNinjaGenerator*>(this->GetGlobalGenerator());
}
-// TODO: Picked up from cmLocalUnixMakefileGenerator3. Refactor it.
-std::string
-cmLocalNinjaGenerator
-::GetObjectFileName(const cmTarget& target,
- const cmSourceFile& source)
-{
- // Make sure we never hit this old case.
- if(source.GetProperty("MACOSX_PACKAGE_LOCATION"))
- {
- std::string msg = "MACOSX_PACKAGE_LOCATION set on source file: ";
- msg += source.GetFullPath();
- this->GetMakefile()->IssueMessage(cmake::INTERNAL_ERROR,
- msg.c_str());
- }
-
- // Start with the target directory.
- std::string obj = this->GetTargetDirectory(target);
- obj += "/";
-
- // Get the object file name without the target directory.
- std::string dir_max;
- dir_max += this->Makefile->GetCurrentOutputDirectory();
- dir_max += "/";
- dir_max += obj;
- std::string objectName =
- this->GetObjectFileNameWithoutTarget(source, dir_max, 0);
- // Append the object name to the target directory.
- obj += objectName;
- return obj;
-}
-
//----------------------------------------------------------------------------
// Virtual protected methods.
diff --git a/Source/cmLocalNinjaGenerator.h b/Source/cmLocalNinjaGenerator.h
index 28b431d..ea44b2f 100644
--- a/Source/cmLocalNinjaGenerator.h
+++ b/Source/cmLocalNinjaGenerator.h
@@ -59,9 +59,6 @@ public:
const char* GetConfigName() const
{ return this->ConfigName.c_str(); }
- std::string GetObjectFileName(const cmTarget& target,
- const cmSourceFile& source);
-
/// @return whether we are processing the top CMakeLists.txt file.
bool isRootMakefile() const;
diff --git a/Source/cmLocalUnixMakefileGenerator3.cxx b/Source/cmLocalUnixMakefileGenerator3.cxx
index fdf59b2..a645303 100644
--- a/Source/cmLocalUnixMakefileGenerator3.cxx
+++ b/Source/cmLocalUnixMakefileGenerator3.cxx
@@ -358,6 +358,7 @@ void cmLocalUnixMakefileGenerator3
(t->second.GetType() == cmTarget::STATIC_LIBRARY) ||
(t->second.GetType() == cmTarget::SHARED_LIBRARY) ||
(t->second.GetType() == cmTarget::MODULE_LIBRARY) ||
+ (t->second.GetType() == cmTarget::OBJECT_LIBRARY) ||
(t->second.GetType() == cmTarget::UTILITY))
{
emitted.insert(t->second.GetName());
@@ -2009,45 +2010,6 @@ void cmLocalUnixMakefileGenerator3
}
//----------------------------------------------------------------------------
-std::string
-cmLocalUnixMakefileGenerator3
-::GetObjectFileName(cmTarget& target,
- const cmSourceFile& source,
- std::string* nameWithoutTargetDir,
- bool* hasSourceExtension)
-{
- // Make sure we never hit this old case.
- if(source.GetProperty("MACOSX_PACKAGE_LOCATION"))
- {
- std::string msg = "MACOSX_PACKAGE_LOCATION set on source file: ";
- msg += source.GetFullPath();
- this->GetMakefile()->IssueMessage(cmake::INTERNAL_ERROR,
- msg.c_str());
- }
-
- // Start with the target directory.
- std::string obj = this->GetTargetDirectory(target);
- obj += "/";
-
- // Get the object file name without the target directory.
- std::string dir_max;
- dir_max += this->Makefile->GetCurrentOutputDirectory();
- dir_max += "/";
- dir_max += obj;
- std::string objectName =
- this->GetObjectFileNameWithoutTarget(source, dir_max,
- hasSourceExtension);
- if(nameWithoutTargetDir)
- {
- *nameWithoutTargetDir = objectName;
- }
-
- // Append the object name to the target directory.
- obj += objectName;
- return obj;
-}
-
-//----------------------------------------------------------------------------
void cmLocalUnixMakefileGenerator3::WriteDisclaimer(std::ostream& os)
{
os
diff --git a/Source/cmLocalUnixMakefileGenerator3.h b/Source/cmLocalUnixMakefileGenerator3.h
index 4bde082..e374959 100644
--- a/Source/cmLocalUnixMakefileGenerator3.h
+++ b/Source/cmLocalUnixMakefileGenerator3.h
@@ -284,11 +284,6 @@ protected:
cmTarget& target,
const std::vector<std::string>& objects);
- std::string GetObjectFileName(cmTarget& target,
- const cmSourceFile& source,
- std::string* nameWithoutTargetDir = 0,
- bool* hasSourceExtension = 0);
-
void AppendRuleDepend(std::vector<std::string>& depends,
const char* ruleFileName);
void AppendRuleDepends(std::vector<std::string>& depends,
diff --git a/Source/cmLocalVisualStudio6Generator.cxx b/Source/cmLocalVisualStudio6Generator.cxx
index 678c5bf..5b99dfd 100644
--- a/Source/cmLocalVisualStudio6Generator.cxx
+++ b/Source/cmLocalVisualStudio6Generator.cxx
@@ -15,6 +15,7 @@
#include "cmSystemTools.h"
#include "cmSourceFile.h"
#include "cmCacheManager.h"
+#include "cmGeneratorTarget.h"
#include "cmake.h"
#include "cmComputeLinkInformation.h"
@@ -126,6 +127,7 @@ void cmLocalVisualStudio6Generator::OutputDSPFile()
switch(l->second.GetType())
{
case cmTarget::STATIC_LIBRARY:
+ case cmTarget::OBJECT_LIBRARY:
this->SetBuildType(STATIC_LIBRARY, l->first.c_str(), l->second);
break;
case cmTarget::SHARED_LIBRARY:
@@ -336,9 +338,6 @@ void cmLocalVisualStudio6Generator::WriteDSPFile(std::ostream& fout,
}
}
- // Compute which sources need unique object computation.
- this->ComputeObjectNameRequirements(classes);
-
// Write the DSP file's header.
this->WriteDSPHeader(fout, libName, target, sourceGroups);
@@ -358,6 +357,8 @@ void cmLocalVisualStudio6Generator
::WriteGroup(const cmSourceGroup *sg, cmTarget& target,
std::ostream &fout, const char *libName)
{
+ cmGeneratorTarget* gt =
+ this->GlobalGenerator->GetGeneratorTarget(&target);
const std::vector<const cmSourceFile *> &sourceFiles =
sg->GetSourceFiles();
// If the group is empty, don't write it at all.
@@ -374,28 +375,6 @@ void cmLocalVisualStudio6Generator
this->WriteDSPBeginGroup(fout, name.c_str(), "");
}
- // Compute the maximum length configuration name.
- std::string config_max;
- for(std::vector<std::string>::iterator i = this->Configurations.begin();
- i != this->Configurations.end(); ++i)
- {
- // Strip the subdirectory name out of the configuration name.
- std::string config = this->GetConfigName(*i);
- if(config.size() > config_max.size())
- {
- config_max = config;
- }
- }
-
- // Compute the maximum length full path to the intermediate
- // files directory for any configuration. This is used to construct
- // object file names that do not produce paths that are too long.
- std::string dir_max;
- dir_max += this->Makefile->GetCurrentOutputDirectory();
- dir_max += "/";
- dir_max += config_max;
- dir_max += "/";
-
// Loop through each source in the source group.
for(std::vector<const cmSourceFile *>::const_iterator sf =
sourceFiles.begin(); sf != sourceFiles.end(); ++sf)
@@ -406,11 +385,9 @@ void cmLocalVisualStudio6Generator
std::string compileFlags;
std::vector<std::string> depends;
std::string objectNameDir;
- if(this->NeedObjectName.find(*sf) != this->NeedObjectName.end())
+ if(gt->ExplicitObjectName.find(*sf) != gt->ExplicitObjectName.end())
{
- objectNameDir =
- cmSystemTools::GetFilenamePath(
- this->GetObjectFileNameWithoutTarget(*(*sf), dir_max));
+ objectNameDir = cmSystemTools::GetFilenamePath(gt->Objects[*sf]);
}
// Add per-source file flags.
@@ -1264,8 +1241,18 @@ void cmLocalVisualStudio6Generator
outputNameMinSizeRel = target.GetFullName("MinSizeRel");
outputNameRelWithDebInfo = target.GetFullName("RelWithDebInfo");
}
+ else if(target.GetType() == cmTarget::OBJECT_LIBRARY)
+ {
+ outputName = target.GetName();
+ outputName += ".lib";
+ outputNameDebug = outputName;
+ outputNameRelease = outputName;
+ outputNameMinSizeRel = outputName;
+ outputNameRelWithDebInfo = outputName;
+ }
// Compute the output directory for the target.
+ std::string outputDirOld;
std::string outputDirDebug;
std::string outputDirRelease;
std::string outputDirMinSizeRel;
@@ -1275,6 +1262,11 @@ void cmLocalVisualStudio6Generator
target.GetType() == cmTarget::SHARED_LIBRARY ||
target.GetType() == cmTarget::MODULE_LIBRARY)
{
+#ifdef CM_USE_OLD_VS6
+ outputDirOld =
+ removeQuotes(this->ConvertToOptionallyRelativeOutputPath
+ (target.GetDirectory().c_str()));
+#endif
outputDirDebug =
removeQuotes(this->ConvertToOptionallyRelativeOutputPath(
target.GetDirectory("Debug").c_str()));
@@ -1288,6 +1280,14 @@ void cmLocalVisualStudio6Generator
removeQuotes(this->ConvertToOptionallyRelativeOutputPath(
target.GetDirectory("RelWithDebInfo").c_str()));
}
+ else if(target.GetType() == cmTarget::OBJECT_LIBRARY)
+ {
+ std::string outputDir = cmake::GetCMakeFilesDirectoryPostSlash();
+ outputDirDebug = outputDir + "Debug";
+ outputDirRelease = outputDir + "Release";
+ outputDirMinSizeRel = outputDir + "MinSizeRel";
+ outputDirRelWithDebInfo = outputDir + "RelWithDebInfo";
+ }
// Compute the proper link information for the target.
std::string optionsDebug;
@@ -1428,6 +1428,16 @@ void cmLocalVisualStudio6Generator
staticLibOptionsRelWithDebInfo += " ";
staticLibOptionsRelWithDebInfo = libflagsRelWithDebInfo;
}
+ std::string objects;
+ this->OutputObjects(target, "LIB", objects);
+ if(!objects.empty())
+ {
+ objects = "\n" + objects;
+ staticLibOptionsDebug += objects;
+ staticLibOptionsRelease += objects;
+ staticLibOptionsMinSizeRel += objects;
+ staticLibOptionsRelWithDebInfo += objects;
+ }
}
// Add the export symbol definition for shared library objects.
@@ -1456,7 +1466,8 @@ void cmLocalVisualStudio6Generator
libnameExports.c_str());
cmSystemTools::ReplaceString(line, "CMAKE_MFC_FLAG",
mfcFlag);
- if(target.GetType() == cmTarget::STATIC_LIBRARY )
+ if(target.GetType() == cmTarget::STATIC_LIBRARY ||
+ target.GetType() == cmTarget::OBJECT_LIBRARY)
{
cmSystemTools::ReplaceString(line, "CM_STATIC_LIB_ARGS_DEBUG",
staticLibOptionsDebug.c_str());
@@ -1555,7 +1566,7 @@ void cmLocalVisualStudio6Generator
(exePath.c_str())).c_str());
#endif
- if(targetBuilds)
+ if(targetBuilds || target.GetType() == cmTarget::OBJECT_LIBRARY)
{
cmSystemTools::ReplaceString(line, "OUTPUT_DIRECTORY_DEBUG",
outputDirDebug.c_str());
@@ -1565,13 +1576,11 @@ void cmLocalVisualStudio6Generator
outputDirMinSizeRel.c_str());
cmSystemTools::ReplaceString(line, "OUTPUT_DIRECTORY_RELWITHDEBINFO",
outputDirRelWithDebInfo.c_str());
-#ifdef CM_USE_OLD_VS6
- std::string outPath = target.GetDirectory();
- cmSystemTools::ReplaceString
- (line, "OUTPUT_DIRECTORY",
- removeQuotes(this->ConvertToOptionallyRelativeOutputPath
- (outPath.c_str())).c_str());
-#endif
+ if(!outputDirOld.empty())
+ {
+ cmSystemTools::ReplaceString(line, "OUTPUT_DIRECTORY",
+ outputDirOld.c_str());
+ }
}
cmSystemTools::ReplaceString(line,
@@ -1588,7 +1597,7 @@ void cmLocalVisualStudio6Generator
std::string flagsDebug = " ";
std::string flagsDebugRel = " ";
if(target.GetType() >= cmTarget::EXECUTABLE &&
- target.GetType() <= cmTarget::MODULE_LIBRARY)
+ target.GetType() <= cmTarget::OBJECT_LIBRARY)
{
const char* linkLanguage = target.GetLinkerLanguage();
if(!linkLanguage)
@@ -1743,6 +1752,8 @@ void cmLocalVisualStudio6Generator
ItemVector const& linkLibs = cli.GetItems();
std::vector<std::string> const& linkDirs = cli.GetDirectories();
+ this->OutputObjects(target, "LINK", options);
+
// Build the link options code.
for(std::vector<std::string>::const_iterator d = linkDirs.begin();
d != linkDirs.end(); ++d)
@@ -1787,6 +1798,28 @@ void cmLocalVisualStudio6Generator
}
}
+//----------------------------------------------------------------------------
+void cmLocalVisualStudio6Generator
+::OutputObjects(cmTarget& target, const char* tool,
+ std::string& options)
+{
+ // VS 6 does not support per-config source locations so we
+ // list object library content on the link line instead.
+ cmGeneratorTarget* gt =
+ this->GlobalGenerator->GetGeneratorTarget(&target);
+ std::vector<std::string> objs;
+ gt->UseObjectLibraries(objs);
+ for(std::vector<std::string>::const_iterator
+ oi = objs.begin(); oi != objs.end(); ++oi)
+ {
+ options += "# ADD ";
+ options += tool;
+ options += "32 ";
+ options += this->ConvertToOptionallyRelativeOutputPath(oi->c_str());
+ options += "\n";
+ }
+}
+
std::string
cmLocalVisualStudio6Generator
::GetTargetDirectory(cmTarget const&) const
@@ -1795,6 +1828,36 @@ cmLocalVisualStudio6Generator
return "";
}
+//----------------------------------------------------------------------------
+std::string
+cmLocalVisualStudio6Generator
+::ComputeLongestObjectDirectory(cmTarget&) const
+{
+ // Compute the maximum length configuration name.
+ std::string config_max;
+ for(std::vector<std::string>::const_iterator
+ i = this->Configurations.begin();
+ i != this->Configurations.end(); ++i)
+ {
+ // Strip the subdirectory name out of the configuration name.
+ std::string config = this->GetConfigName(*i);
+ if(config.size() > config_max.size())
+ {
+ config_max = config;
+ }
+ }
+
+ // Compute the maximum length full path to the intermediate
+ // files directory for any configuration. This is used to construct
+ // object file names that do not produce paths that are too long.
+ std::string dir_max;
+ dir_max += this->Makefile->GetCurrentOutputDirectory();
+ dir_max += "/";
+ dir_max += config_max;
+ dir_max += "/";
+ return dir_max;
+}
+
std::string
cmLocalVisualStudio6Generator
::GetConfigName(std::string const& configuration) const
diff --git a/Source/cmLocalVisualStudio6Generator.h b/Source/cmLocalVisualStudio6Generator.h
index 4e588c3..a680633 100644
--- a/Source/cmLocalVisualStudio6Generator.h
+++ b/Source/cmLocalVisualStudio6Generator.h
@@ -50,6 +50,7 @@ public:
void SetBuildType(BuildType, const char* libName, cmTarget&);
virtual std::string GetTargetDirectory(cmTarget const& target) const;
+ virtual std::string ComputeLongestObjectDirectory(cmTarget&) const;
private:
std::string DSPHeaderTemplate;
std::string DSPFooterTemplate;
@@ -86,6 +87,8 @@ private:
void ComputeLinkOptions(cmTarget& target, const char* configName,
const std::string extraOptions,
std::string& options);
+ void OutputObjects(cmTarget& target, const char* tool,
+ std::string& options);
std::string GetTargetIncludeOptions(cmTarget &target);
std::vector<std::string> Configurations;
diff --git a/Source/cmLocalVisualStudio7Generator.cxx b/Source/cmLocalVisualStudio7Generator.cxx
index c5714cc..363d370 100644
--- a/Source/cmLocalVisualStudio7Generator.cxx
+++ b/Source/cmLocalVisualStudio7Generator.cxx
@@ -17,6 +17,7 @@
#include "cmSystemTools.h"
#include "cmSourceFile.h"
#include "cmCacheManager.h"
+#include "cmGeneratorTarget.h"
#include "cmake.h"
#include "cmComputeLinkInformation.h"
@@ -38,6 +39,7 @@ public:
LocalGenerator(e) {}
typedef cmComputeLinkInformation::ItemVector ItemVector;
void OutputLibraries(std::ostream& fout, ItemVector const& libs);
+ void OutputObjects(std::ostream& fout, cmTarget* t, const char* isep = 0);
private:
cmLocalVisualStudio7Generator* LocalGenerator;
};
@@ -641,6 +643,8 @@ void cmLocalVisualStudio7Generator::WriteConfiguration(std::ostream& fout,
bool targetBuilds = true;
switch(target.GetType())
{
+ case cmTarget::OBJECT_LIBRARY:
+ targetBuilds = false; // TODO: PDB for object library?
case cmTarget::STATIC_LIBRARY:
projectType = "typeStaticLibrary";
configType = "4";
@@ -1000,6 +1004,22 @@ void cmLocalVisualStudio7Generator::OutputBuildTool(std::ostream& fout,
}
switch(target.GetType())
{
+ case cmTarget::OBJECT_LIBRARY:
+ {
+ std::string libpath = this->GetTargetDirectory(target);
+ libpath += "/";
+ libpath += configName;
+ libpath += "/";
+ libpath += target.GetName();
+ libpath += ".lib";
+ const char* tool =
+ this->FortranProject? "VFLibrarianTool":"VCLibrarianTool";
+ fout << "\t\t\t<Tool\n"
+ << "\t\t\t\tName=\"" << tool << "\"\n";
+ fout << "\t\t\t\tOutputFile=\""
+ << this->ConvertToXMLOutputPathSingle(libpath.c_str()) << "\"/>\n";
+ break;
+ }
case cmTarget::STATIC_LIBRARY:
{
std::string targetNameFull = target.GetFullName(configName);
@@ -1014,6 +1034,15 @@ void cmLocalVisualStudio7Generator::OutputBuildTool(std::ostream& fout,
fout << "\t\t\t<Tool\n"
<< "\t\t\t\tName=\"" << tool << "\"\n";
+ if(this->GetVersion() < VS8)
+ {
+ cmOStringStream libdeps;
+ this->Internal->OutputObjects(libdeps, &target);
+ if(!libdeps.str().empty())
+ {
+ fout << "\t\t\t\tAdditionalDependencies=\"" << libdeps.str() << "\"\n";
+ }
+ }
std::string libflags;
if(const char* flags = target.GetProperty("STATIC_LIBRARY_FLAGS"))
{
@@ -1074,8 +1103,12 @@ void cmLocalVisualStudio7Generator::OutputBuildTool(std::ostream& fout,
// Use the NOINHERIT macro to avoid getting VS project default
// libraries which may be set by the user to something bad.
fout << "\t\t\t\tAdditionalDependencies=\"$(NOINHERIT) "
- << this->Makefile->GetSafeDefinition(standardLibsVar.c_str())
- << " ";
+ << this->Makefile->GetSafeDefinition(standardLibsVar.c_str());
+ if(this->GetVersion() < VS8)
+ {
+ this->Internal->OutputObjects(fout, &target, " ");
+ }
+ fout << " ";
this->Internal->OutputLibraries(fout, cli.GetItems());
fout << "\"\n";
temp = target.GetDirectory(configName);
@@ -1155,8 +1188,12 @@ void cmLocalVisualStudio7Generator::OutputBuildTool(std::ostream& fout,
// Use the NOINHERIT macro to avoid getting VS project default
// libraries which may be set by the user to something bad.
fout << "\t\t\t\tAdditionalDependencies=\"$(NOINHERIT) "
- << this->Makefile->GetSafeDefinition(standardLibsVar.c_str())
- << " ";
+ << this->Makefile->GetSafeDefinition(standardLibsVar.c_str());
+ if(this->GetVersion() < VS8)
+ {
+ this->Internal->OutputObjects(fout, &target, " ");
+ }
+ fout << " ";
this->Internal->OutputLibraries(fout, cli.GetItems());
fout << "\"\n";
temp = target.GetDirectory(configName);
@@ -1244,6 +1281,30 @@ cmLocalVisualStudio7GeneratorInternals
//----------------------------------------------------------------------------
void
+cmLocalVisualStudio7GeneratorInternals
+::OutputObjects(std::ostream& fout, cmTarget* t, const char* isep)
+{
+ // VS < 8 does not support per-config source locations so we
+ // list object library content on the link line instead.
+ cmLocalVisualStudio7Generator* lg = this->LocalGenerator;
+ cmGeneratorTarget* gt =
+ lg->GetGlobalGenerator()->GetGeneratorTarget(t);
+ std::vector<std::string> objs;
+ gt->UseObjectLibraries(objs);
+ const char* sep = isep? isep : "";
+ for(std::vector<std::string>::const_iterator
+ oi = objs.begin(); oi != objs.end(); ++oi)
+ {
+ std::string rel = lg->Convert(oi->c_str(),
+ cmLocalGenerator::START_OUTPUT,
+ cmLocalGenerator::UNCHANGED);
+ fout << sep << lg->ConvertToXMLOutputPath(rel.c_str());
+ sep = " ";
+ }
+}
+
+//----------------------------------------------------------------------------
+void
cmLocalVisualStudio7Generator
::OutputLibraryDirectories(std::ostream& fout,
std::vector<std::string> const& dirs)
@@ -1310,9 +1371,6 @@ void cmLocalVisualStudio7Generator::WriteVCProjFile(std::ostream& fout,
sourceGroup.AssignSource(*i);
}
- // Compute which sources need unique object computation.
- this->ComputeObjectNameRequirements(classes);
-
// open the project
this->WriteProjectStart(fout, libName, target, sourceGroups);
// write the configuration information
@@ -1328,7 +1386,27 @@ void cmLocalVisualStudio7Generator::WriteVCProjFile(std::ostream& fout,
this->WriteGroup(&sg, target, fout, libName, configs);
}
- //}
+ if(this->GetVersion() >= VS8)
+ {
+ // VS >= 8 support per-config source locations so we
+ // list object library content as external objects.
+ cmGeneratorTarget* gt =
+ this->GlobalGenerator->GetGeneratorTarget(&target);
+ std::vector<std::string> objs;
+ gt->UseObjectLibraries(objs);
+ if(!objs.empty())
+ {
+ // TODO: Separate sub-filter for each object library used?
+ fout << "\t\t<Filter Name=\"Object Libraries\">\n";
+ for(std::vector<std::string>::const_iterator
+ oi = objs.begin(); oi != objs.end(); ++oi)
+ {
+ std::string o = this->ConvertToXMLOutputPathSingle(oi->c_str());
+ fout << "\t\t\t<File RelativePath=\"" << o << "\" />\n";
+ }
+ fout << "\t\t</Filter>\n";
+ }
+ }
fout << "\t</Files>\n";
@@ -1352,8 +1430,7 @@ public:
cmLocalVisualStudio7GeneratorFCInfo(cmLocalVisualStudio7Generator* lg,
cmTarget& target,
cmSourceFile const& sf,
- std::vector<std::string>* configs,
- std::string const& dir_max);
+ std::vector<std::string>* configs);
std::map<cmStdString, cmLVS7GFileConfig> FileConfigMap;
};
@@ -1361,13 +1438,14 @@ cmLocalVisualStudio7GeneratorFCInfo
::cmLocalVisualStudio7GeneratorFCInfo(cmLocalVisualStudio7Generator* lg,
cmTarget& target,
cmSourceFile const& sf,
- std::vector<std::string>* configs,
- std::string const& dir_max)
+ std::vector<std::string>* configs)
{
+ cmGeneratorTarget* gt =
+ lg->GetGlobalGenerator()->GetGeneratorTarget(&target);
std::string objectName;
- if(lg->NeedObjectName.find(&sf) != lg->NeedObjectName.end())
+ if(gt->ExplicitObjectName.find(&sf) != gt->ExplicitObjectName.end())
{
- objectName = lg->GetObjectFileNameWithoutTarget(sf, dir_max);
+ objectName = gt->Objects[&sf];
}
// Compute per-source, per-config information.
@@ -1478,11 +1556,11 @@ cmLocalVisualStudio7GeneratorFCInfo
}
}
-
-void cmLocalVisualStudio7Generator
-::ComputeMaxDirectoryLength(std::string& maxdir,
- cmTarget& target)
-{
+//----------------------------------------------------------------------------
+std::string
+cmLocalVisualStudio7Generator
+::ComputeLongestObjectDirectory(cmTarget& target) const
+{
std::vector<std::string> *configs =
static_cast<cmGlobalVisualStudio7Generator *>
(this->GlobalGenerator)->GetConfigurations();
@@ -1507,7 +1585,7 @@ void cmLocalVisualStudio7Generator
dir_max += "/";
dir_max += config_max;
dir_max += "/";
- maxdir = dir_max;
+ return dir_max;
}
void cmLocalVisualStudio7Generator
@@ -1530,19 +1608,13 @@ void cmLocalVisualStudio7Generator
this->WriteVCProjBeginGroup(fout, name.c_str(), "");
}
- // Compute the maximum length full path to the intermediate
- // files directory for any configuration. This is used to construct
- // object file names that do not produce paths that are too long.
- std::string dir_max;
- this->ComputeMaxDirectoryLength(dir_max, target);
-
// Loop through each source in the source group.
std::string objectName;
for(std::vector<const cmSourceFile *>::const_iterator sf =
sourceFiles.begin(); sf != sourceFiles.end(); ++sf)
{
std::string source = (*sf)->GetFullPath();
- FCInfo fcinfo(this, target, *(*sf), configs, dir_max);
+ FCInfo fcinfo(this, target, *(*sf), configs);
if (source != libName || target.GetType() == cmTarget::UTILITY ||
target.GetType() == cmTarget::GLOBAL_TARGET )
diff --git a/Source/cmLocalVisualStudio7Generator.h b/Source/cmLocalVisualStudio7Generator.h
index 6ddf82a..9d3a9f2 100644
--- a/Source/cmLocalVisualStudio7Generator.h
+++ b/Source/cmLocalVisualStudio7Generator.h
@@ -60,11 +60,7 @@ public:
virtual std::string GetTargetDirectory(cmTarget const&) const;
cmSourceFile* CreateVCProjBuildRule();
void WriteStampFiles();
- // Compute the maximum length full path to the intermediate
- // files directory for any configuration. This is used to construct
- // object file names that do not produce paths that are too long.
- void ComputeMaxDirectoryLength(std::string& maxdir,
- cmTarget& target);
+ virtual std::string ComputeLongestObjectDirectory(cmTarget&) const;
virtual void ReadAndStoreExternalGUID(const char* name,
const char* path);
diff --git a/Source/cmLocalVisualStudioGenerator.cxx b/Source/cmLocalVisualStudioGenerator.cxx
index f389b35..4bcf4de 100644
--- a/Source/cmLocalVisualStudioGenerator.cxx
+++ b/Source/cmLocalVisualStudioGenerator.cxx
@@ -65,69 +65,6 @@ cmLocalVisualStudioGenerator::MaybeCreateImplibDir(cmTarget& target,
}
//----------------------------------------------------------------------------
-bool cmLocalVisualStudioGenerator::SourceFileCompiles(const cmSourceFile* sf)
-{
- // Identify the language of the source file.
- if(const char* lang = this->GetSourceFileLanguage(*sf))
- {
- // Check whether this source will actually be compiled.
- return (!sf->GetCustomCommand() &&
- !sf->GetPropertyAsBool("HEADER_FILE_ONLY") &&
- !sf->GetPropertyAsBool("EXTERNAL_OBJECT"));
- }
- else
- {
- // Unknown source file language. Assume it will not be compiled.
- return false;
- }
-}
-
-//----------------------------------------------------------------------------
-void
-cmLocalVisualStudioGenerator::ComputeObjectNameRequirements(
- std::vector<cmSourceFile*> const& sources
- )
-{
- // Clear the current set of requirements.
- this->NeedObjectName.clear();
-
- // Count the number of object files with each name. Note that
- // windows file names are not case sensitive.
- std::map<cmStdString, int> counts;
- for(std::vector<cmSourceFile*>::const_iterator s = sources.begin();
- s != sources.end(); ++s)
- {
- const cmSourceFile* sf = *s;
- if(this->SourceFileCompiles(sf))
- {
- std::string objectName = cmSystemTools::LowerCase(
- cmSystemTools::GetFilenameWithoutLastExtension(
- sf->GetFullPath()));
- objectName += ".obj";
- counts[objectName] += 1;
- }
- }
-
- // For all source files producing duplicate names we need unique
- // object name computation.
- for(std::vector<cmSourceFile*>::const_iterator s = sources.begin();
- s != sources.end(); ++s)
- {
- const cmSourceFile* sf = *s;
- if(this->SourceFileCompiles(sf))
- {
- std::string objectName = cmSystemTools::LowerCase(
- cmSystemTools::GetFilenameWithoutLastExtension(sf->GetFullPath()));
- objectName += ".obj";
- if(counts[objectName] > 1)
- {
- this->NeedObjectName.insert(sf);
- }
- }
- }
-}
-
-//----------------------------------------------------------------------------
const char* cmLocalVisualStudioGenerator::ReportErrorLabel() const
{
return ":VCReportError";
diff --git a/Source/cmLocalVisualStudioGenerator.h b/Source/cmLocalVisualStudioGenerator.h
index e58c757..410cc9a 100644
--- a/Source/cmLocalVisualStudioGenerator.h
+++ b/Source/cmLocalVisualStudioGenerator.h
@@ -56,6 +56,8 @@ public:
/** Version of Visual Studio. */
VSVersion GetVersion() const { return this->Version; }
+ virtual std::string ComputeLongestObjectDirectory(cmTarget&) const = 0;
+
protected:
virtual const char* ReportErrorLabel() const;
virtual bool CustomCommandUseLocal() const { return false; }
@@ -64,12 +66,6 @@ protected:
cmsys::auto_ptr<cmCustomCommand>
MaybeCreateImplibDir(cmTarget& target, const char* config, bool isFortran);
- // Safe object file name generation.
- void ComputeObjectNameRequirements(std::vector<cmSourceFile*> const&);
- bool SourceFileCompiles(const cmSourceFile* sf);
- std::set<const cmSourceFile*> NeedObjectName;
- friend class cmVisualStudio10TargetGenerator;
-
VSVersion Version;
};
diff --git a/Source/cmMakefile.cxx b/Source/cmMakefile.cxx
index f90c35c..56e3305 100644
--- a/Source/cmMakefile.cxx
+++ b/Source/cmMakefile.cxx
@@ -782,6 +782,7 @@ void cmMakefile::SetLocalGenerator(cmLocalGenerator* lg)
"\\.(h|hh|h\\+\\+|hm|hpp|hxx|in|txx|inl)$");
this->AddSourceGroup("CMake Rules", "\\.rule$");
this->AddSourceGroup("Resources", "\\.plist$");
+ this->AddSourceGroup("Object Files", "\\.(lo|o|obj)$");
#endif
this->WarnUnused = this->GetCMakeInstance()->GetWarnUnused();
@@ -853,6 +854,14 @@ cmMakefile::AddCustomCommandToTarget(const char* target,
cmTargets::iterator ti = this->Targets.find(target);
if(ti != this->Targets.end())
{
+ if(ti->second.GetType() == cmTarget::OBJECT_LIBRARY)
+ {
+ cmOStringStream e;
+ e << "Target \"" << target << "\" is an OBJECT library "
+ "that may not have PRE_BUILD, PRE_LINK, or POST_BUILD commands.";
+ this->IssueMessage(cmake::FATAL_ERROR, e.str());
+ return;
+ }
// Add the command to the appropriate build step for the target.
std::vector<std::string> no_output;
cmCustomCommand cc(this, no_output, depends,
@@ -945,7 +954,7 @@ cmMakefile::AddCustomCommandToOutput(const std::vector<std::string>& outputs,
outName += ".rule";
const char* dir =
this->LocalGenerator->GetGlobalGenerator()->
- GetCMakeCFGInitDirectory();
+ GetCMakeCFGIntDir();
if(dir && dir[0] == '$')
{
cmSystemTools::ReplaceString(outName, dir,
@@ -1912,8 +1921,11 @@ cmTarget* cmMakefile::AddLibrary(const char* lname, cmTarget::TargetType type,
// wrong type ? default to STATIC
if ( (type != cmTarget::STATIC_LIBRARY)
&& (type != cmTarget::SHARED_LIBRARY)
- && (type != cmTarget::MODULE_LIBRARY))
+ && (type != cmTarget::MODULE_LIBRARY)
+ && (type != cmTarget::OBJECT_LIBRARY))
{
+ this->IssueMessage(cmake::INTERNAL_ERROR,
+ "cmMakefile::AddLibrary given invalid target type.");
type = cmTarget::STATIC_LIBRARY;
}
@@ -2865,7 +2877,7 @@ void cmMakefile::EnableLanguage(std::vector<std::string> const & lang,
{
this->AddDefinition("CMAKE_CFG_INTDIR",
this->LocalGenerator->GetGlobalGenerator()
- ->GetCMakeCFGInitDirectory());
+ ->GetCMakeCFGIntDir());
this->LocalGenerator->GetGlobalGenerator()->EnableLanguage(lang, this,
optional);
}
diff --git a/Source/cmMakefileLibraryTargetGenerator.cxx b/Source/cmMakefileLibraryTargetGenerator.cxx
index b4174cc..38aa59d 100644
--- a/Source/cmMakefileLibraryTargetGenerator.cxx
+++ b/Source/cmMakefileLibraryTargetGenerator.cxx
@@ -101,6 +101,9 @@ void cmMakefileLibraryTargetGenerator::WriteRuleFiles()
this->WriteModuleLibraryRules(true);
}
break;
+ case cmTarget::OBJECT_LIBRARY:
+ this->WriteObjectLibraryRules();
+ break;
default:
// If language is not known, this is an error.
cmSystemTools::Error("Unknown Library Type");
@@ -122,6 +125,29 @@ void cmMakefileLibraryTargetGenerator::WriteRuleFiles()
}
//----------------------------------------------------------------------------
+void cmMakefileLibraryTargetGenerator::WriteObjectLibraryRules()
+{
+ std::vector<std::string> commands;
+ std::vector<std::string> depends;
+
+ // Add post-build rules.
+ this->LocalGenerator->
+ AppendCustomCommands(commands, this->Target->GetPostBuildCommands(),
+ this->Target);
+
+ // Depend on the object files.
+ this->AppendObjectDepends(depends);
+
+ // Write the rule.
+ this->LocalGenerator->WriteMakeRule(*this->BuildFileStream, 0,
+ this->Target->GetName(),
+ depends, commands, true);
+
+ // Write the main driver rule to build everything in this target.
+ this->WriteTargetDriverRule(this->Target->GetName(), false);
+}
+
+//----------------------------------------------------------------------------
void cmMakefileLibraryTargetGenerator::WriteStaticLibraryRules()
{
const char* linkLanguage =
diff --git a/Source/cmMakefileLibraryTargetGenerator.h b/Source/cmMakefileLibraryTargetGenerator.h
index f3c47db..e6a5867 100644
--- a/Source/cmMakefileLibraryTargetGenerator.h
+++ b/Source/cmMakefileLibraryTargetGenerator.h
@@ -25,6 +25,7 @@ public:
virtual void WriteRuleFiles();
protected:
+ void WriteObjectLibraryRules();
void WriteStaticLibraryRules();
void WriteSharedLibraryRules(bool relink);
void WriteModuleLibraryRules(bool relink);
diff --git a/Source/cmMakefileTargetGenerator.cxx b/Source/cmMakefileTargetGenerator.cxx
index b9120c4..a0e0481 100644
--- a/Source/cmMakefileTargetGenerator.cxx
+++ b/Source/cmMakefileTargetGenerator.cxx
@@ -11,6 +11,7 @@
============================================================================*/
#include "cmMakefileTargetGenerator.h"
+#include "cmGeneratorTarget.h"
#include "cmGeneratedFileStream.h"
#include "cmGlobalGenerator.h"
#include "cmGlobalUnixMakefileGenerator3.h"
@@ -42,6 +43,7 @@ cmMakefileTargetGenerator::cmMakefileTargetGenerator(cmTarget* target)
this->GlobalGenerator =
static_cast<cmGlobalUnixMakefileGenerator3*>(
this->LocalGenerator->GetGlobalGenerator());
+ this->GeneratorTarget = this->GlobalGenerator->GetGeneratorTarget(target);
cmake* cm = this->GlobalGenerator->GetCMakeInstance();
this->NoRuleMessages = false;
if(const char* ruleStatus = cm->GetProperty("RULE_MESSAGES"))
@@ -63,6 +65,7 @@ cmMakefileTargetGenerator::New(cmTarget *tgt)
case cmTarget::STATIC_LIBRARY:
case cmTarget::SHARED_LIBRARY:
case cmTarget::MODULE_LIBRARY:
+ case cmTarget::OBJECT_LIBRARY:
result = new cmMakefileLibraryTargetGenerator(tgt);
break;
case cmTarget::UTILITY:
@@ -131,58 +134,49 @@ void cmMakefileTargetGenerator::WriteTargetBuildRules()
// First generate the object rule files. Save a list of all object
// files for this target.
- const std::vector<cmSourceFile*>& sources = this->Target->GetSourceFiles();
- for(std::vector<cmSourceFile*>::const_iterator source = sources.begin();
- source != sources.end(); ++source)
+ for(std::vector<cmSourceFile*>::const_iterator
+ si = this->GeneratorTarget->CustomCommands.begin();
+ si != this->GeneratorTarget->CustomCommands.end(); ++si)
{
- cmTarget::SourceFileFlags tsFlags =
- this->Target->GetTargetSourceFileFlags(*source);
- if(cmCustomCommand* cc = (*source)->GetCustomCommand())
+ cmCustomCommand const* cc = (*si)->GetCustomCommand();
+ this->GenerateCustomRuleFile(*cc);
+ if (clean)
{
- this->GenerateCustomRuleFile(*cc);
- if (clean)
- {
- const std::vector<std::string>& outputs = cc->GetOutputs();
- for(std::vector<std::string>::const_iterator o = outputs.begin();
- o != outputs.end(); ++o)
- {
- this->CleanFiles.push_back
- (this->Convert(o->c_str(),
- cmLocalGenerator::START_OUTPUT,
- cmLocalGenerator::UNCHANGED));
- }
- }
- }
- else if(tsFlags.Type != cmTarget::SourceFileTypeNormal)
- {
- this->WriteMacOSXContentRules(*(*source), tsFlags.MacFolder);
- }
- else if(!(*source)->GetPropertyAsBool("HEADER_FILE_ONLY"))
- {
- if(!this->GlobalGenerator->IgnoreFile
- ((*source)->GetExtension().c_str()))
- {
- // Generate this object file's rule file.
- this->WriteObjectRuleFiles(*(*source));
- }
- else if((*source)->GetPropertyAsBool("EXTERNAL_OBJECT"))
- {
- // This is an external object file. Just add it.
- this->ExternalObjects.push_back((*source)->GetFullPath());
- }
- else if(cmSystemTools::UpperCase((*source)->GetExtension()) == "DEF")
- {
- this->ModuleDefinitionFile = (*source)->GetFullPath();
- }
- else
+ const std::vector<std::string>& outputs = cc->GetOutputs();
+ for(std::vector<std::string>::const_iterator o = outputs.begin();
+ o != outputs.end(); ++o)
{
- // We only get here if a source file is not an external object
- // and has an extension that is listed as an ignored file type
- // for this language. No message or diagnosis should be
- // given.
+ this->CleanFiles.push_back
+ (this->Convert(o->c_str(),
+ cmLocalGenerator::START_OUTPUT,
+ cmLocalGenerator::UNCHANGED));
}
}
}
+ for(std::vector<cmSourceFile*>::const_iterator
+ si = this->GeneratorTarget->OSXContent.begin();
+ si != this->GeneratorTarget->OSXContent.end(); ++si)
+ {
+ cmTarget::SourceFileFlags tsFlags =
+ this->Target->GetTargetSourceFileFlags(*si);
+ this->WriteMacOSXContentRules(**si, tsFlags.MacFolder);
+ }
+ for(std::vector<cmSourceFile*>::const_iterator
+ si = this->GeneratorTarget->ExternalObjects.begin();
+ si != this->GeneratorTarget->ExternalObjects.end(); ++si)
+ {
+ this->ExternalObjects.push_back((*si)->GetFullPath());
+ }
+ for(std::vector<cmSourceFile*>::const_iterator
+ si = this->GeneratorTarget->ObjectSources.begin();
+ si != this->GeneratorTarget->ObjectSources.end(); ++si)
+ {
+ // Generate this object file's rule file.
+ this->WriteObjectRuleFiles(**si);
+ }
+
+ // Add object library contents as external objects.
+ this->GeneratorTarget->UseObjectLibraries(this->ExternalObjects);
}
@@ -428,12 +422,10 @@ void cmMakefileTargetGenerator::WriteObjectRuleFiles(cmSourceFile& source)
}
// Get the full path name of the object file.
- bool hasSourceExtension;
- std::string objNoTargetDir;
- std::string obj =
- this->LocalGenerator->GetObjectFileName(*this->Target, source,
- &objNoTargetDir,
- &hasSourceExtension);
+ std::string const& objectName = this->GeneratorTarget->Objects[&source];
+ std::string obj = this->LocalGenerator->GetTargetDirectory(*this->Target);
+ obj += "/";
+ obj += objectName;
// Avoid generating duplicate rules.
if(this->ObjectFiles.find(obj) == this->ObjectFiles.end())
@@ -487,10 +479,6 @@ void cmMakefileTargetGenerator::WriteObjectRuleFiles(cmSourceFile& source)
AddImplicitDepends(*this->Target, lang,
objFullPath.c_str(),
srcFullPath.c_str());
-
- // add this to the list of objects for this local generator
- this->LocalGenerator->AddLocalObjectFile(
- this->Target, &source, objNoTargetDir, hasSourceExtension);
}
//----------------------------------------------------------------------------
@@ -1612,7 +1600,7 @@ void cmMakefileTargetGenerator
//----------------------------------------------------------------------------
void cmMakefileTargetGenerator
-::AppendLinkDepends(std::vector<std::string>& depends)
+::AppendObjectDepends(std::vector<std::string>& depends)
{
// Add dependencies on the compiled object files.
std::string relPath = this->LocalGenerator->GetHomeRelativeOutputPath();
@@ -1625,25 +1613,32 @@ void cmMakefileTargetGenerator
depends.push_back(objTarget);
}
- // Add dependencies on targets that must be built first.
- this->AppendTargetDepends(depends);
+ // Add dependencies on the external object files.
+ for(std::vector<std::string>::const_iterator obj
+ = this->ExternalObjects.begin();
+ obj != this->ExternalObjects.end(); ++obj)
+ {
+ depends.push_back(*obj);
+ }
// Add a dependency on the rule file itself.
this->LocalGenerator->AppendRuleDepend(depends,
this->BuildFileNameFull.c_str());
+}
- // Add a dependency on the link definitions file, if any.
- if(!this->ModuleDefinitionFile.empty())
- {
- depends.push_back(this->ModuleDefinitionFile);
- }
+//----------------------------------------------------------------------------
+void cmMakefileTargetGenerator
+::AppendLinkDepends(std::vector<std::string>& depends)
+{
+ this->AppendObjectDepends(depends);
- // Add dependencies on the external object files.
- for(std::vector<std::string>::const_iterator obj
- = this->ExternalObjects.begin();
- obj != this->ExternalObjects.end(); ++obj)
+ // Add dependencies on targets that must be built first.
+ this->AppendTargetDepends(depends);
+
+ // Add a dependency on the link definitions file, if any.
+ if(!this->GeneratorTarget->ModuleDefinitionFile.empty())
{
- depends.push_back(*obj);
+ depends.push_back(this->GeneratorTarget->ModuleDefinitionFile);
}
// Add user-specified dependencies.
@@ -1971,7 +1966,7 @@ void cmMakefileTargetGenerator::AddFortranFlags(std::string& flags)
//----------------------------------------------------------------------------
void cmMakefileTargetGenerator::AddModuleDefinitionFlag(std::string& flags)
{
- if(this->ModuleDefinitionFile.empty())
+ if(this->GeneratorTarget->ModuleDefinitionFile.empty())
{
return;
}
@@ -1988,7 +1983,7 @@ void cmMakefileTargetGenerator::AddModuleDefinitionFlag(std::string& flags)
// vs6's "cl -link" pass it to the linker.
std::string flag = defFileFlag;
flag += (this->LocalGenerator->ConvertToLinkReference(
- this->ModuleDefinitionFile.c_str()));
+ this->GeneratorTarget->ModuleDefinitionFile.c_str()));
this->LocalGenerator->AppendFlags(flags, flag.c_str());
}
diff --git a/Source/cmMakefileTargetGenerator.h b/Source/cmMakefileTargetGenerator.h
index 8fba13f..e1e554b 100644
--- a/Source/cmMakefileTargetGenerator.h
+++ b/Source/cmMakefileTargetGenerator.h
@@ -17,6 +17,7 @@
class cmCustomCommand;
class cmDependInformation;
class cmDepends;
+class cmGeneratorTarget;
class cmGeneratedFileStream;
class cmGlobalUnixMakefileGenerator3;
class cmLocalUnixMakefileGenerator3;
@@ -117,6 +118,9 @@ protected:
// append intertarget dependencies
void AppendTargetDepends(std::vector<std::string>& depends);
+ // Append object file dependencies.
+ void AppendObjectDepends(std::vector<std::string>& depends);
+
// Append link rule dependencies (objects, etc.).
void AppendLinkDepends(std::vector<std::string>& depends);
@@ -157,6 +161,7 @@ protected:
void RemoveForbiddenFlags(const char* flagVar, const char* linkLang,
std::string& linkFlags);
cmTarget *Target;
+ cmGeneratorTarget* GeneratorTarget;
cmLocalUnixMakefileGenerator3 *LocalGenerator;
cmGlobalUnixMakefileGenerator3 *GlobalGenerator;
cmMakefile *Makefile;
@@ -198,9 +203,6 @@ protected:
std::vector<std::string> Objects;
std::vector<std::string> ExternalObjects;
- // The windows module definition source file (.def), if any.
- std::string ModuleDefinitionFile;
-
// Set of object file names that will be built in this directory.
std::set<cmStdString> ObjectFiles;
diff --git a/Source/cmNinjaNormalTargetGenerator.cxx b/Source/cmNinjaNormalTargetGenerator.cxx
index 35f3baf..2bad32c 100644
--- a/Source/cmNinjaNormalTargetGenerator.cxx
+++ b/Source/cmNinjaNormalTargetGenerator.cxx
@@ -43,10 +43,13 @@ cmNinjaNormalTargetGenerator(cmTarget* target)
this->TargetNamePDB,
GetLocalGenerator()->GetConfigName());
- // on Windows the output dir is already needed at compile time
- // ensure the directory exists (OutDir test)
- std::string outpath = target->GetDirectory(this->GetConfigName());
- cmSystemTools::MakeDirectory(outpath.c_str());
+ if(target->GetType() != cmTarget::OBJECT_LIBRARY)
+ {
+ // on Windows the output dir is already needed at compile time
+ // ensure the directory exists (OutDir test)
+ std::string outpath = target->GetDirectory(this->GetConfigName());
+ cmSystemTools::MakeDirectory(outpath.c_str());
+ }
}
cmNinjaNormalTargetGenerator::~cmNinjaNormalTargetGenerator()
@@ -67,8 +70,15 @@ void cmNinjaNormalTargetGenerator::Generate()
// Write the build statements
this->WriteObjectBuildStatements();
- this->WriteLinkRule();
- this->WriteLinkStatement();
+ if(this->GetTarget()->GetType() == cmTarget::OBJECT_LIBRARY)
+ {
+ this->WriteObjectLibStatement();
+ }
+ else
+ {
+ this->WriteLinkRule();
+ this->WriteLinkStatement();
+ }
this->GetBuildFileStream() << "\n";
this->GetRulesFileStream() << "\n";
@@ -470,3 +480,21 @@ void cmNinjaNormalTargetGenerator::WriteLinkStatement()
this->GetGlobalGenerator()->AddTargetAlias(this->GetTargetName(),
this->GetTarget());
}
+
+//----------------------------------------------------------------------------
+void cmNinjaNormalTargetGenerator::WriteObjectLibStatement()
+{
+ // Write a phony output that depends on all object files.
+ cmNinjaDeps outputs;
+ this->GetLocalGenerator()->AppendTargetOutputs(this->GetTarget(), outputs);
+ cmNinjaDeps depends = this->GetObjects();
+ cmGlobalNinjaGenerator::WritePhonyBuild(this->GetBuildFileStream(),
+ "Object library "
+ + this->GetTargetName(),
+ outputs,
+ depends);
+
+ // Add aliases for the target name.
+ this->GetGlobalGenerator()->AddTargetAlias(this->GetTargetName(),
+ this->GetTarget());
+}
diff --git a/Source/cmNinjaNormalTargetGenerator.h b/Source/cmNinjaNormalTargetGenerator.h
index 99f5a13..1702caf 100644
--- a/Source/cmNinjaNormalTargetGenerator.h
+++ b/Source/cmNinjaNormalTargetGenerator.h
@@ -32,6 +32,7 @@ private:
void WriteLanguagesRules();
void WriteLinkRule();
void WriteLinkStatement();
+ void WriteObjectLibStatement();
std::vector<std::string> ComputeLinkCmd();
private:
diff --git a/Source/cmNinjaTargetGenerator.cxx b/Source/cmNinjaTargetGenerator.cxx
index bea234f..c76d175 100644
--- a/Source/cmNinjaTargetGenerator.cxx
+++ b/Source/cmNinjaTargetGenerator.cxx
@@ -14,6 +14,7 @@
#include "cmGlobalNinjaGenerator.h"
#include "cmLocalNinjaGenerator.h"
#include "cmGeneratedFileStream.h"
+#include "cmGeneratorTarget.h"
#include "cmNinjaNormalTargetGenerator.h"
#include "cmNinjaUtilityTargetGenerator.h"
#include "cmSystemTools.h"
@@ -33,6 +34,7 @@ cmNinjaTargetGenerator::New(cmTarget* target)
case cmTarget::SHARED_LIBRARY:
case cmTarget::STATIC_LIBRARY:
case cmTarget::MODULE_LIBRARY:
+ case cmTarget::OBJECT_LIBRARY:
return new cmNinjaNormalTargetGenerator(target);
case cmTarget::UTILITY:
@@ -60,6 +62,8 @@ cmNinjaTargetGenerator::cmNinjaTargetGenerator(cmTarget* target)
static_cast<cmLocalNinjaGenerator*>(Makefile->GetLocalGenerator())),
Objects()
{
+ this->GeneratorTarget =
+ this->GetGlobalGenerator()->GetGeneratorTarget(target);
}
cmNinjaTargetGenerator::~cmNinjaTargetGenerator()
@@ -218,7 +222,8 @@ ComputeDefines(cmSourceFile *source, const std::string& language)
cmNinjaDeps cmNinjaTargetGenerator::ComputeLinkDeps() const
{
// Static libraries never depend on other targets for linking.
- if (this->Target->GetType() == cmTarget::STATIC_LIBRARY)
+ if (this->Target->GetType() == cmTarget::STATIC_LIBRARY ||
+ this->Target->GetType() == cmTarget::OBJECT_LIBRARY)
return cmNinjaDeps();
cmComputeLinkInformation* cli =
@@ -231,9 +236,9 @@ cmNinjaDeps cmNinjaTargetGenerator::ComputeLinkDeps() const
std::transform(deps.begin(), deps.end(), result.begin(), MapToNinjaPath());
// Add a dependency on the link definitions file, if any.
- if(!this->ModuleDefinitionFile.empty())
+ if(!this->GeneratorTarget->ModuleDefinitionFile.empty())
{
- result.push_back(this->ModuleDefinitionFile);
+ result.push_back(this->GeneratorTarget->ModuleDefinitionFile);
}
return result;
@@ -253,7 +258,10 @@ cmNinjaTargetGenerator
std::string path = this->LocalGenerator->GetHomeRelativeOutputPath();
if(!path.empty())
path += "/";
- path += this->LocalGenerator->GetObjectFileName(*this->Target, *source);
+ std::string const& objectName = this->GeneratorTarget->Objects[source];
+ path += this->LocalGenerator->GetTargetDirectory(*this->Target);
+ path += "/";
+ path += objectName;
return path;
}
@@ -381,12 +389,37 @@ cmNinjaTargetGenerator
<< this->GetTargetName()
<< "\n\n";
- // For each source files of this target.
- for(std::vector<cmSourceFile*>::const_iterator i =
- this->GetTarget()->GetSourceFiles().begin();
- i != this->GetTarget()->GetSourceFiles().end();
- ++i)
- this->WriteObjectBuildStatement(*i);
+ for(std::vector<cmSourceFile*>::const_iterator
+ si = this->GeneratorTarget->CustomCommands.begin();
+ si != this->GeneratorTarget->CustomCommands.end(); ++si)
+ {
+ cmCustomCommand const* cc = (*si)->GetCustomCommand();
+ this->GetLocalGenerator()->AddCustomCommandTarget(cc, this->GetTarget());
+ }
+ // TODO: this->GeneratorTarget->OSXContent
+ for(std::vector<cmSourceFile*>::const_iterator
+ si = this->GeneratorTarget->ExternalObjects.begin();
+ si != this->GeneratorTarget->ExternalObjects.end(); ++si)
+ {
+ this->Objects.push_back(this->GetSourceFilePath(*si));
+ }
+ for(std::vector<cmSourceFile*>::const_iterator
+ si = this->GeneratorTarget->ObjectSources.begin();
+ si != this->GeneratorTarget->ObjectSources.end(); ++si)
+ {
+ this->WriteObjectBuildStatement(*si);
+ }
+
+ {
+ // Add object library contents as external objects.
+ std::vector<std::string> objs;
+ this->GeneratorTarget->UseObjectLibraries(objs);
+ for(std::vector<std::string>::iterator oi = objs.begin();
+ oi != objs.end(); ++oi)
+ {
+ this->Objects.push_back(ConvertToNinjaPath(oi->c_str()));
+ }
+ }
this->GetBuildFileStream() << "\n";
}
@@ -395,26 +428,10 @@ void
cmNinjaTargetGenerator
::WriteObjectBuildStatement(cmSourceFile* source)
{
- if (cmCustomCommand *cc = source->GetCustomCommand())
- this->GetLocalGenerator()->AddCustomCommandTarget(cc, this->GetTarget());
-
cmNinjaDeps emptyDeps;
std::string comment;
const char* language = source->GetLanguage();
- // If we cannot get the language this is probably a non-source file provided
- // in the list (typically an header file).
- if (!language) {
- if (source->GetPropertyAsBool("EXTERNAL_OBJECT"))
- this->Objects.push_back(this->GetSourceFilePath(source));
- if(cmSystemTools::UpperCase(source->GetExtension()) == "DEF")
- this->ModuleDefinitionFile = GetSourceFilePath(source);
- return;
- }
-
- if (source->GetPropertyAsBool("HEADER_FILE_ONLY"))
- return;
-
std::string rule = this->LanguageCompilerRule(language);
cmNinjaDeps outputs;
@@ -439,21 +456,16 @@ cmNinjaTargetGenerator
std::back_inserter(orderOnlyDeps), MapToNinjaPath());
}
- // Add order-only dependency on any header file with a custom command.
- {
- const std::vector<cmSourceFile*>& sources =
- this->GetTarget()->GetSourceFiles();
- for(std::vector<cmSourceFile*>::const_iterator si = sources.begin();
- si != sources.end(); ++si) {
- if (!(*si)->GetLanguage()) {
- if (cmCustomCommand* cc = (*si)->GetCustomCommand()) {
- const std::vector<std::string>& ccoutputs = cc->GetOutputs();
- std::transform(ccoutputs.begin(), ccoutputs.end(),
- std::back_inserter(orderOnlyDeps), MapToNinjaPath());
- }
- }
+ // Add order-only dependencies on custom command outputs.
+ for(std::vector<cmSourceFile*>::const_iterator
+ si = this->GeneratorTarget->CustomCommands.begin();
+ si != this->GeneratorTarget->CustomCommands.end(); ++si)
+ {
+ cmCustomCommand const* cc = (*si)->GetCustomCommand();
+ const std::vector<std::string>& ccoutputs = cc->GetOutputs();
+ std::transform(ccoutputs.begin(), ccoutputs.end(),
+ std::back_inserter(orderOnlyDeps), MapToNinjaPath());
}
- }
// If the source file is GENERATED and does not have a custom command
// (either attached to this source file or another one), assume that one of
@@ -497,7 +509,7 @@ void
cmNinjaTargetGenerator
::AddModuleDefinitionFlag(std::string& flags)
{
- if(this->ModuleDefinitionFile.empty())
+ if(this->GeneratorTarget->ModuleDefinitionFile.empty())
{
return;
}
@@ -514,6 +526,6 @@ cmNinjaTargetGenerator
// vs6's "cl -link" pass it to the linker.
std::string flag = defFileFlag;
flag += (this->LocalGenerator->ConvertToLinkReference(
- this->ModuleDefinitionFile.c_str()));
+ this->GeneratorTarget->ModuleDefinitionFile.c_str()));
this->LocalGenerator->AppendFlags(flags, flag.c_str());
}
diff --git a/Source/cmNinjaTargetGenerator.h b/Source/cmNinjaTargetGenerator.h
index 3e70a2c..f639116 100644
--- a/Source/cmNinjaTargetGenerator.h
+++ b/Source/cmNinjaTargetGenerator.h
@@ -20,6 +20,7 @@
class cmTarget;
class cmGlobalNinjaGenerator;
class cmGeneratedFileStream;
+class cmGeneratorTarget;
class cmMakefile;
class cmSourceFile;
class cmCustomCommand;
@@ -112,13 +113,11 @@ protected:
private:
cmTarget* Target;
+ cmGeneratorTarget* GeneratorTarget;
cmMakefile* Makefile;
cmLocalNinjaGenerator* LocalGenerator;
/// List of object files for this target.
cmNinjaDeps Objects;
-
- // The windows module definition source file (.def), if any.
- std::string ModuleDefinitionFile;
};
#endif // ! cmNinjaTargetGenerator_h
diff --git a/Source/cmSourceGroup.cxx b/Source/cmSourceGroup.cxx
index 19ae8fc..2b34f2b 100644
--- a/Source/cmSourceGroup.cxx
+++ b/Source/cmSourceGroup.cxx
@@ -120,12 +120,6 @@ const std::vector<const cmSourceFile*>& cmSourceGroup::GetSourceFiles() const
}
//----------------------------------------------------------------------------
-std::vector<const cmSourceFile*>& cmSourceGroup::GetSourceFiles()
-{
- return this->SourceFiles;
-}
-
-//----------------------------------------------------------------------------
void cmSourceGroup::AddChild(cmSourceGroup child)
{
this->Internal->GroupChildren.push_back(child);
diff --git a/Source/cmSourceGroup.h b/Source/cmSourceGroup.h
index 71ccb51..641dcbd 100644
--- a/Source/cmSourceGroup.h
+++ b/Source/cmSourceGroup.h
@@ -100,7 +100,6 @@ public:
* source group.
*/
const std::vector<const cmSourceFile*>& GetSourceFiles() const;
- std::vector<const cmSourceFile*>& GetSourceFiles();
std::vector<cmSourceGroup> const& GetGroupChildren() const;
private:
diff --git a/Source/cmTarget.cxx b/Source/cmTarget.cxx
index 2fbca80..a516cbc 100644
--- a/Source/cmTarget.cxx
+++ b/Source/cmTarget.cxx
@@ -37,6 +37,8 @@ const char* cmTarget::GetTargetTypeName(TargetType targetType)
return "MODULE_LIBRARY";
case cmTarget::SHARED_LIBRARY:
return "SHARED_LIBRARY";
+ case cmTarget::OBJECT_LIBRARY:
+ return "OBJECT_LIBRARY";
case cmTarget::EXECUTABLE:
return "EXECUTABLE";
case cmTarget::UTILITY:
@@ -1727,7 +1729,15 @@ void cmTarget::AddSources(std::vector<std::string> const& srcs)
for(std::vector<std::string>::const_iterator i = srcs.begin();
i != srcs.end(); ++i)
{
- this->AddSource(i->c_str());
+ const char* src = i->c_str();
+ if(src[0] == '$' && src[1] == '<')
+ {
+ this->ProcessSourceExpression(*i);
+ }
+ else
+ {
+ this->AddSource(src);
+ }
}
}
@@ -1746,6 +1756,24 @@ cmSourceFile* cmTarget::AddSource(const char* s)
}
//----------------------------------------------------------------------------
+void cmTarget::ProcessSourceExpression(std::string const& expr)
+{
+ if(strncmp(expr.c_str(), "$<TARGET_OBJECTS:", 17) == 0 &&
+ expr[expr.size()-1] == '>')
+ {
+ std::string objLibName = expr.substr(17, expr.size()-18);
+ this->ObjectLibraries.push_back(objLibName);
+ }
+ else
+ {
+ cmOStringStream e;
+ e << "Unrecognized generator expression:\n"
+ << " " << expr;
+ this->Makefile->IssueMessage(cmake::FATAL_ERROR, e.str());
+ }
+}
+
+//----------------------------------------------------------------------------
struct cmTarget::SourceFileFlags
cmTarget::GetTargetSourceFileFlags(const cmSourceFile* sf)
{
@@ -4545,7 +4573,21 @@ void cmTarget::ComputeLinkImplementation(const char* config,
// This target needs runtime libraries for its source languages.
std::set<cmStdString> languages;
+ // Get languages used in our source files.
this->GetLanguages(languages);
+ // Get languages used in object library sources.
+ for(std::vector<std::string>::iterator i = this->ObjectLibraries.begin();
+ i != this->ObjectLibraries.end(); ++i)
+ {
+ if(cmTarget* objLib = this->Makefile->FindTargetToUse(i->c_str()))
+ {
+ if(objLib->GetType() == cmTarget::OBJECT_LIBRARY)
+ {
+ objLib->GetLanguages(languages);
+ }
+ }
+ }
+ // Copy the set of langauges to the link implementation.
for(std::set<cmStdString>::iterator li = languages.begin();
li != languages.end(); ++li)
{
diff --git a/Source/cmTarget.h b/Source/cmTarget.h
index ff05cd3..d41c827 100644
--- a/Source/cmTarget.h
+++ b/Source/cmTarget.h
@@ -59,7 +59,8 @@ class cmTarget
public:
cmTarget();
enum TargetType { EXECUTABLE, STATIC_LIBRARY,
- SHARED_LIBRARY, MODULE_LIBRARY, UTILITY, GLOBAL_TARGET,
+ SHARED_LIBRARY, MODULE_LIBRARY,
+ OBJECT_LIBRARY, UTILITY, GLOBAL_TARGET,
UNKNOWN_LIBRARY};
static const char* GetTargetTypeName(TargetType targetType);
enum CustomCommandType { PRE_BUILD, PRE_LINK, POST_BUILD };
@@ -116,6 +117,10 @@ public:
*/
std::vector<cmSourceFile*> const& GetSourceFiles();
void AddSourceFile(cmSourceFile* sf);
+ std::vector<std::string> const& GetObjectLibraries() const
+ {
+ return this->ObjectLibraries;
+ }
/** Get sources that must be built before the given source. */
std::vector<cmSourceFile*> const* GetSourceDepends(cmSourceFile* sf);
@@ -548,6 +553,7 @@ private:
std::vector<cmCustomCommand> PostBuildCommands;
TargetType TargetTypeValue;
std::vector<cmSourceFile*> SourceFiles;
+ std::vector<std::string> ObjectLibraries;
LinkLibraryVectorType LinkLibraries;
LinkLibraryVectorType PrevLinkedLibraries;
bool LinkLibrariesAnalyzed;
@@ -589,6 +595,8 @@ private:
void MaybeInvalidatePropertyCache(const char* prop);
+ void ProcessSourceExpression(std::string const& expr);
+
// The cmMakefile instance that owns this target. This should
// always be set.
cmMakefile* Makefile;
diff --git a/Source/cmTargetLinkLibrariesCommand.cxx b/Source/cmTargetLinkLibrariesCommand.cxx
index 36c4ca8..dbea1c3 100644
--- a/Source/cmTargetLinkLibrariesCommand.cxx
+++ b/Source/cmTargetLinkLibrariesCommand.cxx
@@ -84,6 +84,16 @@ bool cmTargetLinkLibrariesCommand
return true;
}
+ if(this->Target->GetType() == cmTarget::OBJECT_LIBRARY)
+ {
+ cmOStringStream e;
+ e << "Object library target \"" << args[0] << "\" "
+ << "may not link to anything.";
+ this->Makefile->IssueMessage(cmake::FATAL_ERROR, e.str());
+ cmSystemTools::SetFatalErrorOccured();
+ return true;
+ }
+
// but we might not have any libs after variable expansion
if(args.size() < 2)
{
diff --git a/Source/cmVisualStudio10TargetGenerator.cxx b/Source/cmVisualStudio10TargetGenerator.cxx
index 66f9a36..6caaad1 100644
--- a/Source/cmVisualStudio10TargetGenerator.cxx
+++ b/Source/cmVisualStudio10TargetGenerator.cxx
@@ -11,6 +11,7 @@
============================================================================*/
#include "cmVisualStudio10TargetGenerator.h"
#include "cmGlobalVisualStudio10Generator.h"
+#include "cmGeneratorTarget.h"
#include "cmTarget.h"
#include "cmComputeLinkInformation.h"
#include "cmGeneratedFileStream.h"
@@ -62,6 +63,7 @@ cmVisualStudio10TargetGenerator(cmTarget* target,
{
this->GlobalGenerator = gg;
this->Target = target;
+ this->GeneratorTarget = gg->GetGeneratorTarget(target);
this->Makefile = target->GetMakefile();
this->LocalGenerator =
(cmLocalVisualStudio7Generator*)
@@ -70,7 +72,6 @@ cmVisualStudio10TargetGenerator(cmTarget* target,
this->GlobalGenerator->CreateGUID(this->Name.c_str());
this->GUID = this->GlobalGenerator->GetGUID(this->Name.c_str());
this->Platform = gg->GetPlatformName();
- this->ComputeObjectNames();
this->BuildFileStream = 0;
}
@@ -147,7 +148,7 @@ void cmVisualStudio10TargetGenerator::Generate()
this->Target->SetProperty("GENERATOR_FILE_NAME",this->Name.c_str());
this->Target->SetProperty("GENERATOR_FILE_NAME_EXT",
".vcxproj");
- if(this->Target->GetType() <= cmTarget::MODULE_LIBRARY)
+ if(this->Target->GetType() <= cmTarget::OBJECT_LIBRARY)
{
if(!this->ComputeClOptions())
{
@@ -252,8 +253,7 @@ void cmVisualStudio10TargetGenerator::Generate()
this->WritePathAndIncrementalLinkOptions();
this->WriteItemDefinitionGroups();
this->WriteCustomCommands();
- this->WriteObjSources();
- this->WriteCLSources();
+ this->WriteAllSources();
this->WriteDotNetReferences();
this->WriteWinRTReferences();
this->WriteProjectReferences();
@@ -358,6 +358,7 @@ void cmVisualStudio10TargetGenerator::WriteProjectConfigurationValues()
case cmTarget::MODULE_LIBRARY:
configType += "DynamicLibrary";
break;
+ case cmTarget::OBJECT_LIBRARY:
case cmTarget::STATIC_LIBRARY:
configType += "StaticLibrary";
break;
@@ -388,7 +389,7 @@ void cmVisualStudio10TargetGenerator::WriteProjectConfigurationValues()
mfcLine += useOfMfcValue + "</UseOfMfc>\n";
this->WriteString(mfcLine.c_str(), 2);
- if(this->Target->GetType() <= cmTarget::MODULE_LIBRARY &&
+ if(this->Target->GetType() <= cmTarget::OBJECT_LIBRARY &&
this->ClOptions[*i]->UsingUnicode() ||
this->Target->GetPropertyAsBool("VS_WINRT_EXTENSIONS"))
{
@@ -421,12 +422,11 @@ void cmVisualStudio10TargetGenerator::WriteProjectConfigurationValues()
void cmVisualStudio10TargetGenerator::WriteCustomCommands()
{
this->SourcesVisited.clear();
- std::vector<cmSourceFile*> const& sources = this->Target->GetSourceFiles();
- for(std::vector<cmSourceFile*>::const_iterator source = sources.begin();
- source != sources.end(); ++source)
+ for(std::vector<cmSourceFile*>::const_iterator
+ si = this->GeneratorTarget->CustomCommands.begin();
+ si != this->GeneratorTarget->CustomCommands.end(); ++si)
{
- cmSourceFile* sf = *source;
- this->WriteCustomCommand(sf);
+ this->WriteCustomCommand(*si);
}
}
@@ -634,6 +634,25 @@ void cmVisualStudio10TargetGenerator::WriteGroups()
this->WriteGroupSources("Midl", idls, sourceGroups);
this->WriteGroupSources("CustomBuild", customBuild, sourceGroups);
+ // Add object library contents as external objects.
+ std::vector<std::string> objs;
+ this->GeneratorTarget->UseObjectLibraries(objs);
+ if(!objs.empty())
+ {
+ this->WriteString("<ItemGroup>\n", 1);
+ for(std::vector<std::string>::const_iterator
+ oi = objs.begin(); oi != objs.end(); ++oi)
+ {
+ std::string obj = *oi;
+ this->WriteString("<Object Include=\"", 2);
+ this->ConvertToWindowsSlash(obj);
+ (*this->BuildFileStream ) << obj << "\">\n";
+ this->WriteString("<Filter>Object Libraries</Filter>\n", 3);
+ this->WriteString("</Object>\n", 2);
+ }
+ this->WriteString("</ItemGroup>\n", 1);
+ }
+
this->WriteString("<ItemGroup>\n", 1);
for(std::set<cmSourceGroup*>::iterator g = groupsUsed.begin();
g != groupsUsed.end(); ++g)
@@ -657,6 +676,18 @@ void cmVisualStudio10TargetGenerator::WriteGroups()
this->WriteString("</Filter>\n", 2);
}
}
+ if(!objs.empty())
+ {
+ this->WriteString("<Filter Include=\"Object Libraries\">\n", 2);
+ std::string guidName = "SG_Filter_Object Libraries";
+ this->GlobalGenerator->CreateGUID(guidName.c_str());
+ this->WriteString("<UniqueIdentifier>", 3);
+ std::string guid =
+ this->GlobalGenerator->GetGUID(guidName.c_str());
+ (*this->BuildFileStream) << "{" << guid << "}"
+ << "</UniqueIdentifier>\n";
+ this->WriteString("</Filter>\n", 2);
+ }
this->WriteString("</ItemGroup>\n", 1);
this->WriteGroupSources("None", none, sourceGroups);
this->WriteString("</Project>\n", 0);
@@ -763,107 +794,56 @@ WriteGroupSources(const char* name,
this->WriteString("</ItemGroup>\n", 1);
}
-void cmVisualStudio10TargetGenerator::WriteObjSources()
-{
- if(this->Target->GetType() > cmTarget::MODULE_LIBRARY)
- {
- return;
- }
- bool first = true;
- std::vector<cmSourceFile*>const & sources = this->Target->GetSourceFiles();
- for(std::vector<cmSourceFile*>::const_iterator source = sources.begin();
- source != sources.end(); ++source)
- {
- std::string ext =
- cmSystemTools::LowerCase((*source)->GetExtension());
- if(ext == "obj" || ext == "o")
- {
- if(first)
- {
- this->WriteString("<ItemGroup>\n", 1);
- first = false;
- }
- // If an object file is generated, then vs10
- // will use it in the build, and we have to list
- // it as None instead of Object
- if((*source)->GetPropertyAsBool("GENERATED"))
- {
- this->WriteString("<None Include=\"", 2);
- }
- // If it is not a generated object then we have
- // to use the Object type
- else
- {
- this->WriteString("<Object Include=\"", 2);
- }
- (*this->BuildFileStream ) << (*source)->GetFullPath() << "\" />\n";
- }
- }
- if(!first)
+void cmVisualStudio10TargetGenerator::WriteSource(
+ const char* tool, cmSourceFile* sf, bool end)
+{
+ std::string sourceFile = sf->GetFullPath();
+ // do not use a relative path here because it means that you
+ // can not use as long a path to the file.
+ this->ConvertToWindowsSlash(sourceFile);
+ this->WriteString("<", 2);
+ (*this->BuildFileStream ) << tool <<
+ " Include=\"" << sourceFile << (end? "\" />\n" : "\" ");
+}
+
+void cmVisualStudio10TargetGenerator::WriteSources(
+ const char* tool, std::vector<cmSourceFile*> const& sources)
+{
+ for(std::vector<cmSourceFile*>::const_iterator
+ si = sources.begin(); si != sources.end(); ++si)
{
- this->WriteString("</ItemGroup>\n", 1);
+ this->WriteSource(tool, *si);
}
}
-
-void cmVisualStudio10TargetGenerator::WriteCLSources()
+void cmVisualStudio10TargetGenerator::WriteAllSources()
{
if(this->Target->GetType() > cmTarget::UTILITY)
{
return;
}
this->WriteString("<ItemGroup>\n", 1);
- std::vector<cmSourceFile*>const& sources = this->Target->GetSourceFiles();
- for(std::vector<cmSourceFile*>::const_iterator source = sources.begin();
- source != sources.end(); ++source)
+
+ this->WriteSources("ClInclude", this->GeneratorTarget->HeaderSources);
+ this->WriteSources("Midl", this->GeneratorTarget->IDLSources);
+
+ for(std::vector<cmSourceFile*>::const_iterator
+ si = this->GeneratorTarget->ObjectSources.begin();
+ si != this->GeneratorTarget->ObjectSources.end(); ++si)
{
- std::string ext = cmSystemTools::LowerCase((*source)->GetExtension());
- if((*source)->GetCustomCommand() || ext == "o" || ext == "obj")
- {
- continue;
- }
- // If it is not a custom command and it is not a pre-built obj file,
- // then add it as a source (c/c++/header/rc/idl) file
- bool header = (*source)->GetPropertyAsBool("HEADER_FILE_ONLY")
- || this->GlobalGenerator->IgnoreFile(ext.c_str());
- const char* lang = (*source)->GetLanguage();
- bool cl = lang && (strcmp(lang, "C") == 0 || strcmp(lang, "CXX") ==0);
- bool rc = lang && (strcmp(lang, "RC") == 0);
- bool idl = ext == "idl";
- std::string sourceFile = (*source)->GetFullPath();
- // do not use a relative path here because it means that you
- // can not use as long a path to the file.
- this->ConvertToWindowsSlash(sourceFile);
- // output the source file
- if(header)
- {
- this->WriteString("<ClInclude Include=\"", 2);
- }
- else if(cl)
- {
- this->WriteString("<ClCompile Include=\"", 2);
- }
- else if(rc)
- {
- this->WriteString("<ResourceCompile Include=\"", 2);
- }
- else if(idl)
- {
- this->WriteString("<Midl Include=\"", 2);
- }
- else
- {
- this->WriteString("<None Include=\"", 2);
- }
- (*this->BuildFileStream ) << sourceFile << "\"";
+ const char* lang = (*si)->GetLanguage();
+ bool cl = strcmp(lang, "C") == 0 || strcmp(lang, "CXX") == 0;
+ bool rc = strcmp(lang, "RC") == 0;
+ const char* tool = cl? "ClCompile" : (rc? "ResourceCompile" : "None");
+ this->WriteSource(tool, *si, false);
// ouput any flags specific to this source file
- if(!header && cl && this->OutputSourceSpecificFlags(*source))
+ if(cl && this->OutputSourceSpecificFlags(*si))
{
// if the source file has specific flags the tag
// is ended on a new line
this->WriteString("</ClCompile>\n", 2);
}
- else if(!header && rc && this->OutputSourceSpecificFlags(*source))
+ else if(rc && this->OutputSourceSpecificFlags(*si))
{
this->WriteString("</ResourceCompile>\n", 2);
}
@@ -872,26 +852,32 @@ void cmVisualStudio10TargetGenerator::WriteCLSources()
(*this->BuildFileStream ) << " />\n";
}
}
- this->WriteString("</ItemGroup>\n", 1);
-}
-void cmVisualStudio10TargetGenerator::ComputeObjectNames()
-{
- // get the classes from the source lists then add them to the groups
- std::vector<cmSourceFile*>const & classes = this->Target->GetSourceFiles();
- for(std::vector<cmSourceFile*>::const_iterator i = classes.begin();
- i != classes.end(); i++)
- {
- // Add the file to the list of sources.
- std::string source = (*i)->GetFullPath();
- if(cmSystemTools::UpperCase((*i)->GetExtension()) == "DEF")
- {
- this->ModuleDefinitionFile = (*i)->GetFullPath();
- }
+ for(std::vector<cmSourceFile*>::const_iterator
+ si = this->GeneratorTarget->ExternalObjects.begin();
+ si != this->GeneratorTarget->ExternalObjects.end(); ++si)
+ {
+ // If an object file is generated in this target, then vs10 will use
+ // it in the build, and we have to list it as None instead of Object.
+ std::vector<cmSourceFile*> const* d = this->Target->GetSourceDepends(*si);
+ this->WriteSource((d && !d->empty())? "None":"Object", *si);
+ }
+
+ this->WriteSources("None", this->GeneratorTarget->ExtraSources);
+
+ // Add object library contents as external objects.
+ std::vector<std::string> objs;
+ this->GeneratorTarget->UseObjectLibraries(objs);
+ for(std::vector<std::string>::const_iterator
+ oi = objs.begin(); oi != objs.end(); ++oi)
+ {
+ std::string obj = *oi;
+ this->WriteString("<Object Include=\"", 2);
+ this->ConvertToWindowsSlash(obj);
+ (*this->BuildFileStream ) << obj << "\" />\n";
}
- // Compute which sources need unique object computation.
- this->LocalGenerator->ComputeObjectNameRequirements(classes);
+ this->WriteString("</ItemGroup>\n", 1);
}
bool cmVisualStudio10TargetGenerator::OutputSourceSpecificFlags(
@@ -900,16 +886,11 @@ bool cmVisualStudio10TargetGenerator::OutputSourceSpecificFlags(
cmSourceFile& sf = *source;
cmLocalVisualStudio7Generator* lg = this->LocalGenerator;
- // Compute the maximum length full path to the intermediate
- // files directory for any configuration. This is used to construct
- // object file names that do not produce paths that are too long.
- std::string dir_max;
- lg->ComputeMaxDirectoryLength(dir_max, *this->Target);
-
std::string objectName;
- if(lg->NeedObjectName.find(&sf) != lg->NeedObjectName.end())
+ if(this->GeneratorTarget->ExplicitObjectName.find(&sf)
+ != this->GeneratorTarget->ExplicitObjectName.end())
{
- objectName = lg->GetObjectFileNameWithoutTarget(sf, dir_max);
+ objectName = this->GeneratorTarget->Objects[&sf];
}
std::string flags;
std::string defines;
@@ -1030,20 +1011,29 @@ void cmVisualStudio10TargetGenerator::WritePathAndIncrementalLinkOptions()
}
else
{
- std::string targetNameFull =
- this->Target->GetFullName(config->c_str());
std::string intermediateDir = this->LocalGenerator->
GetTargetDirectory(*this->Target);
intermediateDir += "/";
intermediateDir += *config;
intermediateDir += "/";
+ std::string outDir;
+ std::string targetNameFull;
+ if(ttype == cmTarget::OBJECT_LIBRARY)
+ {
+ outDir = intermediateDir;
+ targetNameFull = this->Target->GetName();
+ targetNameFull += ".lib";
+ }
+ else
+ {
+ outDir = this->Target->GetDirectory(config->c_str()) + "/";
+ targetNameFull = this->Target->GetFullName(config->c_str());
+ }
this->ConvertToWindowsSlash(intermediateDir);
- std::string outDir = this->Target->GetDirectory(config->c_str());
this->ConvertToWindowsSlash(outDir);
this->WritePlatformConfigTag("OutDir", config->c_str(), 3);
*this->BuildFileStream << outDir
- << "\\"
<< "</OutDir>\n";
this->WritePlatformConfigTag("IntDir", config->c_str(), 3);
@@ -1277,11 +1267,15 @@ void cmVisualStudio10TargetGenerator::WriteClOptions(
*this->BuildFileStream << configName
<< "</AssemblerListingLocation>\n";
this->WriteString("<ObjectFileName>$(IntDir)</ObjectFileName>\n", 3);
- this->WriteString("<ProgramDataBaseFileName>", 3);
- *this->BuildFileStream << this->Target->GetDirectory(configName.c_str())
- << "/"
- << this->Target->GetPDBName(configName.c_str())
- << "</ProgramDataBaseFileName>\n";
+ if(this->Target->GetType() != cmTarget::OBJECT_LIBRARY)
+ {
+ // TODO: PDB for object library?
+ this->WriteString("<ProgramDataBaseFileName>", 3);
+ *this->BuildFileStream << this->Target->GetDirectory(configName.c_str())
+ << "/"
+ << this->Target->GetPDBName(configName.c_str())
+ << "</ProgramDataBaseFileName>\n";
+ }
this->WriteString("</ClCompile>\n", 2);
}
@@ -1513,10 +1507,10 @@ void cmVisualStudio10TargetGenerator::WriteLinkOptions(std::string const&
linkOptions.AddFlag("ImportLibrary", imLib.c_str());
linkOptions.AddFlag("ProgramDataBaseFile", pdb.c_str());
linkOptions.Parse(flags.c_str());
- if(!this->ModuleDefinitionFile.empty())
+ if(!this->GeneratorTarget->ModuleDefinitionFile.empty())
{
linkOptions.AddFlag("ModuleDefinitionFile",
- this->ModuleDefinitionFile.c_str());
+ this->GeneratorTarget->ModuleDefinitionFile.c_str());
}
linkOptions.RemoveFlag("GenerateManifest");
@@ -1592,7 +1586,7 @@ void cmVisualStudio10TargetGenerator::WriteItemDefinitionGroups()
this->WritePlatformConfigTag("ItemDefinitionGroup", i->c_str(), 1);
*this->BuildFileStream << "\n";
// output cl compile flags <ClCompile></ClCompile>
- if(this->Target->GetType() <= cmTarget::MODULE_LIBRARY)
+ if(this->Target->GetType() <= cmTarget::OBJECT_LIBRARY)
{
this->WriteClOptions(*i, includes);
// output rc compile flags <ResourceCompile></ResourceCompile>
diff --git a/Source/cmVisualStudio10TargetGenerator.h b/Source/cmVisualStudio10TargetGenerator.h
index 90035f2..20a443b 100644
--- a/Source/cmVisualStudio10TargetGenerator.h
+++ b/Source/cmVisualStudio10TargetGenerator.h
@@ -15,6 +15,7 @@
class cmTarget;
class cmMakefile;
+class cmGeneratorTarget;
class cmGeneratedFileStream;
class cmGlobalVisualStudio10Generator;
class cmSourceFile;
@@ -46,10 +47,11 @@ private:
void WriteString(const char* line, int indentLevel);
void WriteProjectConfigurations();
void WriteProjectConfigurationValues();
- void WriteCLSources();
+ void WriteSource(const char* tool, cmSourceFile* sf, bool end = true);
+ void WriteSources(const char* tool, std::vector<cmSourceFile*> const&);
+ void WriteAllSources();
void WriteDotNetReferences();
void WriteWinRTReferences();
- void WriteObjSources();
void WritePathAndIncrementalLinkOptions();
void WriteItemDefinitionGroups();
bool ComputeClOptions();
@@ -75,7 +77,6 @@ private:
void WriteEvents(std::string const& configName);
void WriteEvent(const char* name, std::vector<cmCustomCommand> & commands,
std::string const& configName);
- void ComputeObjectNames();
void WriteGroupSources(const char* name,
std::vector<cmSourceFile*> const& sources,
std::vector<cmSourceGroup>& );
@@ -87,9 +88,9 @@ private:
typedef cmVisualStudioGeneratorOptions Options;
typedef std::map<cmStdString, Options*> OptionsMap;
OptionsMap ClOptions;
- std::string ModuleDefinitionFile;
std::string PathToVcxproj;
cmTarget* Target;
+ cmGeneratorTarget* GeneratorTarget;
cmMakefile* Makefile;
std::string Platform;
std::string GUID;
diff --git a/Source/cmake.h b/Source/cmake.h
index 161e656..94c6f12 100644
--- a/Source/cmake.h
+++ b/Source/cmake.h
@@ -102,8 +102,8 @@ class cmake
//@{
/**
* Set/Get the home directory (or output directory) in the project. The
- * home directory is the top directory of the project. It is where
- * cmake was run. Remember that CMake processes
+ * home directory is the top directory of the project. It is the
+ * path-to-source cmake was run with. Remember that CMake processes
* CMakeLists files by recursing up the tree starting at the StartDirectory
* and going up until it reaches the HomeDirectory.
*/
@@ -294,7 +294,7 @@ class cmake
void SetWorkingMode(WorkingMode mode) { this->CurrentWorkingMode = mode; }
WorkingMode GetWorkingMode() { return this->CurrentWorkingMode; }
- ///! Debug the try compile stuff by not delelting the files
+ ///! Debug the try compile stuff by not deleting the files
bool GetDebugTryCompile(){return this->DebugTryCompile;}
void DebugTryCompileOn(){this->DebugTryCompile = true;}
@@ -372,7 +372,7 @@ class cmake
/** Display a message to the user. */
void IssueMessage(cmake::MessageType t, std::string const& text,
cmListFileBacktrace const& backtrace);
- // * run the --build option
+ ///! run the --build option
int Build(const std::string& dir,
const std::string& target,
const std::string& config,
@@ -436,7 +436,7 @@ protected:
void SetDirectoriesFromFile(const char* arg);
//! Make sure all commands are what they say they are and there is no
- //macros.
+ /// macros.
void CleanupCommandsAndMacros();
void GenerateGraphViz(const char* fileName) const;
diff --git a/Source/kwsys/kwsysDateStamp.cmake b/Source/kwsys/kwsysDateStamp.cmake
index 6ee6e5b..6c61321 100644
--- a/Source/kwsys/kwsysDateStamp.cmake
+++ b/Source/kwsys/kwsysDateStamp.cmake
@@ -18,4 +18,4 @@ SET(KWSYS_DATE_STAMP_YEAR 2012)
SET(KWSYS_DATE_STAMP_MONTH 03)
# KWSys version date day component. Format is DD.
-SET(KWSYS_DATE_STAMP_DAY 19)
+SET(KWSYS_DATE_STAMP_DAY 27)
diff --git a/Tests/CMakeLists.txt b/Tests/CMakeLists.txt
index 5f125a4..c0b7cd6 100644
--- a/Tests/CMakeLists.txt
+++ b/Tests/CMakeLists.txt
@@ -199,6 +199,7 @@ IF(BUILD_TESTING)
ADD_TEST_MACRO(CxxOnly CxxOnly)
ADD_TEST_MACRO(IPO COnly/COnly)
ADD_TEST_MACRO(OutDir runtime/OutDir)
+ ADD_TEST_MACRO(ObjectLibrary UseCshared)
ADD_TEST_MACRO(NewlineArgs NewlineArgs)
ADD_TEST_MACRO(SetLang SetLang)
ADD_TEST_MACRO(ExternalOBJ ExternalOBJ)
diff --git a/Tests/CMakeOnly/AllFindModules/CMakeLists.txt b/Tests/CMakeOnly/AllFindModules/CMakeLists.txt
index 22b1b7b..6604208 100644
--- a/Tests/CMakeOnly/AllFindModules/CMakeLists.txt
+++ b/Tests/CMakeOnly/AllFindModules/CMakeLists.txt
@@ -48,11 +48,21 @@ endif (NOT QT4_FOUND)
macro(check_version_string MODULE_NAME VERSION_VAR)
if (${MODULE_NAME}_FOUND)
if (DEFINED ${VERSION_VAR})
- if (NOT ${VERSION_VAR} MATCHES "^[0-9][0-9\\.]*[-A-Za-z_\\+]*[0-9\\.]*$")
- message(SEND_ERROR "${VERSION_VAR} has unexpected content ${${VERSION_VAR}}")
+ message(STATUS "${VERSION_VAR}='${${VERSION_VAR}}'")
+ if (NOT ${VERSION_VAR} MATCHES "^[0-9]")
+ message(SEND_ERROR "unexpected: ${VERSION_VAR} does not begin with a decimal digit")
+ endif()
+ if ("${${VERSION_VAR}}" STREQUAL "")
+ message(SEND_ERROR "unexpected: ${VERSION_VAR} is empty")
+ endif()
+ if (${VERSION_VAR} VERSION_EQUAL 0)
+ message(SEND_ERROR "unexpected: ${VERSION_VAR} is VERSION_EQUAL 0")
+ endif()
+ if (NOT ${VERSION_VAR} VERSION_GREATER 0)
+ message(SEND_ERROR "unexpected: ${VERSION_VAR} is NOT VERSION_GREATER 0")
endif()
else()
- message(SEND_ERROR "${MODULE_NAME}_FOUND is set but no version number is defined")
+ message(SEND_ERROR "${MODULE_NAME}_FOUND is set but version number variable ${VERSION_VAR} is NOT DEFINED")
endif()
endif ()
endmacro(check_version_string)
diff --git a/Tests/CTestUpdateHG.cmake.in b/Tests/CTestUpdateHG.cmake.in
index 5a9daae..640d2c6 100644
--- a/Tests/CTestUpdateHG.cmake.in
+++ b/Tests/CTestUpdateHG.cmake.in
@@ -28,7 +28,10 @@ run_child(
WORKING_DIRECTORY ${TOP}/repo.hg
COMMAND ${HG} init
)
-set(REPO file:///${TOP}/repo.hg)
+if(NOT "${TOP}" MATCHES "^/")
+ set(slash /)
+endif()
+set(REPO file://${slash}${TOP}/repo.hg)
#-----------------------------------------------------------------------------
# Import initial content into the repository.
diff --git a/Tests/ExternalOBJ/CMakeLists.txt b/Tests/ExternalOBJ/CMakeLists.txt
index f12de11..683e799 100644
--- a/Tests/ExternalOBJ/CMakeLists.txt
+++ b/Tests/ExternalOBJ/CMakeLists.txt
@@ -59,3 +59,5 @@ ADD_EXECUTABLE(ExternalOBJ executable.cxx ${CUSTOM_OBJECT})
# not didn't work. So, repeat the executable using the object
# directly and not from the output of the copy.
ADD_EXECUTABLE(ExternalOBJ2 executable.cxx ${EXTERNAL_OBJECT})
+
+ADD_SUBDIRECTORY(Sub)
diff --git a/Tests/ExternalOBJ/Sub/CMakeLists.txt b/Tests/ExternalOBJ/Sub/CMakeLists.txt
new file mode 100644
index 0000000..35cd30c
--- /dev/null
+++ b/Tests/ExternalOBJ/Sub/CMakeLists.txt
@@ -0,0 +1,3 @@
+set_property(SOURCE ${CUSTOM_OBJECT} PROPERTY GENERATED 1)
+add_executable(ExternalOBJSub ../executable.cxx ${CUSTOM_OBJECT})
+add_dependencies(ExternalOBJSub ExternalOBJ) # depend on generating target
diff --git a/Tests/FindPackageTest/CMakeLists.txt b/Tests/FindPackageTest/CMakeLists.txt
index 73f24e0..5862094 100644
--- a/Tests/FindPackageTest/CMakeLists.txt
+++ b/Tests/FindPackageTest/CMakeLists.txt
@@ -37,6 +37,12 @@ FIND_PACKAGE(VersionTestB 1.2)
FIND_PACKAGE(VersionTestC 1.2.3)
FIND_PACKAGE(VersionTestD 1.2.3.4)
+
+FIND_PACKAGE(LotsOfComponents COMPONENTS AComp OPTIONAL_COMPONENTS BComp CComp)
+IF(NOT LOTSOFCOMPONENTS_FOUND)
+ MESSAGE(SEND_ERROR "LotsOfComponents not found !")
+ENDIF()
+
#-----------------------------------------------------------------------------
# Test system package registry if possible.
SET(CMakeTestSystemPackage "")
@@ -82,6 +88,7 @@ SET(PACKAGES
RecursiveA RecursiveB RecursiveC
ArchA ArchB ArchC ArchD
EnvA EnvB
+ SetFoundTRUE SetFoundFALSE
${CMakeTestSystemPackage}
)
FOREACH(p ${PACKAGES})
@@ -117,6 +124,10 @@ FIND_PACKAGE(VersionedC 4.0 EXACT NAMES zot)
FIND_PACKAGE(VersionedD 1.1 EXACT NAMES Baz)
FIND_PACKAGE(VersionedE 1.2 EXACT NAMES Baz)
+# Test Config files which set Xyz_FOUND themselves:
+FIND_PACKAGE(SetFoundTRUE NO_MODULE)
+FIND_PACKAGE(SetFoundFALSE NO_MODULE)
+
# Test wrong initial path when result is present.
SET(WrongA_DIR "${VersionedD_DIR}")
FIND_PACKAGE(WrongA 1.2 EXACT NAMES Baz)
@@ -201,6 +212,8 @@ SET(ArchC_EXPECTED "lib/arch/zot-3.1/zot-config.cmake")
SET(ArchD_EXPECTED "lib/arch/cmake/zot-4.0/zot-config.cmake")
SET(EnvA_EXPECTED "lib/zot-3.1/zot-config.cmake")
SET(EnvB_MISSING "EnvB_DIR-NOTFOUND")
+SET(SetFoundTRUE_EXPECTED "cmake/SetFoundTRUEConfig.cmake")
+SET(SetFoundFALSE_MISSING "${CMAKE_CURRENT_SOURCE_DIR}/cmake")
SET(CMakeTestSystemPackage_EXPECTED "SystemPackage/CMakeTestSystemPackageConfig.cmake")
# Check the results.
@@ -212,6 +225,11 @@ FOREACH(p ${PACKAGES})
"Package ${p} should have been [${${p}_MISSING}] but "
"was [${${p}_DIR}]")
ENDIF()
+ IF(${p}_FOUND)
+ MESSAGE(SEND_ERROR
+ "Package ${p} should not have been found, but ${p}_FOUND is set to "
+ "\"${${p}_FOUND}\"")
+ ENDIF()
ELSEIF(${p}_FOUND)
# Convert to relative path for comparison to expected location.
FILE(RELATIVE_PATH REL_${p}_CONFIG "${CMAKE_CURRENT_SOURCE_DIR}"
@@ -318,6 +336,8 @@ configure_package_config_file(RelocatableConfig.cmake.in "${CMAKE_CURRENT_BINARY
PATH_VARS INCLUDE_INSTALL_DIR SHARE_INSTALL_DIR CURRENT_BUILD_DIR
)
+set(Relocatable_FIND_COMPONENTS AComp BComp CComp)
+set(Relocatable_FIND_REQUIRED_BComp 1)
include("${CMAKE_CURRENT_BINARY_DIR}/RelocatableConfig.cmake")
if(NOT "${RELOC_INCLUDE_DIR}" STREQUAL "${CMAKE_CURRENT_BINARY_DIR}/include")
@@ -332,6 +352,14 @@ if(NOT "${RELOC_BUILD_DIR}" STREQUAL "${CMAKE_CURRENT_BINARY_DIR}")
message(SEND_ERROR "RELOC_BUILD_DIR set by configure_package_config_file() is set to \"${RELOC_BUILD_DIR}\" (expected \"${CMAKE_CURRENT_BINARY_DIR}\")")
endif()
+if(NOT DEFINED Relocatable_FOUND)
+ message(SEND_ERROR "Relocatable_FOUND not defined !")
+endif()
+
+if(Relocatable_FOUND)
+ message(SEND_ERROR "Relocatable_FOUND set to TRUE !")
+endif()
+
#-----------------------------------------------------------------------------
# Test write_basic_config_version_file().
diff --git a/Tests/FindPackageTest/FindLotsOfComponents.cmake b/Tests/FindPackageTest/FindLotsOfComponents.cmake
new file mode 100644
index 0000000..9076d86
--- /dev/null
+++ b/Tests/FindPackageTest/FindLotsOfComponents.cmake
@@ -0,0 +1,10 @@
+set(LOC_FOO TRUE)
+
+set(LotsOfComponents_AComp_FOUND TRUE)
+set(LotsOfComponents_BComp_FOUND FALSE)
+set(LotsOfComponents_CComp_FOUND TRUE)
+
+include(FindPackageHandleStandardArgs)
+
+find_package_handle_standard_args(LotsOfComponents REQUIRED_VARS LOC_FOO
+ HANDLE_COMPONENTS)
diff --git a/Tests/FindPackageTest/RelocatableConfig.cmake.in b/Tests/FindPackageTest/RelocatableConfig.cmake.in
index 7a34b2f..4a4b4e9 100644
--- a/Tests/FindPackageTest/RelocatableConfig.cmake.in
+++ b/Tests/FindPackageTest/RelocatableConfig.cmake.in
@@ -3,3 +3,9 @@
set(RELOC_INCLUDE_DIR "@PACKAGE_INCLUDE_INSTALL_DIR@")
set(RELOC_SHARE_DIR "@PACKAGE_SHARE_INSTALL_DIR@")
set_and_check(RELOC_BUILD_DIR "@PACKAGE_CURRENT_BUILD_DIR@")
+
+set(Relocatable_AComp_FOUND TRUE)
+set(Relocatable_BComp_FOUND FALSE)
+set(Relocatable_CComp_FOUND FALSE)
+
+check_required_components(Relocatable)
diff --git a/Tests/FindPackageTest/cmake/SetFoundFALSEConfig.cmake b/Tests/FindPackageTest/cmake/SetFoundFALSEConfig.cmake
new file mode 100644
index 0000000..ae6bd14
--- /dev/null
+++ b/Tests/FindPackageTest/cmake/SetFoundFALSEConfig.cmake
@@ -0,0 +1 @@
+set(SetFoundFALSE_FOUND FALSE)
diff --git a/Tests/FindPackageTest/cmake/SetFoundTRUEConfig.cmake b/Tests/FindPackageTest/cmake/SetFoundTRUEConfig.cmake
new file mode 100644
index 0000000..19d0711
--- /dev/null
+++ b/Tests/FindPackageTest/cmake/SetFoundTRUEConfig.cmake
@@ -0,0 +1 @@
+set(SetFoundTRUE_FOUND TRUE)
diff --git a/Tests/ObjectLibrary/A/CMakeLists.txt b/Tests/ObjectLibrary/A/CMakeLists.txt
new file mode 100644
index 0000000..121a8ac
--- /dev/null
+++ b/Tests/ObjectLibrary/A/CMakeLists.txt
@@ -0,0 +1,17 @@
+# Add -fPIC so objects can be used in shared libraries.
+# TODO: Need property for this.
+if(CMAKE_SHARED_LIBRARY_C_FLAGS AND NOT WATCOM)
+ set(CMAKE_C_FLAGS "${CMAKE_SHARED_LIBRARY_C_FLAGS} ${CMAKE_C_FLAGS}")
+endif()
+
+add_definitions(-DA_DEF)
+
+add_custom_command(
+ OUTPUT a1.c
+ DEPENDS a1.c.in
+ COMMAND ${CMAKE_COMMAND} -E copy ${CMAKE_CURRENT_SOURCE_DIR}/a1.c.in
+ ${CMAKE_CURRENT_BINARY_DIR}/a1.c
+ )
+include_directories(${CMAKE_CURRENT_SOURCE_DIR})
+
+add_library(A OBJECT a1.c a2.c)
diff --git a/Tests/ObjectLibrary/A/a.h b/Tests/ObjectLibrary/A/a.h
new file mode 100644
index 0000000..7259f98
--- /dev/null
+++ b/Tests/ObjectLibrary/A/a.h
@@ -0,0 +1,6 @@
+#ifndef A_DEF
+# error "A_DEF not defined"
+#endif
+#ifdef B_DEF
+# error "B_DEF must not be defined"
+#endif
diff --git a/Tests/ObjectLibrary/A/a1.c.in b/Tests/ObjectLibrary/A/a1.c.in
new file mode 100644
index 0000000..d1eaf58
--- /dev/null
+++ b/Tests/ObjectLibrary/A/a1.c.in
@@ -0,0 +1,2 @@
+#include "a.h"
+int a1(void) { return 0; }
diff --git a/Tests/ObjectLibrary/A/a2.c b/Tests/ObjectLibrary/A/a2.c
new file mode 100644
index 0000000..d8f225e
--- /dev/null
+++ b/Tests/ObjectLibrary/A/a2.c
@@ -0,0 +1,2 @@
+#include "a.h"
+int a2(void) { return 0; }
diff --git a/Tests/ObjectLibrary/AB.def b/Tests/ObjectLibrary/AB.def
new file mode 100644
index 0000000..3f2b5c0
--- /dev/null
+++ b/Tests/ObjectLibrary/AB.def
@@ -0,0 +1,5 @@
+EXPORTS
+a1
+a2
+b1
+b2
diff --git a/Tests/ObjectLibrary/B/CMakeLists.txt b/Tests/ObjectLibrary/B/CMakeLists.txt
new file mode 100644
index 0000000..67172d1
--- /dev/null
+++ b/Tests/ObjectLibrary/B/CMakeLists.txt
@@ -0,0 +1,15 @@
+if("${CMAKE_GENERATOR}" MATCHES "Visual Studio 6")
+ # VS 6 generator does not use per-target object locations.
+ set(vs6 _vs6)
+endif()
+
+# Add -fPIC so objects can be used in shared libraries.
+# TODO: Need property for this.
+if(CMAKE_SHARED_LIBRARY_C_FLAGS AND NOT WATCOM)
+ set(CMAKE_C_FLAGS "${CMAKE_SHARED_LIBRARY_C_FLAGS} ${CMAKE_C_FLAGS}")
+endif()
+
+add_definitions(-DB_DEF)
+add_library(B OBJECT b1.c b2.c)
+add_library(Bexport OBJECT b1${vs6}.c b2${vs6}.c)
+set_property(TARGET Bexport PROPERTY COMPILE_DEFINITIONS Bexport)
diff --git a/Tests/ObjectLibrary/B/b.h b/Tests/ObjectLibrary/B/b.h
new file mode 100644
index 0000000..11b22f4
--- /dev/null
+++ b/Tests/ObjectLibrary/B/b.h
@@ -0,0 +1,11 @@
+#ifdef A_DEF
+# error "A_DEF must not be defined"
+#endif
+#ifndef B_DEF
+# error "B_DEF not defined"
+#endif
+#if defined(_WIN32) && defined(Bexport)
+# define EXPORT_B __declspec(dllexport)
+#else
+# define EXPORT_B
+#endif
diff --git a/Tests/ObjectLibrary/B/b1.c b/Tests/ObjectLibrary/B/b1.c
new file mode 100644
index 0000000..fdeffe4
--- /dev/null
+++ b/Tests/ObjectLibrary/B/b1.c
@@ -0,0 +1,2 @@
+#include "b.h"
+EXPORT_B int b1(void) { return 0; }
diff --git a/Tests/ObjectLibrary/B/b1_vs6.c b/Tests/ObjectLibrary/B/b1_vs6.c
new file mode 100644
index 0000000..b606e10
--- /dev/null
+++ b/Tests/ObjectLibrary/B/b1_vs6.c
@@ -0,0 +1 @@
+#include "b1.c"
diff --git a/Tests/ObjectLibrary/B/b2.c b/Tests/ObjectLibrary/B/b2.c
new file mode 100644
index 0000000..6e0d17c
--- /dev/null
+++ b/Tests/ObjectLibrary/B/b2.c
@@ -0,0 +1,2 @@
+#include "b.h"
+EXPORT_B int b2(void) { return 0; }
diff --git a/Tests/ObjectLibrary/B/b2_vs6.c b/Tests/ObjectLibrary/B/b2_vs6.c
new file mode 100644
index 0000000..d96a43e
--- /dev/null
+++ b/Tests/ObjectLibrary/B/b2_vs6.c
@@ -0,0 +1 @@
+#include "b2.c"
diff --git a/Tests/ObjectLibrary/CMakeLists.txt b/Tests/ObjectLibrary/CMakeLists.txt
new file mode 100644
index 0000000..8723415
--- /dev/null
+++ b/Tests/ObjectLibrary/CMakeLists.txt
@@ -0,0 +1,52 @@
+cmake_minimum_required(VERSION 2.8)
+project(ObjectLibrary C)
+
+add_subdirectory(A)
+add_subdirectory(B)
+
+add_library(Cstatic STATIC c.c $<TARGET_OBJECTS:A> $<TARGET_OBJECTS:B>)
+add_executable(UseCstatic main.c)
+target_link_libraries(UseCstatic Cstatic)
+
+add_library(Cshared SHARED c.c $<TARGET_OBJECTS:A> $<TARGET_OBJECTS:Bexport>)
+add_executable(UseCshared main.c)
+set_property(TARGET UseCshared PROPERTY COMPILE_DEFINITIONS SHARED_C)
+target_link_libraries(UseCshared Cshared)
+
+add_executable(UseCinternal main.c c.c $<TARGET_OBJECTS:A> $<TARGET_OBJECTS:B>)
+
+if("${CMAKE_GENERATOR}" MATCHES "^Visual Studio (6|7|7 .NET 2003)$")
+ # VS 6 and 7 generators do not add objects as sources so we need a
+ # dummy object to convince the IDE to build the targets below.
+ set(dummy dummy.obj) # In MinGW: gcc -c dummy.c -o dummy.obj
+elseif("${CMAKE_GENERATOR}" MATCHES "Xcode")
+ # Xcode does not seem to support targets without sources.
+ set(dummy dummy.c)
+endif()
+
+# Test static library without its own sources.
+add_library(ABstatic STATIC ${dummy} $<TARGET_OBJECTS:A> $<TARGET_OBJECTS:B>)
+add_executable(UseABstatic mainAB.c)
+target_link_libraries(UseABstatic ABstatic)
+
+# Test module definition file to export object library symbols in the test
+# below if the platform needs and supports it.
+set(ABshared_SRCS $<TARGET_OBJECTS:A>)
+if(CMAKE_LINK_DEF_FILE_FLAG OR NOT WIN32)
+ list(APPEND ABshared_SRCS $<TARGET_OBJECTS:B> AB.def)
+else()
+ set(NO_A NO_A)
+ list(APPEND ABshared_SRCS $<TARGET_OBJECTS:Bexport>)
+endif()
+
+# Test shared library without its own sources.
+add_library(ABshared SHARED ${dummy} ${ABshared_SRCS})
+add_executable(UseABshared mainAB.c)
+set_property(TARGET UseABshared PROPERTY COMPILE_DEFINITIONS SHARED_B ${NO_A})
+target_link_libraries(UseABshared ABshared)
+
+# Test executable without its own sources.
+add_library(ABmain OBJECT mainAB.c)
+add_executable(UseABinternal ${dummy}
+ $<TARGET_OBJECTS:ABmain> $<TARGET_OBJECTS:A> $<TARGET_OBJECTS:B>
+ )
diff --git a/Tests/ObjectLibrary/c.c b/Tests/ObjectLibrary/c.c
new file mode 100644
index 0000000..968095b
--- /dev/null
+++ b/Tests/ObjectLibrary/c.c
@@ -0,0 +1,19 @@
+#if defined(_WIN32) && defined(Cshared_EXPORTS)
+# define EXPORT_C __declspec(dllexport)
+#else
+# define EXPORT_C
+#endif
+
+extern int a1(void);
+extern int a2(void);
+extern int b1(void);
+extern int b2(void);
+EXPORT_C int c(void)
+{
+ return 0
+ + a1()
+ + a2()
+ + b1()
+ + b2()
+ ;
+}
diff --git a/Tests/ObjectLibrary/dummy.c b/Tests/ObjectLibrary/dummy.c
new file mode 100644
index 0000000..2b17d81
--- /dev/null
+++ b/Tests/ObjectLibrary/dummy.c
@@ -0,0 +1 @@
+int dummy(void) {return 0;}
diff --git a/Tests/ObjectLibrary/dummy.obj b/Tests/ObjectLibrary/dummy.obj
new file mode 100644
index 0000000..77f6f2f
--- /dev/null
+++ b/Tests/ObjectLibrary/dummy.obj
Binary files differ
diff --git a/Tests/ObjectLibrary/main.c b/Tests/ObjectLibrary/main.c
new file mode 100644
index 0000000..6819f1c
--- /dev/null
+++ b/Tests/ObjectLibrary/main.c
@@ -0,0 +1,16 @@
+#if defined(_WIN32) && defined(SHARED_C)
+# define IMPORT_C __declspec(dllimport)
+#else
+# define IMPORT_C
+#endif
+extern IMPORT_C int b1(void);
+extern IMPORT_C int b2(void);
+extern IMPORT_C int c(void);
+int main(void)
+{
+ return 0
+ + c()
+ + b1()
+ + b2()
+ ;
+}
diff --git a/Tests/ObjectLibrary/mainAB.c b/Tests/ObjectLibrary/mainAB.c
new file mode 100644
index 0000000..556898b
--- /dev/null
+++ b/Tests/ObjectLibrary/mainAB.c
@@ -0,0 +1,22 @@
+#if defined(_WIN32) && defined(SHARED_B)
+# define IMPORT_B __declspec(dllimport)
+#else
+# define IMPORT_B
+#endif
+extern IMPORT_B int b1(void);
+extern IMPORT_B int b2(void);
+#ifndef NO_A
+extern int a1(void);
+extern int a2(void);
+#endif
+int main(void)
+{
+ return 0
+#ifndef NO_A
+ + a1()
+ + a2()
+#endif
+ + b1()
+ + b2()
+ ;
+}
diff --git a/Tests/RunCMake/CMakeLists.txt b/Tests/RunCMake/CMakeLists.txt
index 63fc9f8..0b79efa 100644
--- a/Tests/RunCMake/CMakeLists.txt
+++ b/Tests/RunCMake/CMakeLists.txt
@@ -40,5 +40,7 @@ macro(add_RunCMake_test test)
)
endmacro()
+add_RunCMake_test(ObjectLibrary)
+
add_RunCMake_test(build_command)
add_RunCMake_test(find_package)
diff --git a/Tests/RunCMake/ObjectLibrary/BadObjSource1-result.txt b/Tests/RunCMake/ObjectLibrary/BadObjSource1-result.txt
new file mode 100644
index 0000000..d00491f
--- /dev/null
+++ b/Tests/RunCMake/ObjectLibrary/BadObjSource1-result.txt
@@ -0,0 +1 @@
+1
diff --git a/Tests/RunCMake/ObjectLibrary/BadObjSource1-stderr.txt b/Tests/RunCMake/ObjectLibrary/BadObjSource1-stderr.txt
new file mode 100644
index 0000000..b31225b
--- /dev/null
+++ b/Tests/RunCMake/ObjectLibrary/BadObjSource1-stderr.txt
@@ -0,0 +1,8 @@
+CMake Error at BadObjSource1.cmake:1 \(add_library\):
+ OBJECT library "A" contains:
+
+ bad.def
+
+ but may contain only headers and sources that compile.
+Call Stack \(most recent call first\):
+ CMakeLists.txt:3 \(include\)
diff --git a/Tests/RunCMake/ObjectLibrary/BadObjSource1.cmake b/Tests/RunCMake/ObjectLibrary/BadObjSource1.cmake
new file mode 100644
index 0000000..aa3514d
--- /dev/null
+++ b/Tests/RunCMake/ObjectLibrary/BadObjSource1.cmake
@@ -0,0 +1 @@
+add_library(A OBJECT a.c bad.def)
diff --git a/Tests/RunCMake/ObjectLibrary/BadObjSource2-result.txt b/Tests/RunCMake/ObjectLibrary/BadObjSource2-result.txt
new file mode 100644
index 0000000..d00491f
--- /dev/null
+++ b/Tests/RunCMake/ObjectLibrary/BadObjSource2-result.txt
@@ -0,0 +1 @@
+1
diff --git a/Tests/RunCMake/ObjectLibrary/BadObjSource2-stderr.txt b/Tests/RunCMake/ObjectLibrary/BadObjSource2-stderr.txt
new file mode 100644
index 0000000..906cf0b
--- /dev/null
+++ b/Tests/RunCMake/ObjectLibrary/BadObjSource2-stderr.txt
@@ -0,0 +1,8 @@
+CMake Error at BadObjSource2.cmake:1 \(add_library\):
+ OBJECT library "A" contains:
+
+ bad.obj
+
+ but may contain only headers and sources that compile.
+Call Stack \(most recent call first\):
+ CMakeLists.txt:3 \(include\)
diff --git a/Tests/RunCMake/ObjectLibrary/BadObjSource2.cmake b/Tests/RunCMake/ObjectLibrary/BadObjSource2.cmake
new file mode 100644
index 0000000..7957c99
--- /dev/null
+++ b/Tests/RunCMake/ObjectLibrary/BadObjSource2.cmake
@@ -0,0 +1 @@
+add_library(A OBJECT a.c bad.obj)
diff --git a/Tests/RunCMake/ObjectLibrary/BadSourceExpression1-result.txt b/Tests/RunCMake/ObjectLibrary/BadSourceExpression1-result.txt
new file mode 100644
index 0000000..d00491f
--- /dev/null
+++ b/Tests/RunCMake/ObjectLibrary/BadSourceExpression1-result.txt
@@ -0,0 +1 @@
+1
diff --git a/Tests/RunCMake/ObjectLibrary/BadSourceExpression1-stderr.txt b/Tests/RunCMake/ObjectLibrary/BadSourceExpression1-stderr.txt
new file mode 100644
index 0000000..a1cac36
--- /dev/null
+++ b/Tests/RunCMake/ObjectLibrary/BadSourceExpression1-stderr.txt
@@ -0,0 +1,6 @@
+CMake Error at BadSourceExpression1.cmake:1 \(add_library\):
+ Unrecognized generator expression:
+
+ \$<BAD_EXPRESSION>
+Call Stack \(most recent call first\):
+ CMakeLists.txt:3 \(include\)
diff --git a/Tests/RunCMake/ObjectLibrary/BadSourceExpression1.cmake b/Tests/RunCMake/ObjectLibrary/BadSourceExpression1.cmake
new file mode 100644
index 0000000..020c9a0
--- /dev/null
+++ b/Tests/RunCMake/ObjectLibrary/BadSourceExpression1.cmake
@@ -0,0 +1 @@
+add_library(A STATIC a.c $<BAD_EXPRESSION>)
diff --git a/Tests/RunCMake/ObjectLibrary/BadSourceExpression2-result.txt b/Tests/RunCMake/ObjectLibrary/BadSourceExpression2-result.txt
new file mode 100644
index 0000000..d00491f
--- /dev/null
+++ b/Tests/RunCMake/ObjectLibrary/BadSourceExpression2-result.txt
@@ -0,0 +1 @@
+1
diff --git a/Tests/RunCMake/ObjectLibrary/BadSourceExpression2-stderr.txt b/Tests/RunCMake/ObjectLibrary/BadSourceExpression2-stderr.txt
new file mode 100644
index 0000000..f1fcbe8
--- /dev/null
+++ b/Tests/RunCMake/ObjectLibrary/BadSourceExpression2-stderr.txt
@@ -0,0 +1,4 @@
+CMake Error at BadSourceExpression2.cmake:1 \(add_library\):
+ Objects of target "DoesNotExist" referenced but no such target exists.
+Call Stack \(most recent call first\):
+ CMakeLists.txt:3 \(include\)
diff --git a/Tests/RunCMake/ObjectLibrary/BadSourceExpression2.cmake b/Tests/RunCMake/ObjectLibrary/BadSourceExpression2.cmake
new file mode 100644
index 0000000..ed5dc43
--- /dev/null
+++ b/Tests/RunCMake/ObjectLibrary/BadSourceExpression2.cmake
@@ -0,0 +1 @@
+add_library(A STATIC a.c $<TARGET_OBJECTS:DoesNotExist>)
diff --git a/Tests/RunCMake/ObjectLibrary/BadSourceExpression3-result.txt b/Tests/RunCMake/ObjectLibrary/BadSourceExpression3-result.txt
new file mode 100644
index 0000000..d00491f
--- /dev/null
+++ b/Tests/RunCMake/ObjectLibrary/BadSourceExpression3-result.txt
@@ -0,0 +1 @@
+1
diff --git a/Tests/RunCMake/ObjectLibrary/BadSourceExpression3-stderr.txt b/Tests/RunCMake/ObjectLibrary/BadSourceExpression3-stderr.txt
new file mode 100644
index 0000000..ad14a35
--- /dev/null
+++ b/Tests/RunCMake/ObjectLibrary/BadSourceExpression3-stderr.txt
@@ -0,0 +1,4 @@
+CMake Error at BadSourceExpression3.cmake:2 \(add_library\):
+ Objects of target "NotObjLib" referenced but is not an OBJECT library.
+Call Stack \(most recent call first\):
+ CMakeLists.txt:3 \(include\)
diff --git a/Tests/RunCMake/ObjectLibrary/BadSourceExpression3.cmake b/Tests/RunCMake/ObjectLibrary/BadSourceExpression3.cmake
new file mode 100644
index 0000000..c3d9a62
--- /dev/null
+++ b/Tests/RunCMake/ObjectLibrary/BadSourceExpression3.cmake
@@ -0,0 +1,2 @@
+add_library(NotObjLib STATIC a.c)
+add_library(A STATIC a.c $<TARGET_OBJECTS:NotObjLib>)
diff --git a/Tests/RunCMake/ObjectLibrary/CMakeLists.txt b/Tests/RunCMake/ObjectLibrary/CMakeLists.txt
new file mode 100644
index 0000000..a7f0779
--- /dev/null
+++ b/Tests/RunCMake/ObjectLibrary/CMakeLists.txt
@@ -0,0 +1,3 @@
+cmake_minimum_required(VERSION 2.8)
+project(${RunCMake_TEST} C)
+include(${RunCMake_TEST}.cmake)
diff --git a/Tests/RunCMake/ObjectLibrary/Export-result.txt b/Tests/RunCMake/ObjectLibrary/Export-result.txt
new file mode 100644
index 0000000..d00491f
--- /dev/null
+++ b/Tests/RunCMake/ObjectLibrary/Export-result.txt
@@ -0,0 +1 @@
+1
diff --git a/Tests/RunCMake/ObjectLibrary/Export-stderr.txt b/Tests/RunCMake/ObjectLibrary/Export-stderr.txt
new file mode 100644
index 0000000..bdadca4
--- /dev/null
+++ b/Tests/RunCMake/ObjectLibrary/Export-stderr.txt
@@ -0,0 +1,4 @@
+CMake Error at Export.cmake:2 \(export\):
+ export given OBJECT library "A" which may not be exported.
+Call Stack \(most recent call first\):
+ CMakeLists.txt:3 \(include\)
diff --git a/Tests/RunCMake/ObjectLibrary/Export.cmake b/Tests/RunCMake/ObjectLibrary/Export.cmake
new file mode 100644
index 0000000..a3f104e
--- /dev/null
+++ b/Tests/RunCMake/ObjectLibrary/Export.cmake
@@ -0,0 +1,2 @@
+add_library(A OBJECT a.c)
+export(TARGETS A FILE AExport.cmake)
diff --git a/Tests/RunCMake/ObjectLibrary/ExportLanguages.cmake b/Tests/RunCMake/ObjectLibrary/ExportLanguages.cmake
new file mode 100644
index 0000000..0796c21
--- /dev/null
+++ b/Tests/RunCMake/ObjectLibrary/ExportLanguages.cmake
@@ -0,0 +1,15 @@
+enable_language(CXX)
+add_library(A OBJECT a.cxx)
+add_library(B STATIC a.c $<TARGET_OBJECTS:A>)
+
+# Verify that object library languages are propagated.
+export(TARGETS B NAMESPACE Exp FILE BExport.cmake)
+include(${CMAKE_CURRENT_BINARY_DIR}/BExport.cmake)
+get_property(configs TARGET ExpB PROPERTY IMPORTED_CONFIGURATIONS)
+foreach(c ${configs})
+ get_property(langs TARGET ExpB PROPERTY IMPORTED_LINK_INTERFACE_LANGUAGES_${c})
+ list(FIND langs CXX pos)
+ if(${pos} LESS 0)
+ message(FATAL_ERROR "Target export does not list object library languages.")
+ endif()
+endforeach()
diff --git a/Tests/RunCMake/ObjectLibrary/Import-result.txt b/Tests/RunCMake/ObjectLibrary/Import-result.txt
new file mode 100644
index 0000000..d00491f
--- /dev/null
+++ b/Tests/RunCMake/ObjectLibrary/Import-result.txt
@@ -0,0 +1 @@
+1
diff --git a/Tests/RunCMake/ObjectLibrary/Import-stderr.txt b/Tests/RunCMake/ObjectLibrary/Import-stderr.txt
new file mode 100644
index 0000000..74b496a
--- /dev/null
+++ b/Tests/RunCMake/ObjectLibrary/Import-stderr.txt
@@ -0,0 +1,4 @@
+CMake Error at Import.cmake:1 \(add_library\):
+ The OBJECT library type may not be used for IMPORTED libraries.
+Call Stack \(most recent call first\):
+ CMakeLists.txt:3 \(include\)
diff --git a/Tests/RunCMake/ObjectLibrary/Import.cmake b/Tests/RunCMake/ObjectLibrary/Import.cmake
new file mode 100644
index 0000000..806b44a
--- /dev/null
+++ b/Tests/RunCMake/ObjectLibrary/Import.cmake
@@ -0,0 +1 @@
+add_library(A OBJECT IMPORTED)
diff --git a/Tests/RunCMake/ObjectLibrary/Install-result.txt b/Tests/RunCMake/ObjectLibrary/Install-result.txt
new file mode 100644
index 0000000..d00491f
--- /dev/null
+++ b/Tests/RunCMake/ObjectLibrary/Install-result.txt
@@ -0,0 +1 @@
+1
diff --git a/Tests/RunCMake/ObjectLibrary/Install-stderr.txt b/Tests/RunCMake/ObjectLibrary/Install-stderr.txt
new file mode 100644
index 0000000..d2f9f4a
--- /dev/null
+++ b/Tests/RunCMake/ObjectLibrary/Install-stderr.txt
@@ -0,0 +1,4 @@
+CMake Error at Install.cmake:2 \(install\):
+ install TARGETS given OBJECT library "A" which may not be installed.
+Call Stack \(most recent call first\):
+ CMakeLists.txt:3 \(include\)
diff --git a/Tests/RunCMake/ObjectLibrary/Install.cmake b/Tests/RunCMake/ObjectLibrary/Install.cmake
new file mode 100644
index 0000000..c1d214b
--- /dev/null
+++ b/Tests/RunCMake/ObjectLibrary/Install.cmake
@@ -0,0 +1,2 @@
+add_library(A OBJECT a.c)
+install(TARGETS A DESTINATION lib)
diff --git a/Tests/RunCMake/ObjectLibrary/LinkObjLHS-result.txt b/Tests/RunCMake/ObjectLibrary/LinkObjLHS-result.txt
new file mode 100644
index 0000000..d00491f
--- /dev/null
+++ b/Tests/RunCMake/ObjectLibrary/LinkObjLHS-result.txt
@@ -0,0 +1 @@
+1
diff --git a/Tests/RunCMake/ObjectLibrary/LinkObjLHS-stderr.txt b/Tests/RunCMake/ObjectLibrary/LinkObjLHS-stderr.txt
new file mode 100644
index 0000000..90e828b
--- /dev/null
+++ b/Tests/RunCMake/ObjectLibrary/LinkObjLHS-stderr.txt
@@ -0,0 +1,4 @@
+CMake Error at LinkObjLHS.cmake:2 \(target_link_libraries\):
+ Object library target "AnObjLib" may not link to anything.
+Call Stack \(most recent call first\):
+ CMakeLists.txt:3 \(include\)
diff --git a/Tests/RunCMake/ObjectLibrary/LinkObjLHS.cmake b/Tests/RunCMake/ObjectLibrary/LinkObjLHS.cmake
new file mode 100644
index 0000000..5d7831a
--- /dev/null
+++ b/Tests/RunCMake/ObjectLibrary/LinkObjLHS.cmake
@@ -0,0 +1,2 @@
+add_library(AnObjLib OBJECT a.c)
+target_link_libraries(AnObjLib OtherLib)
diff --git a/Tests/RunCMake/ObjectLibrary/LinkObjRHS1-result.txt b/Tests/RunCMake/ObjectLibrary/LinkObjRHS1-result.txt
new file mode 100644
index 0000000..d00491f
--- /dev/null
+++ b/Tests/RunCMake/ObjectLibrary/LinkObjRHS1-result.txt
@@ -0,0 +1 @@
+1
diff --git a/Tests/RunCMake/ObjectLibrary/LinkObjRHS1-stderr.txt b/Tests/RunCMake/ObjectLibrary/LinkObjRHS1-stderr.txt
new file mode 100644
index 0000000..8809f89
--- /dev/null
+++ b/Tests/RunCMake/ObjectLibrary/LinkObjRHS1-stderr.txt
@@ -0,0 +1,6 @@
+CMake Error at LinkObjRHS1.cmake:3 \(target_link_libraries\):
+ Target "AnObjLib" of type OBJECT_LIBRARY may not be linked into another
+ target. One may link only to STATIC or SHARED libraries, or to executables
+ with the ENABLE_EXPORTS property set.
+Call Stack \(most recent call first\):
+ CMakeLists.txt:3 \(include\)
diff --git a/Tests/RunCMake/ObjectLibrary/LinkObjRHS1.cmake b/Tests/RunCMake/ObjectLibrary/LinkObjRHS1.cmake
new file mode 100644
index 0000000..113d6a8
--- /dev/null
+++ b/Tests/RunCMake/ObjectLibrary/LinkObjRHS1.cmake
@@ -0,0 +1,3 @@
+add_library(A STATIC a.c)
+add_library(AnObjLib OBJECT a.c)
+target_link_libraries(A AnObjLib)
diff --git a/Tests/RunCMake/ObjectLibrary/LinkObjRHS2-result.txt b/Tests/RunCMake/ObjectLibrary/LinkObjRHS2-result.txt
new file mode 100644
index 0000000..d00491f
--- /dev/null
+++ b/Tests/RunCMake/ObjectLibrary/LinkObjRHS2-result.txt
@@ -0,0 +1 @@
+1
diff --git a/Tests/RunCMake/ObjectLibrary/LinkObjRHS2-stderr.txt b/Tests/RunCMake/ObjectLibrary/LinkObjRHS2-stderr.txt
new file mode 100644
index 0000000..3295fca
--- /dev/null
+++ b/Tests/RunCMake/ObjectLibrary/LinkObjRHS2-stderr.txt
@@ -0,0 +1,6 @@
+CMake Error at LinkObjRHS2.cmake:1 \(add_library\):
+ Target "A" links to OBJECT library "AnObjLib" but this is not allowed. One
+ may link only to STATIC or SHARED libraries, or to executables with the
+ ENABLE_EXPORTS property set.
+Call Stack \(most recent call first\):
+ CMakeLists.txt:3 \(include\)
diff --git a/Tests/RunCMake/ObjectLibrary/LinkObjRHS2.cmake b/Tests/RunCMake/ObjectLibrary/LinkObjRHS2.cmake
new file mode 100644
index 0000000..6163729
--- /dev/null
+++ b/Tests/RunCMake/ObjectLibrary/LinkObjRHS2.cmake
@@ -0,0 +1,3 @@
+add_library(A SHARED a.c)
+target_link_libraries(A AnObjLib)
+add_library(AnObjLib OBJECT a.c)
diff --git a/Tests/RunCMake/ObjectLibrary/ObjWithObj-result.txt b/Tests/RunCMake/ObjectLibrary/ObjWithObj-result.txt
new file mode 100644
index 0000000..d00491f
--- /dev/null
+++ b/Tests/RunCMake/ObjectLibrary/ObjWithObj-result.txt
@@ -0,0 +1 @@
+1
diff --git a/Tests/RunCMake/ObjectLibrary/ObjWithObj-stderr.txt b/Tests/RunCMake/ObjectLibrary/ObjWithObj-stderr.txt
new file mode 100644
index 0000000..d67b4ae
--- /dev/null
+++ b/Tests/RunCMake/ObjectLibrary/ObjWithObj-stderr.txt
@@ -0,0 +1,4 @@
+CMake Error at ObjWithObj.cmake:2 \(add_library\):
+ Only executables and non-OBJECT libraries may reference target objects.
+Call Stack \(most recent call first\):
+ CMakeLists.txt:3 \(include\)
diff --git a/Tests/RunCMake/ObjectLibrary/ObjWithObj.cmake b/Tests/RunCMake/ObjectLibrary/ObjWithObj.cmake
new file mode 100644
index 0000000..d0ef34b
--- /dev/null
+++ b/Tests/RunCMake/ObjectLibrary/ObjWithObj.cmake
@@ -0,0 +1,2 @@
+add_library(A OBJECT a.c)
+add_library(B OBJECT $<TARGET_OBJECTS:A>)
diff --git a/Tests/RunCMake/ObjectLibrary/PostBuild-result.txt b/Tests/RunCMake/ObjectLibrary/PostBuild-result.txt
new file mode 100644
index 0000000..d00491f
--- /dev/null
+++ b/Tests/RunCMake/ObjectLibrary/PostBuild-result.txt
@@ -0,0 +1 @@
+1
diff --git a/Tests/RunCMake/ObjectLibrary/PostBuild-stderr.txt b/Tests/RunCMake/ObjectLibrary/PostBuild-stderr.txt
new file mode 100644
index 0000000..4b067bb
--- /dev/null
+++ b/Tests/RunCMake/ObjectLibrary/PostBuild-stderr.txt
@@ -0,0 +1,5 @@
+CMake Error at PostBuild.cmake:2 \(add_custom_command\):
+ Target "A" is an OBJECT library that may not have PRE_BUILD, PRE_LINK, or
+ POST_BUILD commands.
+Call Stack \(most recent call first\):
+ CMakeLists.txt:3 \(include\)
diff --git a/Tests/RunCMake/ObjectLibrary/PostBuild.cmake b/Tests/RunCMake/ObjectLibrary/PostBuild.cmake
new file mode 100644
index 0000000..dea9a09
--- /dev/null
+++ b/Tests/RunCMake/ObjectLibrary/PostBuild.cmake
@@ -0,0 +1,4 @@
+add_library(A OBJECT a.c)
+add_custom_command(TARGET A POST_BUILD
+ COMMAND ${CMAKE_COMMAND} -E echo "A post-build"
+ )
diff --git a/Tests/RunCMake/ObjectLibrary/PreBuild-result.txt b/Tests/RunCMake/ObjectLibrary/PreBuild-result.txt
new file mode 100644
index 0000000..d00491f
--- /dev/null
+++ b/Tests/RunCMake/ObjectLibrary/PreBuild-result.txt
@@ -0,0 +1 @@
+1
diff --git a/Tests/RunCMake/ObjectLibrary/PreBuild-stderr.txt b/Tests/RunCMake/ObjectLibrary/PreBuild-stderr.txt
new file mode 100644
index 0000000..3b27a6d
--- /dev/null
+++ b/Tests/RunCMake/ObjectLibrary/PreBuild-stderr.txt
@@ -0,0 +1,5 @@
+CMake Error at PreBuild.cmake:2 \(add_custom_command\):
+ Target "A" is an OBJECT library that may not have PRE_BUILD, PRE_LINK, or
+ POST_BUILD commands.
+Call Stack \(most recent call first\):
+ CMakeLists.txt:3 \(include\)
diff --git a/Tests/RunCMake/ObjectLibrary/PreBuild.cmake b/Tests/RunCMake/ObjectLibrary/PreBuild.cmake
new file mode 100644
index 0000000..e4424c1
--- /dev/null
+++ b/Tests/RunCMake/ObjectLibrary/PreBuild.cmake
@@ -0,0 +1,4 @@
+add_library(A OBJECT a.c)
+add_custom_command(TARGET A PRE_BUILD
+ COMMAND ${CMAKE_COMMAND} -E echo "A pre-build"
+ )
diff --git a/Tests/RunCMake/ObjectLibrary/PreLink-result.txt b/Tests/RunCMake/ObjectLibrary/PreLink-result.txt
new file mode 100644
index 0000000..d00491f
--- /dev/null
+++ b/Tests/RunCMake/ObjectLibrary/PreLink-result.txt
@@ -0,0 +1 @@
+1
diff --git a/Tests/RunCMake/ObjectLibrary/PreLink-stderr.txt b/Tests/RunCMake/ObjectLibrary/PreLink-stderr.txt
new file mode 100644
index 0000000..947b9f1
--- /dev/null
+++ b/Tests/RunCMake/ObjectLibrary/PreLink-stderr.txt
@@ -0,0 +1,5 @@
+CMake Error at PreLink.cmake:2 \(add_custom_command\):
+ Target "A" is an OBJECT library that may not have PRE_BUILD, PRE_LINK, or
+ POST_BUILD commands.
+Call Stack \(most recent call first\):
+ CMakeLists.txt:3 \(include\)
diff --git a/Tests/RunCMake/ObjectLibrary/PreLink.cmake b/Tests/RunCMake/ObjectLibrary/PreLink.cmake
new file mode 100644
index 0000000..b889055
--- /dev/null
+++ b/Tests/RunCMake/ObjectLibrary/PreLink.cmake
@@ -0,0 +1,4 @@
+add_library(A OBJECT a.c)
+add_custom_command(TARGET A PRE_LINK
+ COMMAND ${CMAKE_COMMAND} -E echo "A pre-link"
+ )
diff --git a/Tests/RunCMake/ObjectLibrary/RunCMakeTest.cmake b/Tests/RunCMake/ObjectLibrary/RunCMakeTest.cmake
new file mode 100644
index 0000000..55db14d
--- /dev/null
+++ b/Tests/RunCMake/ObjectLibrary/RunCMakeTest.cmake
@@ -0,0 +1,18 @@
+include(RunCMake)
+
+run_cmake(BadSourceExpression1)
+run_cmake(BadSourceExpression2)
+run_cmake(BadSourceExpression3)
+run_cmake(BadObjSource1)
+run_cmake(BadObjSource2)
+run_cmake(Export)
+run_cmake(ExportLanguages)
+run_cmake(Import)
+run_cmake(Install)
+run_cmake(LinkObjLHS)
+run_cmake(LinkObjRHS1)
+run_cmake(LinkObjRHS2)
+run_cmake(ObjWithObj)
+run_cmake(PostBuild)
+run_cmake(PreBuild)
+run_cmake(PreLink)
diff --git a/Tests/RunCMake/ObjectLibrary/a.c b/Tests/RunCMake/ObjectLibrary/a.c
new file mode 100644
index 0000000..af20d3f
--- /dev/null
+++ b/Tests/RunCMake/ObjectLibrary/a.c
@@ -0,0 +1 @@
+int a(void) { return 0; }
diff --git a/Tests/RunCMake/ObjectLibrary/a.cxx b/Tests/RunCMake/ObjectLibrary/a.cxx
new file mode 100644
index 0000000..ae9c87c
--- /dev/null
+++ b/Tests/RunCMake/ObjectLibrary/a.cxx
@@ -0,0 +1 @@
+extern "C" int acxx(void) { return 0; }
diff --git a/Tests/RunCMake/ObjectLibrary/bad.def b/Tests/RunCMake/ObjectLibrary/bad.def
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/Tests/RunCMake/ObjectLibrary/bad.def
diff --git a/Tests/RunCMake/ObjectLibrary/bad.obj b/Tests/RunCMake/ObjectLibrary/bad.obj
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/Tests/RunCMake/ObjectLibrary/bad.obj
diff --git a/Tests/RunCMake/find_package/ComponentRequiredAndOptional-result.txt b/Tests/RunCMake/find_package/ComponentRequiredAndOptional-result.txt
new file mode 100644
index 0000000..d00491f
--- /dev/null
+++ b/Tests/RunCMake/find_package/ComponentRequiredAndOptional-result.txt
@@ -0,0 +1 @@
+1
diff --git a/Tests/RunCMake/find_package/ComponentRequiredAndOptional-stderr.txt b/Tests/RunCMake/find_package/ComponentRequiredAndOptional-stderr.txt
new file mode 100644
index 0000000..db8f512
--- /dev/null
+++ b/Tests/RunCMake/find_package/ComponentRequiredAndOptional-stderr.txt
@@ -0,0 +1,8 @@
+CMake Error at ComponentRequiredAndOptional.cmake:1 \(find_package\):
+ find_package called with components that are both required and optional:
+
+ CompA
+ CompB
+
+Call Stack \(most recent call first\):
+ CMakeLists.txt:3 \(include\)
diff --git a/Tests/RunCMake/find_package/ComponentRequiredAndOptional.cmake b/Tests/RunCMake/find_package/ComponentRequiredAndOptional.cmake
new file mode 100644
index 0000000..0355f5a
--- /dev/null
+++ b/Tests/RunCMake/find_package/ComponentRequiredAndOptional.cmake
@@ -0,0 +1 @@
+find_package(NotHere REQUIRED CompA CompB CompC OPTIONAL_COMPONENTS CompA CompB CompD)
diff --git a/Tests/RunCMake/find_package/RunCMakeTest.cmake b/Tests/RunCMake/find_package/RunCMakeTest.cmake
index ba57f99..42705b7 100644
--- a/Tests/RunCMake/find_package/RunCMakeTest.cmake
+++ b/Tests/RunCMake/find_package/RunCMakeTest.cmake
@@ -1,5 +1,6 @@
include(RunCMake)
+run_cmake(ComponentRequiredAndOptional)
run_cmake(MissingNormal)
run_cmake(MissingNormalRequired)
run_cmake(MissingNormalVersion)
@@ -12,3 +13,4 @@ run_cmake(MissingConfigOneName)
run_cmake(MissingConfigRequired)
run_cmake(MissingConfigVersion)
run_cmake(MixedModeOptions)
+run_cmake(SetFoundFALSE)
diff --git a/Tests/RunCMake/find_package/SetFoundFALSE-stderr.txt b/Tests/RunCMake/find_package/SetFoundFALSE-stderr.txt
new file mode 100644
index 0000000..695f645
--- /dev/null
+++ b/Tests/RunCMake/find_package/SetFoundFALSE-stderr.txt
@@ -0,0 +1,9 @@
+CMake Warning at SetFoundFALSE.cmake:2 \(find_package\):
+ Found package configuration file:
+
+ .*/Tests/RunCMake/find_package/SetFoundFALSEConfig.cmake
+
+ but it set SetFoundFALSE_FOUND to FALSE so package "SetFoundFALSE" is
+ considered to be NOT FOUND.
+Call Stack \(most recent call first\):
+ CMakeLists.txt:3 \(include\)
diff --git a/Tests/RunCMake/find_package/SetFoundFALSE.cmake b/Tests/RunCMake/find_package/SetFoundFALSE.cmake
new file mode 100644
index 0000000..fbcec3c
--- /dev/null
+++ b/Tests/RunCMake/find_package/SetFoundFALSE.cmake
@@ -0,0 +1,2 @@
+set(SetFoundFALSE_DIR "${CMAKE_CURRENT_SOURCE_DIR}")
+find_package(SetFoundFALSE CONFIG)
diff --git a/Tests/RunCMake/find_package/SetFoundFALSEConfig.cmake b/Tests/RunCMake/find_package/SetFoundFALSEConfig.cmake
new file mode 100644
index 0000000..ae6bd14
--- /dev/null
+++ b/Tests/RunCMake/find_package/SetFoundFALSEConfig.cmake
@@ -0,0 +1 @@
+set(SetFoundFALSE_FOUND FALSE)
diff --git a/Utilities/KWIML/test/test_INT_format.h.in b/Utilities/KWIML/test/test_INT_format.h.in
index a8ea263..71b443d 100644
--- a/Utilities/KWIML/test/test_INT_format.h.in
+++ b/Utilities/KWIML/test/test_INT_format.h.in
@@ -25,8 +25,8 @@
T const x = VALUE(T, U); \
T y = C(V); \
printf(LANG #C ":" \
- " expression [%"@KWIML@_INT_PRI##PRI"]," \
- " literal [%"@KWIML@_INT_PRI##PRI"]", x, y); \
+ " expression [%" @KWIML@_INT_PRI##PRI "]," \
+ " literal [%" @KWIML@_INT_PRI##PRI "]", x, y); \
if(x == y) \
{ \
printf(", PASSED\n"); \
@@ -42,7 +42,7 @@
{ \
T const x = VALUE(T, U); \
char const* str = STR; \
- sprintf(buf, "%"@KWIML@_INT_PRI##PRI, x); \
+ sprintf(buf, "%" @KWIML@_INT_PRI##PRI, x); \
printf(LANG "@KWIML@_INT_PRI" #PRI ":" \
" expected [%s], got [%s]", str, buf); \
if(strcmp(str, buf) == 0) \
@@ -62,13 +62,13 @@
T const x = VALUE(T, U); \
T y; \
char const* str = STR; \
- if(sscanf(str, "%"@KWIML@_INT_SCN##SCN, &y) != 1) \
+ if(sscanf(str, "%" @KWIML@_INT_SCN##SCN, &y) != 1) \
{ \
y = 0; \
} \
printf(LANG "@KWIML@_INT_SCN" #SCN ":" \
- " expected [%"@KWIML@_INT_PRI##PRI"]," \
- " got [%"@KWIML@_INT_PRI##PRI"]", x, y); \
+ " expected [%" @KWIML@_INT_PRI##PRI "]," \
+ " got [%" @KWIML@_INT_PRI##PRI "]", x, y); \
if(x == y) \
{ \
printf(", PASSED\n"); \
diff --git a/bootstrap b/bootstrap
index 665c6c5..3be3d1f 100755
--- a/bootstrap
+++ b/bootstrap
@@ -208,6 +208,7 @@ CMAKE_CXX_SOURCES="\
cmExportInstallFileGenerator \
cmInstallDirectoryGenerator \
cmGeneratedFileStream \
+ cmGeneratorTarget \
cmGeneratorExpression \
cmGlobalGenerator \
cmLocalGenerator \