summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--CTestCustom.cmake.in3
-rw-r--r--Help/generator/CodeLite.rst6
-rw-r--r--Help/manual/cmake-server.7.rst126
-rw-r--r--Help/manual/cmake-variables.7.rst1
-rw-r--r--Help/release/dev/codelite-organize-by-target.rst6
-rw-r--r--Help/variable/CMAKE_CODELITE_USE_TARGETS.rst7
-rw-r--r--Modules/CPack.cmake2
-rw-r--r--Modules/CPackNSIS.cmake5
-rw-r--r--Modules/CPackRPM.cmake261
-rw-r--r--Modules/FindBoost.cmake16
-rw-r--r--Modules/FindMatlab.cmake7
-rw-r--r--Source/CMakeVersion.cmake2
-rw-r--r--Source/CPack/cmCPackNSISGenerator.cxx41
-rw-r--r--Source/CPack/cmCPackNSISGenerator.h5
-rw-r--r--Source/cmExtraCodeLiteGenerator.cxx334
-rw-r--r--Source/cmExtraCodeLiteGenerator.h21
-rw-r--r--Source/cmGlobalGenerator.cxx23
-rw-r--r--Source/cmGlobalGenerator.h10
-rw-r--r--Source/cmNinjaTargetGenerator.cxx12
-rw-r--r--Source/cmServerDictionary.h13
-rw-r--r--Source/cmServerProtocol.cxx190
-rw-r--r--Source/cmServerProtocol.h11
-rw-r--r--Source/kwsys/testConsoleBuf.cxx37
-rw-r--r--Tests/FortranModules/CMakeLists.txt2
-rw-r--r--Tests/FortranModules/non_pp_include.f903
-rw-r--r--Tests/FortranModules/test_non_pp_include_main.f905
-rw-r--r--Tests/RunCMake/CPack/DEBUGINFO.cmake8
-rw-r--r--Tests/RunCMake/CPack/RPM/DEBUGINFO-ExpectedFiles.cmake4
-rw-r--r--Tests/Server/CMakeLists.txt1
-rw-r--r--Tests/Server/cmakelib.py66
-rw-r--r--Tests/Server/server-test.py18
-rw-r--r--Tests/Server/tc_globalSettings.json140
32 files changed, 1235 insertions, 151 deletions
diff --git a/CTestCustom.cmake.in b/CTestCustom.cmake.in
index 848917842d..710681ccec 100644
--- a/CTestCustom.cmake.in
+++ b/CTestCustom.cmake.in
@@ -49,6 +49,7 @@ list(APPEND CTEST_CUSTOM_WARNING_EXCEPTION
"stl_deque.h:1051"
"(Lexer|Parser).*warning.*conversion.*may (alter its value|change the sign)"
"(Lexer|Parser).*warning.*(statement is unreachable|will never be executed)"
+ "(Lexer|Parser).*warning.*variable.*was set but never used"
"PGC-W-0095-Type cast required for this conversion.*ProcessUNIX.c"
"[Qq]t([Cc]ore|[Gg]ui|[Ww]idgets).*warning.*conversion.*may alter its value"
"warning:.*is.*very unsafe.*consider using.*"
@@ -70,6 +71,8 @@ list(APPEND CTEST_CUSTOM_WARNING_EXCEPTION
# Ignore clang's summary warning, assuming prior text has matched some
# other warning expression:
"[0-9,]+ warnings? generated."
+ # similarly for PGI
+ "compilation completed with warnings"
# scanbuild exceptions
"char_traits.h:.*: warning: Null pointer argument in call to string length function"
diff --git a/Help/generator/CodeLite.rst b/Help/generator/CodeLite.rst
index dbc46d72be..3e60aa6d65 100644
--- a/Help/generator/CodeLite.rst
+++ b/Help/generator/CodeLite.rst
@@ -5,7 +5,11 @@ Generates CodeLite project files.
Project files for CodeLite will be created in the top directory and
in every subdirectory which features a CMakeLists.txt file containing
-a PROJECT() call. The appropriate make program can build the
+a :command:`project` call.
+The :variable:`CMAKE_CODELITE_USE_TARGETS` variable may be set to ``ON``
+to change the default behaviour from projects to targets as the basis
+for project files.
+The appropriate make program can build the
project through the default make target. A "make install" target is
also provided.
diff --git a/Help/manual/cmake-server.7.rst b/Help/manual/cmake-server.7.rst
index 61d6896cd9..b8a425c82b 100644
--- a/Help/manual/cmake-server.7.rst
+++ b/Help/manual/cmake-server.7.rst
@@ -248,3 +248,129 @@ which will result in a response type "reply"::
]== CMake Server ==]
indicating that the server is ready for action.
+
+
+Type "globalSettings"
+^^^^^^^^^^^^^^^^^^^^^
+
+This request can be sent after the initial handshake. It will return a
+JSON structure with information on cmake state.
+
+Example::
+
+ [== CMake Server ==[
+ {"type":"globalSettings"}
+ ]== CMake Server ==]
+
+which will result in a response type "reply"::
+
+ [== CMake Server ==[
+ {
+ "buildDirectory": "/tmp/test-build",
+ "capabilities": {
+ "generators": [
+ {
+ "extraGenerators": [],
+ "name": "Watcom WMake",
+ "platformSupport": false,
+ "toolsetSupport": false
+ },
+ <...>
+ ],
+ "serverMode": false,
+ "version": {
+ "isDirty": false,
+ "major": 3,
+ "minor": 6,
+ "patch": 20160830,
+ "string": "3.6.20160830-gd6abad",
+ "suffix": "gd6abad"
+ }
+ },
+ "checkSystemVars": false,
+ "cookie": "",
+ "extraGenerator": "",
+ "generator": "Ninja",
+ "debugOutput": false,
+ "inReplyTo": "globalSettings",
+ "sourceDirectory": "/home/code/cmake",
+ "trace": false,
+ "traceExpand": false,
+ "type": "reply",
+ "warnUninitialized": false,
+ "warnUnused": false,
+ "warnUnusedCli": true
+ }
+ ]== CMake Server ==]
+
+
+Type "setGlobalSettings"
+^^^^^^^^^^^^^^^^^^^^^^^^
+
+This request can be sent to change the global settings attributes. Unknown
+attributes are going to be ignored. Read-only attributes reported by
+"globalSettings" are all capabilities, buildDirectory, generator,
+extraGenerator and sourceDirectory. Any attempt to set these will be ignored,
+too.
+
+All other settings will be changed.
+
+The server will respond with an empty reply message or an error.
+
+Example::
+
+ [== CMake Server ==[
+ {"type":"setGlobalSettings","debugOutput":true}
+ ]== CMake Server ==]
+
+CMake will reply to this with::
+
+ [== CMake Server ==[
+ {"inReplyTo":"setGlobalSettings","type":"reply"}
+ ]== CMake Server ==]
+
+
+Type "configure"
+^^^^^^^^^^^^^^^^
+
+This request will configure a project for build.
+
+To configure a build directory already containing cmake files, it is enough to
+set "buildDirectory" via "setGlobalSettings". To create a fresh build directory
+you also need to set "currentGenerator" and "sourceDirectory" via "setGlobalSettings"
+in addition to "buildDirectory".
+
+You may a list of strings to "configure" via the "cacheArguments" key. These
+strings will be interpreted similar to command line arguments related to
+cache handling that are passed to the cmake command line client.
+
+Example::
+
+ [== CMake Server ==[
+ {"type":"configure", "cacheArguments":["-Dsomething=else"]}
+ ]== CMake Server ==]
+
+CMake will reply like this (after reporting progress for some time)::
+
+ [== CMake Server ==[
+ {"cookie":"","inReplyTo":"configure","type":"reply"}
+ ]== CMake Server ==]
+
+
+Type "compute"
+^^^^^^^^^^^^^^
+
+This requist will generate build system files in the build directory and
+is only available after a project was successfully "configure"d.
+
+Example::
+
+ [== CMake Server ==[
+ {"type":"compute"}
+ ]== CMake Server ==]
+
+CMake will reply (after reporting progress information)::
+
+ [== CMake Server ==[
+ {"cookie":"","inReplyTo":"compute","type":"reply"}
+ ]== CMake Server ==]
diff --git a/Help/manual/cmake-variables.7.rst b/Help/manual/cmake-variables.7.rst
index d9da3d6e7f..b74f8670e6 100644
--- a/Help/manual/cmake-variables.7.rst
+++ b/Help/manual/cmake-variables.7.rst
@@ -112,6 +112,7 @@ Variables that Change Behavior
/variable/CMAKE_AUTOMOC_RELAXED_MODE
/variable/CMAKE_BACKWARDS_COMPATIBILITY
/variable/CMAKE_BUILD_TYPE
+ /variable/CMAKE_CODELITE_USE_TARGETS
/variable/CMAKE_COLOR_MAKEFILE
/variable/CMAKE_CONFIGURATION_TYPES
/variable/CMAKE_DEBUG_TARGET_PROPERTIES
diff --git a/Help/release/dev/codelite-organize-by-target.rst b/Help/release/dev/codelite-organize-by-target.rst
new file mode 100644
index 0000000000..0979228350
--- /dev/null
+++ b/Help/release/dev/codelite-organize-by-target.rst
@@ -0,0 +1,6 @@
+codelite-organize-by-target
+---------------------------
+
+* The :generator:`CodeLite` generator gained a new
+ :variable:`CMAKE_CODELITE_USE_TARGETS` option
+ to change project creation from projects to targets.
diff --git a/Help/variable/CMAKE_CODELITE_USE_TARGETS.rst b/Help/variable/CMAKE_CODELITE_USE_TARGETS.rst
new file mode 100644
index 0000000000..4aede0361e
--- /dev/null
+++ b/Help/variable/CMAKE_CODELITE_USE_TARGETS.rst
@@ -0,0 +1,7 @@
+CMAKE_CODELITE_USE_TARGETS
+--------------------------
+
+Change the way the CodeLite generator creates projectfiles.
+
+If this variable is set to ``ON`` the generator creates projectfiles
+based on targets rather than projects.
diff --git a/Modules/CPack.cmake b/Modules/CPack.cmake
index 99f22ecf62..50d9fc370b 100644
--- a/Modules/CPack.cmake
+++ b/Modules/CPack.cmake
@@ -604,6 +604,8 @@ if(CMAKE_OSX_SYSROOT)
_cpack_set_default(CPACK_OSX_SYSROOT "${_CMAKE_OSX_SYSROOT_PATH}")
endif()
+_cpack_set_default(CPACK_BUILD_SOURCE_DIRS "${CMAKE_SOURCE_DIR};${CMAKE_BINARY_DIR}")
+
if(DEFINED CPACK_COMPONENTS_ALL)
if(CPACK_MONOLITHIC_INSTALL)
message("CPack warning: both CPACK_COMPONENTS_ALL and CPACK_MONOLITHIC_INSTALL have been set.\nDefaulting to a monolithic installation.")
diff --git a/Modules/CPackNSIS.cmake b/Modules/CPackNSIS.cmake
index db5984a66a..4693ce5ac2 100644
--- a/Modules/CPackNSIS.cmake
+++ b/Modules/CPackNSIS.cmake
@@ -96,6 +96,11 @@
# Contact information for questions and comments about the installation
# process.
#
+# .. variable:: CPACK_NSIS_<compName>_INSTALL_DIRECTORY
+#
+# Custom install directory for the specified component <compName> instead
+# of $INSTDIR.
+#
# .. variable:: CPACK_NSIS_CREATE_ICONS_EXTRA
#
# Additional NSIS commands for creating start menu shortcuts.
diff --git a/Modules/CPackRPM.cmake b/Modules/CPackRPM.cmake
index d78f7fa646..9ed60d318e 100644
--- a/Modules/CPackRPM.cmake
+++ b/Modules/CPackRPM.cmake
@@ -60,14 +60,6 @@
# * Mandatory : YES
# * Default : :variable:`CPACK_PACKAGE_DESCRIPTION_SUMMARY`
#
-# .. variable:: CPACK_RPM_DEBUGINFO_PACKAGE
-# CPACK_RPM_<component>_DEBUGINFO_PACKAGE
-#
-# Option to additionally generate debuginfo RPM package(s).
-#
-# * Mandatory : NO
-# * Default : OFF
-#
# .. variable:: CPACK_RPM_PACKAGE_NAME
# CPACK_RPM_<component>_PACKAGE_NAME
#
@@ -707,6 +699,96 @@
# package installation may cause initial symbolic link to point to an
# invalid location.
#
+# Packaging of debug information
+# ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+#
+# Debuginfo packages contain debug symbols and sources for debugging packaged
+# binaries.
+#
+# .. note::
+#
+# Currently multiple debuginfo packages are generated if component based
+# packaging is used - one debuginfo package per component. This duplicates
+# sources if multiple binaries are using them. This is a side effect of
+# how CPackRPM currently generates component packages and will be addressed
+# in later versions of the generator.
+#
+# Debuginfo RPM packaging has it's own set of variables:
+#
+# .. variable:: CPACK_RPM_DEBUGINFO_PACKAGE
+# CPACK_RPM_<component>_DEBUGINFO_PACKAGE
+#
+# Enable generation of debuginfo RPM package(s).
+#
+# * Mandatory : NO
+# * Default : OFF
+#
+# .. note::
+#
+# Binaries must contain debug symbols before packaging so use either ``Debug``
+# or ``RelWithDebInfo`` for :variable:`CMAKE_BUILD_TYPE` variable value.
+#
+# .. note::
+#
+# Packages generated from packages without binary files, with binary files but
+# without execute permissions or without debug symbols will be empty.
+#
+# .. variable:: CPACK_BUILD_SOURCE_DIRS
+#
+# Provides locations of root directories of source files from which binaries
+# were built.
+#
+# * Mandatory : YES if :variable:`CPACK_RPM_DEBUGINFO_PACKAGE` is set
+# * Default : -
+#
+# .. note::
+#
+# For CMake project :variable:`CPACK_BUILD_SOURCE_DIRS` is set by default to
+# point to :variable:`CMAKE_SOURCE_DIR` and :variable:`CMAKE_BINARY_DIR` paths.
+#
+# .. note::
+#
+# Sources with path prefixes that do not fall under any location provided with
+# :variable:`CPACK_BUILD_SOURCE_DIRS` will not be present in debuginfo package.
+#
+# .. variable:: CPACK_RPM_BUILD_SOURCE_DIRS_PREFIX
+# CPACK_RPM_<component>_BUILD_SOURCE_DIRS_PREFIX
+#
+# Prefix of location where sources will be placed during package installation.
+#
+# * Mandatory : YES if :variable:`CPACK_RPM_DEBUGINFO_PACKAGE` is set
+# * Default : "/usr/src/debug/<CPACK_PACKAGE_FILE_NAME>" and
+# for component packaging "/usr/src/debug/<CPACK_PACKAGE_FILE_NAME>-<component>"
+#
+# .. note::
+#
+# Each source path prefix is additionaly suffixed by ``src_<index>`` where
+# index is index of the path used from :variable:`CPACK_BUILD_SOURCE_DIRS`
+# variable. This produces ``<CPACK_RPM_BUILD_SOURCE_DIRS_PREFIX>/src_<index>``
+# replacement path.
+# Limitation is that replaced path part must be shorter or of equal
+# length than the length of its replacement. If that is not the case either
+# :variable:`CPACK_RPM_BUILD_SOURCE_DIRS_PREFIX` variable has to be set to
+# a shorter path or source directories must be placed on a longer path.
+#
+# .. variable:: CPACK_RPM_DEBUGINFO_EXCLUDE_DIRS
+#
+# Directories containing sources that should be excluded from debuginfo packages.
+#
+# * Mandatory : NO
+# * Default : "/usr /usr/src /usr/src/debug"
+#
+# Listed paths are owned by other RPM packages and should therefore not be
+# deleted on debuginfo package uninstallation.
+#
+# .. variable:: CPACK_RPM_DEBUGINFO_EXCLUDE_DIRS_ADDITION
+#
+# Paths that should be appended to :variable:`CPACK_RPM_DEBUGINFO_EXCLUDE_DIRS`
+# for exclusion.
+#
+# * Mandatory : NO
+# * Default : -
+#
# Packaging of sources (SRPM)
# ^^^^^^^^^^^^^^^^^^^^^^^^^^^
#
@@ -1321,13 +1403,37 @@ endif()
# We need to check if the binaries were compiled with debug symbols
# because without them the package will be useless
function(cpack_rpm_debugsymbol_check INSTALL_FILES WORKING_DIR)
+ if(NOT CPACK_BUILD_SOURCE_DIRS)
+ message(FATAL_ERROR "CPackRPM: CPACK_BUILD_SOURCE_DIRS variable is not set!"
+ " Required for debuginfo packaging. See documentation of"
+ " CPACK_RPM_DEBUGINFO_PACKAGE variable for details.")
+ endif()
+
# With objdump we should check the debug symbols
find_program(OBJDUMP_EXECUTABLE objdump)
if(NOT OBJDUMP_EXECUTABLE)
- message(WARNING "CPackRPM: objdump binary could not be found!")
+ message(FATAL_ERROR "CPackRPM: objdump binary could not be found!"
+ " Required for debuginfo packaging. See documentation of"
+ " CPACK_RPM_DEBUGINFO_PACKAGE variable for details.")
endif()
+ # With debugedit we prepare source files list
+ find_program(DEBUGEDIT_EXECUTABLE debugedit "/usr/lib/rpm/")
+ if(NOT DEBUGEDIT_EXECUTABLE)
+ message(FATAL_ERROR "CPackRPM: debugedit binary could not be found!"
+ " Required for debuginfo packaging. See documentation of"
+ " CPACK_RPM_DEBUGINFO_PACKAGE variable for details.")
+ endif()
+
+ unset(mkdir_list_)
+ unset(cp_list_)
+ unset(additional_sources_)
+
foreach(F IN LISTS INSTALL_FILES)
+ if(IS_DIRECTORY "${WORKING_DIR}/${F}" OR IS_SYMLINK "${WORKING_DIR}/${F}")
+ continue()
+ endif()
+
execute_process(COMMAND "${OBJDUMP_EXECUTABLE}" -h ${WORKING_DIR}/${F}
WORKING_DIRECTORY "${CPACK_TOPLEVEL_DIRECTORY}"
RESULT_VARIABLE OBJDUMP_EXEC_RESULT
@@ -1335,11 +1441,98 @@ function(cpack_rpm_debugsymbol_check INSTALL_FILES WORKING_DIR)
# Check that if the given file was executable or not
if(NOT OBJDUMP_EXEC_RESULT)
string(FIND "${OBJDUMP_OUT}" "debug" FIND_RESULT)
- if(NOT FIND_RESULT GREATER -1)
+ if(FIND_RESULT GREATER -1)
+ set(index_ 0)
+ foreach(source_dir_ IN LISTS CPACK_BUILD_SOURCE_DIRS)
+ string(LENGTH "${source_dir_}" source_dir_len_)
+ string(LENGTH "${CPACK_RPM_BUILD_SOURCE_DIRS_PREFIX}/src_${index_}" debuginfo_dir_len)
+ if(source_dir_len_ LESS debuginfo_dir_len)
+ message(FATAL_ERROR "CPackRPM: source dir path '${source_dir_}' is"
+ " longer than debuginfo sources dir path '${CPACK_RPM_BUILD_SOURCE_DIRS_PREFIX}/src_${index_}'!"
+ " Source dir path must be shorter than debuginfo sources dir path."
+ " Set CPACK_RPM_BUILD_SOURCE_DIRS_PREFIX variable to a shorter value"
+ " or make source dir path longer."
+ " Required for debuginfo packaging. See documentation of"
+ " CPACK_RPM_DEBUGINFO_PACKAGE variable for details.")
+ endif()
+
+ file(REMOVE "${CPACK_RPM_DIRECTORY}/${CPACK_PACKAGE_FILE_NAME}${CPACK_RPM_PACKAGE_COMPONENT_PART_PATH}/debugsources_add.list")
+ execute_process(COMMAND "${DEBUGEDIT_EXECUTABLE}" -b "${source_dir_}" -d "${CPACK_RPM_BUILD_SOURCE_DIRS_PREFIX}/src_${index_}" -i -l "${CPACK_RPM_DIRECTORY}/${CPACK_PACKAGE_FILE_NAME}${CPACK_RPM_PACKAGE_COMPONENT_PART_PATH}/debugsources_add.list" "${WORKING_DIR}/${F}"
+ RESULT_VARIABLE res_
+ OUTPUT_VARIABLE opt_
+ ERROR_VARIABLE err_
+ )
+
+ file(STRINGS
+ "${CPACK_RPM_DIRECTORY}/${CPACK_PACKAGE_FILE_NAME}${CPACK_RPM_PACKAGE_COMPONENT_PART_PATH}/debugsources_add.list"
+ sources_)
+ list(REMOVE_DUPLICATES sources_)
+
+ foreach(source_ IN LISTS sources_)
+ if(EXISTS "${source_dir_}/${source_}" AND NOT IS_DIRECTORY "${source_dir_}/${source_}")
+ get_filename_component(path_part_ "${source_}" DIRECTORY)
+ list(APPEND mkdir_list_ "%{buildroot}${CPACK_RPM_BUILD_SOURCE_DIRS_PREFIX}/src_${index_}/${path_part_}")
+ list(APPEND cp_list_ "cp \"${source_dir_}/${source_}\" \"%{buildroot}${CPACK_RPM_BUILD_SOURCE_DIRS_PREFIX}/src_${index_}/${path_part_}\"")
+
+ list(APPEND additional_sources_ "${CPACK_RPM_BUILD_SOURCE_DIRS_PREFIX}/src_${index_}/${source_}")
+ endif()
+ endforeach()
+
+ math(EXPR index_ "${index_} + 1")
+ endforeach()
+ else()
message(WARNING "CPackRPM: File: ${F} does not contain debug symbols. They will possibly be missing from debuginfo package!")
endif()
endif()
endforeach()
+
+ list(REMOVE_DUPLICATES mkdir_list_)
+ unset(TMP_RPM_DEBUGINFO_INSTALL)
+ foreach(part_ IN LISTS mkdir_list_)
+ string(APPEND TMP_RPM_DEBUGINFO_INSTALL "mkdir -p \"${part_}\"\n")
+ endforeach()
+
+ list(REMOVE_DUPLICATES cp_list_)
+ foreach(part_ IN LISTS cp_list_)
+ string(APPEND TMP_RPM_DEBUGINFO_INSTALL "${part_}\n")
+ endforeach()
+
+ if(NOT DEFINED CPACK_RPM_DEBUGINFO_EXCLUDE_DIRS)
+ set(CPACK_RPM_DEBUGINFO_EXCLUDE_DIRS /usr /usr/src /usr/src/debug)
+ if(CPACK_RPM_DEBUGINFO_EXCLUDE_DIRS_ADDITION)
+ if(CPACK_RPM_PACKAGE_DEBUG)
+ message("CPackRPM:Debug: Adding ${CPACK_RPM_DEBUGINFO_EXCLUDE_DIRS_ADDITION} to builtin omit list.")
+ endif()
+ list(APPEND CPACK_RPM_DEBUGINFO_EXCLUDE_DIRS "${CPACK_RPM_DEBUGINFO_EXCLUDE_DIRS_ADDITION}")
+ endif()
+ endif()
+ if(CPACK_RPM_PACKAGE_DEBUG)
+ message("CPackRPM:Debug: CPACK_RPM_DEBUGINFO_EXCLUDE_DIRS= ${CPACK_RPM_DEBUGINFO_EXCLUDE_DIRS}")
+ endif()
+
+ list(REMOVE_DUPLICATES additional_sources_)
+ unset(additional_sources_all_)
+ foreach(source_ IN LISTS additional_sources_)
+ string(REPLACE "/" ";" split_source_ " ${source_}")
+ list(REMOVE_AT split_source_ 0)
+ unset(tmp_path_)
+ # Now generate all segments of the path
+ foreach(segment_ IN LISTS split_source_)
+ string(APPEND tmp_path_ "/${segment_}")
+ list(APPEND additional_sources_all_ "${tmp_path_}")
+ endforeach()
+ endforeach()
+
+ list(REMOVE_DUPLICATES additional_sources_all_)
+ list(REMOVE_ITEM additional_sources_all_ ${CPACK_RPM_DEBUGINFO_EXCLUDE_DIRS})
+
+ unset(TMP_DEBUGINFO_ADDITIONAL_SOURCES)
+ foreach(source_ IN LISTS additional_sources_all_)
+ string(APPEND TMP_DEBUGINFO_ADDITIONAL_SOURCES "${source_}\n")
+ endforeach()
+
+ set(TMP_RPM_DEBUGINFO_INSTALL "${TMP_RPM_DEBUGINFO_INSTALL}" PARENT_SCOPE)
+ set(TMP_DEBUGINFO_ADDITIONAL_SOURCES "${TMP_DEBUGINFO_ADDITIONAL_SOURCES}" PARENT_SCOPE)
endfunction()
function(cpack_rpm_variable_fallback OUTPUT_VAR_NAME)
@@ -1860,6 +2053,41 @@ function(cpack_rpm_generate_package)
set(CPACK_RPM_ABSOLUTE_INSTALL_FILES "")
endif()
+ cpack_rpm_variable_fallback("CPACK_RPM_DEBUGINFO_PACKAGE"
+ "CPACK_RPM_${CPACK_RPM_PACKAGE_COMPONENT}_DEBUGINFO_PACKAGE"
+ "CPACK_RPM_${CPACK_RPM_PACKAGE_COMPONENT_UPPER}_DEBUGINFO_PACKAGE"
+ "CPACK_RPM_DEBUGINFO_PACKAGE")
+ if(CPACK_RPM_DEBUGINFO_PACKAGE)
+ cpack_rpm_variable_fallback("CPACK_RPM_BUILD_SOURCE_DIRS_PREFIX"
+ "CPACK_RPM_${CPACK_RPM_PACKAGE_COMPONENT}_BUILD_SOURCE_DIRS_PREFIX"
+ "CPACK_RPM_${CPACK_RPM_PACKAGE_COMPONENT_UPPER}_BUILD_SOURCE_DIRS_PREFIX"
+ "CPACK_RPM_BUILD_SOURCE_DIRS_PREFIX")
+ if(NOT CPACK_RPM_BUILD_SOURCE_DIRS_PREFIX)
+ set(CPACK_RPM_BUILD_SOURCE_DIRS_PREFIX "/usr/src/debug/${CPACK_PACKAGE_FILE_NAME}${CPACK_RPM_PACKAGE_COMPONENT_PART_PATH}")
+ endif()
+ cpack_rpm_debugsymbol_check("${CPACK_RPM_INSTALL_FILES}" "${WDIR}")
+
+ set(TMP_RPM_DEBUGINFO "
+# Modified version of %%debug_package macro
+# defined in /usr/lib/rpm/macros as that one
+# can't handle injection of extra source files.
+%ifnarch noarch
+%global __debug_package 1
+%package debuginfo
+Summary: Debug information for package %{name}
+Group: Development/Debug
+AutoReqProv: 0
+%description debuginfo
+This package provides debug information for package %{name}.
+Debug information is useful when developing applications that use this
+package or when debugging this package.
+%files debuginfo -f debugfiles.list
+%defattr(-,root,root)
+${TMP_DEBUGINFO_ADDITIONAL_SOURCES}
+%endif
+")
+ endif()
+
# Prepare install files
cpack_rpm_prepare_install_files(
"${CPACK_RPM_INSTALL_FILES}"
@@ -1919,15 +2147,6 @@ function(cpack_rpm_generate_package)
"CPACK_RPM_${CPACK_RPM_PACKAGE_COMPONENT_UPPER}_USER_BINARY_SPECFILE")
endif()
- cpack_rpm_variable_fallback("CPACK_RPM_DEBUGINFO_PACKAGE"
- "CPACK_RPM_${CPACK_RPM_PACKAGE_COMPONENT}_DEBUGINFO_PACKAGE"
- "CPACK_RPM_${CPACK_RPM_PACKAGE_COMPONENT_UPPER}_DEBUGINFO_PACKAGE"
- "CPACK_RPM_DEBUGINFO_PACKAGE")
- if(CPACK_RPM_DEBUGINFO_PACKAGE)
- cpack_rpm_debugsymbol_check("${CPACK_ABSOLUTE_DESTINATION_FILES}" "${WDIR}")
- set(TMP_RPM_DEBUGINFO "%debug_package")
- endif()
-
cpack_rpm_variable_fallback("CPACK_RPM_FILE_NAME"
"CPACK_RPM_${CPACK_RPM_PACKAGE_COMPONENT}_FILE_NAME"
"CPACK_RPM_${CPACK_RPM_PACKAGE_COMPONENT_UPPER}_FILE_NAME"
@@ -2104,6 +2323,8 @@ then
fi
mv %_topdir/tmpBBroot $RPM_BUILD_ROOT
+\@TMP_RPM_DEBUGINFO_INSTALL\@
+
%clean
%post
@@ -2158,7 +2379,7 @@ mv %_topdir/tmpBBroot $RPM_BUILD_ROOT
execute_process(
COMMAND "${RPMBUILD_EXECUTABLE}" ${RPMBUILD_FLAGS}
--define "_topdir ${CPACK_RPM_DIRECTORY}"
- --buildroot "%_topdir/${CPACK_PACKAGE_FILE_NAME}${CPACK_RPM_PACKAGE_COMPONENT_PART_PATH}" # TODO should I remove this variable? or change the path?
+ --buildroot "%_topdir/${CPACK_PACKAGE_FILE_NAME}${CPACK_RPM_PACKAGE_COMPONENT_PART_PATH}"
--target "${CPACK_RPM_PACKAGE_ARCHITECTURE}"
"${CPACK_RPM_BINARY_SPECFILE}"
WORKING_DIRECTORY "${CPACK_TOPLEVEL_DIRECTORY}/${CPACK_PACKAGE_FILE_NAME}${CPACK_RPM_PACKAGE_COMPONENT_PART_PATH}"
diff --git a/Modules/FindBoost.cmake b/Modules/FindBoost.cmake
index 1f03841f4a..b3e8db914a 100644
--- a/Modules/FindBoost.cmake
+++ b/Modules/FindBoost.cmake
@@ -742,6 +742,21 @@ function(_Boost_COMPONENT_DEPENDENCIES component _ret)
set(_Boost_THREAD_DEPENDENCIES chrono system date_time atomic)
set(_Boost_WAVE_DEPENDENCIES filesystem system serialization thread chrono date_time atomic)
set(_Boost_WSERIALIZATION_DEPENDENCIES serialization)
+ elseif(NOT Boost_VERSION VERSION_LESS 106200 AND Boost_VERSION VERSION_LESS 106300)
+ set(_Boost_CHRONO_DEPENDENCIES system)
+ set(_Boost_CONTEXT_DEPENDENCIES thread chrono system date_time)
+ set(_Boost_COROUTINE_DEPENDENCIES context system)
+ set(_Boost_FIBER_DEPENDENCIES context thread chrono system date_time)
+ set(_Boost_FILESYSTEM_DEPENDENCIES system)
+ set(_Boost_IOSTREAMS_DEPENDENCIES regex)
+ set(_Boost_LOG_DEPENDENCIES date_time log_setup system filesystem thread regex chrono atomic)
+ set(_Boost_MATH_DEPENDENCIES math_c99 math_c99f math_c99l math_tr1 math_tr1f math_tr1l atomic)
+ set(_Boost_MPI_DEPENDENCIES serialization)
+ set(_Boost_MPI_PYTHON_DEPENDENCIES python mpi serialization)
+ set(_Boost_RANDOM_DEPENDENCIES system)
+ set(_Boost_THREAD_DEPENDENCIES chrono system date_time atomic)
+ set(_Boost_WAVE_DEPENDENCIES filesystem system serialization thread chrono date_time atomic)
+ set(_Boost_WSERIALIZATION_DEPENDENCIES serialization)
else()
message(WARNING "Imported targets not available for Boost version ${Boost_VERSION}")
set(_Boost_IMPORTED_TARGETS FALSE)
@@ -777,6 +792,7 @@ function(_Boost_COMPONENT_HEADERS component _hdrs)
set(_Boost_COROUTINE_HEADERS "boost/coroutine/all.hpp")
set(_Boost_EXCEPTION_HEADERS "boost/exception/exception.hpp")
set(_Boost_DATE_TIME_HEADERS "boost/date_time/date.hpp")
+ set(_Boost_FIBER_HEADERS "boost/fiber/all.hpp")
set(_Boost_FILESYSTEM_HEADERS "boost/filesystem/path.hpp")
set(_Boost_GRAPH_HEADERS "boost/graph/adjacency_list.hpp")
set(_Boost_GRAPH_PARALLEL_HEADERS "boost/graph/adjacency_list.hpp")
diff --git a/Modules/FindMatlab.cmake b/Modules/FindMatlab.cmake
index 8b41bb938c..d016848a88 100644
--- a/Modules/FindMatlab.cmake
+++ b/Modules/FindMatlab.cmake
@@ -225,6 +225,7 @@ set(_FindMatlab_SELF_DIR "${CMAKE_CURRENT_LIST_DIR}")
include(FindPackageHandleStandardArgs)
include(CheckCXXCompilerFlag)
+include(CheckCCompilerFlag)
# The currently supported versions. Other version can be added by the user by
@@ -871,7 +872,11 @@ function(matlab_add_mex)
if(NOT WIN32)
# we do not need all this on Windows
# pthread options
- check_cxx_compiler_flag(-pthread HAS_MINUS_PTHREAD)
+ if(CMAKE_CXX_COMPILER_LOADED)
+ check_cxx_compiler_flag(-pthread HAS_MINUS_PTHREAD)
+ elseif(CMAKE_C_COMPILER_LOADED)
+ check_c_compiler_flag(-pthread HAS_MINUS_PTHREAD)
+ endif()
# we should use try_compile instead, the link flags are discarded from
# this compiler_flag function.
#check_cxx_compiler_flag(-Wl,--exclude-libs,ALL HAS_SYMBOL_HIDING_CAPABILITY)
diff --git a/Source/CMakeVersion.cmake b/Source/CMakeVersion.cmake
index 9a10ddbe14..e4f5e01aea 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 6)
-set(CMake_VERSION_PATCH 20160926)
+set(CMake_VERSION_PATCH 20160928)
#set(CMake_VERSION_RC 1)
diff --git a/Source/CPack/cmCPackNSISGenerator.cxx b/Source/CPack/cmCPackNSISGenerator.cxx
index 2db94f118d..b49da7f188 100644
--- a/Source/CPack/cmCPackNSISGenerator.cxx
+++ b/Source/CPack/cmCPackNSISGenerator.cxx
@@ -71,14 +71,26 @@ int cmCPackNSISGenerator::PackageFiles()
std::ostringstream str;
std::vector<std::string>::const_iterator it;
for (it = files.begin(); it != files.end(); ++it) {
+ std::string outputDir = "$INSTDIR";
std::string fileN =
cmSystemTools::RelativePath(toplevel.c_str(), it->c_str());
if (!this->Components.empty()) {
+ const std::string::size_type pos = fileN.find('/');
+
+ // Use the custom component install directory if we have one
+ if (pos != std::string::npos) {
+ const std::string componentName = fileN.substr(0, pos);
+ outputDir = CustomComponentInstallDirectory(componentName);
+ } else {
+ outputDir = CustomComponentInstallDirectory(fileN);
+ }
+
// Strip off the component part of the path.
- fileN = fileN.substr(fileN.find('/') + 1, std::string::npos);
+ fileN = fileN.substr(pos + 1, std::string::npos);
}
std::replace(fileN.begin(), fileN.end(), '/', '\\');
- str << " Delete \"$INSTDIR\\" << fileN << "\"" << std::endl;
+
+ str << " Delete \"" << outputDir << "\\" << fileN << "\"" << std::endl;
}
cmCPackLogger(cmCPackLog::LOG_DEBUG, "Uninstall Files: " << str.str()
<< std::endl);
@@ -108,7 +120,12 @@ int cmCPackNSISGenerator::PackageFiles()
}
}
std::replace(fileN.begin(), fileN.end(), '/', '\\');
- dstr << " RMDir \"$INSTDIR\\" << fileN << "\"" << std::endl;
+
+ const std::string componentOutputDir =
+ CustomComponentInstallDirectory(componentName);
+
+ dstr << " RMDir \"" << componentOutputDir << "\\" << fileN << "\""
+ << std::endl;
if (!componentName.empty()) {
this->Components[componentName].Directories.push_back(fileN);
}
@@ -650,7 +667,10 @@ std::string cmCPackNSISGenerator::CreateComponentDescription(
}
componentCode += " SectionIn" + out.str() + "\n";
}
- componentCode += " SetOutPath \"$INSTDIR\"\n";
+
+ const std::string componentOutputDir =
+ CustomComponentInstallDirectory(component->Name);
+ componentCode += " SetOutPath \"" + componentOutputDir + "\"\n";
// Create the actual installation commands
if (component->IsDownloaded) {
@@ -796,13 +816,13 @@ std::string cmCPackNSISGenerator::CreateComponentDescription(
++pathIt) {
path = *pathIt;
std::replace(path.begin(), path.end(), '/', '\\');
- macrosOut << " Delete \"$INSTDIR\\" << path << "\"\n";
+ macrosOut << " Delete \"" << componentOutputDir << "\\" << path << "\"\n";
}
for (pathIt = component->Directories.begin();
pathIt != component->Directories.end(); ++pathIt) {
path = *pathIt;
std::replace(path.begin(), path.end(), '/', '\\');
- macrosOut << " RMDir \"$INSTDIR\\" << path << "\"\n";
+ macrosOut << " RMDir \"" << componentOutputDir << "\\" << path << "\"\n";
}
macrosOut << " noremove_" << component->Name << ":\n";
macrosOut << "!macroend\n";
@@ -914,6 +934,15 @@ std::string cmCPackNSISGenerator::CreateComponentGroupDescription(
return code;
}
+std::string cmCPackNSISGenerator::CustomComponentInstallDirectory(
+ const std::string& componentName)
+{
+ const char* outputDir =
+ this->GetOption("CPACK_NSIS_" + componentName + "_INSTALL_DIRECTORY");
+ const std::string componentOutputDir = (outputDir ? outputDir : "$INSTDIR");
+ return componentOutputDir;
+}
+
std::string cmCPackNSISGenerator::TranslateNewlines(std::string str)
{
cmSystemTools::ReplaceString(str, "\n", "$\\r$\\n");
diff --git a/Source/CPack/cmCPackNSISGenerator.h b/Source/CPack/cmCPackNSISGenerator.h
index ae03e6b5d3..bd7d752eea 100644
--- a/Source/CPack/cmCPackNSISGenerator.h
+++ b/Source/CPack/cmCPackNSISGenerator.h
@@ -84,6 +84,11 @@ protected:
std::string CreateComponentGroupDescription(cmCPackComponentGroup* group,
std::ostream& macrosOut);
+ /// Returns the custom install directory if available for the specified
+ /// component, otherwise $INSTDIR is returned.
+ std::string CustomComponentInstallDirectory(
+ const std::string& componentName);
+
/// Translations any newlines found in the string into \\r\\n, so that the
/// resulting string can be used within NSIS.
static std::string TranslateNewlines(std::string str);
diff --git a/Source/cmExtraCodeLiteGenerator.cxx b/Source/cmExtraCodeLiteGenerator.cxx
index a039f49e30..aaaa07ad14 100644
--- a/Source/cmExtraCodeLiteGenerator.cxx
+++ b/Source/cmExtraCodeLiteGenerator.cxx
@@ -70,6 +70,8 @@ void cmExtraCodeLiteGenerator::Generate()
// loop projects and locate the root project.
// and extract the information for creating the worspace
+ // root makefile
+ const cmMakefile* rmf = CM_NULLPTR;
for (std::map<std::string, std::vector<cmLocalGenerator*> >::const_iterator
it = projectMap.begin();
it != projectMap.end(); ++it) {
@@ -84,6 +86,7 @@ void cmExtraCodeLiteGenerator::Generate()
workspaceFileName = workspaceOutputDir + "/";
workspaceFileName += workspaceProjectName + ".workspace";
this->WorkspacePath = it->second[0]->GetCurrentBinaryDirectory();
+ rmf = it->second[0]->GetMakefile();
;
break;
}
@@ -96,26 +99,14 @@ void cmExtraCodeLiteGenerator::Generate()
xml.StartElement("CodeLite_Workspace");
xml.Attribute("Name", workspaceProjectName);
- // for each sub project in the workspace create a codelite project
- for (std::map<std::string, std::vector<cmLocalGenerator*> >::const_iterator
- it = projectMap.begin();
- it != projectMap.end(); ++it) {
- // retrive project information
- std::string outputDir = it->second[0]->GetCurrentBinaryDirectory();
- std::string projectName = it->second[0]->GetProjectName();
- std::string filename = outputDir + "/" + projectName + ".project";
-
- // Make the project file relative to the workspace
- filename = cmSystemTools::RelativePath(this->WorkspacePath.c_str(),
- filename.c_str());
+ bool const targetsAreProjects =
+ rmf && rmf->IsOn("CMAKE_CODELITE_USE_TARGETS");
- // create a project file
- this->CreateProjectFile(it->second);
- xml.StartElement("Project");
- xml.Attribute("Name", projectName);
- xml.Attribute("Path", filename);
- xml.Attribute("Active", "No");
- xml.EndElement();
+ std::vector<std::string> ProjectNames;
+ if (targetsAreProjects) {
+ ProjectNames = CreateProjectsByTarget(&xml);
+ } else {
+ ProjectNames = CreateProjectsByProjectMaps(&xml);
}
xml.StartElement("BuildMatrix");
@@ -123,14 +114,10 @@ void cmExtraCodeLiteGenerator::Generate()
xml.Attribute("Name", this->ConfigName);
xml.Attribute("Selected", "yes");
- for (std::map<std::string, std::vector<cmLocalGenerator*> >::const_iterator
- it = projectMap.begin();
- it != projectMap.end(); ++it) {
- // retrive project information
- std::string projectName = it->second[0]->GetProjectName();
-
+ for (std::vector<std::string>::iterator it(ProjectNames.begin());
+ it != ProjectNames.end(); it++) {
xml.StartElement("Project");
- xml.Attribute("Name", projectName);
+ xml.Attribute("Name", *it);
xml.Attribute("ConfigName", this->ConfigName);
xml.EndElement();
}
@@ -140,6 +127,79 @@ void cmExtraCodeLiteGenerator::Generate()
xml.EndElement(); // CodeLite_Workspace
}
+// Create projects where targets are the projects
+std::vector<std::string> cmExtraCodeLiteGenerator::CreateProjectsByTarget(
+ cmXMLWriter* xml)
+{
+ std::vector<std::string> retval;
+ // for each target in the workspace create a codelite project
+ const std::vector<cmLocalGenerator*>& lgs =
+ this->GlobalGenerator->GetLocalGenerators();
+ for (std::vector<cmLocalGenerator*>::const_iterator lg(lgs.begin());
+ lg != lgs.end(); lg++) {
+ for (std::vector<cmGeneratorTarget*>::const_iterator lt =
+ (*lg)->GetGeneratorTargets().begin();
+ lt != (*lg)->GetGeneratorTargets().end(); lt++) {
+ cmState::TargetType type = (*lt)->GetType();
+ std::string outputDir = (*lg)->GetCurrentBinaryDirectory();
+ std::string filename = outputDir + "/" + (*lt)->GetName() + ".project";
+ retval.push_back((*lt)->GetName());
+ // Make the project file relative to the workspace
+ std::string relafilename = cmSystemTools::RelativePath(
+ this->WorkspacePath.c_str(), filename.c_str());
+ std::string visualname = (*lt)->GetName();
+ switch (type) {
+ case cmState::SHARED_LIBRARY:
+ case cmState::STATIC_LIBRARY:
+ case cmState::MODULE_LIBRARY:
+ visualname = "lib" + visualname;
+ case cmState::EXECUTABLE:
+ xml->StartElement("Project");
+ xml->Attribute("Name", visualname);
+ xml->Attribute("Path", relafilename);
+ xml->Attribute("Active", "No");
+ xml->EndElement();
+
+ CreateNewProjectFile(*lt, filename);
+ break;
+ default:
+ break;
+ }
+ }
+ }
+ return retval;
+}
+
+// The "older way of doing it.
+std::vector<std::string> cmExtraCodeLiteGenerator::CreateProjectsByProjectMaps(
+ cmXMLWriter* xml)
+{
+ std::vector<std::string> retval;
+ // for each sub project in the workspace create a codelite project
+ for (std::map<std::string, std::vector<cmLocalGenerator*> >::const_iterator
+ it = this->GlobalGenerator->GetProjectMap().begin();
+ it != this->GlobalGenerator->GetProjectMap().end(); it++) {
+
+ std::string outputDir = it->second[0]->GetCurrentBinaryDirectory();
+ std::string projectName = it->second[0]->GetProjectName();
+ retval.push_back(projectName);
+ std::string filename = outputDir + "/" + projectName + ".project";
+
+ // Make the project file relative to the workspace
+ filename = cmSystemTools::RelativePath(this->WorkspacePath.c_str(),
+ filename.c_str());
+
+ // create a project file
+ this->CreateProjectFile(it->second);
+ xml->StartElement("Project");
+ xml->Attribute("Name", projectName);
+ xml->Attribute("Path", filename);
+ xml->Attribute("Active", "No");
+ xml->EndElement();
+ }
+ return retval;
+}
+
/* create the project file */
void cmExtraCodeLiteGenerator::CreateProjectFile(
const std::vector<cmLocalGenerator*>& lgs)
@@ -152,6 +212,70 @@ void cmExtraCodeLiteGenerator::CreateProjectFile(
this->CreateNewProjectFile(lgs, filename);
}
+std::string cmExtraCodeLiteGenerator::CollectSourceFiles(
+ const cmMakefile* makefile, const cmGeneratorTarget* gt,
+ std::map<std::string, cmSourceFile*>& cFiles,
+ std::set<std::string>& otherFiles)
+{
+ const std::vector<std::string>& srcExts =
+ this->GlobalGenerator->GetCMakeInstance()->GetSourceExtensions();
+
+ std::string projectType;
+ switch (gt->GetType()) {
+ case cmState::EXECUTABLE: {
+ projectType = "Executable";
+ } break;
+ case cmState::STATIC_LIBRARY: {
+ projectType = "Static Library";
+ } break;
+ case cmState::SHARED_LIBRARY: {
+ projectType = "Dynamic Library";
+ } break;
+ case cmState::MODULE_LIBRARY: {
+ projectType = "Dynamic Library";
+ } break;
+ default: // intended fallthrough
+ break;
+ }
+
+ switch (gt->GetType()) {
+ case cmState::EXECUTABLE:
+ case cmState::STATIC_LIBRARY:
+ case cmState::SHARED_LIBRARY:
+ case cmState::MODULE_LIBRARY: {
+ std::vector<cmSourceFile*> sources;
+ gt->GetSourceFiles(sources,
+ makefile->GetSafeDefinition("CMAKE_BUILD_TYPE"));
+ for (std::vector<cmSourceFile*>::const_iterator si = sources.begin();
+ si != sources.end(); si++) {
+ // check whether it is a C/C++ implementation file
+ bool isCFile = false;
+ std::string lang = (*si)->GetLanguage();
+ if (lang == "C" || lang == "CXX") {
+ std::string srcext = (*si)->GetExtension();
+ for (std::vector<std::string>::const_iterator ext = srcExts.begin();
+ ext != srcExts.end(); ++ext) {
+ if (srcext == *ext) {
+ isCFile = true;
+ break;
+ }
+ }
+ }
+
+ // then put it accordingly into one of the two containers
+ if (isCFile) {
+ cFiles[(*si)->GetFullPath()] = *si;
+ } else {
+ otherFiles.insert((*si)->GetFullPath());
+ }
+ }
+ }
+ default: // intended fallthrough
+ break;
+ }
+ return projectType;
+}
+
void cmExtraCodeLiteGenerator::CreateNewProjectFile(
const std::vector<cmLocalGenerator*>& lgs, const std::string& filename)
{
@@ -168,81 +292,41 @@ void cmExtraCodeLiteGenerator::CreateNewProjectFile(
xml.Attribute("Name", lgs[0]->GetProjectName());
xml.Attribute("InternalType", "");
+ std::string projectType;
+
// Collect all used source files in the project
// Sort them into two containers, one for C/C++ implementation files
// which may have an acompanying header, one for all other files
- std::string projectType;
-
- std::vector<std::string> srcExts =
- this->GlobalGenerator->GetCMakeInstance()->GetSourceExtensions();
- std::vector<std::string> headerExts =
- this->GlobalGenerator->GetCMakeInstance()->GetHeaderExtensions();
-
std::map<std::string, cmSourceFile*> cFiles;
std::set<std::string> otherFiles;
+
for (std::vector<cmLocalGenerator*>::const_iterator lg = lgs.begin();
lg != lgs.end(); lg++) {
cmMakefile* makefile = (*lg)->GetMakefile();
std::vector<cmGeneratorTarget*> targets = (*lg)->GetGeneratorTargets();
for (std::vector<cmGeneratorTarget*>::iterator ti = targets.begin();
ti != targets.end(); ti++) {
+ projectType = CollectSourceFiles(makefile, *ti, cFiles, otherFiles);
+ }
+ }
- switch ((*ti)->GetType()) {
- case cmState::EXECUTABLE: {
- projectType = "Executable";
- } break;
- case cmState::STATIC_LIBRARY: {
- projectType = "Static Library";
- } break;
- case cmState::SHARED_LIBRARY: {
- projectType = "Dynamic Library";
- } break;
- case cmState::MODULE_LIBRARY: {
- projectType = "Dynamic Library";
- } break;
- default: // intended fallthrough
- break;
- }
+ // Get the project path ( we need it later to convert files to
+ // their relative path)
+ std::string projectPath = cmSystemTools::GetFilenamePath(filename);
- switch ((*ti)->GetType()) {
- case cmState::EXECUTABLE:
- case cmState::STATIC_LIBRARY:
- case cmState::SHARED_LIBRARY:
- case cmState::MODULE_LIBRARY: {
- std::vector<cmSourceFile*> sources;
- cmGeneratorTarget* gt = *ti;
- gt->GetSourceFiles(sources,
- makefile->GetSafeDefinition("CMAKE_BUILD_TYPE"));
- for (std::vector<cmSourceFile*>::const_iterator si = sources.begin();
- si != sources.end(); si++) {
- // check whether it is a C/C++ implementation file
- bool isCFile = false;
- std::string lang = (*si)->GetLanguage();
- if (lang == "C" || lang == "CXX") {
- std::string srcext = (*si)->GetExtension();
- for (std::vector<std::string>::const_iterator ext =
- srcExts.begin();
- ext != srcExts.end(); ++ext) {
- if (srcext == *ext) {
- isCFile = true;
- break;
- }
- }
- }
+ CreateProjectSourceEntries(cFiles, otherFiles, &xml, projectPath, mf,
+ projectType);
- // then put it accordingly into one of the two containers
- if (isCFile) {
- cFiles[(*si)->GetFullPath()] = *si;
- } else {
- otherFiles.insert((*si)->GetFullPath());
- }
- }
- }
- default: // intended fallthrough
- break;
- }
- }
- }
+ xml.EndElement(); // CodeLite_Project
+}
+
+void cmExtraCodeLiteGenerator::FindMatchingHeaderfiles(
+ std::map<std::string, cmSourceFile*>& cFiles,
+ std::set<std::string>& otherFiles)
+{
+
+ const std::vector<std::string>& headerExts =
+ this->GlobalGenerator->GetCMakeInstance()->GetHeaderExtensions();
// The following loop tries to add header files matching to implementation
// files to the project. It does that by iterating over all source files,
@@ -275,11 +359,17 @@ void cmExtraCodeLiteGenerator::CreateNewProjectFile(
}
}
}
+}
- // Get the project path ( we need it later to convert files to
- // their relative path)
- std::string projectPath = cmSystemTools::GetFilenamePath(filename);
+void cmExtraCodeLiteGenerator::CreateProjectSourceEntries(
+ std::map<std::string, cmSourceFile*>& cFiles,
+ std::set<std::string>& otherFiles, cmXMLWriter* _xml,
+ const std::string& projectPath, const cmMakefile* mf,
+ const std::string& projectType)
+{
+ cmXMLWriter& xml(*_xml);
+ FindMatchingHeaderfiles(cFiles, otherFiles);
// Create 2 virtual folders: src and include
// and place all the implementation files into the src
// folder, the rest goes to the include folder
@@ -292,8 +382,10 @@ void cmExtraCodeLiteGenerator::CreateNewProjectFile(
cFiles.begin();
sit != cFiles.end(); ++sit) {
xml.StartElement("File");
- xml.Attribute("Name", cmSystemTools::RelativePath(projectPath.c_str(),
- sit->first.c_str()));
+ std::string fpath(sit->first);
+ std::string frelapath =
+ cmSystemTools::RelativePath(projectPath.c_str(), sit->first.c_str());
+ xml.Attribute("Name", frelapath);
xml.EndElement();
}
xml.EndElement(); // VirtualDirectory
@@ -350,11 +442,18 @@ void cmExtraCodeLiteGenerator::CreateNewProjectFile(
xml.EndElement(); // ResourceCompiler
xml.StartElement("General");
- xml.Attribute("OutputFile", "$(IntermediateDirectory)/$(ProjectName)");
+ std::string outputPath = mf->GetSafeDefinition("EXECUTABLE_OUTPUT_PATH");
+ if (!outputPath.empty())
+ xml.Attribute("OutputFile", outputPath + "/$(ProjectName)");
+ else
+ xml.Attribute("OutputFile", "$(IntermediateDirectory)/$(ProjectName)");
xml.Attribute("IntermediateDirectory", "./");
xml.Attribute("Command", "./$(ProjectName)");
xml.Attribute("CommandArguments", "");
- xml.Attribute("WorkingDirectory", "$(IntermediateDirectory)");
+ if (!outputPath.empty())
+ xml.Attribute("WorkingDirectory", outputPath);
+ else
+ xml.Attribute("WorkingDirectory", "$(IntermediateDirectory)");
xml.Attribute("PauseExecWhenProcTerminates", "yes");
xml.EndElement(); // General
@@ -408,6 +507,53 @@ void cmExtraCodeLiteGenerator::CreateNewProjectFile(
xml.EndElement(); // GlobalSettings
xml.EndElement(); // Settings
+}
+
+void cmExtraCodeLiteGenerator::CreateNewProjectFile(
+ const cmGeneratorTarget* gt, const std::string& filename)
+{
+ const cmMakefile* mf = gt->Makefile;
+ cmGeneratedFileStream fout(filename.c_str());
+ if (!fout) {
+ return;
+ }
+ cmXMLWriter xml(fout);
+
+ ////////////////////////////////////
+ xml.StartDocument("utf-8");
+ xml.StartElement("CodeLite_Project");
+ std::string visualname = gt->GetName();
+ switch (gt->GetType()) {
+ case cmState::STATIC_LIBRARY:
+ case cmState::SHARED_LIBRARY:
+ case cmState::MODULE_LIBRARY:
+ visualname = "lib" + visualname;
+ default: // intended fallthrough
+ break;
+ }
+ xml.Attribute("Name", visualname);
+ xml.Attribute("InternalType", "");
+
+ // Collect all used source files in the project
+ // Sort them into two containers, one for C/C++ implementation files
+ // which may have an acompanying header, one for all other files
+ std::string projectType;
+
+ std::vector<std::string> headerExts =
+ this->GlobalGenerator->GetCMakeInstance()->GetHeaderExtensions();
+
+ std::map<std::string, cmSourceFile*> cFiles;
+ std::set<std::string> otherFiles;
+
+ projectType = CollectSourceFiles(mf, gt, cFiles, otherFiles);
+
+ // Get the project path ( we need it later to convert files to
+ // their relative path)
+ std::string projectPath = cmSystemTools::GetFilenamePath(filename);
+
+ CreateProjectSourceEntries(cFiles, otherFiles, &xml, projectPath, mf,
+ projectType);
+
xml.EndElement(); // CodeLite_Project
}
diff --git a/Source/cmExtraCodeLiteGenerator.h b/Source/cmExtraCodeLiteGenerator.h
index f5765d85d0..9c571a5f15 100644
--- a/Source/cmExtraCodeLiteGenerator.h
+++ b/Source/cmExtraCodeLiteGenerator.h
@@ -18,11 +18,16 @@
#include "cmExternalMakefileProjectGenerator.h"
+#include <map>
+#include <set>
#include <string>
#include <vector>
class cmLocalGenerator;
class cmMakefile;
+class cmGeneratorTarget;
+class cmXMLWriter;
+class cmSourceFile;
class cmExtraCodeLiteGenerator : public cmExternalMakefileProjectGenerator
{
@@ -38,6 +43,20 @@ protected:
std::string GetCleanCommand(const cmMakefile* mf) const;
std::string GetRebuildCommand(const cmMakefile* mf) const;
std::string GetSingleFileBuildCommand(const cmMakefile* mf) const;
+ std::vector<std::string> CreateProjectsByTarget(cmXMLWriter* xml);
+ std::vector<std::string> CreateProjectsByProjectMaps(cmXMLWriter* xml);
+ std::string CollectSourceFiles(const cmMakefile* makefile,
+ const cmGeneratorTarget* gt,
+ std::map<std::string, cmSourceFile*>& cFiles,
+ std::set<std::string>& otherFiles);
+ void FindMatchingHeaderfiles(std::map<std::string, cmSourceFile*>& cFiles,
+ std::set<std::string>& otherFiles);
+ void CreateProjectSourceEntries(std::map<std::string, cmSourceFile*>& cFiles,
+ std::set<std::string>& otherFiles,
+ cmXMLWriter* xml,
+ const std::string& projectPath,
+ const cmMakefile* mf,
+ const std::string& projectType);
public:
cmExtraCodeLiteGenerator();
@@ -49,6 +68,8 @@ public:
void CreateNewProjectFile(const std::vector<cmLocalGenerator*>& lgs,
const std::string& filename);
+ void CreateNewProjectFile(const cmGeneratorTarget* lg,
+ const std::string& filename);
};
#endif
diff --git a/Source/cmGlobalGenerator.cxx b/Source/cmGlobalGenerator.cxx
index 95747f2f74..4c62be7de4 100644
--- a/Source/cmGlobalGenerator.cxx
+++ b/Source/cmGlobalGenerator.cxx
@@ -1059,6 +1059,7 @@ void cmGlobalGenerator::Configure()
cmMakefile* dirMf = new cmMakefile(this, snapshot);
this->Makefiles.push_back(dirMf);
+ this->IndexMakefile(dirMf);
this->BinaryDirectories.insert(
this->CMakeInstance->GetHomeOutputDirectory());
@@ -1528,6 +1529,7 @@ void cmGlobalGenerator::ClearGeneratorMembers()
this->TargetDependencies.clear();
this->TargetSearchIndex.clear();
this->GeneratorTargetSearchIndex.clear();
+ this->MakefileSearchIndex.clear();
this->ProjectMap.clear();
this->RuleHashes.clear();
this->DirectoryContentMap.clear();
@@ -1805,6 +1807,7 @@ std::string cmGlobalGenerator::GenerateCMakeBuildCommand(
void cmGlobalGenerator::AddMakefile(cmMakefile* mf)
{
this->Makefiles.push_back(mf);
+ this->IndexMakefile(mf);
// update progress
// estimate how many lg there will be
@@ -1962,12 +1965,9 @@ void cmGlobalGenerator::FillProjectMap()
cmMakefile* cmGlobalGenerator::FindMakefile(const std::string& start_dir) const
{
- for (std::vector<cmMakefile*>::const_iterator it = this->Makefiles.begin();
- it != this->Makefiles.end(); ++it) {
- std::string sd = (*it)->GetCurrentSourceDirectory();
- if (sd == start_dir) {
- return *it;
- }
+ MakefileMap::const_iterator i = this->MakefileSearchIndex.find(start_dir);
+ if (i != this->MakefileSearchIndex.end()) {
+ return i->second;
}
return CM_NULLPTR;
}
@@ -2012,6 +2012,17 @@ void cmGlobalGenerator::IndexGeneratorTarget(cmGeneratorTarget* gt)
}
}
+void cmGlobalGenerator::IndexMakefile(cmMakefile* mf)
+{
+ // FIXME: add_subdirectory supports multiple build directories
+ // sharing the same source directory. We currently index only the
+ // first one, because that is what FindMakefile has always returned.
+ // All of its callers will need to be modified to support looking
+ // up directories by build directory path.
+ this->MakefileSearchIndex.insert(
+ MakefileMap::value_type(mf->GetCurrentSourceDirectory(), mf));
+}
+
cmTarget* cmGlobalGenerator::FindTargetImpl(std::string const& name) const
{
TargetMap::const_iterator i = this->TargetSearchIndex.find(name);
diff --git a/Source/cmGlobalGenerator.h b/Source/cmGlobalGenerator.h
index 7bc389d878..8f1d70c1a5 100644
--- a/Source/cmGlobalGenerator.h
+++ b/Source/cmGlobalGenerator.h
@@ -462,13 +462,16 @@ private:
typedef std::unordered_map<std::string, cmTarget*> TargetMap;
typedef std::unordered_map<std::string, cmGeneratorTarget*>
GeneratorTargetMap;
+ typedef std::unordered_map<std::string, cmMakefile*> MakefileMap;
#else
typedef cmsys::hash_map<std::string, cmTarget*> TargetMap;
typedef cmsys::hash_map<std::string, cmGeneratorTarget*> GeneratorTargetMap;
+ typedef cmsys::hash_map<std::string, cmMakefile*> MakefileMap;
#endif
#else
typedef std::map<std::string, cmTarget*> TargetMap;
typedef std::map<std::string, cmGeneratorTarget*> GeneratorTargetMap;
+ typedef std::map<std::string, cmMakefile*> MakefileMap;
#endif
// Map efficiently from target name to cmTarget instance.
// Do not use this structure for looping over all targets.
@@ -476,6 +479,11 @@ private:
TargetMap TargetSearchIndex;
GeneratorTargetMap GeneratorTargetSearchIndex;
+ // Map efficiently from source directory path to cmMakefile instance.
+ // Do not use this structure for looping over all directories.
+ // It may not contain all of them (see note in IndexMakefile method).
+ MakefileMap MakefileSearchIndex;
+
cmMakefile* TryCompileOuterMakefile;
// If you add a new map here, make sure it is copied
// in EnableLanguagesFromGenerator
@@ -528,6 +536,8 @@ private:
void ClearGeneratorMembers();
+ void IndexMakefile(cmMakefile* mf);
+
virtual const char* GetBuildIgnoreErrorsFlag() const { return CM_NULLPTR; }
// Cache directory content and target files to be built.
diff --git a/Source/cmNinjaTargetGenerator.cxx b/Source/cmNinjaTargetGenerator.cxx
index b418ce3806..f88eb7bb29 100644
--- a/Source/cmNinjaTargetGenerator.cxx
+++ b/Source/cmNinjaTargetGenerator.cxx
@@ -841,6 +841,18 @@ void cmNinjaTargetGenerator::WriteObjectBuildStatement(
// directive.
ppVars["INCLUDES"] = vars["INCLUDES"];
+ // Prepend source file's original directory as an include directory
+ // so e.g. Fortran INCLUDE statements can look for files in it.
+ std::vector<std::string> sourceDirectory;
+ sourceDirectory.push_back(
+ cmSystemTools::GetParentDirectory(source->GetFullPath()));
+
+ std::string sourceDirectoryFlag = this->LocalGenerator->GetIncludeFlags(
+ sourceDirectory, this->GeneratorTarget, language, false, false,
+ this->GetConfigName());
+
+ vars["INCLUDES"] = sourceDirectoryFlag + " " + vars["INCLUDES"];
+
// Explicit preprocessing always uses a depfile.
ppVars["DEP_FILE"] =
cmGlobalNinjaGenerator::EncodeDepfileSpace(ppFileName + ".d");
diff --git a/Source/cmServerDictionary.h b/Source/cmServerDictionary.h
index 156ade2719..fc1b44dbbb 100644
--- a/Source/cmServerDictionary.h
+++ b/Source/cmServerDictionary.h
@@ -16,15 +16,23 @@
// Vocabulary:
+static const std::string kCOMPUTE_TYPE = "compute";
+static const std::string kCONFIGURE_TYPE = "configure";
static const std::string kERROR_TYPE = "error";
+static const std::string kGLOBAL_SETTINGS_TYPE = "globalSettings";
static const std::string kHANDSHAKE_TYPE = "handshake";
static const std::string kMESSAGE_TYPE = "message";
static const std::string kPROGRESS_TYPE = "progress";
static const std::string kREPLY_TYPE = "reply";
+static const std::string kSET_GLOBAL_SETTINGS_TYPE = "setGlobalSettings";
static const std::string kSIGNAL_TYPE = "signal";
static const std::string kBUILD_DIRECTORY_KEY = "buildDirectory";
+static const std::string kCACHE_ARGUMENTS_KEY = "cacheArguments";
+static const std::string kCAPABILITIES_KEY = "capabilities";
+static const std::string kCHECK_SYSTEM_VARS_KEY = "checkSystemVars";
static const std::string kCOOKIE_KEY = "cookie";
+static const std::string kDEBUG_OUTPUT_KEY = "debugOutput";
static const std::string kERROR_MESSAGE_KEY = "errorMessage";
static const std::string kEXTRA_GENERATOR_KEY = "extraGenerator";
static const std::string kGENERATOR_KEY = "generator";
@@ -43,7 +51,12 @@ static const std::string kSOURCE_DIRECTORY_KEY = "sourceDirectory";
static const std::string kSUPPORTED_PROTOCOL_VERSIONS =
"supportedProtocolVersions";
static const std::string kTITLE_KEY = "title";
+static const std::string kTRACE_EXPAND_KEY = "traceExpand";
+static const std::string kTRACE_KEY = "trace";
static const std::string kTYPE_KEY = "type";
+static const std::string kWARN_UNINITIALIZED_KEY = "warnUninitialized";
+static const std::string kWARN_UNUSED_CLI_KEY = "warnUnusedCli";
+static const std::string kWARN_UNUSED_KEY = "warnUnused";
static const std::string kSTART_MAGIC = "[== CMake Server ==[";
static const std::string kEND_MAGIC = "]== CMake Server ==]";
diff --git a/Source/cmServerProtocol.cxx b/Source/cmServerProtocol.cxx
index 755de0c041..134edf3029 100644
--- a/Source/cmServerProtocol.cxx
+++ b/Source/cmServerProtocol.cxx
@@ -13,6 +13,7 @@
#include "cmServerProtocol.h"
#include "cmExternalMakefileProjectGenerator.h"
+#include "cmGlobalGenerator.h"
#include "cmServer.h"
#include "cmServerDictionary.h"
#include "cmSystemTools.h"
@@ -279,6 +280,19 @@ const cmServerResponse cmServerProtocol1_0::Process(
{
assert(this->m_State >= STATE_ACTIVE);
+ if (request.Type == kCOMPUTE_TYPE) {
+ return this->ProcessCompute(request);
+ }
+ if (request.Type == kCONFIGURE_TYPE) {
+ return this->ProcessConfigure(request);
+ }
+ if (request.Type == kGLOBAL_SETTINGS_TYPE) {
+ return this->ProcessGlobalSettings(request);
+ }
+ if (request.Type == kSET_GLOBAL_SETTINGS_TYPE) {
+ return this->ProcessSetGlobalSettings(request);
+ }
+
return request.ReportError("Unknown command!");
}
@@ -286,3 +300,179 @@ bool cmServerProtocol1_0::IsExperimental() const
{
return true;
}
+
+cmServerResponse cmServerProtocol1_0::ProcessCompute(
+ const cmServerRequest& request)
+{
+ if (this->m_State > STATE_CONFIGURED) {
+ return request.ReportError("This build system was already generated.");
+ }
+ if (this->m_State < STATE_CONFIGURED) {
+ return request.ReportError("This project was not configured yet.");
+ }
+
+ cmake* cm = this->CMakeInstance();
+ int ret = cm->Generate();
+
+ if (ret < 0) {
+ return request.ReportError("Failed to compute build system.");
+ }
+ m_State = STATE_COMPUTED;
+ return request.Reply(Json::Value());
+}
+
+cmServerResponse cmServerProtocol1_0::ProcessConfigure(
+ const cmServerRequest& request)
+{
+ if (this->m_State == STATE_INACTIVE) {
+ return request.ReportError("This instance is inactive.");
+ }
+
+ // Make sure the types of cacheArguments matches (if given):
+ std::vector<std::string> cacheArgs;
+ bool cacheArgumentsError = false;
+ const Json::Value passedArgs = request.Data[kCACHE_ARGUMENTS_KEY];
+ if (!passedArgs.isNull()) {
+ if (passedArgs.isString()) {
+ cacheArgs.push_back(passedArgs.asString());
+ } else if (passedArgs.isArray()) {
+ for (auto i = passedArgs.begin(); i != passedArgs.end(); ++i) {
+ if (!i->isString()) {
+ cacheArgumentsError = true;
+ break;
+ }
+ cacheArgs.push_back(i->asString());
+ }
+ } else {
+ cacheArgumentsError = true;
+ }
+ }
+ if (cacheArgumentsError) {
+ request.ReportError(
+ "cacheArguments must be unset, a string or an array of strings.");
+ }
+
+ cmake* cm = this->CMakeInstance();
+ std::string sourceDir = cm->GetHomeDirectory();
+ const std::string buildDir = cm->GetHomeOutputDirectory();
+
+ if (buildDir.empty()) {
+ return request.ReportError(
+ "No build directory set via setGlobalSettings.");
+ }
+
+ if (cm->LoadCache(buildDir)) {
+ // build directory has been set up before
+ const char* cachedSourceDir =
+ cm->GetState()->GetInitializedCacheValue("CMAKE_HOME_DIRECTORY");
+ if (!cachedSourceDir) {
+ return request.ReportError("No CMAKE_HOME_DIRECTORY found in cache.");
+ }
+ if (sourceDir.empty()) {
+ sourceDir = std::string(cachedSourceDir);
+ cm->SetHomeDirectory(sourceDir);
+ }
+
+ const char* cachedGenerator =
+ cm->GetState()->GetInitializedCacheValue("CMAKE_GENERATOR");
+ if (cachedGenerator) {
+ cmGlobalGenerator* gen = cm->GetGlobalGenerator();
+ if (gen && gen->GetName() != cachedGenerator) {
+ return request.ReportError("Configured generator does not match with "
+ "CMAKE_GENERATOR found in cache.");
+ }
+ }
+ } else {
+ // build directory has not been set up before
+ if (sourceDir.empty()) {
+ return request.ReportError("No sourceDirectory set via "
+ "setGlobalSettings and no cache found in "
+ "buildDirectory.");
+ }
+ }
+
+ if (cm->AddCMakePaths() != 1) {
+ return request.ReportError("Failed to set CMake paths.");
+ }
+
+ if (!cm->SetCacheArgs(cacheArgs)) {
+ return request.ReportError("cacheArguments could not be set.");
+ }
+
+ int ret = cm->Configure();
+ if (ret < 0) {
+ return request.ReportError("Configuration failed.");
+ }
+ m_State = STATE_CONFIGURED;
+ return request.Reply(Json::Value());
+}
+
+cmServerResponse cmServerProtocol1_0::ProcessGlobalSettings(
+ const cmServerRequest& request)
+{
+ cmake* cm = this->CMakeInstance();
+ Json::Value obj = Json::objectValue;
+
+ // Capabilities information:
+ obj[kCAPABILITIES_KEY] = cm->ReportCapabilitiesJson(true);
+
+ obj[kDEBUG_OUTPUT_KEY] = cm->GetDebugOutput();
+ obj[kTRACE_KEY] = cm->GetTrace();
+ obj[kTRACE_EXPAND_KEY] = cm->GetTraceExpand();
+ obj[kWARN_UNINITIALIZED_KEY] = cm->GetWarnUninitialized();
+ obj[kWARN_UNUSED_KEY] = cm->GetWarnUnused();
+ obj[kWARN_UNUSED_CLI_KEY] = cm->GetWarnUnusedCli();
+ obj[kCHECK_SYSTEM_VARS_KEY] = cm->GetCheckSystemVars();
+
+ obj[kSOURCE_DIRECTORY_KEY] = cm->GetHomeDirectory();
+ obj[kBUILD_DIRECTORY_KEY] = cm->GetHomeOutputDirectory();
+
+ // Currently used generator:
+ cmGlobalGenerator* gen = cm->GetGlobalGenerator();
+ obj[kGENERATOR_KEY] = gen ? gen->GetName() : std::string();
+ obj[kEXTRA_GENERATOR_KEY] =
+ gen ? gen->GetExtraGeneratorName() : std::string();
+
+ return request.Reply(obj);
+}
+
+static void setBool(const cmServerRequest& request, const std::string& key,
+ std::function<void(bool)> setter)
+{
+ if (request.Data[key].isNull()) {
+ return;
+ }
+ setter(request.Data[key].asBool());
+}
+
+cmServerResponse cmServerProtocol1_0::ProcessSetGlobalSettings(
+ const cmServerRequest& request)
+{
+ const std::vector<std::string> boolValues = {
+ kDEBUG_OUTPUT_KEY, kTRACE_KEY, kTRACE_EXPAND_KEY,
+ kWARN_UNINITIALIZED_KEY, kWARN_UNUSED_KEY, kWARN_UNUSED_CLI_KEY,
+ kCHECK_SYSTEM_VARS_KEY
+ };
+ for (auto i : boolValues) {
+ if (!request.Data[i].isNull() && !request.Data[i].isBool()) {
+ return request.ReportError("\"" + i +
+ "\" must be unset or a bool value.");
+ }
+ }
+
+ cmake* cm = this->CMakeInstance();
+
+ setBool(request, kDEBUG_OUTPUT_KEY,
+ [cm](bool e) { cm->SetDebugOutputOn(e); });
+ setBool(request, kTRACE_KEY, [cm](bool e) { cm->SetTrace(e); });
+ setBool(request, kTRACE_EXPAND_KEY, [cm](bool e) { cm->SetTraceExpand(e); });
+ setBool(request, kWARN_UNINITIALIZED_KEY,
+ [cm](bool e) { cm->SetWarnUninitialized(e); });
+ setBool(request, kWARN_UNUSED_KEY, [cm](bool e) { cm->SetWarnUnused(e); });
+ setBool(request, kWARN_UNUSED_CLI_KEY,
+ [cm](bool e) { cm->SetWarnUnusedCli(e); });
+ setBool(request, kCHECK_SYSTEM_VARS_KEY,
+ [cm](bool e) { cm->SetCheckSystemVars(e); });
+
+ return request.Reply(Json::Value());
+}
diff --git a/Source/cmServerProtocol.h b/Source/cmServerProtocol.h
index 0383dfe504..e772eca431 100644
--- a/Source/cmServerProtocol.h
+++ b/Source/cmServerProtocol.h
@@ -13,6 +13,7 @@
#pragma once
#include "cmListFileCache.h"
+#include "cmake.h"
#if defined(CMAKE_BUILD_WITH_CMAKE)
#include "cm_jsoncpp_writer.h"
@@ -116,10 +117,18 @@ private:
bool DoActivate(const cmServerRequest& request,
std::string* errorMessage) override;
+ // Handle requests:
+ cmServerResponse ProcessCompute(const cmServerRequest& request);
+ cmServerResponse ProcessConfigure(const cmServerRequest& request);
+ cmServerResponse ProcessGlobalSettings(const cmServerRequest& request);
+ cmServerResponse ProcessSetGlobalSettings(const cmServerRequest& request);
+
enum State
{
STATE_INACTIVE,
- STATE_ACTIVE
+ STATE_ACTIVE,
+ STATE_CONFIGURED,
+ STATE_COMPUTED
};
State m_State = STATE_INACTIVE;
};
diff --git a/Source/kwsys/testConsoleBuf.cxx b/Source/kwsys/testConsoleBuf.cxx
index 3dc3337076..d7775e6d88 100644
--- a/Source/kwsys/testConsoleBuf.cxx
+++ b/Source/kwsys/testConsoleBuf.cxx
@@ -103,7 +103,7 @@ static void dumpBuffers(const T *expected, const T *received, size_t size) {
}
std::cerr << std::endl;
}
- std::cerr << std::endl << std::flush;
+ std::cerr << std::endl;
}
//----------------------------------------------------------------------------
@@ -331,21 +331,23 @@ static int testPipe()
didFail = encodedTestString.compare(buffer2) == 0 ? 0 : 1;
}
if (didFail != 0) {
- std::cerr << "Pipe's output didn't match expected output!" << std::endl << std::flush;
+ std::cerr << "Pipe's output didn't match expected output!" << std::endl;
dumpBuffers<char>(encodedTestString.c_str(), buffer, encodedTestString.size());
dumpBuffers<char>(encodedInputTestString.c_str(), buffer + encodedTestString.size() + 1, encodedInputTestString.size());
dumpBuffers<char>(encodedTestString.c_str(), buffer2, encodedTestString.size());
}
} catch (const std::runtime_error &ex) {
DWORD lastError = GetLastError();
- std::cerr << "In function " << __FUNCTION__ << ":" << ex.what() << std::endl << std::flush;
+ std::cerr << "In function testPipe, line " << __LINE__ << ": "
+ << ex.what() << std::endl;
displayError(lastError);
}
finishProcess(didFail == 0);
}
} catch (const std::runtime_error &ex) {
DWORD lastError = GetLastError();
- std::cerr << "In function " << __FUNCTION__ << ":" << ex.what() << std::endl << std::flush;
+ std::cerr << "In function testPipe, line " << __LINE__ << ": "
+ << ex.what() << std::endl;
displayError(lastError);
}
finishPipe(inPipeRead, inPipeWrite);
@@ -368,11 +370,11 @@ static int testFile()
(errFile = createFile(L"stderrFile.txt")) == INVALID_HANDLE_VALUE) {
throw std::runtime_error("createFile failed!");
}
- int length = 0;
DWORD bytesWritten = 0;
char buffer[200];
char buffer2[200];
+ int length;
if ((length = WideCharToMultiByte(TestCodepage, 0, UnicodeInputTestString, -1,
buffer, sizeof(buffer),
NULL, NULL)) == 0) {
@@ -424,21 +426,23 @@ static int testFile()
didFail = encodedTestString.compare(buffer2) == 0 ? 0 : 1;
}
if (didFail != 0) {
- std::cerr << "File's output didn't match expected output!" << std::endl << std::flush;
+ std::cerr << "File's output didn't match expected output!" << std::endl;
dumpBuffers<char>(encodedTestString.c_str(), buffer, encodedTestString.size());
dumpBuffers<char>(encodedInputTestString.c_str(), buffer + encodedTestString.size() + 1, encodedInputTestString.size() - 1);
dumpBuffers<char>(encodedTestString.c_str(), buffer2, encodedTestString.size());
}
} catch (const std::runtime_error &ex) {
DWORD lastError = GetLastError();
- std::cerr << "In function " << __FUNCTION__ << ":" << ex.what() << std::endl << std::flush;
+ std::cerr << "In function testFile, line " << __LINE__ << ": "
+ << ex.what() << std::endl;
displayError(lastError);
}
finishProcess(didFail == 0);
}
} catch (const std::runtime_error &ex) {
DWORD lastError = GetLastError();
- std::cerr << "In function " << __FUNCTION__ << ":" << ex.what() << std::endl << std::flush;
+ std::cerr << "In function testFile, line " << __LINE__ << ": "
+ << ex.what() << std::endl;
displayError(lastError);
}
finishFile(inFile);
@@ -508,18 +512,18 @@ static int testConsole()
forceNewConsole = true;
}
} else {
- std::cerr << "RegGetValueW(FontFamily) failed!" << std::endl << std::flush;
+ std::cerr << "RegGetValueW(FontFamily) failed!" << std::endl;
}
RegCloseKey(hConsoleKey);
} else {
- std::cerr << "RegOpenKeyExW(HKEY_CURRENT_USER\\Console) failed!" << std::endl << std::flush;
+ std::cerr << "RegOpenKeyExW(HKEY_CURRENT_USER\\Console) failed!" << std::endl;
}
}
if (forceNewConsole || GetConsoleMode(parentOut, &consoleMode) == 0) {
// Not a real console, let's create new one.
FreeConsole();
if (!AllocConsole()) {
- std::cerr << "AllocConsole failed!" << std::endl << std::flush;
+ std::cerr << "AllocConsole failed!" << std::endl;
return didFail;
}
SECURITY_ATTRIBUTES securityAttributes;
@@ -561,11 +565,11 @@ static int testConsole()
consoleFont.FontFamily = TestFontFamily;
wcscpy(consoleFont.FaceName, TestFaceName);
if (!setConsoleFont(hOut, FALSE, &consoleFont)) {
- std::cerr << "SetCurrentConsoleFontEx failed!" << std::endl << std::flush;
+ std::cerr << "SetCurrentConsoleFontEx failed!" << std::endl;
}
}
} else {
- std::cerr << "GetCurrentConsoleFontEx failed!" << std::endl << std::flush;
+ std::cerr << "GetCurrentConsoleFontEx failed!" << std::endl;
}
} else {
#endif
@@ -599,7 +603,7 @@ static int testConsole()
INPUT_RECORD inputBuffer[(sizeof(UnicodeInputTestString) /
sizeof(UnicodeInputTestString[0])) * 2];
memset(&inputBuffer, 0, sizeof(inputBuffer));
- unsigned int i = 0;
+ unsigned int i;
for (i = 0; i < (sizeof(UnicodeInputTestString) /
sizeof(UnicodeInputTestString[0]) - 1); i++) {
writeInputKeyEvent(&inputBuffer[i*2], UnicodeInputTestString[i]);
@@ -650,7 +654,7 @@ static int testConsole()
) {
didFail = 0;
} else {
- std::cerr << "Console's output didn't match expected output!" << std::endl << std::flush;
+ std::cerr << "Console's output didn't match expected output!" << std::endl;
dumpBuffers<wchar_t>(wideTestString.c_str(), outputBuffer, wideTestString.size());
dumpBuffers<wchar_t>(wideTestString.c_str(), outputBuffer + screenBufferInfo.dwSize.X * 1, wideTestString.size());
dumpBuffers<wchar_t>(UnicodeInputTestString, outputBuffer + screenBufferInfo.dwSize.X * 2, (sizeof(UnicodeInputTestString) - 1) / sizeof(WCHAR));
@@ -659,7 +663,8 @@ static int testConsole()
delete[] outputBuffer;
} catch (const std::runtime_error &ex) {
DWORD lastError = GetLastError();
- std::cerr << "In function " << __FUNCTION__ << ":" << ex.what() << std::endl << std::flush;
+ std::cerr << "In function testConsole, line " << __LINE__ << ": "
+ << ex.what() << std::endl;
displayError(lastError);
}
finishProcess(didFail == 0);
diff --git a/Tests/FortranModules/CMakeLists.txt b/Tests/FortranModules/CMakeLists.txt
index ff1277146c..3996600023 100644
--- a/Tests/FortranModules/CMakeLists.txt
+++ b/Tests/FortranModules/CMakeLists.txt
@@ -52,6 +52,8 @@ add_definitions(-DFOO -DBAR=1)
include_directories(${CMAKE_CURRENT_SOURCE_DIR}/include)
add_executable(test_preprocess test_preprocess.F90 test_preprocess_module.F90)
+add_executable(test_non_pp_include test_non_pp_include_main.f90)
+
# Build the external project separately using a custom target.
# Make sure it uses the same build configuration as this test.
if(CMAKE_CONFIGURATION_TYPES)
diff --git a/Tests/FortranModules/non_pp_include.f90 b/Tests/FortranModules/non_pp_include.f90
new file mode 100644
index 0000000000..7eb172596f
--- /dev/null
+++ b/Tests/FortranModules/non_pp_include.f90
@@ -0,0 +1,3 @@
+SUBROUTINE NON_PP_INCLUDE_SUBROUTINE
+ PRINT *, "Hello World!"
+END SUBROUTINE NON_PP_INCLUDE_SUBROUTINE
diff --git a/Tests/FortranModules/test_non_pp_include_main.f90 b/Tests/FortranModules/test_non_pp_include_main.f90
new file mode 100644
index 0000000000..8a04fbdf45
--- /dev/null
+++ b/Tests/FortranModules/test_non_pp_include_main.f90
@@ -0,0 +1,5 @@
+INCLUDE "non_pp_include.f90"
+
+PROGRAM MAINF90
+ CALL NON_PP_INCLUDE_SUBROUTINE
+END PROGRAM MAINF90
diff --git a/Tests/RunCMake/CPack/DEBUGINFO.cmake b/Tests/RunCMake/CPack/DEBUGINFO.cmake
index 2a65b7f220..d98b6823f9 100644
--- a/Tests/RunCMake/CPack/DEBUGINFO.cmake
+++ b/Tests/RunCMake/CPack/DEBUGINFO.cmake
@@ -1,5 +1,11 @@
set(CMAKE_BUILD_WITH_INSTALL_RPATH 1)
+# PGI compiler doesn't add build id to binaries by default
+if(CMAKE_CXX_COMPILER_ID STREQUAL "PGI")
+ string(APPEND CMAKE_EXE_LINKER_FLAGS "-Wl,--build-id")
+ string(APPEND CMAKE_SHARED_LINKER_FLAGS "-Wl,--build-id")
+endif()
+
set(CPACK_RPM_COMPONENT_INSTALL "ON")
set(CMAKE_BUILD_TYPE Debug)
@@ -23,4 +29,6 @@ set(CPACK_RPM_APPLICATIONS_FILE_NAME "RPM-DEFAULT")
set(CPACK_RPM_APPLICATIONS_DEBUGINFO_PACKAGE ON)
set(CPACK_RPM_LIBS_DEBUGINFO_PACKAGE ON)
+set(CPACK_RPM_BUILD_SOURCE_DIRS_PREFIX "/src")
+
set(CPACK_PACKAGE_NAME "debuginfo")
diff --git a/Tests/RunCMake/CPack/RPM/DEBUGINFO-ExpectedFiles.cmake b/Tests/RunCMake/CPack/RPM/DEBUGINFO-ExpectedFiles.cmake
index 265ca92a11..a583e3237d 100644
--- a/Tests/RunCMake/CPack/RPM/DEBUGINFO-ExpectedFiles.cmake
+++ b/Tests/RunCMake/CPack/RPM/DEBUGINFO-ExpectedFiles.cmake
@@ -9,6 +9,6 @@ set(EXPECTED_FILE_3 "debuginfo*-libs.rpm")
set(EXPECTED_FILE_CONTENT_3 "^/usr/bas${whitespaces_}/usr/bas/libtest_lib.so$")
set(EXPECTED_FILE_4 "debuginfo-applications-debuginfo*.rpm")
-set(EXPECTED_FILE_CONTENT_4 ".*")
+set(EXPECTED_FILE_CONTENT_4 ".*/src${whitespaces_}/src/src_1${whitespaces_}/src/src_1/main.cpp.*")
set(EXPECTED_FILE_5 "debuginfo-libs-debuginfo*.rpm")
-set(EXPECTED_FILE_CONTENT_5 ".*")
+set(EXPECTED_FILE_CONTENT_5 ".*/src${whitespaces_}/src/src_1${whitespaces_}/src/src_1/test_lib.cpp.*")
diff --git a/Tests/Server/CMakeLists.txt b/Tests/Server/CMakeLists.txt
index 8daf12a5e1..03f50429db 100644
--- a/Tests/Server/CMakeLists.txt
+++ b/Tests/Server/CMakeLists.txt
@@ -19,5 +19,6 @@ macro(do_test bsname file)
endmacro()
do_test("test_handshake" "tc_handshake.json")
+do_test("test_globalSettings" "tc_globalSettings.json")
add_executable(Server empty.cpp)
diff --git a/Tests/Server/cmakelib.py b/Tests/Server/cmakelib.py
index 0f9807898b..8beaeefa25 100644
--- a/Tests/Server/cmakelib.py
+++ b/Tests/Server/cmakelib.py
@@ -106,6 +106,7 @@ def waitForReply(cmakeCommand, originalType, cookie):
packet = waitForRawMessage(cmakeCommand)
if packet['cookie'] != cookie or packet['type'] != 'reply' or packet['inReplyTo'] != originalType:
sys.exit(1)
+ return packet
def waitForError(cmakeCommand, originalType, cookie, message):
packet = waitForRawMessage(cmakeCommand)
@@ -117,10 +118,71 @@ def waitForProgress(cmakeCommand, originalType, cookie, current, message):
if packet['cookie'] != cookie or packet['type'] != 'progress' or packet['inReplyTo'] != originalType or packet['progressCurrent'] != current or packet['progressMessage'] != message:
sys.exit(1)
-def handshake(cmakeCommand, major, minor):
+def handshake(cmakeCommand, major, minor, source, build, generator, extraGenerator):
version = { 'major': major }
if minor >= 0:
version['minor'] = minor
- writePayload(cmakeCommand, { 'type': 'handshake', 'protocolVersion': version, 'cookie': 'TEST_HANDSHAKE' })
+ writePayload(cmakeCommand, { 'type': 'handshake', 'protocolVersion': version,
+ 'cookie': 'TEST_HANDSHAKE', 'sourceDirectory': source, 'buildDirectory': build,
+ 'generator': generator, 'extraGenerator': extraGenerator })
waitForReply(cmakeCommand, 'handshake', 'TEST_HANDSHAKE')
+
+def validateGlobalSettings(cmakeCommand, cmakeCommandPath, data):
+ packet = waitForReply(cmakeCommand, 'globalSettings', '')
+
+ capabilities = packet['capabilities']
+
+ # validate version:
+ cmakeoutput = subprocess.check_output([ cmakeCommandPath, "--version" ], universal_newlines=True)
+ cmakeVersion = cmakeoutput.splitlines()[0][14:]
+
+ version = capabilities['version']
+ versionString = version['string']
+ vs = str(version['major']) + '.' + str(version['minor']) + '.' + str(version['patch'])
+ if (versionString != vs and not versionString.startswith(vs + '-')):
+ sys.exit(1)
+ if (versionString != cmakeVersion):
+ sys.exit(1)
+
+ # validate generators:
+ generatorObjects = capabilities['generators']
+
+ cmakeoutput = subprocess.check_output([ cmakeCommandPath, "--help" ], universal_newlines=True)
+ index = cmakeoutput.index('\nGenerators\n\n')
+ cmakeGenerators = []
+ for line in cmakeoutput[index + 12:].splitlines():
+ if not line.startswith(' '):
+ continue
+ if line.startswith(' '):
+ continue
+ equalPos = line.find('=')
+ tmp = ''
+ if (equalPos > 0):
+ tmp = line[2:equalPos].strip()
+ else:
+ tmp = line.strip()
+ if tmp.endswith(" [arch]"):
+ tmp = tmp[0:len(tmp) - 7]
+ if (len(tmp) > 0) and (" - " not in tmp) and (tmp != 'KDevelop3'):
+ cmakeGenerators.append(tmp)
+
+ generators = []
+ for genObj in generatorObjects:
+ generators.append(genObj['name'])
+
+ generators.sort()
+ cmakeGenerators.sort()
+
+ for gen in cmakeGenerators:
+ if (not gen in generators):
+ sys.exit(1)
+
+ gen = packet['generator']
+ if (gen != '' and not (gen in generators)):
+ sys.exit(1)
+
+ for i in data:
+ print("Validating", i)
+ if (packet[i] != data[i]):
+ sys.exit(1)
diff --git a/Tests/Server/server-test.py b/Tests/Server/server-test.py
index e0a3b3b6ef..d2bf92ebbd 100644
--- a/Tests/Server/server-test.py
+++ b/Tests/Server/server-test.py
@@ -68,9 +68,25 @@ for obj in testData:
if debug: print("Doing handshake:", json.dumps(data))
major = -1
minor = -1
+ generator = 'Ninja'
+ extraGenerator = 'CodeBlocks'
+ sourceDirectory = sourceDir
+ buildDirectory = buildDir
if 'major' in data: major = data['major']
if 'minor' in data: minor = data['minor']
- cmakelib.handshake(proc, major, minor)
+ if 'buildDirectory' in data: buildDirectory = data['buildDirectory']
+ if 'sourceDirectory' in data: sourceDirectory = data['sourceDirectory']
+ if 'generator' in data: generator = data['generator']
+ if 'extraGenerator' in data: extraGenerator = data['extraGenerator']
+ cmakelib.handshake(proc, major, minor, sourceDirectory, buildDirectory,
+ generator, extraGenerator)
+ elif 'validateGlobalSettings' in obj:
+ data = obj['validateGlobalSettings']
+ if not 'buildDirectory' in data: data['buildDirectory'] = buildDir
+ if not 'sourceDirectory' in data: data['sourceDirectory'] = sourceDir
+ if not 'generator' in data: data['generator'] = 'Ninja'
+ if not 'extraGenerator' in data: data['extraGenerator'] = 'CodeBlocks'
+ cmakelib.validateGlobalSettings(proc, cmakeCommand, data)
elif 'message' in obj:
print("MESSAGE:", obj["message"])
else:
diff --git a/Tests/Server/tc_globalSettings.json b/Tests/Server/tc_globalSettings.json
new file mode 100644
index 0000000000..d72fb41ac3
--- /dev/null
+++ b/Tests/Server/tc_globalSettings.json
@@ -0,0 +1,140 @@
+[
+{ "message": "Testing globalSettings" },
+
+{ "handshake": {"major": 1} },
+
+{ "send": { "type": "globalSettings"} },
+{ "validateGlobalSettings": { "warnUnused": false, "debugOutput": false, "warnUninitialized": false, "traceExpand": false, "trace": false, "warnUnusedCli": true, "checkSystemVars": false } },
+
+
+
+{ "message": "Change settings:" },
+
+{ "send": { "type": "setGlobalSettings", "warnUnused": true } },
+{ "reply": { "type": "setGlobalSettings" } },
+
+{ "send": { "type": "globalSettings"} },
+{ "validateGlobalSettings": { "warnUnused": true, "debugOutput": false, "warnUninitialized": false, "traceExpand": false, "trace": false, "warnUnusedCli": true, "checkSystemVars": false } },
+
+{ "send": { "type": "setGlobalSettings", "warnUnused": false } },
+{ "reply": { "type": "setGlobalSettings" } },
+
+{ "send": { "type": "globalSettings"} },
+{ "validateGlobalSettings": { "warnUnused": false, "debugOutput": false, "warnUninitialized": false, "traceExpand": false, "trace": false, "warnUnusedCli": true, "checkSystemVars": false } },
+
+{ "send": { "type": "setGlobalSettings", "debugOutput": true } },
+{ "reply": { "type": "setGlobalSettings" } },
+
+{ "send": { "type": "globalSettings"} },
+{ "validateGlobalSettings": { "warnUnused": false, "debugOutput": true, "warnUninitialized": false, "traceExpand": false, "trace": false, "warnUnusedCli": true, "checkSystemVars": false } },
+
+{ "send": { "type": "setGlobalSettings", "debugOutput": false } },
+{ "reply": { "type": "setGlobalSettings" } },
+
+{ "send": { "type": "globalSettings"} },
+{ "validateGlobalSettings": { "warnUnused": false, "debugOutput": false, "warnUninitialized": false, "traceExpand": false, "trace": false, "warnUnusedCli": true, "checkSystemVars": false } },
+
+{ "send": { "type": "setGlobalSettings", "warnUninitialized": true } },
+{ "reply": { "type": "setGlobalSettings" } },
+
+{ "send": { "type": "globalSettings"} },
+{ "validateGlobalSettings": { "warnUnused": false, "debugOutput": false, "warnUninitialized": true, "traceExpand": false, "trace": false, "warnUnusedCli": true, "checkSystemVars": false } },
+
+{ "send": { "type": "setGlobalSettings", "warnUninitialized": false } },
+{ "reply": { "type": "setGlobalSettings" } },
+
+{ "send": { "type": "globalSettings"} },
+{ "validateGlobalSettings": { "warnUnused": false, "debugOutput": false, "warnUninitialized": false, "traceExpand": false, "trace": false, "warnUnusedCli": true, "checkSystemVars": false } },
+
+{ "send": { "type": "setGlobalSettings", "traceExpand": true } },
+{ "reply": { "type": "setGlobalSettings" } },
+
+{ "send": { "type": "globalSettings"} },
+{ "validateGlobalSettings": { "warnUnused": false, "debugOutput": false, "warnUninitialized": false, "traceExpand": true, "trace": false, "warnUnusedCli": true, "checkSystemVars": false } },
+
+{ "send": { "type": "setGlobalSettings", "traceExpand": false } },
+{ "reply": { "type": "setGlobalSettings" } },
+
+{ "send": { "type": "globalSettings"} },
+{ "validateGlobalSettings": { "warnUnused": false, "debugOutput": false, "warnUninitialized": false, "traceExpand": false, "trace": false, "warnUnusedCli": true, "checkSystemVars": false } },
+
+
+
+{ "send": { "type": "setGlobalSettings", "trace": true } },
+{ "reply": { "type": "setGlobalSettings" } },
+
+{ "send": { "type": "globalSettings"} },
+{ "validateGlobalSettings": { "warnUnused": false, "debugOutput": false, "warnUninitialized": false, "traceExpand": false, "trace": true, "warnUnusedCli": true, "checkSystemVars": false } },
+
+{ "send": { "type": "setGlobalSettings", "trace": false } },
+{ "reply": { "type": "setGlobalSettings" } },
+
+{ "send": { "type": "globalSettings"} },
+{ "validateGlobalSettings": { "warnUnused": false, "debugOutput": false, "warnUninitialized": false, "traceExpand": false, "trace": false, "warnUnusedCli": true, "checkSystemVars": false } },
+
+{ "send": { "type": "setGlobalSettings", "warnUnusedCli": false } },
+{ "reply": { "type": "setGlobalSettings" } },
+
+{ "send": { "type": "globalSettings"} },
+{ "validateGlobalSettings": { "warnUnused": false, "debugOutput": false, "warnUninitialized": false, "traceExpand": false, "trace": false, "warnUnusedCli": false, "checkSystemVars": false } },
+
+{ "send": { "type": "setGlobalSettings", "warnUnusedCli": true } },
+{ "reply": { "type": "setGlobalSettings" } },
+
+{ "send": { "type": "globalSettings"} },
+{ "validateGlobalSettings": { "warnUnused": false, "debugOutput": false, "warnUninitialized": false, "traceExpand": false, "trace": false, "warnUnusedCli": true, "checkSystemVars": false } },
+
+{ "send": { "type": "setGlobalSettings", "checkSystemVars": true } },
+{ "reply": { "type": "setGlobalSettings" } },
+
+{ "send": { "type": "globalSettings"} },
+{ "validateGlobalSettings": { "warnUnused": false, "debugOutput": false, "warnUninitialized": false, "traceExpand": false, "trace": false, "warnUnusedCli": true, "checkSystemVars": true } },
+
+{ "send": { "type": "setGlobalSettings", "checkSystemVars": false } },
+{ "reply": { "type": "setGlobalSettings" } },
+
+{ "send": { "type": "globalSettings"} },
+{ "validateGlobalSettings": { "warnUnused": false, "debugOutput": false, "warnUninitialized": false, "traceExpand": false, "trace": false, "warnUnusedCli": true, "checkSystemVars": false } },
+
+{ "send": { "type": "setGlobalSettings", "warnUnused": true, "debugOutput": true, "warnUninitialized": true, "traceExpand": true, "trace": true, "warnUnusedCli": false, "checkSystemVars": true } },
+{ "reply": { "type": "setGlobalSettings" } },
+
+{ "send": { "type": "globalSettings"} },
+{ "validateGlobalSettings": { "warnUnused": true, "debugOutput": true, "warnUninitialized": true, "traceExpand": true, "trace": true, "warnUnusedCli": false, "checkSystemVars": true } },
+
+{ "message": "Ignore unknown/readonly" },
+
+{ "send": { "type": "setGlobalSettings", "unknownKey": "unknownValue", "extraGenerator": "XXX", "generator": "YYY", "sourceDirectory": "/tmp/source", "buildDirectory": "/tmp/build" } },
+{ "reply": { "type": "setGlobalSettings" } },
+
+{ "send": { "type": "globalSettings"} },
+{ "validateGlobalSettings": { "warnUnused": true, "debugOutput": true, "warnUninitialized": true, "traceExpand": true, "trace": true, "warnUnusedCli": false, "checkSystemVars": true } },
+
+{ "message": "Error paths:" },
+
+{ "send": { "type": "setGlobalSettings", "debugOutput": true, "warnUnused": 1 } },
+{ "error": { "type": "setGlobalSettings", "message": "\"warnUnused\" must be unset or a bool value." } },
+
+{ "send": { "type": "setGlobalSettings", "warnUnused": true, "debugOutput": 1 } },
+{ "error": { "type": "setGlobalSettings", "message": "\"debugOutput\" must be unset or a bool value." } },
+
+{ "send": { "type": "setGlobalSettings", "warnUninitialized": 1, "warnUnused": true, "debugOutput": true } },
+{ "error": { "type": "setGlobalSettings", "message": "\"warnUninitialized\" must be unset or a bool value." } },
+
+{ "send": { "type": "setGlobalSettings", "warnUnused": true, "debugOutput": true, "traceExpand": 1 } },
+{ "error": { "type": "setGlobalSettings", "message": "\"traceExpand\" must be unset or a bool value." } },
+
+{ "send": { "type": "setGlobalSettings", "debugOutput": true, "trace": 1, "warnUnused": true } },
+{ "error": { "type": "setGlobalSettings", "message": "\"trace\" must be unset or a bool value." } },
+
+{ "send": { "type": "setGlobalSettings", "warnUnused": true, "debugOutput": true, "warnUnusedCli": 1.0 } },
+{ "error": { "type": "setGlobalSettings", "message": "\"warnUnusedCli\" must be unset or a bool value." } },
+
+{ "send": { "type": "setGlobalSettings", "warnUnused": true, "debugOutput": true, "checkSystemVars": "some string" } },
+{ "error": { "type": "setGlobalSettings", "message": "\"checkSystemVars\" must be unset or a bool value." } },
+
+{ "send": { "type": "globalSettings"} },
+{ "validateGlobalSettings": { "warnUnused": true, "debugOutput": true, "warnUninitialized": true, "traceExpand": true, "trace": true, "warnUnusedCli": false, "checkSystemVars": true } },
+
+{ "message": "Everything ok." }
+]