diff options
34 files changed, 1238 insertions, 154 deletions
diff --git a/CTestCustom.cmake.in b/CTestCustom.cmake.in index 8489178..710681c 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 dbc46d7..3e60aa6 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 61d6896..b8a425c 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 d9da3d6..b74f867 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 0000000..0979228 --- /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 0000000..4aede03 --- /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 99f22ec..50d9fc3 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 db5984a..4693ce5 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 d78f7fa..9ed60d3 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 1f03841..b3e8db9 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/FindJNI.cmake b/Modules/FindJNI.cmake index 658d6ca..285b965 100644 --- a/Modules/FindJNI.cmake +++ b/Modules/FindJNI.cmake @@ -53,7 +53,7 @@ macro(java_append_library_directories _var) set(_java_libarch "alpha") elseif(CMAKE_SYSTEM_PROCESSOR MATCHES "^arm") # Subdir is "arm" for both big-endian (arm) and little-endian (armel). - set(_java_libarch "arm") + set(_java_libarch "arm" "aarch32") elseif(CMAKE_SYSTEM_PROCESSOR MATCHES "^mips") # mips* machines are bi-endian mostly so processor does not tell # endianess of the underlying system. diff --git a/Modules/FindMatlab.cmake b/Modules/FindMatlab.cmake index 8b41bb9..d016848 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/Modules/NSIS.template.in b/Modules/NSIS.template.in index c66a89b..9001888 100644 --- a/Modules/NSIS.template.in +++ b/Modules/NSIS.template.in @@ -905,7 +905,7 @@ Function .onInit MessageBox MB_YESNOCANCEL|MB_ICONEXCLAMATION \ "@CPACK_NSIS_PACKAGE_NAME@ is already installed. $\n$\nDo you want to uninstall the old version before installing the new one?" \ - IDYES uninst IDNO inst + /SD IDYES IDYES uninst IDNO inst Abort ;Run the uninstaller @@ -913,7 +913,7 @@ uninst: ClearErrors StrLen $2 "\Uninstall.exe" StrCpy $3 $0 -$2 # remove "\Uninstall.exe" from UninstallString to get path - ExecWait '"$0" _?=$3' ;Do not copy the uninstaller to a temp file + ExecWait '"$0" /S _?=$3' ;Do not copy the uninstaller to a temp file IfErrors uninst_failed inst uninst_failed: diff --git a/Source/CMakeVersion.cmake b/Source/CMakeVersion.cmake index 9a10ddb..e4f5e01 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 2db94f1..b49da7f 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 ae03e6b..bd7d752 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 a039f49..aaaa07a 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 f5765d8..9c571a5 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 95747f2..4c62be7 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 7bc389d..8f1d70c 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 b418ce3..f88eb7b 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 156ade2..fc1b44d 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 755de0c..134edf3 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 0383dfe..e772eca 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 3dc3337..d7775e6 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 ff12771..3996600 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 0000000..7eb1725 --- /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 0000000..8a04fbd --- /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 2a65b7f..d98b682 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 265ca92..a583e32 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 8daf12a..03f5042 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 0f98078..8beaeef 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 e0a3b3b..d2bf92e 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 0000000..d72fb41 --- /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." } +] |