summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--.hooks-config (renamed from .hooks-config.bash)7
-rw-r--r--Help/command/add_library.rst2
-rw-r--r--Help/command/install.rst6
-rw-r--r--Help/manual/cmake-developer.7.rst2
-rw-r--r--Help/manual/cmake-packages.7.rst4
-rw-r--r--Help/prop_tgt/FRAMEWORK.rst4
-rw-r--r--Help/release/dev/static-frameworks.rst6
-rw-r--r--Modules/CompilerId/VS-10.csproj.in8
-rw-r--r--Modules/FindBoost.cmake2
-rw-r--r--Source/CMakeVersion.cmake2
-rw-r--r--Source/cmGeneratorTarget.cxx3
-rw-r--r--Source/cmGlobalVisualStudioGenerator.cxx8
-rw-r--r--Source/cmGlobalXCodeGenerator.cxx39
-rw-r--r--Source/cmInstallCommand.cxx42
-rw-r--r--Source/cmMakefileLibraryTargetGenerator.cxx35
-rw-r--r--Source/cmTarget.cxx3
-rw-r--r--Tests/CMakeTests/File-TIMESTAMP-NotBogus.cmake1
-rw-r--r--Tests/CTestTestStopTime/GetDate.cmake1
-rw-r--r--Tests/Framework/CMakeLists.txt47
-rw-r--r--Tests/RunCMake/CMakeLists.txt3
-rw-r--r--Tests/RunCMake/Framework/FrameworkLayout.cmake5
-rw-r--r--Tests/RunCMake/Framework/FrameworkTypeSHARED-build-stdout.txt1
-rw-r--r--Tests/RunCMake/Framework/FrameworkTypeSTATIC-build-stdout.txt1
-rw-r--r--Tests/RunCMake/Framework/RunCMakeTest.cmake69
-rw-r--r--Tests/RunCMake/RunCMake.cmake2
-rw-r--r--Tests/RunCMake/XcodeProject/XcodeBundles.cmake52
-rw-r--r--Utilities/.gitattributes1
-rwxr-xr-xUtilities/Git/pre-commit13
-rw-r--r--Utilities/GitSetup/.gitattributes5
-rw-r--r--Utilities/GitSetup/README7
-rw-r--r--Utilities/GitSetup/config.sample10
-rwxr-xr-xUtilities/GitSetup/git-gerrit-push74
-rwxr-xr-xUtilities/GitSetup/git-gitlab-push177
-rwxr-xr-xUtilities/GitSetup/setup-gerrit15
-rwxr-xr-xUtilities/GitSetup/setup-gitlab140
-rwxr-xr-xUtilities/GitSetup/setup-hooks1
-rwxr-xr-xUtilities/GitSetup/setup-stage9
-rwxr-xr-xUtilities/GitSetup/setup-upstream104
-rwxr-xr-xUtilities/Scripts/update-gitsetup.bash20
-rwxr-xr-xUtilities/SetupForDevelopment.sh4
40 files changed, 803 insertions, 132 deletions
diff --git a/.hooks-config.bash b/.hooks-config
index ea9342a..064371c 100644
--- a/.hooks-config.bash
+++ b/.hooks-config
@@ -4,6 +4,7 @@
# Loaded by .git/hooks/(pre-commit|commit-msg|prepare-commit-msg)
# during git commit after local hooks have been installed.
-hooks_chain_pre_commit="Utilities/Git/pre-commit"
-hooks_chain_commit_msg="Utilities/Git/commit-msg"
-hooks_chain_prepare_commit_msg="Utilities/Git/prepare-commit-msg"
+[hooks "chain"]
+ pre-commit = Utilities/Git/pre-commit
+ commit-msg = Utilities/Git/commit-msg
+ prepare-commit-msg = Utilities/Git/prepare-commit-msg
diff --git a/Help/command/add_library.rst b/Help/command/add_library.rst
index 36adcbe..af75a39 100644
--- a/Help/command/add_library.rst
+++ b/Help/command/add_library.rst
@@ -33,7 +33,7 @@ type is ``STATIC`` or ``SHARED`` based on whether the current value of the
variable :variable:`BUILD_SHARED_LIBS` is ``ON``. For ``SHARED`` and
``MODULE`` libraries the :prop_tgt:`POSITION_INDEPENDENT_CODE` target
property is set to ``ON`` automatically.
-A ``SHARED`` library may be marked with the :prop_tgt:`FRAMEWORK`
+A ``SHARED`` or ``STATIC`` library may be marked with the :prop_tgt:`FRAMEWORK`
target property to create an OS X Framework.
If a library does not export any symbols, it must not be declared as a
diff --git a/Help/command/install.rst b/Help/command/install.rst
index d57dd75..70087a4 100644
--- a/Help/command/install.rst
+++ b/Help/command/install.rst
@@ -90,8 +90,10 @@ project. There are five kinds of target files that may be installed:
``ARCHIVE``, ``LIBRARY``, ``RUNTIME``, ``FRAMEWORK``, and ``BUNDLE``.
Executables are treated as ``RUNTIME`` targets, except that those
marked with the ``MACOSX_BUNDLE`` property are treated as ``BUNDLE``
-targets on OS X. Static libraries are always treated as ``ARCHIVE``
-targets. Module libraries are always treated as ``LIBRARY`` targets.
+targets on OS X. Static libraries are treated as ``ARCHIVE`` targets,
+except that those marked with the ``FRAMEWORK`` property are treated
+as ``FRAMEWORK`` targets on OS X.
+Module libraries are always treated as ``LIBRARY`` targets.
For non-DLL platforms shared libraries are treated as ``LIBRARY``
targets, except that those marked with the ``FRAMEWORK`` property are
treated as ``FRAMEWORK`` targets on OS X. For DLL platforms the DLL
diff --git a/Help/manual/cmake-developer.7.rst b/Help/manual/cmake-developer.7.rst
index 6557686..46b922b 100644
--- a/Help/manual/cmake-developer.7.rst
+++ b/Help/manual/cmake-developer.7.rst
@@ -11,7 +11,7 @@ Introduction
============
This manual is intended for reference by developers modifying the CMake
-source tree itself.
+source tree itself, and by those authoring externally-maintained modules.
Permitted C++ Subset
diff --git a/Help/manual/cmake-packages.7.rst b/Help/manual/cmake-packages.7.rst
index c27c612..c9442bc 100644
--- a/Help/manual/cmake-packages.7.rst
+++ b/Help/manual/cmake-packages.7.rst
@@ -449,12 +449,12 @@ be true. This can be tested with logic in the package configuration file:
foreach(_comp ${ClimbingStats_FIND_COMPONENTS})
if (NOT ";${_supported_components};" MATCHES _comp)
set(ClimbingStats_FOUND False)
- set(ClimbingStats_NOTFOUND_MESSAGE "Unsupported component: ${_comp}")
+ set(ClimbingStats_NOT_FOUND_MESSAGE "Unsupported component: ${_comp}")
endif()
include("${CMAKE_CURRENT_LIST_DIR}/ClimbingStats${_comp}Targets.cmake")
endforeach()
-Here, the ``ClimbingStats_NOTFOUND_MESSAGE`` is set to a diagnosis that the package
+Here, the ``ClimbingStats_NOT_FOUND_MESSAGE`` is set to a diagnosis that the package
could not be found because an invalid component was specified. This message
variable can be set for any case where the ``_FOUND`` variable is set to ``False``,
and will be displayed to the user.
diff --git a/Help/prop_tgt/FRAMEWORK.rst b/Help/prop_tgt/FRAMEWORK.rst
index 8120c36..495d30e 100644
--- a/Help/prop_tgt/FRAMEWORK.rst
+++ b/Help/prop_tgt/FRAMEWORK.rst
@@ -1,9 +1,9 @@
FRAMEWORK
---------
-Build ``SHARED`` library as Framework Bundle on the OS X and iOS.
+Build ``SHARED`` or ``STATIC`` library as Framework Bundle on the OS X and iOS.
-If a ``SHARED`` library target has this property set to ``TRUE`` it will be
+If such a library target has this property set to ``TRUE`` it will be
built as a framework when built on the OS X and iOS. It will have the
directory structure required for a framework and will be suitable to
be used with the ``-framework`` option
diff --git a/Help/release/dev/static-frameworks.rst b/Help/release/dev/static-frameworks.rst
new file mode 100644
index 0000000..eae80bd
--- /dev/null
+++ b/Help/release/dev/static-frameworks.rst
@@ -0,0 +1,6 @@
+static-frameworks
+-----------------
+
+* The :prop_tgt:`FRAMEWORK` property could now also be applied to
+ static libraries on Apple targets. It will result in a proper
+ Framework but with a static library inside.
diff --git a/Modules/CompilerId/VS-10.csproj.in b/Modules/CompilerId/VS-10.csproj.in
index 833dca7..ed5e847 100644
--- a/Modules/CompilerId/VS-10.csproj.in
+++ b/Modules/CompilerId/VS-10.csproj.in
@@ -47,9 +47,9 @@
</ItemGroup>
<Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" />
<PropertyGroup>
- <PostBuildEvent>cd /D &quot;$(MSBuildToolsPath)&quot;
-if not %errorlevel%==0 exit -1
-if not exist @id_cl@ exit -2
-%40echo CMAKE_@id_lang@_COMPILER=$(MSBuildToolsPath)\@id_cl@</PostBuildEvent>
+ <PostBuildEvent>if not "$(RoslynTargetsPath)"=="" if exist "$(RoslynTargetsPath)\@id_cl@" set _CSC=$(RoslynTargetsPath)
+if exist "$(MSBuildToolsPath)\@id_cl@" set _CSC=$(MSBuildToolsPath)
+if "%_CSC%"=="" exit -1
+%40echo CMAKE_@id_lang@_COMPILER=%_CSC%\@id_cl@</PostBuildEvent>
</PropertyGroup>
</Project>
diff --git a/Modules/FindBoost.cmake b/Modules/FindBoost.cmake
index 266d135..e795aad 100644
--- a/Modules/FindBoost.cmake
+++ b/Modules/FindBoost.cmake
@@ -1463,7 +1463,7 @@ if(NOT _Boost_THREAD_DEPENDENCY_LIBS EQUAL -1)
endif()
# If the user changed any of our control inputs flush previous results.
-if(_Boost_CHANGE_LIBDIR OR _Boost_CHANGE_LIBNAME)
+if(_Boost_CHANGE_LIBDIR_DEBUG OR _Boost_CHANGE_LIBDIR_RELEASE OR _Boost_CHANGE_LIBNAME)
foreach(COMPONENT ${_Boost_COMPONENTS_SEARCHED})
string(TOUPPER ${COMPONENT} UPPERCOMPONENT)
foreach(c DEBUG RELEASE)
diff --git a/Source/CMakeVersion.cmake b/Source/CMakeVersion.cmake
index 8621bdf..6a3dae3 100644
--- a/Source/CMakeVersion.cmake
+++ b/Source/CMakeVersion.cmake
@@ -1,5 +1,5 @@
# CMake version number components.
set(CMake_VERSION_MAJOR 3)
set(CMake_VERSION_MINOR 7)
-set(CMake_VERSION_PATCH 20170131)
+set(CMake_VERSION_PATCH 20170201)
#set(CMake_VERSION_RC 1)
diff --git a/Source/cmGeneratorTarget.cxx b/Source/cmGeneratorTarget.cxx
index dcf3764..6ce8140 100644
--- a/Source/cmGeneratorTarget.cxx
+++ b/Source/cmGeneratorTarget.cxx
@@ -5308,7 +5308,8 @@ bool cmGeneratorTarget::IsLinkable() const
bool cmGeneratorTarget::IsFrameworkOnApple() const
{
- return (this->GetType() == cmStateEnums::SHARED_LIBRARY &&
+ return ((this->GetType() == cmStateEnums::SHARED_LIBRARY ||
+ this->GetType() == cmStateEnums::STATIC_LIBRARY) &&
this->Makefile->IsOn("APPLE") &&
this->GetPropertyAsBool("FRAMEWORK"));
}
diff --git a/Source/cmGlobalVisualStudioGenerator.cxx b/Source/cmGlobalVisualStudioGenerator.cxx
index 5edb81f..cc2536c 100644
--- a/Source/cmGlobalVisualStudioGenerator.cxx
+++ b/Source/cmGlobalVisualStudioGenerator.cxx
@@ -856,6 +856,14 @@ void cmGlobalVisualStudioGenerator::AddSymbolExportCommand(
std::string objFile = obj_dir + map_it->second;
objs.push_back(objFile);
}
+ std::vector<cmSourceFile const*> externalObjectSources;
+ gt->GetExternalObjects(externalObjectSources, configName);
+ for (std::vector<cmSourceFile const*>::const_iterator it =
+ externalObjectSources.begin();
+ it != externalObjectSources.end(); ++it) {
+ objs.push_back((*it)->GetFullPath());
+ }
+
gt->UseObjectLibraries(objs, configName);
for (std::vector<std::string>::iterator it = objs.begin(); it != objs.end();
++it) {
diff --git a/Source/cmGlobalXCodeGenerator.cxx b/Source/cmGlobalXCodeGenerator.cxx
index d448315..8627cf2 100644
--- a/Source/cmGlobalXCodeGenerator.cxx
+++ b/Source/cmGlobalXCodeGenerator.cxx
@@ -1816,8 +1816,34 @@ void cmGlobalXCodeGenerator::CreateBuildSettings(cmGeneratorTarget* gtgt,
// Handle settings for each target type.
switch (gtgt->GetType()) {
- case cmStateEnums::OBJECT_LIBRARY:
- case cmStateEnums::STATIC_LIBRARY: {
+ case cmStateEnums::STATIC_LIBRARY:
+ if (gtgt->GetPropertyAsBool("FRAMEWORK")) {
+ std::string fw_version = gtgt->GetFrameworkVersion();
+ buildSettings->AddAttribute("FRAMEWORK_VERSION",
+ this->CreateString(fw_version));
+ const char* ext = gtgt->GetProperty("BUNDLE_EXTENSION");
+ if (ext) {
+ buildSettings->AddAttribute("WRAPPER_EXTENSION",
+ this->CreateString(ext));
+ }
+
+ std::string plist = this->ComputeInfoPListLocation(gtgt);
+ // Xcode will create the final version of Info.plist at build time,
+ // so let it replace the framework name. This avoids creating
+ // a per-configuration Info.plist file.
+ this->CurrentLocalGenerator->GenerateFrameworkInfoPList(
+ gtgt, "$(EXECUTABLE_NAME)", plist.c_str());
+ buildSettings->AddAttribute("INFOPLIST_FILE",
+ this->CreateString(plist));
+ buildSettings->AddAttribute("MACH_O_TYPE",
+ this->CreateString("staticlib"));
+ } else {
+ buildSettings->AddAttribute("LIBRARY_STYLE",
+ this->CreateString("STATIC"));
+ }
+ break;
+
+ case cmStateEnums::OBJECT_LIBRARY: {
buildSettings->AddAttribute("LIBRARY_STYLE",
this->CreateString("STATIC"));
break;
@@ -2336,8 +2362,10 @@ const char* cmGlobalXCodeGenerator::GetTargetFileType(
switch (target->GetType()) {
case cmStateEnums::OBJECT_LIBRARY:
- case cmStateEnums::STATIC_LIBRARY:
return "archive.ar";
+ case cmStateEnums::STATIC_LIBRARY:
+ return (target->GetPropertyAsBool("FRAMEWORK") ? "wrapper.framework"
+ : "archive.ar");
case cmStateEnums::MODULE_LIBRARY:
if (target->IsXCTestOnApple())
return "wrapper.cfbundle";
@@ -2367,8 +2395,11 @@ const char* cmGlobalXCodeGenerator::GetTargetProductType(
switch (target->GetType()) {
case cmStateEnums::OBJECT_LIBRARY:
- case cmStateEnums::STATIC_LIBRARY:
return "com.apple.product-type.library.static";
+ case cmStateEnums::STATIC_LIBRARY:
+ return (target->GetPropertyAsBool("FRAMEWORK")
+ ? "com.apple.product-type.framework"
+ : "com.apple.product-type.library.static");
case cmStateEnums::MODULE_LIBRARY:
if (target->IsXCTestOnApple())
return "com.apple.product-type.bundle.unit-test";
diff --git a/Source/cmInstallCommand.cxx b/Source/cmInstallCommand.cxx
index fadebb4..4c331c7 100644
--- a/Source/cmInstallCommand.cxx
+++ b/Source/cmInstallCommand.cxx
@@ -471,17 +471,39 @@ bool cmInstallCommand::HandleTargetsMode(std::vector<std::string> const& args)
}
} break;
case cmStateEnums::STATIC_LIBRARY: {
- // Static libraries use ARCHIVE properties.
- if (!archiveArgs.GetDestination().empty()) {
- archiveGenerator =
- CreateInstallTargetGenerator(target, archiveArgs, false);
+ // If it is marked with FRAMEWORK property use the FRAMEWORK set of
+ // INSTALL properties. Otherwise, use the LIBRARY properties.
+ if (target.IsFrameworkOnApple()) {
+ // When in namelink only mode skip frameworks.
+ if (namelinkMode == cmInstallTargetGenerator::NamelinkModeOnly) {
+ continue;
+ }
+
+ // Use the FRAMEWORK properties.
+ if (!frameworkArgs.GetDestination().empty()) {
+ frameworkGenerator =
+ CreateInstallTargetGenerator(target, frameworkArgs, false);
+ } else {
+ std::ostringstream e;
+ e << "TARGETS given no FRAMEWORK DESTINATION for static library "
+ "FRAMEWORK target \""
+ << target.GetName() << "\".";
+ this->SetError(e.str());
+ return false;
+ }
} else {
- std::ostringstream e;
- e << "TARGETS given no ARCHIVE DESTINATION for static library "
- "target \""
- << target.GetName() << "\".";
- this->SetError(e.str());
- return false;
+ // Static libraries use ARCHIVE properties.
+ if (!archiveArgs.GetDestination().empty()) {
+ archiveGenerator =
+ CreateInstallTargetGenerator(target, archiveArgs, false);
+ } else {
+ std::ostringstream e;
+ e << "TARGETS given no ARCHIVE DESTINATION for static library "
+ "target \""
+ << target.GetName() << "\".";
+ this->SetError(e.str());
+ return false;
+ }
}
} break;
case cmStateEnums::MODULE_LIBRARY: {
diff --git a/Source/cmMakefileLibraryTargetGenerator.cxx b/Source/cmMakefileLibraryTargetGenerator.cxx
index 27b7c21..ff8b604 100644
--- a/Source/cmMakefileLibraryTargetGenerator.cxx
+++ b/Source/cmMakefileLibraryTargetGenerator.cxx
@@ -597,12 +597,26 @@ void cmMakefileLibraryTargetGenerator::WriteLibraryRules(
// Clean files associated with this library.
std::vector<std::string> libCleanFiles;
libCleanFiles.push_back(this->LocalGenerator->MaybeConvertToRelativePath(
- this->LocalGenerator->GetCurrentBinaryDirectory(), targetFullPath));
- if (targetNameReal != targetName) {
+ this->LocalGenerator->GetCurrentBinaryDirectory(), targetFullPathReal));
+
+ std::vector<std::string> commands1;
+ // Add a command to remove any existing files for this library.
+ // for static libs only
+ if (this->GeneratorTarget->GetType() == cmStateEnums::STATIC_LIBRARY) {
+ this->LocalGenerator->AppendCleanCommand(commands1, libCleanFiles,
+ this->GeneratorTarget, "target");
+ this->LocalGenerator->CreateCDCommand(
+ commands1, this->Makefile->GetCurrentBinaryDirectory(),
+ this->LocalGenerator->GetBinaryDirectory());
+ commands.insert(commands.end(), commands1.begin(), commands1.end());
+ commands1.clear();
+ }
+
+ if (targetName != targetNameReal) {
libCleanFiles.push_back(this->LocalGenerator->MaybeConvertToRelativePath(
- this->LocalGenerator->GetCurrentBinaryDirectory(), targetFullPathReal));
+ this->LocalGenerator->GetCurrentBinaryDirectory(), targetFullPath));
}
- if (targetNameSO != targetName && targetNameSO != targetNameReal) {
+ if (targetNameSO != targetNameReal && targetNameSO != targetName) {
libCleanFiles.push_back(this->LocalGenerator->MaybeConvertToRelativePath(
this->LocalGenerator->GetCurrentBinaryDirectory(), targetFullPathSO));
}
@@ -634,19 +648,6 @@ void cmMakefileLibraryTargetGenerator::WriteLibraryRules(
}
#endif
- std::vector<std::string> commands1;
- // Add a command to remove any existing files for this library.
- // for static libs only
- if (this->GeneratorTarget->GetType() == cmStateEnums::STATIC_LIBRARY) {
- this->LocalGenerator->AppendCleanCommand(commands1, libCleanFiles,
- this->GeneratorTarget, "target");
- this->LocalGenerator->CreateCDCommand(
- commands1, this->Makefile->GetCurrentBinaryDirectory(),
- this->LocalGenerator->GetBinaryDirectory());
- commands.insert(commands.end(), commands1.begin(), commands1.end());
- commands1.clear();
- }
-
// Add the pre-build and pre-link rules building but not when relinking.
if (!relink) {
this->LocalGenerator->AppendCustomCommands(
diff --git a/Source/cmTarget.cxx b/Source/cmTarget.cxx
index 8c62c48..fe3472d 100644
--- a/Source/cmTarget.cxx
+++ b/Source/cmTarget.cxx
@@ -451,7 +451,8 @@ bool cmTarget::HasImportLibrary() const
bool cmTarget::IsFrameworkOnApple() const
{
- return (this->GetType() == cmStateEnums::SHARED_LIBRARY &&
+ return ((this->GetType() == cmStateEnums::SHARED_LIBRARY ||
+ this->GetType() == cmStateEnums::STATIC_LIBRARY) &&
this->Makefile->IsOn("APPLE") &&
this->GetPropertyAsBool("FRAMEWORK"));
}
diff --git a/Tests/CMakeTests/File-TIMESTAMP-NotBogus.cmake b/Tests/CMakeTests/File-TIMESTAMP-NotBogus.cmake
index d0e5fe3..f1aa390 100644
--- a/Tests/CMakeTests/File-TIMESTAMP-NotBogus.cmake
+++ b/Tests/CMakeTests/File-TIMESTAMP-NotBogus.cmake
@@ -1,6 +1,7 @@
set(STAMP_FILENAME "${CMAKE_CURRENT_BINARY_DIR}/FileTimestamp-Stamp")
set(STAMP_FORMAT "%Y-%m-%d")
+unset(ENV{SOURCE_DATE_EPOCH})
string(TIMESTAMP timestamp1 "${STAMP_FORMAT}")
file(WRITE "${STAMP_FILENAME}" "foo")
diff --git a/Tests/CTestTestStopTime/GetDate.cmake b/Tests/CTestTestStopTime/GetDate.cmake
index 1f4cb24..46ab2fb 100644
--- a/Tests/CTestTestStopTime/GetDate.cmake
+++ b/Tests/CTestTestStopTime/GetDate.cmake
@@ -49,6 +49,7 @@ macro(GET_DATE)
# 01/12/2006 08:55:12
# mm/dd/YYYY HH:MM:SS
#
+ unset(ENV{SOURCE_DATE_EPOCH})
string(TIMESTAMP "${GD_PREFIX}OV" "%m/%d/%Y %H:%M:%S")
if(${GD_PREFIX}VERBOSE)
diff --git a/Tests/Framework/CMakeLists.txt b/Tests/Framework/CMakeLists.txt
index 271aaf1..a313c2c 100644
--- a/Tests/Framework/CMakeLists.txt
+++ b/Tests/Framework/CMakeLists.txt
@@ -57,29 +57,30 @@ add_custom_target(fooCustom ALL COMMAND ${CMAKE_COMMAND} -E copy foo-post-build
add_dependencies(fooCustom foo)
# Make a static library and apply the framework properties to it to verify
-# that everything still builds correctly, but it will not actually produce
-# a framework... The framework properties only apply when the library type
-# is SHARED.
+# that everything still builds correctly. Xcode prior to version 5 does not
+# support static Frameworks.
#
-add_library(fooStatic STATIC
- foo.cxx
- foo.h
- foo2.h
- fooExtensionlessResource
- fooPublic.h
- fooPublicExtensionlessHeader
- fooPrivate.h
- fooPrivateExtensionlessHeader
- fooNeither.h
- fooBoth.h
- test.lua
- fooDeepPublic.h
-)
-set_target_properties(fooStatic PROPERTIES
- FRAMEWORK TRUE
- FRAMEWORK_VERSION none
-)
-add_executable(barStatic bar.cxx)
-target_link_libraries(barStatic fooStatic)
+if(NOT XCODE OR NOT XCODE_VERSION VERSION_LESS 5)
+ add_library(fooStatic STATIC
+ foo.cxx
+ foo.h
+ foo2.h
+ fooExtensionlessResource
+ fooPublic.h
+ fooPublicExtensionlessHeader
+ fooPrivate.h
+ fooPrivateExtensionlessHeader
+ fooNeither.h
+ fooBoth.h
+ test.lua
+ fooDeepPublic.h
+ )
+ set_target_properties(fooStatic PROPERTIES
+ FRAMEWORK TRUE
+ FRAMEWORK_VERSION none
+ )
+ add_executable(barStatic bar.cxx)
+ target_link_libraries(barStatic fooStatic)
+endif()
include(CPack)
diff --git a/Tests/RunCMake/CMakeLists.txt b/Tests/RunCMake/CMakeLists.txt
index c2c744f..63016f1 100644
--- a/Tests/RunCMake/CMakeLists.txt
+++ b/Tests/RunCMake/CMakeLists.txt
@@ -276,8 +276,7 @@ if(XCODE_VERSION AND NOT "${XCODE_VERSION}" VERSION_LESS 3)
add_RunCMake_test(XcodeProject -DXCODE_VERSION=${XCODE_VERSION})
endif()
-if(NOT XCODE
- AND CMAKE_C_COMPILER_ID STREQUAL "AppleClang"
+if(CMAKE_C_COMPILER_ID STREQUAL "AppleClang"
AND NOT CMAKE_C_COMPILER_VERSION VERSION_LESS 6.0)
add_RunCMake_test(Framework)
endif()
diff --git a/Tests/RunCMake/Framework/FrameworkLayout.cmake b/Tests/RunCMake/Framework/FrameworkLayout.cmake
index 5184755..ae32134 100644
--- a/Tests/RunCMake/Framework/FrameworkLayout.cmake
+++ b/Tests/RunCMake/Framework/FrameworkLayout.cmake
@@ -1,7 +1,7 @@
cmake_minimum_required(VERSION 3.4)
enable_language(C)
-add_library(Framework SHARED
+add_library(Framework ${FRAMEWORK_TYPE}
foo.c
foo.h
res.txt)
@@ -9,3 +9,6 @@ set_target_properties(Framework PROPERTIES
FRAMEWORK TRUE
PUBLIC_HEADER foo.h
RESOURCE "res.txt")
+
+add_custom_command(TARGET Framework POST_BUILD
+ COMMAND /usr/bin/file $<TARGET_FILE:Framework>)
diff --git a/Tests/RunCMake/Framework/FrameworkTypeSHARED-build-stdout.txt b/Tests/RunCMake/Framework/FrameworkTypeSHARED-build-stdout.txt
new file mode 100644
index 0000000..8d90f5f
--- /dev/null
+++ b/Tests/RunCMake/Framework/FrameworkTypeSHARED-build-stdout.txt
@@ -0,0 +1 @@
+.*/Framework: Mach-O[^\n]* dynamically linked shared library.*
diff --git a/Tests/RunCMake/Framework/FrameworkTypeSTATIC-build-stdout.txt b/Tests/RunCMake/Framework/FrameworkTypeSTATIC-build-stdout.txt
new file mode 100644
index 0000000..c9f50b6
--- /dev/null
+++ b/Tests/RunCMake/Framework/FrameworkTypeSTATIC-build-stdout.txt
@@ -0,0 +1 @@
+.*/Framework: current ar archive random library.*
diff --git a/Tests/RunCMake/Framework/RunCMakeTest.cmake b/Tests/RunCMake/Framework/RunCMakeTest.cmake
index eeea6f1..e64892d 100644
--- a/Tests/RunCMake/Framework/RunCMakeTest.cmake
+++ b/Tests/RunCMake/Framework/RunCMakeTest.cmake
@@ -1,33 +1,40 @@
include(RunCMake)
-# iOS
-
-set(RunCMake_TEST_BINARY_DIR ${RunCMake_BINARY_DIR}/iOSFrameworkLayout-build)
-set(RunCMake_TEST_NO_CLEAN 1)
-set(RunCMake_TEST_OPTIONS "-DCMAKE_TOOLCHAIN_FILE=${RunCMake_SOURCE_DIR}/ios.cmake")
-
-file(REMOVE_RECURSE "${RunCMake_TEST_BINARY_DIR}")
-file(MAKE_DIRECTORY "${RunCMake_TEST_BINARY_DIR}")
-
-run_cmake(FrameworkLayout)
-run_cmake_command(iOSFrameworkLayout-build ${CMAKE_COMMAND} --build .)
-
-unset(RunCMake_TEST_BINARY_DIR)
-unset(RunCMake_TEST_NO_CLEAN)
-unset(RunCMake_TEST_OPTIONS)
-
-# OSX
-
-set(RunCMake_TEST_BINARY_DIR ${RunCMake_BINARY_DIR}/OSXFrameworkLayout-build)
-set(RunCMake_TEST_NO_CLEAN 1)
-set(RunCMake_TEST_OPTIONS "-DCMAKE_TOOLCHAIN_FILE=${RunCMake_SOURCE_DIR}/osx.cmake")
-
-file(REMOVE_RECURSE "${RunCMake_TEST_BINARY_DIR}")
-file(MAKE_DIRECTORY "${RunCMake_TEST_BINARY_DIR}")
-
-run_cmake(FrameworkLayout)
-run_cmake_command(OSXFrameworkLayout-build ${CMAKE_COMMAND} --build .)
-
-unset(RunCMake_TEST_BINARY_DIR)
-unset(RunCMake_TEST_NO_CLEAN)
-unset(RunCMake_TEST_OPTIONS)
+function(framework_layout_test Name Toolchain Type)
+ set(RunCMake_TEST_BINARY_DIR ${RunCMake_BINARY_DIR}/${Toolchain}${Type}FrameworkLayout-build)
+ set(RunCMake_TEST_NO_CLEAN 1)
+ set(RunCMake_TEST_OPTIONS "-DCMAKE_TOOLCHAIN_FILE=${RunCMake_SOURCE_DIR}/${Toolchain}.cmake")
+ list(APPEND RunCMake_TEST_OPTIONS "-DFRAMEWORK_TYPE=${Type}")
+
+ file(REMOVE_RECURSE "${RunCMake_TEST_BINARY_DIR}")
+ file(MAKE_DIRECTORY "${RunCMake_TEST_BINARY_DIR}")
+
+ run_cmake(FrameworkLayout)
+ run_cmake_command(${Name} ${CMAKE_COMMAND} --build .)
+endfunction()
+
+# build check cannot cope with multi-configuration generators directory layout
+if(NOT RunCMake_GENERATOR STREQUAL "Xcode")
+ framework_layout_test(iOSFrameworkLayout-build ios SHARED)
+ framework_layout_test(iOSFrameworkLayout-build ios STATIC)
+ framework_layout_test(OSXFrameworkLayout-build osx SHARED)
+ framework_layout_test(OSXFrameworkLayout-build osx STATIC)
+endif()
+
+function(framework_type_test Toolchain Type)
+ set(RunCMake_TEST_BINARY_DIR ${RunCMake_BINARY_DIR}/${Toolchain}${Type}FrameworkType-build)
+ set(RunCMake_TEST_NO_CLEAN 1)
+ set(RunCMake_TEST_OPTIONS "-DCMAKE_TOOLCHAIN_FILE=${RunCMake_SOURCE_DIR}/${Toolchain}.cmake")
+ list(APPEND RunCMake_TEST_OPTIONS "-DFRAMEWORK_TYPE=${Type}")
+
+ file(REMOVE_RECURSE "${RunCMake_TEST_BINARY_DIR}")
+ file(MAKE_DIRECTORY "${RunCMake_TEST_BINARY_DIR}")
+
+ run_cmake(FrameworkLayout)
+ run_cmake_command(FrameworkType${Type}-build ${CMAKE_COMMAND} --build .)
+endfunction()
+
+framework_type_test(ios SHARED)
+framework_type_test(ios STATIC)
+framework_type_test(osx SHARED)
+framework_type_test(osx STATIC)
diff --git a/Tests/RunCMake/RunCMake.cmake b/Tests/RunCMake/RunCMake.cmake
index 6cc3054..5f66da0 100644
--- a/Tests/RunCMake/RunCMake.cmake
+++ b/Tests/RunCMake/RunCMake.cmake
@@ -101,7 +101,7 @@ function(run_cmake test)
endif()
foreach(o out err)
string(REGEX REPLACE "\r\n" "\n" actual_std${o} "${actual_std${o}}")
- string(REGEX REPLACE "(^|\n)((==[0-9]+==|BullseyeCoverage|[a-z]+\\([0-9]+\\) malloc:|Error kstat returned|[^\n]*from Time Machine by path|[^\n]*Bullseye Testing Technology)[^\n]*\n)+" "\\1" actual_std${o} "${actual_std${o}}")
+ string(REGEX REPLACE "(^|\n)((==[0-9]+==|BullseyeCoverage|[a-z]+\\([0-9]+\\) malloc:|Error kstat returned|[^\n]*is a member of multiple groups|[^\n]*from Time Machine by path|[^\n]*Bullseye Testing Technology)[^\n]*\n)+" "\\1" actual_std${o} "${actual_std${o}}")
string(REGEX REPLACE "\n+$" "" actual_std${o} "${actual_std${o}}")
set(expect_${o} "")
if(DEFINED expect_std${o})
diff --git a/Tests/RunCMake/XcodeProject/XcodeBundles.cmake b/Tests/RunCMake/XcodeProject/XcodeBundles.cmake
index ad4268d..833eb85 100644
--- a/Tests/RunCMake/XcodeProject/XcodeBundles.cmake
+++ b/Tests/RunCMake/XcodeProject/XcodeBundles.cmake
@@ -50,30 +50,56 @@ if (NOT TEST_IOS AND NOT TEST_WATCHOS AND NOT TEST_TVOS)
add_dependencies(AppBundleExtTest AppBundleExt)
endif()
-# Framework (not supported for iOS on Xcode < 6)
+# Shared Framework (not supported for iOS on Xcode < 6)
if(NOT TEST_IOS OR NOT XCODE_VERSION VERSION_LESS 6)
- add_library(Framework SHARED main.c)
- set_target_properties(Framework PROPERTIES FRAMEWORK TRUE)
+ add_library(SharedFramework SHARED main.c)
+ set_target_properties(SharedFramework PROPERTIES FRAMEWORK TRUE)
- add_custom_target(FrameworkTest ALL
+ add_custom_target(SharedFrameworkTest ALL
COMMAND ${CMAKE_COMMAND} -E copy
- "$<TARGET_FILE:Framework>" "$<TARGET_FILE:Framework>.old")
+ "$<TARGET_FILE:SharedFramework>" "$<TARGET_FILE:SharedFramework>.old")
- add_dependencies(FrameworkTest Framework)
+ add_dependencies(SharedFrameworkTest SharedFramework)
# with custom extension
- add_library(FrameworkExt SHARED main.c)
- set_target_properties(FrameworkExt PROPERTIES FRAMEWORK TRUE)
- set_target_properties(FrameworkExt PROPERTIES BUNDLE_EXTENSION "foo")
- install(TARGETS FrameworkExt FRAMEWORK DESTINATION FooExtension)
+ add_library(SharedFrameworkExt SHARED main.c)
+ set_target_properties(SharedFrameworkExt PROPERTIES FRAMEWORK TRUE)
+ set_target_properties(SharedFrameworkExt PROPERTIES BUNDLE_EXTENSION "foo")
+ install(TARGETS SharedFrameworkExt FRAMEWORK DESTINATION FooExtension)
- add_custom_target(FrameworkExtTest ALL
+ add_custom_target(SharedFrameworkExtTest ALL
COMMAND ${CMAKE_COMMAND} -E copy
- "$<TARGET_FILE:FrameworkExt>" "$<TARGET_FILE:FrameworkExt>.old")
+ "$<TARGET_FILE:SharedFrameworkExt>" "$<TARGET_FILE:SharedFrameworkExt>.old")
- add_dependencies(FrameworkExtTest FrameworkExt)
+ add_dependencies(SharedFrameworkExtTest SharedFrameworkExt)
+endif()
+
+# Static Framework (not supported for Xcode < 6)
+
+if(NOT XCODE_VERSION VERSION_LESS 6)
+ add_library(StaticFramework STATIC main.c)
+ set_target_properties(StaticFramework PROPERTIES FRAMEWORK TRUE)
+
+ add_custom_target(StaticFrameworkTest ALL
+ COMMAND ${CMAKE_COMMAND} -E copy
+ "$<TARGET_FILE:StaticFramework>" "$<TARGET_FILE:StaticFramework>.old")
+
+ add_dependencies(StaticFrameworkTest StaticFramework)
+
+ # with custom extension
+
+ add_library(StaticFrameworkExt STATIC main.c)
+ set_target_properties(StaticFrameworkExt PROPERTIES FRAMEWORK TRUE)
+ set_target_properties(StaticFrameworkExt PROPERTIES BUNDLE_EXTENSION "foo")
+ install(TARGETS StaticFrameworkExt FRAMEWORK DESTINATION StaticFooExtension)
+
+ add_custom_target(StaticFrameworkExtTest ALL
+ COMMAND ${CMAKE_COMMAND} -E copy
+ "$<TARGET_FILE:StaticFrameworkExt>" "$<TARGET_FILE:StaticFrameworkExt>.old")
+
+ add_dependencies(StaticFrameworkExtTest StaticFrameworkExt)
endif()
# Bundle
diff --git a/Utilities/.gitattributes b/Utilities/.gitattributes
index e3a9e61..c6345eb 100644
--- a/Utilities/.gitattributes
+++ b/Utilities/.gitattributes
@@ -1,2 +1,3 @@
/Git export-ignore
+/GitSetup export-ignore
SetupForDevelopment.sh export-ignore
diff --git a/Utilities/Git/pre-commit b/Utilities/Git/pre-commit
index b232ac0..b63ae5e 100755
--- a/Utilities/Git/pre-commit
+++ b/Utilities/Git/pre-commit
@@ -29,6 +29,19 @@ die 'The following changes add lines too long for our C++ style:
Use lines strictly less than '"$line_too_long"' characters in C++ code.'
+#-----------------------------------------------------------------------------
+
+# Check that development setup is up-to-date.
+lastSetupForDevelopment=$(git config --get hooks.SetupForDevelopment || echo 0)
+eval $(grep '^SetupForDevelopment_VERSION=' "${BASH_SOURCE%/*}/../SetupForDevelopment.sh")
+test -n "$SetupForDevelopment_VERSION" || SetupForDevelopment_VERSION=0
+if test $lastSetupForDevelopment -lt $SetupForDevelopment_VERSION; then
+ die 'Developer setup in this work tree is out of date. Please re-run
+
+ Utilities/SetupForDevelopment.sh
+'
+fi
+
#-------------------------------------------------------------------------------
if test -z "$HOOKS_ALLOW_KWSYS"; then
# Disallow changes to KWSys
diff --git a/Utilities/GitSetup/.gitattributes b/Utilities/GitSetup/.gitattributes
index facbbb2..e96d1f8 100644
--- a/Utilities/GitSetup/.gitattributes
+++ b/Utilities/GitSetup/.gitattributes
@@ -1,7 +1,6 @@
.git* export-ignore
-# Exclude from source archives files specific to Git work tree.
-* export-ignore
-
+config* eol=lf whitespace=indent-with-non-tab
+git-* eol=lf whitespace=indent-with-non-tab
tips eol=lf whitespace=indent-with-non-tab
setup-* eol=lf whitespace=indent-with-non-tab
diff --git a/Utilities/GitSetup/README b/Utilities/GitSetup/README
index cf468fb..2f9f1ec 100644
--- a/Utilities/GitSetup/README
+++ b/Utilities/GitSetup/README
@@ -37,6 +37,13 @@ Commit the merge with an informative message:
the general GitSetup repository "setup" branch.
------------------------------------------------------------------------
+Optionally add to the project ".gitattributes" file the line
+
+ /Utilities/GitSetup export-ignore
+
+to exclude the GitSetup directory from inclusion by "git archive"
+since it does not make sense in source tarballs.
+
Configuration
-------------
diff --git a/Utilities/GitSetup/config.sample b/Utilities/GitSetup/config.sample
index bba2382..eeb468b 100644
--- a/Utilities/GitSetup/config.sample
+++ b/Utilities/GitSetup/config.sample
@@ -20,3 +20,13 @@
site = http://review.source.kitware.com
# pushurl placeholder "$username" is literal
pushurl = $username@review.source.kitware.com:Project
+
+[upstream]
+ url = git://public.kitware.com/Project.git
+
+[gitlab]
+ host = gitlab.kitware.com
+ group-path = group
+ group-name = Group
+ project-path = project
+ project-name = Project
diff --git a/Utilities/GitSetup/git-gerrit-push b/Utilities/GitSetup/git-gerrit-push
new file mode 100755
index 0000000..b46f753
--- /dev/null
+++ b/Utilities/GitSetup/git-gerrit-push
@@ -0,0 +1,74 @@
+#!/usr/bin/env bash
+#=============================================================================
+# Copyright 2010-2015 Kitware, Inc.
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+#=============================================================================
+
+USAGE="[<remote>] [--no-topic] [--dry-run] [--]"
+OPTIONS_SPEC=
+SUBDIRECTORY_OK=Yes
+. "$(git --exec-path)/git-sh-setup"
+
+#-----------------------------------------------------------------------------
+
+remote=''
+refspecs=''
+no_topic=''
+dry_run=''
+
+# Parse the command line options.
+while test $# != 0; do
+ case "$1" in
+ --no-topic) no_topic=1 ;;
+ --dry-run) dry_run=--dry-run ;;
+ --) shift; break ;;
+ -*) usage ;;
+ *) test -z "$remote" || usage ; remote="$1" ;;
+ esac
+ shift
+done
+test $# = 0 || usage
+
+# Default remote.
+test -n "$remote" || remote="gerrit"
+
+if test -z "$no_topic"; then
+ # Identify and validate the topic branch name.
+ head="$(git symbolic-ref HEAD)" && topic="${head#refs/heads/}" || topic=''
+ if test -z "$topic" -o "$topic" = "master"; then
+ die 'Please name your topic:
+ git checkout -b descriptive-name'
+ fi
+ # The topic branch will be pushed by name.
+ refspecs="HEAD:refs/for/master/$topic $refspecs"
+fi
+
+# Fetch the current upstream master branch head.
+# This helps computation of a minimal pack to push.
+echo "Fetching $remote master"
+fetch_out=$(git fetch "$remote" master 2>&1) || die "$fetch_out"
+
+# Exit early if we have nothing to push.
+if test -z "$refspecs"; then
+ echo 'Nothing to push!'
+ exit 0
+fi
+
+# Push. Save output and exit code.
+echo "Pushing to $remote"
+push_stdout=$(git push --porcelain $dry_run "$remote" $refspecs); push_exit=$?
+echo "$push_stdout"
+
+# Reproduce the push exit code.
+exit $push_exit
diff --git a/Utilities/GitSetup/git-gitlab-push b/Utilities/GitSetup/git-gitlab-push
new file mode 100755
index 0000000..768f853
--- /dev/null
+++ b/Utilities/GitSetup/git-gitlab-push
@@ -0,0 +1,177 @@
+#!/usr/bin/env bash
+#=============================================================================
+# Copyright 2010-2015 Kitware, Inc.
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+#=============================================================================
+
+USAGE='[<remote>] [<options>...] [--]
+
+OPTIONS
+
+--dry-run
+ Show what would be pushed without actually updating the destination
+
+-f,--force
+ Force-push the topic HEAD to rewrite the destination branch
+
+--no-default
+ Do not push the default branch (e.g. master)
+
+--no-topic
+ Do not push the topic HEAD.
+'
+OPTIONS_SPEC=
+SUBDIRECTORY_OK=Yes
+. "$(git --exec-path)/git-sh-setup"
+
+egrep-q() {
+ egrep "$@" >/dev/null 2>/dev/null
+}
+
+# Load the project configuration.
+gitlab_upstream='' &&
+gitlab_configured='' &&
+config="${BASH_SOURCE%/*}/config" &&
+protocol=$(git config -f "$config" --get gitlab.protocol ||
+ echo "https") &&
+host=$(git config -f "$config" --get gitlab.host) &&
+site=$(git config -f "$config" --get gitlab.site ||
+ echo "$protocol://$host") &&
+group_path=$(git config -f "$config" --get gitlab.group-path) &&
+project_path=$(git config -f "$config" --get gitlab.project-path) &&
+gitlab_upstream="$site/$group_path/$project_path.git" &&
+gitlab_pushurl=$(git config --get remote.gitlab.pushurl ||
+ git config --get remote.gitlab.url) &&
+gitlab_configured=1
+
+#-----------------------------------------------------------------------------
+
+remote=''
+refspecs=''
+force=''
+lease=false
+lease_flag=''
+no_topic=''
+no_default=''
+dry_run=''
+
+# Parse the command line options.
+while test $# != 0; do
+ case "$1" in
+ -f|--force) force='+'; lease=true ;;
+ --no-topic) no_topic=1 ;;
+ --dry-run) dry_run=--dry-run ;;
+ --no-default) no_default=1 ;;
+ --) shift; break ;;
+ -*) usage ;;
+ *) test -z "$remote" || usage ; remote="$1" ;;
+ esac
+ shift
+done
+test $# = 0 || usage
+
+# Default remote.
+test -n "$remote" || remote="gitlab"
+
+if test -z "$no_topic"; then
+ # Identify and validate the topic branch name.
+ head="$(git symbolic-ref HEAD)" && topic="${head#refs/heads/}" || topic=''
+ if test -z "$topic" -o "$topic" = "master"; then
+ die 'Please name your topic:
+ git checkout -b descriptive-name'
+ fi
+
+ if $lease; then
+ have_ref=false
+ remoteref="refs/remotes/$remote/$topic"
+ if git rev-parse --verify -q "$remoteref"; then
+ have_ref=true
+ else
+ die "It seems that a local ref for the branch is
+missing; forcing a push is dangerous and may overwrite
+previous work. Fetch from the $remote remote first or
+push without '-f' or '--force'."
+ fi
+
+ have_lease_flag=false
+ if git push -h | egrep-q -e '--force-with-lease'; then
+ have_lease_flag=true
+ fi
+
+ if $have_lease_flag && $have_ref; then
+ # Set the lease flag.
+ lease_flag="--force-with-lease=$topic:$remoteref"
+ # Clear the force string.
+ force=''
+ fi
+ fi
+
+ # The topic branch will be pushed by name.
+ refspecs="${force}HEAD:refs/heads/$topic $refspecs"
+fi
+
+# Fetch the current remote master branch head.
+# This helps computation of a minimal pack to push.
+echo "Fetching $remote master"
+fetch_out=$(git fetch "$remote" master 2>&1) || die "$fetch_out"
+gitlab_head=$(git rev-parse FETCH_HEAD) || exit
+
+# Fetch the current upstream master branch head.
+if origin_fetchurl=$(git config --get remote.origin.url) &&
+ test "$origin_fetchurl" = "$gitlab_upstream"; then
+ upstream_remote='origin'
+else
+ upstream_remote="$gitlab_upstream"
+fi
+echo "Fetching $upstream_remote master"
+fetch_out=$(git fetch "$upstream_remote" master 2>&1) || die "$fetch_out"
+upstream_head=$(git rev-parse FETCH_HEAD) || exit
+
+# Add a refspec to keep the remote master up to date if possible.
+if test -z "$no_default" &&
+ base=$(git merge-base "$gitlab_head" "$upstream_head") &&
+ test "$base" = "$gitlab_head"; then
+ refspecs="$upstream_head:refs/heads/master $refspecs"
+fi
+
+# Exit early if we have nothing to push.
+if test -z "$refspecs"; then
+ echo 'Nothing to push!'
+ exit 0
+fi
+
+# Push. Save output and exit code.
+echo "Pushing to $remote"
+push_config='-c advice.pushUpdateRejected=false'
+push_stdout=$(git $push_config push $lease_flag --porcelain $dry_run "$remote" $refspecs); push_exit=$?
+echo "$push_stdout"
+
+if test "$push_exit" -ne 0 && test -z "$force"; then
+ # Advise the user to fetch if needed.
+ if echo "$push_stdout" | egrep-q 'stale info'; then
+ echo "
+You have pushed to your branch from another machine; you may be overwriting
+commits unintentionally. Fetch from the $remote remote and check that you are
+not pushing an outdated branch."
+ fi
+
+ # Advise the user to force-push if needed.
+ if echo "$push_stdout" | egrep-q 'non-fast-forward'; then
+ echo '
+Add "-f" or "--force" to push a rewritten topic.'
+ fi
+fi
+
+# Reproduce the push exit code.
+exit $push_exit
diff --git a/Utilities/GitSetup/setup-gerrit b/Utilities/GitSetup/setup-gerrit
index 9e8fa62..6d46e3c 100755
--- a/Utilities/GitSetup/setup-gerrit
+++ b/Utilities/GitSetup/setup-gerrit
@@ -28,6 +28,7 @@
# gerrit.pushurl = Review site push URL with "$username" placeholder
# gerrit.remote = Gerrit remote name, if not "gerrit"
# gerrit.url = Gerrit project URL, if not "$site/p/$project"
+# optionally with "$username" placeholder
die() {
echo 1>&2 "$@" ; exit 1
@@ -39,11 +40,12 @@ cd "${BASH_SOURCE%/*}" &&
# Load the project configuration.
site=$(git config -f config --get gerrit.site) &&
project=$(git config -f config --get gerrit.project) &&
-pushurl_=$(git config -f config --get gerrit.pushurl) &&
remote=$(git config -f config --get gerrit.remote ||
echo "gerrit") &&
-fetchurl=$(git config -f config --get gerrit.url ||
- echo "$site/p/$project") ||
+fetchurl_=$(git config -f config --get gerrit.url ||
+ echo "$site/p/$project") &&
+pushurl_=$(git config -f config --get gerrit.pushurl ||
+ git config -f config --get gerrit.url) ||
die 'This project is not configured to use Gerrit.'
# Get current gerrit push URL.
@@ -67,7 +69,7 @@ else
'"$project"' changes must be pushed to our Gerrit Code Review site:
- '"$fetchurl"'
+ '"$site/p/$project"'
Register a Gerrit account and select a username (used below).
You will need an OpenID:
@@ -96,13 +98,16 @@ Add your SSH public keys at
if test -z "$gu"; then
gu="$USER"
fi &&
+ fetchurl="${fetchurl_/\$username/$gu}" &&
if test -z "$pushurl"; then
git remote add "$remote" "$fetchurl"
else
git config remote."$remote".url "$fetchurl"
fi &&
pushurl="${pushurl_/\$username/$gu}" &&
- git config remote."$remote".pushurl "$pushurl" &&
+ if test "$pushurl" != "$fetchurl"; then
+ git config remote."$remote".pushurl "$pushurl"
+ fi &&
echo 'Remote "'"$remote"'" is now configured to push to
'"$pushurl"'
diff --git a/Utilities/GitSetup/setup-gitlab b/Utilities/GitSetup/setup-gitlab
new file mode 100755
index 0000000..9c7574d
--- /dev/null
+++ b/Utilities/GitSetup/setup-gitlab
@@ -0,0 +1,140 @@
+#!/usr/bin/env bash
+#=============================================================================
+# Copyright 2010-2015 Kitware, Inc.
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+#=============================================================================
+
+# Run this script to set up the local Git repository to push to
+# a personal fork for this project in GitLab.
+
+# Project configuration instructions:
+#
+# - Run a GitLab server
+#
+# - Populate adjacent "config" file with:
+# gitlab.protocol = Top GitLab protocol, if not 'https'
+# gitlab.host = Top GitLab fully qualified host name
+# gitlab.site = Top GitLab URL, if not "<protocol>://<host>"
+# gitlab.group-name = Name of group containing project in GitLab
+# gitlab.group-path = Path of group containing project in GitLab
+# gitlab.project-name = Name of project within GitLab group
+# gitlab.project-path = Path of project within GitLab group
+# gitlab.url = GitLab push URL with "$username" placeholder,
+# if not "<site>/$username/<project-path>.git"
+# gitlab.pushurl = GitLab push URL with "$username" placeholder,
+# if not "git@<host>:$username/<project-path>.git"
+# gitlab.remote = GitLab remote name, if not "gitlab"
+
+die() {
+ echo 1>&2 "$@" ; exit 1
+}
+
+# Make sure we are inside the repository.
+cd "${BASH_SOURCE%/*}" &&
+
+# Load the project configuration.
+protocol=$(git config -f config --get gitlab.protocol ||
+ echo "https") &&
+host=$(git config -f config --get gitlab.host) &&
+site=$(git config -f config --get gitlab.site ||
+ echo "$protocol://$host") &&
+group_path=$(git config -f config --get gitlab.group-path) &&
+group_name=$(git config -f config --get gitlab.group-name) &&
+project_name=$(git config -f config --get gitlab.project-name) &&
+project_path=$(git config -f config --get gitlab.project-path) &&
+pushurl_=$(git config -f config --get gitlab.pushurl ||
+ echo "git@$host:\$username/$project_path.git") &&
+remote=$(git config -f config --get gitlab.remote ||
+ echo "gitlab") &&
+fetchurl_=$(git config -f config --get gitlab.url ||
+ echo "$site/\$username/$project_path.git") ||
+die 'This project is not configured to use GitLab.'
+
+# Get current gitlab push URL.
+pushurl=$(git config --get remote."$remote".pushurl ||
+ git config --get remote."$remote".url || echo '') &&
+
+# Tell user about current configuration.
+if test -n "$pushurl"; then
+ echo 'Remote "'"$remote"'" is currently configured to push to
+
+ '"$pushurl"'
+' &&
+ read -ep 'Reconfigure GitLab? [y/N]: ' ans &&
+ if [ "$ans" == "y" ] || [ "$ans" == "Y" ]; then
+ setup=1
+ else
+ setup=''
+ fi
+else
+ echo 'Remote "'"$remote"'" is not yet configured.
+' &&
+ read -ep 'Configure GitLab to contribute to '"$project_name"'? [Y/n]: ' ans &&
+ if [ "$ans" == "n" ] || [ "$ans" == "N" ]; then
+ exit 0
+ else
+ setup=1
+ fi
+fi &&
+
+setup_instructions='Add your SSH public keys at
+
+ '"$site"'/profile/keys
+
+Then visit the main repository at:
+
+ '"$site/$group_path/$project_path"'
+
+and use the Fork button in the upper right.
+'
+
+# Perform setup if necessary.
+if test -n "$setup"; then
+ echo 'Sign-in to GitLab to get/set your username at
+
+ '"$site/profile/account"'
+
+'"$setup_instructions" &&
+ read -ep "GitLab username? [$USER]: " gu &&
+ if test -z "$gu"; then
+ gu="$USER"
+ fi &&
+ fetchurl="${fetchurl_/\$username/$gu}" &&
+ if test -z "$pushurl"; then
+ git remote add "$remote" "$fetchurl"
+ else
+ git config remote."$remote".url "$fetchurl"
+ fi &&
+ pushurl="${pushurl_/\$username/$gu}" &&
+ git config remote."$remote".pushurl "$pushurl" &&
+ echo 'Remote "'"$remote"'" is now configured to push to
+
+ '"$pushurl"'
+'
+fi &&
+
+# Optionally test GitLab access.
+if test -n "$pushurl"; then
+ read -ep 'Test access to GitLab (SSH)? [y/N]: ' ans &&
+ if [ "$ans" == "y" ] || [ "$ans" == "Y" ]; then
+ echo -n 'Testing GitLab access by SSH...'
+ if git ls-remote --heads "$pushurl" >/dev/null; then
+ echo 'passed.'
+ else
+ echo 'failed.' &&
+ die 'Could not access your GitLab fork of this project.
+'"$setup_instructions"
+ fi
+ fi
+fi
diff --git a/Utilities/GitSetup/setup-hooks b/Utilities/GitSetup/setup-hooks
index c07985a..ca07712 100755
--- a/Utilities/GitSetup/setup-hooks
+++ b/Utilities/GitSetup/setup-hooks
@@ -55,6 +55,7 @@ fi &&
# Populate ".git/hooks".
echo 'Setting up git hooks...' &&
git_dir=$(git rev-parse --git-dir) &&
+mkdir -p "$git_dir/hooks" &&
cd "$git_dir/hooks" &&
if ! test -e .git; then
git init -q || die 'Could not run git init for hooks.'
diff --git a/Utilities/GitSetup/setup-stage b/Utilities/GitSetup/setup-stage
index 323e47a..ce6ec45 100755
--- a/Utilities/GitSetup/setup-stage
+++ b/Utilities/GitSetup/setup-stage
@@ -37,8 +37,8 @@ die() {
cd "${BASH_SOURCE%/*}" &&
# Load the project configuration.
-fetchurl=$(git config -f config --get stage.url) &&
-pushurl_=$(git config -f config --get stage.pushurl || echo '') &&
+fetchurl_=$(git config -f config --get stage.url) &&
+pushurl_=$(git config -f config --get stage.pushurl || echo "$fetchurl_") &&
remote=$(git config -f config --get stage.remote || echo 'stage') ||
die 'This project is not configured to use a topic stage.'
@@ -65,13 +65,16 @@ fi
# Perform setup if necessary.
if test -n "$setup"; then
echo 'Setting up the topic stage...' &&
+ fetchurl="${fetchurl_}" &&
if test -z "$pushurl"; then
git remote add "$remote" "$fetchurl"
else
git config remote."$remote".url "$fetchurl"
fi &&
pushurl="${pushurl_}" &&
- git config remote."$remote".pushurl "$pushurl" &&
+ if test "$pushurl" != "$fetchurl"; then
+ git config remote."$remote".pushurl "$pushurl"
+ fi &&
echo 'Remote "'"$remote"'" is now configured to push to
'"$pushurl"'
diff --git a/Utilities/GitSetup/setup-upstream b/Utilities/GitSetup/setup-upstream
new file mode 100755
index 0000000..92ce1da
--- /dev/null
+++ b/Utilities/GitSetup/setup-upstream
@@ -0,0 +1,104 @@
+#!/usr/bin/env bash
+#=============================================================================
+# Copyright 2010-2015 Kitware, Inc.
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+#=============================================================================
+
+# Run this script to set up the local Git repository to use the
+# preferred upstream repository URLs.
+
+# Project configuration instructions:
+#
+# - Populate adjacent "config" file with:
+# upstream.url = Preferred fetch url for upstream remote
+# upstream.remote = Preferred name for upstream remote, if not "origin"
+
+die() {
+ echo 1>&2 "$@" ; exit 1
+}
+
+# Make sure we are inside the repository.
+cd "${BASH_SOURCE%/*}" &&
+
+# Load the project configuration.
+url=$(git config -f config --get upstream.url) &&
+remote=$(git config -f config --get upstream.remote ||
+ echo 'origin') ||
+die 'This project is not configured to use a preferred upstream repository.'
+
+# Get current upstream URLs.
+fetchurl=$(git config --get remote."$remote".url || echo '') &&
+pushurl=$(git config --get remote."$remote".pushurl || echo '') &&
+
+if test "$fetchurl" = "$url"; then
+ echo 'Remote "'"$remote"'" already uses recommended upstream repository.'
+ exit 0
+fi
+
+upstream_recommend='
+We recommended configuring the "'"$remote"'" remote to fetch from upstream at
+
+ '"$url"'
+'
+
+# Tell user about current configuration.
+if test -n "$fetchurl"; then
+ echo 'Remote "'"$remote"'" is currently configured to fetch from
+
+ '"$fetchurl"'
+' &&
+ if test -n "$pushurl"; then
+ echo 'and push to
+
+ '"$pushurl"
+ fi &&
+ echo "$upstream_recommend" &&
+ if test -n "$pushurl"; then
+ echo 'and to never push to it directly.
+'
+ fi &&
+
+ read -ep 'Reconfigure "'"$remote"'" remote as recommended? [y/N]: ' ans &&
+ if [ "$ans" == "y" ] || [ "$ans" == "Y" ]; then
+ setup=1
+ else
+ setup=''
+ fi
+else
+ echo 'Remote "'"$remote"'" is not yet configured.' &&
+ echo "$upstream_recommend" &&
+ read -ep 'Configure "'"$remote"'" remote as recommended? [Y/n]: ' ans &&
+ if [ "$ans" == "n" ] || [ "$ans" == "N" ]; then
+ exit 0
+ else
+ setup=1
+ fi
+fi &&
+
+# Perform setup if necessary.
+if test -n "$setup"; then
+ if test -z "$fetchurl"; then
+ git remote add "$remote" "$url"
+ else
+ git config remote."$remote".url "$url" &&
+ if old=$(git config --get remote."$remote".pushurl); then
+ git config --unset remote."$remote".pushurl ||
+ echo 'Warning: failed to unset remote.'"$remote"'.pushurl'
+ fi
+ fi &&
+ echo 'Remote "'"$remote"'" is now configured to fetch from
+
+ '"$url"'
+'
+fi
diff --git a/Utilities/Scripts/update-gitsetup.bash b/Utilities/Scripts/update-gitsetup.bash
new file mode 100755
index 0000000..8f0da76
--- /dev/null
+++ b/Utilities/Scripts/update-gitsetup.bash
@@ -0,0 +1,20 @@
+#!/usr/bin/env bash
+
+set -e
+set -x
+shopt -s dotglob
+
+readonly name="GitSetup"
+readonly ownership="GitSetup Upstream <kwrobot@kitware.com>"
+readonly subtree="Utilities/GitSetup"
+readonly repo="https://gitlab.kitware.com/utils/gitsetup.git"
+readonly tag="setup"
+readonly shortlog=false
+readonly paths="
+"
+
+extract_source () {
+ git_archive
+}
+
+. "${BASH_SOURCE%/*}/update-third-party.bash"
diff --git a/Utilities/SetupForDevelopment.sh b/Utilities/SetupForDevelopment.sh
index 0a9df7e..39152bc 100755
--- a/Utilities/SetupForDevelopment.sh
+++ b/Utilities/SetupForDevelopment.sh
@@ -11,3 +11,7 @@ Utilities/GitSetup/tips
# Rebase master by default
git config rebase.stat true
git config branch.master.rebase true
+
+# Record the version of this setup so Git/pre-commit can check it.
+SetupForDevelopment_VERSION=1
+git config hooks.SetupForDevelopment ${SetupForDevelopment_VERSION}