diff options
354 files changed, 4296 insertions, 1863 deletions
diff --git a/.clang-tidy b/.clang-tidy index 626c754..dace6f1 100644 --- a/.clang-tidy +++ b/.clang-tidy @@ -14,7 +14,6 @@ modernize-*,\ -modernize-raw-string-literal,\ -modernize-return-braced-init-list,\ -modernize-use-auto,\ --modernize-use-equals-default,\ -modernize-use-equals-delete,\ -modernize-use-noexcept,\ -modernize-use-transparent-functors,\ diff --git a/Help/envvar/CMAKE_NO_VERBOSE.rst b/Help/envvar/CMAKE_NO_VERBOSE.rst new file mode 100644 index 0000000..149efbd --- /dev/null +++ b/Help/envvar/CMAKE_NO_VERBOSE.rst @@ -0,0 +1,8 @@ +CMAKE_NO_VERBOSE +---------------- + +Disables verbose output from CMake when :envvar:`VERBOSE` environment variable +is set. + +Only your build tool of choice will still print verbose output when you start +to actually build your project. diff --git a/Help/envvar/VERBOSE.rst b/Help/envvar/VERBOSE.rst new file mode 100644 index 0000000..2d775a5 --- /dev/null +++ b/Help/envvar/VERBOSE.rst @@ -0,0 +1,10 @@ +VERBOSE +------- + +Activates verbose output from CMake and your build tools of choice when +you start to actually build your project. + +Note that any given value is ignored. It's just checked for existence. + +See also :ref:`Build Tool Mode <Build Tool Mode>` and +:envvar:`CMAKE_NO_VERBOSE` environment variable diff --git a/Help/manual/cmake-env-variables.7.rst b/Help/manual/cmake-env-variables.7.rst index edf80f4..c433412 100644 --- a/Help/manual/cmake-env-variables.7.rst +++ b/Help/manual/cmake-env-variables.7.rst @@ -24,11 +24,13 @@ Environment Variables that Control the Build /envvar/CMAKE_BUILD_PARALLEL_LEVEL /envvar/CMAKE_CONFIG_TYPE /envvar/CMAKE_MSVCIDE_RUN_PATH + /envvar/CMAKE_NO_VERBOSE /envvar/CMAKE_OSX_ARCHITECTURES /envvar/DESTDIR /envvar/LDFLAGS /envvar/MACOSX_DEPLOYMENT_TARGET /envvar/PackageName_ROOT + /envvar/VERBOSE Environment Variables for Languages =================================== diff --git a/Help/manual/cmake.1.rst b/Help/manual/cmake.1.rst index eaf57a0..f3b81ec 100644 --- a/Help/manual/cmake.1.rst +++ b/Help/manual/cmake.1.rst @@ -289,6 +289,14 @@ following options: ``--use-stderr`` Ignored. Behavior is default in CMake >= 3.0. +``-v, --verbose`` + Enable verbose output - if supported - including the build commands to be + executed. + + This option can be omitted if :envvar:`VERBOSE` environment variable or + :variable:`CMAKE_VERBOSE_MAKEFILE` cached variable is set. + + ``--`` Pass remaining options to the native tool. diff --git a/Help/release/dev/cmake-build-verbose.rst b/Help/release/dev/cmake-build-verbose.rst new file mode 100644 index 0000000..dee212e --- /dev/null +++ b/Help/release/dev/cmake-build-verbose.rst @@ -0,0 +1,6 @@ +cmake-build-verbose +------------------- + +* The :manual:`cmake(1)` :ref:`Build Tool Mode` (``cmake --build``) gained + ``--verbose`` and ``-v`` options to specify verbose build output. Some + generators such as Xcode don't support this option currently. diff --git a/Help/variable/CMAKE_LANG_COMPILER_ID.rst b/Help/variable/CMAKE_LANG_COMPILER_ID.rst index 033e81c..5323880 100644 --- a/Help/variable/CMAKE_LANG_COMPILER_ID.rst +++ b/Help/variable/CMAKE_LANG_COMPILER_ID.rst @@ -17,6 +17,7 @@ include: Clang = LLVM Clang (clang.llvm.org) Cray = Cray Compiler (cray.com) Embarcadero, Borland = Embarcadero (embarcadero.com) + Flang = Flang LLVM Fortran Compiler G95 = G95 Fortran (g95.org) GNU = GNU Compiler Collection (gcc.gnu.org) GHS = Green Hills Software (www.ghs.com) @@ -28,7 +29,6 @@ include: NVIDIA = NVIDIA CUDA Compiler (nvidia.com) OpenWatcom = Open Watcom (openwatcom.org) PGI = The Portland Group (pgroup.com) - Flang = Flang Fortran Compiler PathScale = PathScale (pathscale.com) SDCC = Small Device C Compiler (sdcc.sourceforge.net) SunPro = Oracle Solaris Studio (oracle.com) diff --git a/Modules/UseJava.cmake b/Modules/UseJava.cmake index 2bcd28e..5600b4c 100644 --- a/Modules/UseJava.cmake +++ b/Modules/UseJava.cmake @@ -446,7 +446,7 @@ function (__java_copy_file src dest comment) endfunction () function(__java_lcat VAR) - foreach(_line ${ARGN}) + foreach(_line IN LISTS ARGN) string(APPEND ${VAR} "${_line}\n") endforeach() @@ -568,7 +568,7 @@ function(add_jar _TARGET_NAME) set(CMAKE_JAVA_INCLUDE_FLAG_SEP ":") endif() - foreach (JAVA_INCLUDE_DIR ${CMAKE_JAVA_INCLUDE_PATH}) + foreach (JAVA_INCLUDE_DIR IN LISTS CMAKE_JAVA_INCLUDE_PATH) string(APPEND CMAKE_JAVA_INCLUDE_PATH_FINAL "${CMAKE_JAVA_INCLUDE_FLAG_SEP}${JAVA_INCLUDE_DIR}") endforeach() @@ -592,7 +592,7 @@ function(add_jar _TARGET_NAME) set(_JAVA_COMPILE_DEPENDS) set(_JAVA_RESOURCE_FILES) set(_JAVA_RESOURCE_FILES_RELATIVE) - foreach(_JAVA_SOURCE_FILE ${_JAVA_SOURCE_FILES}) + foreach(_JAVA_SOURCE_FILE IN LISTS _JAVA_SOURCE_FILES) get_filename_component(_JAVA_EXT ${_JAVA_SOURCE_FILE} EXT) get_filename_component(_JAVA_FILE ${_JAVA_SOURCE_FILE} NAME_WE) get_filename_component(_JAVA_PATH ${_JAVA_SOURCE_FILE} PATH) @@ -607,7 +607,7 @@ function(add_jar _TARGET_NAME) file(RELATIVE_PATH _JAVA_REL_SOURCE_PATH ${CMAKE_CURRENT_SOURCE_DIR} ${_JAVA_FULL}) string(LENGTH ${_JAVA_REL_BINARY_PATH} _BIN_LEN) string(LENGTH ${_JAVA_REL_SOURCE_PATH} _SRC_LEN) - if (${_BIN_LEN} LESS ${_SRC_LEN}) + if (_BIN_LEN LESS _SRC_LEN) set(_JAVA_REL_PATH ${_JAVA_REL_BINARY_PATH}) else () set(_JAVA_REL_PATH ${_JAVA_REL_SOURCE_PATH}) @@ -637,7 +637,7 @@ function(add_jar _TARGET_NAME) endif () endforeach() - foreach(_JAVA_INCLUDE_JAR ${_add_jar_INCLUDE_JARS}) + foreach(_JAVA_INCLUDE_JAR IN LISTS _add_jar_INCLUDE_JARS) if (TARGET ${_JAVA_INCLUDE_JAR}) get_target_property(_JAVA_JAR_PATH ${_JAVA_INCLUDE_JAR} JAR_FILE) if (_JAVA_JAR_PATH) @@ -705,7 +705,7 @@ function(add_jar _TARGET_NAME) # create the jar file set(_JAVA_JAR_OUTPUT_PATH - ${_add_jar_OUTPUT_DIR}/${_JAVA_TARGET_OUTPUT_NAME}) + "${_add_jar_OUTPUT_DIR}/${_JAVA_TARGET_OUTPUT_NAME}") if (CMAKE_JNI_TARGET) add_custom_command( OUTPUT ${_JAVA_JAR_OUTPUT_PATH} @@ -903,15 +903,15 @@ function (find_jar VARIABLE) set(_state "name") - foreach (arg ${ARGN}) - if (${_state} STREQUAL "name") - if (${arg} STREQUAL "VERSIONS") + foreach (arg IN LISTS ARGN) + if (_state STREQUAL "name") + if (arg STREQUAL "VERSIONS") set(_state "versions") - elseif (${arg} STREQUAL "NAMES") + elseif (arg STREQUAL "NAMES") set(_state "names") - elseif (${arg} STREQUAL "PATHS") + elseif (arg STREQUAL "PATHS") set(_state "paths") - elseif (${arg} STREQUAL "DOC") + elseif (arg STREQUAL "DOC") set(_state "doc") else () set(_jar_names ${arg}) @@ -919,22 +919,22 @@ function (find_jar VARIABLE) set(_jar_doc "Finding ${arg} jar") endif () endif () - elseif (${_state} STREQUAL "versions") - if (${arg} STREQUAL "NAMES") + elseif (_state STREQUAL "versions") + if (arg STREQUAL "NAMES") set(_state "names") - elseif (${arg} STREQUAL "PATHS") + elseif (arg STREQUAL "PATHS") set(_state "paths") - elseif (${arg} STREQUAL "DOC") + elseif (arg STREQUAL "DOC") set(_state "doc") else () set(_jar_versions ${_jar_versions} ${arg}) endif () - elseif (${_state} STREQUAL "names") - if (${arg} STREQUAL "VERSIONS") + elseif (_state STREQUAL "names") + if (arg STREQUAL "VERSIONS") set(_state "versions") - elseif (${arg} STREQUAL "PATHS") + elseif (arg STREQUAL "PATHS") set(_state "paths") - elseif (${arg} STREQUAL "DOC") + elseif (arg STREQUAL "DOC") set(_state "doc") else () set(_jar_names ${_jar_names} ${arg}) @@ -942,22 +942,22 @@ function (find_jar VARIABLE) set(_jar_doc "Finding ${arg} jar") endif () endif () - elseif (${_state} STREQUAL "paths") - if (${arg} STREQUAL "VERSIONS") + elseif (_state STREQUAL "paths") + if (arg STREQUAL "VERSIONS") set(_state "versions") - elseif (${arg} STREQUAL "NAMES") + elseif (arg STREQUAL "NAMES") set(_state "names") - elseif (${arg} STREQUAL "DOC") + elseif (arg STREQUAL "DOC") set(_state "doc") else () set(_jar_paths ${_jar_paths} ${arg}) endif () - elseif (${_state} STREQUAL "doc") - if (${arg} STREQUAL "VERSIONS") + elseif (_state STREQUAL "doc") + if (arg STREQUAL "VERSIONS") set(_state "versions") - elseif (${arg} STREQUAL "NAMES") + elseif (arg STREQUAL "NAMES") set(_state "names") - elseif (${arg} STREQUAL "PATHS") + elseif (arg STREQUAL "PATHS") set(_state "paths") else () set(_jar_doc ${arg}) @@ -969,8 +969,8 @@ function (find_jar VARIABLE) message(FATAL_ERROR "find_jar: No name to search for given") endif () - foreach (jar_name ${_jar_names}) - foreach (version ${_jar_versions}) + foreach (jar_name IN LISTS _jar_names) + foreach (version IN LISTS _jar_versions) set(_jar_files ${_jar_files} ${jar_name}-${version}.jar) endforeach () set(_jar_files ${_jar_files} ${jar_name}.jar) @@ -997,252 +997,252 @@ function(create_javadoc _target) set(_state "package") - foreach (arg ${ARGN}) - if (${_state} STREQUAL "package") - if (${arg} STREQUAL "PACKAGES") + foreach (arg IN LISTS ARGN) + if (_state STREQUAL "package") + if (arg STREQUAL "PACKAGES") set(_state "packages") - elseif (${arg} STREQUAL "FILES") + elseif (arg STREQUAL "FILES") set(_state "files") - elseif (${arg} STREQUAL "SOURCEPATH") + elseif (arg STREQUAL "SOURCEPATH") set(_state "sourcepath") - elseif (${arg} STREQUAL "CLASSPATH") + elseif (arg STREQUAL "CLASSPATH") set(_state "classpath") - elseif (${arg} STREQUAL "INSTALLPATH") + elseif (arg STREQUAL "INSTALLPATH") set(_state "installpath") - elseif (${arg} STREQUAL "DOCTITLE") + elseif (arg STREQUAL "DOCTITLE") set(_state "doctitle") - elseif (${arg} STREQUAL "WINDOWTITLE") + elseif (arg STREQUAL "WINDOWTITLE") set(_state "windowtitle") - elseif (${arg} STREQUAL "AUTHOR") + elseif (arg STREQUAL "AUTHOR") set(_state "author") - elseif (${arg} STREQUAL "USE") + elseif (arg STREQUAL "USE") set(_state "use") - elseif (${arg} STREQUAL "VERSION") + elseif (arg STREQUAL "VERSION") set(_state "version") else () set(_javadoc_packages ${arg}) set(_state "packages") endif () - elseif (${_state} STREQUAL "packages") - if (${arg} STREQUAL "FILES") + elseif (_state STREQUAL "packages") + if (arg STREQUAL "FILES") set(_state "files") - elseif (${arg} STREQUAL "SOURCEPATH") + elseif (arg STREQUAL "SOURCEPATH") set(_state "sourcepath") - elseif (${arg} STREQUAL "CLASSPATH") + elseif (arg STREQUAL "CLASSPATH") set(_state "classpath") - elseif (${arg} STREQUAL "INSTALLPATH") + elseif (arg STREQUAL "INSTALLPATH") set(_state "installpath") - elseif (${arg} STREQUAL "DOCTITLE") + elseif (arg STREQUAL "DOCTITLE") set(_state "doctitle") - elseif (${arg} STREQUAL "WINDOWTITLE") + elseif (arg STREQUAL "WINDOWTITLE") set(_state "windowtitle") - elseif (${arg} STREQUAL "AUTHOR") + elseif (arg STREQUAL "AUTHOR") set(_state "author") - elseif (${arg} STREQUAL "USE") + elseif (arg STREQUAL "USE") set(_state "use") - elseif (${arg} STREQUAL "VERSION") + elseif (arg STREQUAL "VERSION") set(_state "version") else () list(APPEND _javadoc_packages ${arg}) endif () - elseif (${_state} STREQUAL "files") - if (${arg} STREQUAL "PACKAGES") + elseif (_state STREQUAL "files") + if (arg STREQUAL "PACKAGES") set(_state "packages") - elseif (${arg} STREQUAL "SOURCEPATH") + elseif (arg STREQUAL "SOURCEPATH") set(_state "sourcepath") - elseif (${arg} STREQUAL "CLASSPATH") + elseif (arg STREQUAL "CLASSPATH") set(_state "classpath") - elseif (${arg} STREQUAL "INSTALLPATH") + elseif (arg STREQUAL "INSTALLPATH") set(_state "installpath") - elseif (${arg} STREQUAL "DOCTITLE") + elseif (arg STREQUAL "DOCTITLE") set(_state "doctitle") - elseif (${arg} STREQUAL "WINDOWTITLE") + elseif (arg STREQUAL "WINDOWTITLE") set(_state "windowtitle") - elseif (${arg} STREQUAL "AUTHOR") + elseif (arg STREQUAL "AUTHOR") set(_state "author") - elseif (${arg} STREQUAL "USE") + elseif (arg STREQUAL "USE") set(_state "use") - elseif (${arg} STREQUAL "VERSION") + elseif (arg STREQUAL "VERSION") set(_state "version") else () list(APPEND _javadoc_files ${arg}) endif () - elseif (${_state} STREQUAL "sourcepath") - if (${arg} STREQUAL "PACKAGES") + elseif (_state STREQUAL "sourcepath") + if (arg STREQUAL "PACKAGES") set(_state "packages") - elseif (${arg} STREQUAL "FILES") + elseif (arg STREQUAL "FILES") set(_state "files") - elseif (${arg} STREQUAL "CLASSPATH") + elseif (arg STREQUAL "CLASSPATH") set(_state "classpath") - elseif (${arg} STREQUAL "INSTALLPATH") + elseif (arg STREQUAL "INSTALLPATH") set(_state "installpath") - elseif (${arg} STREQUAL "DOCTITLE") + elseif (arg STREQUAL "DOCTITLE") set(_state "doctitle") - elseif (${arg} STREQUAL "WINDOWTITLE") + elseif (arg STREQUAL "WINDOWTITLE") set(_state "windowtitle") - elseif (${arg} STREQUAL "AUTHOR") + elseif (arg STREQUAL "AUTHOR") set(_state "author") - elseif (${arg} STREQUAL "USE") + elseif (arg STREQUAL "USE") set(_state "use") - elseif (${arg} STREQUAL "VERSION") + elseif (arg STREQUAL "VERSION") set(_state "version") else () list(APPEND _javadoc_sourcepath ${arg}) endif () - elseif (${_state} STREQUAL "classpath") - if (${arg} STREQUAL "PACKAGES") + elseif (_state STREQUAL "classpath") + if (arg STREQUAL "PACKAGES") set(_state "packages") - elseif (${arg} STREQUAL "FILES") + elseif (arg STREQUAL "FILES") set(_state "files") - elseif (${arg} STREQUAL "SOURCEPATH") + elseif (arg STREQUAL "SOURCEPATH") set(_state "sourcepath") - elseif (${arg} STREQUAL "INSTALLPATH") + elseif (arg STREQUAL "INSTALLPATH") set(_state "installpath") - elseif (${arg} STREQUAL "DOCTITLE") + elseif (arg STREQUAL "DOCTITLE") set(_state "doctitle") - elseif (${arg} STREQUAL "WINDOWTITLE") + elseif (arg STREQUAL "WINDOWTITLE") set(_state "windowtitle") - elseif (${arg} STREQUAL "AUTHOR") + elseif (arg STREQUAL "AUTHOR") set(_state "author") - elseif (${arg} STREQUAL "USE") + elseif (arg STREQUAL "USE") set(_state "use") - elseif (${arg} STREQUAL "VERSION") + elseif (arg STREQUAL "VERSION") set(_state "version") else () list(APPEND _javadoc_classpath ${arg}) endif () - elseif (${_state} STREQUAL "installpath") - if (${arg} STREQUAL "PACKAGES") + elseif (_state STREQUAL "installpath") + if (arg STREQUAL "PACKAGES") set(_state "packages") - elseif (${arg} STREQUAL "FILES") + elseif (arg STREQUAL "FILES") set(_state "files") - elseif (${arg} STREQUAL "SOURCEPATH") + elseif (arg STREQUAL "SOURCEPATH") set(_state "sourcepath") - elseif (${arg} STREQUAL "DOCTITLE") + elseif (arg STREQUAL "DOCTITLE") set(_state "doctitle") - elseif (${arg} STREQUAL "WINDOWTITLE") + elseif (arg STREQUAL "WINDOWTITLE") set(_state "windowtitle") - elseif (${arg} STREQUAL "AUTHOR") + elseif (arg STREQUAL "AUTHOR") set(_state "author") - elseif (${arg} STREQUAL "USE") + elseif (arg STREQUAL "USE") set(_state "use") - elseif (${arg} STREQUAL "VERSION") + elseif (arg STREQUAL "VERSION") set(_state "version") else () set(_javadoc_installpath ${arg}) endif () - elseif (${_state} STREQUAL "doctitle") + elseif (_state STREQUAL "doctitle") if (${arg} STREQUAL "PACKAGES") set(_state "packages") - elseif (${arg} STREQUAL "FILES") + elseif (arg STREQUAL "FILES") set(_state "files") - elseif (${arg} STREQUAL "SOURCEPATH") + elseif (arg STREQUAL "SOURCEPATH") set(_state "sourcepath") - elseif (${arg} STREQUAL "INSTALLPATH") + elseif (arg STREQUAL "INSTALLPATH") set(_state "installpath") - elseif (${arg} STREQUAL "CLASSPATH") + elseif (arg STREQUAL "CLASSPATH") set(_state "classpath") - elseif (${arg} STREQUAL "WINDOWTITLE") + elseif (arg STREQUAL "WINDOWTITLE") set(_state "windowtitle") - elseif (${arg} STREQUAL "AUTHOR") + elseif (arg STREQUAL "AUTHOR") set(_state "author") - elseif (${arg} STREQUAL "USE") + elseif (arg STREQUAL "USE") set(_state "use") - elseif (${arg} STREQUAL "VERSION") + elseif (arg STREQUAL "VERSION") set(_state "version") else () set(_javadoc_doctitle ${arg}) endif () - elseif (${_state} STREQUAL "windowtitle") + elseif (_state STREQUAL "windowtitle") if (${arg} STREQUAL "PACKAGES") set(_state "packages") - elseif (${arg} STREQUAL "FILES") + elseif (arg STREQUAL "FILES") set(_state "files") - elseif (${arg} STREQUAL "SOURCEPATH") + elseif (arg STREQUAL "SOURCEPATH") set(_state "sourcepath") - elseif (${arg} STREQUAL "CLASSPATH") + elseif (arg STREQUAL "CLASSPATH") set(_state "classpath") - elseif (${arg} STREQUAL "INSTALLPATH") + elseif (arg STREQUAL "INSTALLPATH") set(_state "installpath") - elseif (${arg} STREQUAL "DOCTITLE") + elseif (arg STREQUAL "DOCTITLE") set(_state "doctitle") - elseif (${arg} STREQUAL "AUTHOR") + elseif (arg STREQUAL "AUTHOR") set(_state "author") - elseif (${arg} STREQUAL "USE") + elseif (arg STREQUAL "USE") set(_state "use") - elseif (${arg} STREQUAL "VERSION") + elseif (arg STREQUAL "VERSION") set(_state "version") else () set(_javadoc_windowtitle ${arg}) endif () - elseif (${_state} STREQUAL "author") - if (${arg} STREQUAL "PACKAGES") + elseif (_state STREQUAL "author") + if (arg STREQUAL "PACKAGES") set(_state "packages") - elseif (${arg} STREQUAL "FILES") + elseif (arg STREQUAL "FILES") set(_state "files") - elseif (${arg} STREQUAL "SOURCEPATH") + elseif (arg STREQUAL "SOURCEPATH") set(_state "sourcepath") - elseif (${arg} STREQUAL "CLASSPATH") + elseif (arg STREQUAL "CLASSPATH") set(_state "classpath") - elseif (${arg} STREQUAL "INSTALLPATH") + elseif (arg STREQUAL "INSTALLPATH") set(_state "installpath") - elseif (${arg} STREQUAL "DOCTITLE") + elseif (arg STREQUAL "DOCTITLE") set(_state "doctitle") - elseif (${arg} STREQUAL "WINDOWTITLE") + elseif (arg STREQUAL "WINDOWTITLE") set(_state "windowtitle") - elseif (${arg} STREQUAL "AUTHOR") + elseif (arg STREQUAL "AUTHOR") set(_state "author") - elseif (${arg} STREQUAL "USE") + elseif (arg STREQUAL "USE") set(_state "use") - elseif (${arg} STREQUAL "VERSION") + elseif (arg STREQUAL "VERSION") set(_state "version") else () set(_javadoc_author ${arg}) endif () - elseif (${_state} STREQUAL "use") - if (${arg} STREQUAL "PACKAGES") + elseif (_state STREQUAL "use") + if (arg STREQUAL "PACKAGES") set(_state "packages") - elseif (${arg} STREQUAL "FILES") + elseif (arg STREQUAL "FILES") set(_state "files") - elseif (${arg} STREQUAL "SOURCEPATH") + elseif (arg STREQUAL "SOURCEPATH") set(_state "sourcepath") - elseif (${arg} STREQUAL "CLASSPATH") + elseif (arg STREQUAL "CLASSPATH") set(_state "classpath") - elseif (${arg} STREQUAL "INSTALLPATH") + elseif (arg STREQUAL "INSTALLPATH") set(_state "installpath") - elseif (${arg} STREQUAL "DOCTITLE") + elseif (arg STREQUAL "DOCTITLE") set(_state "doctitle") - elseif (${arg} STREQUAL "WINDOWTITLE") + elseif (arg STREQUAL "WINDOWTITLE") set(_state "windowtitle") - elseif (${arg} STREQUAL "AUTHOR") + elseif (arg STREQUAL "AUTHOR") set(_state "author") - elseif (${arg} STREQUAL "USE") + elseif (arg STREQUAL "USE") set(_state "use") - elseif (${arg} STREQUAL "VERSION") + elseif (arg STREQUAL "VERSION") set(_state "version") else () set(_javadoc_use ${arg}) endif () - elseif (${_state} STREQUAL "version") - if (${arg} STREQUAL "PACKAGES") + elseif (_state STREQUAL "version") + if (arg STREQUAL "PACKAGES") set(_state "packages") - elseif (${arg} STREQUAL "FILES") + elseif (arg STREQUAL "FILES") set(_state "files") - elseif (${arg} STREQUAL "SOURCEPATH") + elseif (arg STREQUAL "SOURCEPATH") set(_state "sourcepath") - elseif (${arg} STREQUAL "CLASSPATH") + elseif (arg STREQUAL "CLASSPATH") set(_state "classpath") - elseif (${arg} STREQUAL "INSTALLPATH") + elseif (arg STREQUAL "INSTALLPATH") set(_state "installpath") - elseif (${arg} STREQUAL "DOCTITLE") + elseif (arg STREQUAL "DOCTITLE") set(_state "doctitle") - elseif (${arg} STREQUAL "WINDOWTITLE") + elseif (arg STREQUAL "WINDOWTITLE") set(_state "windowtitle") - elseif (${arg} STREQUAL "AUTHOR") + elseif (arg STREQUAL "AUTHOR") set(_state "author") - elseif (${arg} STREQUAL "USE") + elseif (arg STREQUAL "USE") set(_state "use") - elseif (${arg} STREQUAL "VERSION") + elseif (arg STREQUAL "VERSION") set(_state "version") else () set(_javadoc_version ${arg}) @@ -1255,7 +1255,7 @@ function(create_javadoc _target) if (_javadoc_sourcepath) set(_start TRUE) - foreach(_path ${_javadoc_sourcepath}) + foreach(_path IN LISTS _javadoc_sourcepath) if (_start) set(_sourcepath ${_path}) set(_start FALSE) @@ -1268,7 +1268,7 @@ function(create_javadoc _target) if (_javadoc_classpath) set(_start TRUE) - foreach(_path ${_javadoc_classpath}) + foreach(_path IN LISTS _javadoc_classpath) if (_start) set(_classpath ${_path}) set(_start FALSE) @@ -1435,7 +1435,7 @@ function(export_jars) # Set content of generated exports file string(REPLACE ";" " " __targets__ "${_export_jars_TARGETS}") set(__targetdefs__ "") - foreach(_target ${_export_jars_TARGETS}) + foreach(_target IN LISTS _export_jars_TARGETS) get_target_property(_jarpath ${_target} JAR_FILE) get_filename_component(_jarpath ${_jarpath} PATH) __java_export_jar(__targetdefs__ ${_target} "${_jarpath}") @@ -1473,7 +1473,7 @@ function(install_jar_exports) endif() # Determine relative path from installed export file to install prefix - if(IS_ABSOLUTE ${_install_jar_exports_DESTINATION}) + if(IS_ABSOLUTE "${_install_jar_exports_DESTINATION}") file(RELATIVE_PATH _relpath ${_install_jar_exports_DESTINATION} ${CMAKE_INSTALL_PREFIX} @@ -1492,7 +1492,7 @@ function(install_jar_exports) # Set content of generated exports file string(REPLACE ";" " " __targets__ "${_install_jar_exports_TARGETS}") set(__targetdefs__ "set(_prefix \${CMAKE_CURRENT_LIST_DIR}/${_relpath})\n\n") - foreach(_target ${_install_jar_exports_TARGETS}) + foreach(_target IN LISTS _install_jar_exports_TARGETS) get_target_property(_dir ${_target} INSTALL_DESTINATION) __java_export_jar(__targetdefs__ ${_target} "\${_prefix}/${_dir}") endforeach() diff --git a/Source/CMakeVersion.cmake b/Source/CMakeVersion.cmake index 0362d52..9e64efa 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 13) -set(CMake_VERSION_PATCH 20190129) +set(CMake_VERSION_PATCH 20190130) #set(CMake_VERSION_RC 1) diff --git a/Source/CPack/IFW/cmCPackIFWGenerator.cxx b/Source/CPack/IFW/cmCPackIFWGenerator.cxx index 180c92e..9102e3e 100644 --- a/Source/CPack/IFW/cmCPackIFWGenerator.cxx +++ b/Source/CPack/IFW/cmCPackIFWGenerator.cxx @@ -21,9 +21,7 @@ cmCPackIFWGenerator::cmCPackIFWGenerator() this->Generator = this; } -cmCPackIFWGenerator::~cmCPackIFWGenerator() -{ -} +cmCPackIFWGenerator::~cmCPackIFWGenerator() = default; int cmCPackIFWGenerator::PackageFiles() { diff --git a/Source/CPack/IFW/cmCPackIFWInstaller.cxx b/Source/CPack/IFW/cmCPackIFWInstaller.cxx index 8f492af..01e3ea4 100644 --- a/Source/CPack/IFW/cmCPackIFWInstaller.cxx +++ b/Source/CPack/IFW/cmCPackIFWInstaller.cxx @@ -16,9 +16,7 @@ #include <stddef.h> #include <utility> -cmCPackIFWInstaller::cmCPackIFWInstaller() -{ -} +cmCPackIFWInstaller::cmCPackIFWInstaller() = default; void cmCPackIFWInstaller::printSkippedOptionWarning( const std::string& optionName, const std::string& optionValue) @@ -288,8 +286,7 @@ protected: content = cmSystemTools::TrimWhitespace(content); std::string source = this->basePath + "/" + content; std::string destination = this->path + "/" + content; - if (!cmSystemTools::CopyFileIfDifferent(source.data(), - destination.data())) { + if (!cmSystemTools::CopyFileIfDifferent(source, destination)) { this->hasErrors = true; } } diff --git a/Source/CPack/IFW/cmCPackIFWPackage.cxx b/Source/CPack/IFW/cmCPackIFWPackage.cxx index c96b5d4..a1a52b1 100644 --- a/Source/CPack/IFW/cmCPackIFWPackage.cxx +++ b/Source/CPack/IFW/cmCPackIFWPackage.cxx @@ -24,9 +24,7 @@ cmCPackIFWPackage::CompareStruct::CompareStruct() } //------------------------------------------------------- DependenceStruct --- -cmCPackIFWPackage::DependenceStruct::DependenceStruct() -{ -} +cmCPackIFWPackage::DependenceStruct::DependenceStruct() = default; cmCPackIFWPackage::DependenceStruct::DependenceStruct( const std::string& dependence) diff --git a/Source/CPack/cmCPack7zGenerator.cxx b/Source/CPack/cmCPack7zGenerator.cxx index f0c41a2..7413770 100644 --- a/Source/CPack/cmCPack7zGenerator.cxx +++ b/Source/CPack/cmCPack7zGenerator.cxx @@ -10,6 +10,4 @@ cmCPack7zGenerator::cmCPack7zGenerator() { } -cmCPack7zGenerator::~cmCPack7zGenerator() -{ -} +cmCPack7zGenerator::~cmCPack7zGenerator() = default; diff --git a/Source/CPack/cmCPackArchiveGenerator.cxx b/Source/CPack/cmCPackArchiveGenerator.cxx index 1756218..98fb29d 100644 --- a/Source/CPack/cmCPackArchiveGenerator.cxx +++ b/Source/CPack/cmCPackArchiveGenerator.cxx @@ -22,9 +22,7 @@ cmCPackArchiveGenerator::cmCPackArchiveGenerator(cmArchiveWrite::Compress t, this->ArchiveFormat = format; } -cmCPackArchiveGenerator::~cmCPackArchiveGenerator() -{ -} +cmCPackArchiveGenerator::~cmCPackArchiveGenerator() = default; std::string cmCPackArchiveGenerator::GetArchiveComponentFileName( const std::string& component, bool isGroupName) diff --git a/Source/CPack/cmCPackBundleGenerator.cxx b/Source/CPack/cmCPackBundleGenerator.cxx index f8fd108..3a476f4 100644 --- a/Source/CPack/cmCPackBundleGenerator.cxx +++ b/Source/CPack/cmCPackBundleGenerator.cxx @@ -8,13 +8,9 @@ #include "cmCPackLog.h" #include "cmSystemTools.h" -cmCPackBundleGenerator::cmCPackBundleGenerator() -{ -} +cmCPackBundleGenerator::cmCPackBundleGenerator() = default; -cmCPackBundleGenerator::~cmCPackBundleGenerator() -{ -} +cmCPackBundleGenerator::~cmCPackBundleGenerator() = default; int cmCPackBundleGenerator::InitializeInternal() { diff --git a/Source/CPack/cmCPackDebGenerator.cxx b/Source/CPack/cmCPackDebGenerator.cxx index 46a428f..635de49 100644 --- a/Source/CPack/cmCPackDebGenerator.cxx +++ b/Source/CPack/cmCPackDebGenerator.cxx @@ -432,13 +432,9 @@ bool DebGenerator::generateDeb() const } // end anonymous namespace -cmCPackDebGenerator::cmCPackDebGenerator() -{ -} +cmCPackDebGenerator::cmCPackDebGenerator() = default; -cmCPackDebGenerator::~cmCPackDebGenerator() -{ -} +cmCPackDebGenerator::~cmCPackDebGenerator() = default; int cmCPackDebGenerator::InitializeInternal() { diff --git a/Source/CPack/cmCPackDragNDropGenerator.cxx b/Source/CPack/cmCPackDragNDropGenerator.cxx index be4a18e..013ad81 100644 --- a/Source/CPack/cmCPackDragNDropGenerator.cxx +++ b/Source/CPack/cmCPackDragNDropGenerator.cxx @@ -62,9 +62,7 @@ cmCPackDragNDropGenerator::cmCPackDragNDropGenerator() this->componentPackageMethod = ONE_PACKAGE; } -cmCPackDragNDropGenerator::~cmCPackDragNDropGenerator() -{ -} +cmCPackDragNDropGenerator::~cmCPackDragNDropGenerator() = default; int cmCPackDragNDropGenerator::InitializeInternal() { @@ -212,8 +210,7 @@ int cmCPackDragNDropGenerator::PackageFiles() bool cmCPackDragNDropGenerator::CopyFile(std::ostringstream& source, std::ostringstream& target) { - if (!cmSystemTools::CopyFileIfDifferent(source.str().c_str(), - target.str().c_str())) { + if (!cmSystemTools::CopyFileIfDifferent(source.str(), target.str())) { cmCPackLogger(cmCPackLog::LOG_ERROR, "Error copying " << source.str() << " to " << target.str() << std::endl); diff --git a/Source/CPack/cmCPackFreeBSDGenerator.cxx b/Source/CPack/cmCPackFreeBSDGenerator.cxx index 0ff0054..fcf8af1 100644 --- a/Source/CPack/cmCPackFreeBSDGenerator.cxx +++ b/Source/CPack/cmCPackFreeBSDGenerator.cxx @@ -31,9 +31,7 @@ int cmCPackFreeBSDGenerator::InitializeInternal() return this->Superclass::InitializeInternal(); } -cmCPackFreeBSDGenerator::~cmCPackFreeBSDGenerator() -{ -} +cmCPackFreeBSDGenerator::~cmCPackFreeBSDGenerator() = default; // This is a wrapper, for use only in stream-based output, // that will output a string in UCL escaped fashion (in particular, @@ -103,7 +101,7 @@ public: { } - virtual ~ManifestKey() {} + virtual ~ManifestKey() = default; // Output the value associated with this key to the stream @p s. // Format is to be decided by subclasses. diff --git a/Source/CPack/cmCPackGenerator.cxx b/Source/CPack/cmCPackGenerator.cxx index 4728f69..57c0545 100644 --- a/Source/CPack/cmCPackGenerator.cxx +++ b/Source/CPack/cmCPackGenerator.cxx @@ -43,12 +43,6 @@ cmCPackGenerator::~cmCPackGenerator() this->MakefileMap = nullptr; } -void cmCPackGeneratorProgress(const char* msg, float prog, void* ptr) -{ - cmCPackGenerator* self = static_cast<cmCPackGenerator*>(ptr); - self->DisplayVerboseOutput(msg, prog); -} - void cmCPackGenerator::DisplayVerboseOutput(const char* msg, float progress) { (void)progress; @@ -392,8 +386,7 @@ int cmCPackGenerator::InstallProjectViaInstalledDirectories( std::move(inFileRelative)); } /* If it is not a symlink then do a plain copy */ - else if (!(cmSystemTools::CopyFileIfDifferent(inFile.c_str(), - filePath.c_str()) && + else if (!(cmSystemTools::CopyFileIfDifferent(inFile, filePath) && cmSystemTools::CopyFileTime(inFile.c_str(), filePath.c_str()))) { cmCPackLogger(cmCPackLog::LOG_ERROR, @@ -696,7 +689,9 @@ int cmCPackGenerator::InstallCMakeProject( cm.SetHomeOutputDirectory(""); cm.GetCurrentSnapshot().SetDefaultDefinitions(); cm.AddCMakePaths(); - cm.SetProgressCallback(cmCPackGeneratorProgress, this); + cm.SetProgressCallback([this](const char* msg, float prog) { + this->DisplayVerboseOutput(msg, prog); + }); cm.SetTrace(this->Trace); cm.SetTraceExpand(this->TraceExpand); cmGlobalGenerator gg(&cm); @@ -1077,8 +1072,7 @@ int cmCPackGenerator::DoPackage() << (tempPackageFileName ? tempPackageFileName : "(NULL)") << " to " << (packageFileName ? packageFileName : "(NULL)") << std::endl); - if (!cmSystemTools::CopyFileIfDifferent(tempPackageFileName, - packageFileName)) { + if (!cmSystemTools::CopyFileIfDifferent(pkgFileName, tmpPF)) { cmCPackLogger( cmCPackLog::LOG_ERROR, "Problem copying the package: " diff --git a/Source/CPack/cmCPackNSISGenerator.cxx b/Source/CPack/cmCPackNSISGenerator.cxx index 4b865ca..37ea66e 100644 --- a/Source/CPack/cmCPackNSISGenerator.cxx +++ b/Source/CPack/cmCPackNSISGenerator.cxx @@ -30,9 +30,7 @@ cmCPackNSISGenerator::cmCPackNSISGenerator(bool nsis64) Nsis64 = nsis64; } -cmCPackNSISGenerator::~cmCPackNSISGenerator() -{ -} +cmCPackNSISGenerator::~cmCPackNSISGenerator() = default; int cmCPackNSISGenerator::PackageFiles() { diff --git a/Source/CPack/cmCPackOSXX11Generator.cxx b/Source/CPack/cmCPackOSXX11Generator.cxx index 1908c17..486633c 100644 --- a/Source/CPack/cmCPackOSXX11Generator.cxx +++ b/Source/CPack/cmCPackOSXX11Generator.cxx @@ -11,13 +11,9 @@ #include "cmSystemTools.h" #include "cm_sys_stat.h" -cmCPackOSXX11Generator::cmCPackOSXX11Generator() -{ -} +cmCPackOSXX11Generator::cmCPackOSXX11Generator() = default; -cmCPackOSXX11Generator::~cmCPackOSXX11Generator() -{ -} +cmCPackOSXX11Generator::~cmCPackOSXX11Generator() = default; int cmCPackOSXX11Generator::PackageFiles() { diff --git a/Source/CPack/cmCPackPKGGenerator.cxx b/Source/CPack/cmCPackPKGGenerator.cxx index 9401bca..ae227aa 100644 --- a/Source/CPack/cmCPackPKGGenerator.cxx +++ b/Source/CPack/cmCPackPKGGenerator.cxx @@ -15,9 +15,7 @@ cmCPackPKGGenerator::cmCPackPKGGenerator() this->componentPackageMethod = ONE_PACKAGE; } -cmCPackPKGGenerator::~cmCPackPKGGenerator() -{ -} +cmCPackPKGGenerator::~cmCPackPKGGenerator() = default; bool cmCPackPKGGenerator::SupportsComponentInstallation() const { diff --git a/Source/CPack/cmCPackPackageMakerGenerator.cxx b/Source/CPack/cmCPackPackageMakerGenerator.cxx index 28e0561..246178d 100644 --- a/Source/CPack/cmCPackPackageMakerGenerator.cxx +++ b/Source/CPack/cmCPackPackageMakerGenerator.cxx @@ -30,9 +30,7 @@ cmCPackPackageMakerGenerator::cmCPackPackageMakerGenerator() this->PackageCompatibilityVersion = getVersion(10, 4); } -cmCPackPackageMakerGenerator::~cmCPackPackageMakerGenerator() -{ -} +cmCPackPackageMakerGenerator::~cmCPackPackageMakerGenerator() = default; bool cmCPackPackageMakerGenerator::SupportsComponentInstallation() const { diff --git a/Source/CPack/cmCPackProductBuildGenerator.cxx b/Source/CPack/cmCPackProductBuildGenerator.cxx index e73d01f..a556e0c 100644 --- a/Source/CPack/cmCPackProductBuildGenerator.cxx +++ b/Source/CPack/cmCPackProductBuildGenerator.cxx @@ -17,9 +17,7 @@ cmCPackProductBuildGenerator::cmCPackProductBuildGenerator() this->componentPackageMethod = ONE_PACKAGE; } -cmCPackProductBuildGenerator::~cmCPackProductBuildGenerator() -{ -} +cmCPackProductBuildGenerator::~cmCPackProductBuildGenerator() = default; int cmCPackProductBuildGenerator::PackageFiles() { diff --git a/Source/CPack/cmCPackRPMGenerator.cxx b/Source/CPack/cmCPackRPMGenerator.cxx index 5834829..33ab62b 100644 --- a/Source/CPack/cmCPackRPMGenerator.cxx +++ b/Source/CPack/cmCPackRPMGenerator.cxx @@ -14,13 +14,9 @@ #include "cmCPackLog.h" #include "cmSystemTools.h" -cmCPackRPMGenerator::cmCPackRPMGenerator() -{ -} +cmCPackRPMGenerator::cmCPackRPMGenerator() = default; -cmCPackRPMGenerator::~cmCPackRPMGenerator() -{ -} +cmCPackRPMGenerator::~cmCPackRPMGenerator() = default; int cmCPackRPMGenerator::InitializeInternal() { diff --git a/Source/CPack/cmCPackSTGZGenerator.cxx b/Source/CPack/cmCPackSTGZGenerator.cxx index e55ea87..aba15d2 100644 --- a/Source/CPack/cmCPackSTGZGenerator.cxx +++ b/Source/CPack/cmCPackSTGZGenerator.cxx @@ -13,13 +13,9 @@ #include "cmSystemTools.h" #include "cm_sys_stat.h" -cmCPackSTGZGenerator::cmCPackSTGZGenerator() -{ -} +cmCPackSTGZGenerator::cmCPackSTGZGenerator() = default; -cmCPackSTGZGenerator::~cmCPackSTGZGenerator() -{ -} +cmCPackSTGZGenerator::~cmCPackSTGZGenerator() = default; int cmCPackSTGZGenerator::InitializeInternal() { diff --git a/Source/CPack/cmCPackTGZGenerator.cxx b/Source/CPack/cmCPackTGZGenerator.cxx index eaf8186..6f4676e 100644 --- a/Source/CPack/cmCPackTGZGenerator.cxx +++ b/Source/CPack/cmCPackTGZGenerator.cxx @@ -10,6 +10,4 @@ cmCPackTGZGenerator::cmCPackTGZGenerator() { } -cmCPackTGZGenerator::~cmCPackTGZGenerator() -{ -} +cmCPackTGZGenerator::~cmCPackTGZGenerator() = default; diff --git a/Source/CPack/cmCPackTXZGenerator.cxx b/Source/CPack/cmCPackTXZGenerator.cxx index e55e903..ccbccde 100644 --- a/Source/CPack/cmCPackTXZGenerator.cxx +++ b/Source/CPack/cmCPackTXZGenerator.cxx @@ -10,6 +10,4 @@ cmCPackTXZGenerator::cmCPackTXZGenerator() { } -cmCPackTXZGenerator::~cmCPackTXZGenerator() -{ -} +cmCPackTXZGenerator::~cmCPackTXZGenerator() = default; diff --git a/Source/CPack/cmCPackTarBZip2Generator.cxx b/Source/CPack/cmCPackTarBZip2Generator.cxx index c7a3dd4..85abeb1 100644 --- a/Source/CPack/cmCPackTarBZip2Generator.cxx +++ b/Source/CPack/cmCPackTarBZip2Generator.cxx @@ -10,6 +10,4 @@ cmCPackTarBZip2Generator::cmCPackTarBZip2Generator() { } -cmCPackTarBZip2Generator::~cmCPackTarBZip2Generator() -{ -} +cmCPackTarBZip2Generator::~cmCPackTarBZip2Generator() = default; diff --git a/Source/CPack/cmCPackTarCompressGenerator.cxx b/Source/CPack/cmCPackTarCompressGenerator.cxx index 0a7cd97..55a6de5 100644 --- a/Source/CPack/cmCPackTarCompressGenerator.cxx +++ b/Source/CPack/cmCPackTarCompressGenerator.cxx @@ -10,6 +10,4 @@ cmCPackTarCompressGenerator::cmCPackTarCompressGenerator() { } -cmCPackTarCompressGenerator::~cmCPackTarCompressGenerator() -{ -} +cmCPackTarCompressGenerator::~cmCPackTarCompressGenerator() = default; diff --git a/Source/CPack/cmCPackZIPGenerator.cxx b/Source/CPack/cmCPackZIPGenerator.cxx index 6b77c36..f06494c 100644 --- a/Source/CPack/cmCPackZIPGenerator.cxx +++ b/Source/CPack/cmCPackZIPGenerator.cxx @@ -10,6 +10,4 @@ cmCPackZIPGenerator::cmCPackZIPGenerator() { } -cmCPackZIPGenerator::~cmCPackZIPGenerator() -{ -} +cmCPackZIPGenerator::~cmCPackZIPGenerator() = default; diff --git a/Source/CPack/cpack.cxx b/Source/CPack/cpack.cxx index d4c867b..0413422 100644 --- a/Source/CPack/cpack.cxx +++ b/Source/CPack/cpack.cxx @@ -90,12 +90,8 @@ int cpackDefinitionArgument(const char* argument, const char* cValue, return 1; } -static void cpackProgressCallback(const char* message, float progress, - void* clientdata) +static void cpackProgressCallback(const char* message, float /*unused*/) { - (void)progress; - (void)clientdata; - std::cout << "-- " << message << std::endl; } @@ -212,7 +208,7 @@ int main(int argc, char const* const* argv) cmake cminst(cmake::RoleScript, cmState::CPack); cminst.SetHomeDirectory(""); cminst.SetHomeOutputDirectory(""); - cminst.SetProgressCallback(cpackProgressCallback, nullptr); + cminst.SetProgressCallback(cpackProgressCallback); cminst.GetCurrentSnapshot().SetDefaultDefinitions(); cmGlobalGenerator cmgg(&cminst); cmMakefile globalMF(&cmgg, cminst.GetCurrentSnapshot()); diff --git a/Source/CTest/cmCTestBZR.cxx b/Source/CTest/cmCTestBZR.cxx index 365f267..b154caf 100644 --- a/Source/CTest/cmCTestBZR.cxx +++ b/Source/CTest/cmCTestBZR.cxx @@ -77,9 +77,7 @@ cmCTestBZR::cmCTestBZR(cmCTest* ct, std::ostream& log) cmSystemTools::PutEnv("BZR_PROGRESS_BAR=none"); } -cmCTestBZR::~cmCTestBZR() -{ -} +cmCTestBZR::~cmCTestBZR() = default; class cmCTestBZR::InfoParser : public cmCTestVC::LineParser { diff --git a/Source/CTest/cmCTestBuildAndTestHandler.cxx b/Source/CTest/cmCTestBuildAndTestHandler.cxx index 312d126..38aa1b3 100644 --- a/Source/CTest/cmCTestBuildAndTestHandler.cxx +++ b/Source/CTest/cmCTestBuildAndTestHandler.cxx @@ -109,27 +109,6 @@ int cmCTestBuildAndTestHandler::RunCMake(std::string* outstring, return 0; } -void CMakeMessageCallback(const char* m, const char* /*unused*/, - bool& /*unused*/, void* s) -{ - std::string* out = static_cast<std::string*>(s); - *out += m; - *out += "\n"; -} - -void CMakeProgressCallback(const char* msg, float /*unused*/, void* s) -{ - std::string* out = static_cast<std::string*>(s); - *out += msg; - *out += "\n"; -} - -void CMakeOutputCallback(const char* m, size_t len, void* s) -{ - std::string* out = static_cast<std::string*>(s); - out->append(m, len); -} - class cmCTestBuildAndTestCaptureRAII { cmake& CM; @@ -138,17 +117,30 @@ public: cmCTestBuildAndTestCaptureRAII(cmake& cm, std::string& s) : CM(cm) { - cmSystemTools::SetMessageCallback(CMakeMessageCallback, &s); - cmSystemTools::SetStdoutCallback(CMakeOutputCallback, &s); - cmSystemTools::SetStderrCallback(CMakeOutputCallback, &s); - this->CM.SetProgressCallback(CMakeProgressCallback, &s); + cmSystemTools::SetMessageCallback( + [&s](const char* msg, const char* /*unused*/) { + s += msg; + s += "\n"; + }); + + cmSystemTools::SetStdoutCallback( + [&s](const char* m, size_t len) { s.append(m, len); }); + + cmSystemTools::SetStderrCallback( + [&s](const char* m, size_t len) { s.append(m, len); }); + + this->CM.SetProgressCallback([&s](const char* msg, float /*unused*/) { + s += msg; + s += "\n"; + }); } + ~cmCTestBuildAndTestCaptureRAII() { - this->CM.SetProgressCallback(nullptr, nullptr); - cmSystemTools::SetStderrCallback(nullptr, nullptr); - cmSystemTools::SetStdoutCallback(nullptr, nullptr); - cmSystemTools::SetMessageCallback(nullptr, nullptr); + this->CM.SetProgressCallback(nullptr); + cmSystemTools::SetStderrCallback(nullptr); + cmSystemTools::SetStdoutCallback(nullptr); + cmSystemTools::SetMessageCallback(nullptr); } }; diff --git a/Source/CTest/cmCTestBuildHandler.cxx b/Source/CTest/cmCTestBuildHandler.cxx index d07bd21..d934c00 100644 --- a/Source/CTest/cmCTestBuildHandler.cxx +++ b/Source/CTest/cmCTestBuildHandler.cxx @@ -507,14 +507,13 @@ public: : FTC(ftc) { } - FragmentCompare() {} + FragmentCompare() = default; bool operator()(std::string const& l, std::string const& r) const { // Order files by modification time. Use lexicographic order // among files with the same time. int result; - if (this->FTC->FileTimeCompare(l.c_str(), r.c_str(), &result) && - result != 0) { + if (this->FTC->FileTimeCompare(l, r, &result) && result != 0) { return result < 0; } return l < r; diff --git a/Source/CTest/cmCTestCVS.cxx b/Source/CTest/cmCTestCVS.cxx index 6e1ada1..6e8f73f 100644 --- a/Source/CTest/cmCTestCVS.cxx +++ b/Source/CTest/cmCTestCVS.cxx @@ -16,9 +16,7 @@ cmCTestCVS::cmCTestCVS(cmCTest* ct, std::ostream& log) { } -cmCTestCVS::~cmCTestCVS() -{ -} +cmCTestCVS::~cmCTestCVS() = default; class cmCTestCVS::UpdateParser : public cmCTestVC::LineParser { diff --git a/Source/CTest/cmCTestConfigureHandler.cxx b/Source/CTest/cmCTestConfigureHandler.cxx index 5967b74..6b7601b 100644 --- a/Source/CTest/cmCTestConfigureHandler.cxx +++ b/Source/CTest/cmCTestConfigureHandler.cxx @@ -11,9 +11,7 @@ #include <ostream> #include <string> -cmCTestConfigureHandler::cmCTestConfigureHandler() -{ -} +cmCTestConfigureHandler::cmCTestConfigureHandler() = default; void cmCTestConfigureHandler::Initialize() { diff --git a/Source/CTest/cmCTestCoverageHandler.cxx b/Source/CTest/cmCTestCoverageHandler.cxx index e39e25a..225383c 100644 --- a/Source/CTest/cmCTestCoverageHandler.cxx +++ b/Source/CTest/cmCTestCoverageHandler.cxx @@ -111,9 +111,7 @@ private: cmDuration TimeOut; }; -cmCTestCoverageHandler::cmCTestCoverageHandler() -{ -} +cmCTestCoverageHandler::cmCTestCoverageHandler() = default; void cmCTestCoverageHandler::Initialize() { diff --git a/Source/CTest/cmCTestGIT.cxx b/Source/CTest/cmCTestGIT.cxx index 4ede3d4..210abe5 100644 --- a/Source/CTest/cmCTestGIT.cxx +++ b/Source/CTest/cmCTestGIT.cxx @@ -31,9 +31,7 @@ cmCTestGIT::cmCTestGIT(cmCTest* ct, std::ostream& log) this->CurrentGitVersion = 0; } -cmCTestGIT::~cmCTestGIT() -{ -} +cmCTestGIT::~cmCTestGIT() = default; class cmCTestGIT::OneLineParser : public cmCTestVC::LineParser { @@ -477,7 +475,6 @@ private: std::string EMail; unsigned long Time = 0; long TimeZone = 0; - Person() {} }; void ParsePerson(const char* str, Person& person) diff --git a/Source/CTest/cmCTestGenericHandler.cxx b/Source/CTest/cmCTestGenericHandler.cxx index dc1bba0..d3020b5 100644 --- a/Source/CTest/cmCTestGenericHandler.cxx +++ b/Source/CTest/cmCTestGenericHandler.cxx @@ -18,9 +18,7 @@ cmCTestGenericHandler::cmCTestGenericHandler() this->TestLoad = 0; } -cmCTestGenericHandler::~cmCTestGenericHandler() -{ -} +cmCTestGenericHandler::~cmCTestGenericHandler() = default; void cmCTestGenericHandler::SetOption(const std::string& op, const char* value) { diff --git a/Source/CTest/cmCTestGlobalVC.cxx b/Source/CTest/cmCTestGlobalVC.cxx index d2714d90..a2d4d2c 100644 --- a/Source/CTest/cmCTestGlobalVC.cxx +++ b/Source/CTest/cmCTestGlobalVC.cxx @@ -15,9 +15,7 @@ cmCTestGlobalVC::cmCTestGlobalVC(cmCTest* ct, std::ostream& log) this->PriorRev = this->Unknown; } -cmCTestGlobalVC::~cmCTestGlobalVC() -{ -} +cmCTestGlobalVC::~cmCTestGlobalVC() = default; const char* cmCTestGlobalVC::LocalPath(std::string const& path) { diff --git a/Source/CTest/cmCTestHG.cxx b/Source/CTest/cmCTestHG.cxx index 9c6a80d..6fb99d8 100644 --- a/Source/CTest/cmCTestHG.cxx +++ b/Source/CTest/cmCTestHG.cxx @@ -18,9 +18,7 @@ cmCTestHG::cmCTestHG(cmCTest* ct, std::ostream& log) this->PriorRev = this->Unknown; } -cmCTestHG::~cmCTestHG() -{ -} +cmCTestHG::~cmCTestHG() = default; class cmCTestHG::IdentifyParser : public cmCTestVC::LineParser { diff --git a/Source/CTest/cmCTestMultiProcessHandler.cxx b/Source/CTest/cmCTestMultiProcessHandler.cxx index d3aa2b4..756ac6c 100644 --- a/Source/CTest/cmCTestMultiProcessHandler.cxx +++ b/Source/CTest/cmCTestMultiProcessHandler.cxx @@ -44,7 +44,6 @@ public: : Handler(handler) { } - ~TestComparator() {} // Sorts tests in descending order of cost bool operator()(int index1, int index2) const @@ -70,9 +69,7 @@ cmCTestMultiProcessHandler::cmCTestMultiProcessHandler() this->SerialTestRunning = false; } -cmCTestMultiProcessHandler::~cmCTestMultiProcessHandler() -{ -} +cmCTestMultiProcessHandler::~cmCTestMultiProcessHandler() = default; // Set the tests void cmCTestMultiProcessHandler::SetTests(TestMap& tests, diff --git a/Source/CTest/cmCTestP4.cxx b/Source/CTest/cmCTestP4.cxx index c0bdc17..435be97 100644 --- a/Source/CTest/cmCTestP4.cxx +++ b/Source/CTest/cmCTestP4.cxx @@ -19,9 +19,7 @@ cmCTestP4::cmCTestP4(cmCTest* ct, std::ostream& log) this->PriorRev = this->Unknown; } -cmCTestP4::~cmCTestP4() -{ -} +cmCTestP4::~cmCTestP4() = default; class cmCTestP4::IdentifyParser : public cmCTestVC::LineParser { diff --git a/Source/CTest/cmCTestRunTest.h b/Source/CTest/cmCTestRunTest.h index c786413..918d5fa 100644 --- a/Source/CTest/cmCTestRunTest.h +++ b/Source/CTest/cmCTestRunTest.h @@ -27,8 +27,6 @@ class cmCTestRunTest public: explicit cmCTestRunTest(cmCTestMultiProcessHandler& multiHandler); - ~cmCTestRunTest() = default; - void SetNumberOfRuns(int n) { this->NumberOfRunsLeft = n; } void SetRunUntilFailOn() { this->RunUntilFail = true; } void SetTestProperties(cmCTestTestHandler::cmCTestTestProperties* prop) diff --git a/Source/CTest/cmCTestSVN.cxx b/Source/CTest/cmCTestSVN.cxx index afde61c..3bf66ca 100644 --- a/Source/CTest/cmCTestSVN.cxx +++ b/Source/CTest/cmCTestSVN.cxx @@ -26,9 +26,7 @@ cmCTestSVN::cmCTestSVN(cmCTest* ct, std::ostream& log) this->PriorRev = this->Unknown; } -cmCTestSVN::~cmCTestSVN() -{ -} +cmCTestSVN::~cmCTestSVN() = default; void cmCTestSVN::CleanupImpl() { diff --git a/Source/CTest/cmCTestScriptHandler.cxx b/Source/CTest/cmCTestScriptHandler.cxx index b949023..33b8b4a 100644 --- a/Source/CTest/cmCTestScriptHandler.cxx +++ b/Source/CTest/cmCTestScriptHandler.cxx @@ -53,8 +53,6 @@ struct cmListFileFunction; class cmCTestScriptFunctionBlocker : public cmFunctionBlocker { public: - cmCTestScriptFunctionBlocker() {} - ~cmCTestScriptFunctionBlocker() override {} bool IsFunctionBlocked(const cmListFileFunction& lff, cmMakefile& mf, cmExecutionStatus& /*status*/) override; // virtual bool ShouldRemove(const cmListFileFunction& lff, cmMakefile &mf); @@ -265,15 +263,6 @@ int cmCTestScriptHandler::ExecuteScript(const std::string& total_script_arg) return retVal; } -static void ctestScriptProgressCallback(const char* m, float /*unused*/, - void* cd) -{ - cmCTest* ctest = static_cast<cmCTest*>(cd); - if (m && *m) { - cmCTestLog(ctest, HANDLER_OUTPUT, "-- " << m << std::endl); - } -} - void cmCTestScriptHandler::CreateCMake() { // create a cmake instance to read the configuration script @@ -299,7 +288,11 @@ void cmCTestScriptHandler::CreateCMake() this->ParentMakefile->GetRecursionDepth()); } - this->CMake->SetProgressCallback(ctestScriptProgressCallback, this->CTest); + this->CMake->SetProgressCallback([this](const char* m, float /*unused*/) { + if (m && *m) { + cmCTestLog(this->CTest, HANDLER_OUTPUT, "-- " << m << std::endl); + } + }); this->AddCTestCommand("ctest_build", new cmCTestBuildCommand); this->AddCTestCommand("ctest_configure", new cmCTestConfigureCommand); diff --git a/Source/CTest/cmCTestSubmitHandler.cxx b/Source/CTest/cmCTestSubmitHandler.cxx index 5213bd3..87112da 100644 --- a/Source/CTest/cmCTestSubmitHandler.cxx +++ b/Source/CTest/cmCTestSubmitHandler.cxx @@ -30,10 +30,6 @@ typedef std::vector<char> cmCTestSubmitHandlerVectorOfChar; class cmCTestSubmitHandler::ResponseParser : public cmXMLParser { public: - ResponseParser() { this->Status = STATUS_OK; } - ~ResponseParser() override {} - -public: enum StatusType { STATUS_OK, @@ -41,7 +37,7 @@ public: STATUS_ERROR }; - StatusType Status; + StatusType Status = STATUS_OK; std::string Filename; std::string MD5; std::string Message; diff --git a/Source/CTest/cmCTestUpdateHandler.cxx b/Source/CTest/cmCTestUpdateHandler.cxx index 57e40ce..e3b7e9e 100644 --- a/Source/CTest/cmCTestUpdateHandler.cxx +++ b/Source/CTest/cmCTestUpdateHandler.cxx @@ -34,9 +34,7 @@ static const char* cmCTestUpdateHandlerUpdateToString(int type) return cmCTestUpdateHandlerUpdateStrings[type]; } -cmCTestUpdateHandler::cmCTestUpdateHandler() -{ -} +cmCTestUpdateHandler::cmCTestUpdateHandler() = default; void cmCTestUpdateHandler::Initialize() { diff --git a/Source/CTest/cmCTestVC.cxx b/Source/CTest/cmCTestVC.cxx index 63bd0e6..374e73f 100644 --- a/Source/CTest/cmCTestVC.cxx +++ b/Source/CTest/cmCTestVC.cxx @@ -24,9 +24,7 @@ cmCTestVC::cmCTestVC(cmCTest* ct, std::ostream& log) this->Unknown.Rev = "Unknown"; } -cmCTestVC::~cmCTestVC() -{ -} +cmCTestVC::~cmCTestVC() = default; void cmCTestVC::SetCommandLineTool(std::string const& tool) { diff --git a/Source/CTest/cmParseBlanketJSCoverage.cxx b/Source/CTest/cmParseBlanketJSCoverage.cxx index 308e6f7..63d6a15 100644 --- a/Source/CTest/cmParseBlanketJSCoverage.cxx +++ b/Source/CTest/cmParseBlanketJSCoverage.cxx @@ -20,7 +20,7 @@ public: { } - virtual ~JSONParser() {} + virtual ~JSONParser() = default; std::string getValue(std::string const& line, int type) { diff --git a/Source/CTest/cmParseCoberturaCoverage.cxx b/Source/CTest/cmParseCoberturaCoverage.cxx index 5bb6424..848a034 100644 --- a/Source/CTest/cmParseCoberturaCoverage.cxx +++ b/Source/CTest/cmParseCoberturaCoverage.cxx @@ -13,19 +13,12 @@ class cmParseCoberturaCoverage::XMLParser : public cmXMLParser { public: XMLParser(cmCTest* ctest, cmCTestCoverageHandlerContainer& cont) - : CTest(ctest) + : FilePaths{ cont.SourceDir, cont.BinaryDir } + , CTest(ctest) , Coverage(cont) { - this->InSources = false; - this->InSource = false; - this->SkipThisClass = false; - this->FilePaths.push_back(this->Coverage.SourceDir); - this->FilePaths.push_back(this->Coverage.BinaryDir); - this->CurFileName.clear(); } - ~XMLParser() override {} - protected: void EndElement(const std::string& name) override { @@ -144,9 +137,9 @@ protected: } private: - bool InSources; - bool InSource; - bool SkipThisClass; + bool InSources = false; + bool InSource = false; + bool SkipThisClass = false; std::vector<std::string> FilePaths; typedef cmCTestCoverageHandlerContainer::SingleFileCoverageVector FileLinesType; diff --git a/Source/CTest/cmParseDelphiCoverage.cxx b/Source/CTest/cmParseDelphiCoverage.cxx index d99de06..9eda6f8 100644 --- a/Source/CTest/cmParseDelphiCoverage.cxx +++ b/Source/CTest/cmParseDelphiCoverage.cxx @@ -20,7 +20,7 @@ public: { } - virtual ~HTMLParser() {} + virtual ~HTMLParser() = default; bool initializeDelphiFile( std::string const& filename, diff --git a/Source/CTest/cmParseJacocoCoverage.cxx b/Source/CTest/cmParseJacocoCoverage.cxx index 31e7cd4..61c5dcb 100644 --- a/Source/CTest/cmParseJacocoCoverage.cxx +++ b/Source/CTest/cmParseJacocoCoverage.cxx @@ -18,13 +18,8 @@ public: : CTest(ctest) , Coverage(cont) { - this->FilePath.clear(); - this->PackagePath.clear(); - this->PackageName.clear(); } - ~XMLParser() override {} - protected: void EndElement(const std::string& /*name*/) override {} diff --git a/Source/CTest/cmParseMumpsCoverage.cxx b/Source/CTest/cmParseMumpsCoverage.cxx index 488d237..4a81ee4 100644 --- a/Source/CTest/cmParseMumpsCoverage.cxx +++ b/Source/CTest/cmParseMumpsCoverage.cxx @@ -18,9 +18,7 @@ cmParseMumpsCoverage::cmParseMumpsCoverage( { } -cmParseMumpsCoverage::~cmParseMumpsCoverage() -{ -} +cmParseMumpsCoverage::~cmParseMumpsCoverage() = default; bool cmParseMumpsCoverage::ReadCoverageFile(const char* file) { diff --git a/Source/CTest/cmProcess.cxx b/Source/CTest/cmProcess.cxx index 7737f65..70ef8df 100644 --- a/Source/CTest/cmProcess.cxx +++ b/Source/CTest/cmProcess.cxx @@ -69,9 +69,7 @@ cmProcess::cmProcess(cmCTestRunTest& runner) this->StartTime = std::chrono::steady_clock::time_point(); } -cmProcess::~cmProcess() -{ -} +cmProcess::~cmProcess() = default; void cmProcess::SetCommand(const char* command) { diff --git a/Source/CursesDialog/ccmake.cxx b/Source/CursesDialog/ccmake.cxx index dbf4a28..f2982a6 100644 --- a/Source/CursesDialog/ccmake.cxx +++ b/Source/CursesDialog/ccmake.cxx @@ -65,13 +65,6 @@ void onsig(int /*unused*/) } } -void CMakeMessageHandler(const char* message, const char* title, - bool& /*unused*/, void* clientData) -{ - cmCursesForm* self = static_cast<cmCursesForm*>(clientData); - self->AddError(message, title); -} - int main(int argc, char const* const* argv) { cmsys::Encoding::CommandLineArguments encoding_args = @@ -156,7 +149,10 @@ int main(int argc, char const* const* argv) return 1; } - cmSystemTools::SetMessageCallback(CMakeMessageHandler, myform); + cmSystemTools::SetMessageCallback( + [myform](const char* message, const char* title) { + myform->AddError(message, title); + }); cmCursesForm::CurrentForm = myform; diff --git a/Source/CursesDialog/cmCursesLabelWidget.cxx b/Source/CursesDialog/cmCursesLabelWidget.cxx index 1dfd4ce..83aea5a 100644 --- a/Source/CursesDialog/cmCursesLabelWidget.cxx +++ b/Source/CursesDialog/cmCursesLabelWidget.cxx @@ -14,9 +14,7 @@ cmCursesLabelWidget::cmCursesLabelWidget(int width, int height, int left, this->SetValue(name); } -cmCursesLabelWidget::~cmCursesLabelWidget() -{ -} +cmCursesLabelWidget::~cmCursesLabelWidget() = default; bool cmCursesLabelWidget::HandleInput(int& /*key*/, cmCursesMainForm* /*fm*/, WINDOW* /*w*/) diff --git a/Source/CursesDialog/cmCursesMainForm.cxx b/Source/CursesDialog/cmCursesMainForm.cxx index 188ad69..8ca7802 100644 --- a/Source/CursesDialog/cmCursesMainForm.cxx +++ b/Source/CursesDialog/cmCursesMainForm.cxx @@ -506,12 +506,8 @@ void cmCursesMainForm::UpdateStatusBar(const char* message) pos_form_cursor(this->Form); } -void cmCursesMainForm::UpdateProgress(const char* msg, float prog, void* vp) +void cmCursesMainForm::UpdateProgress(const char* msg, float prog) { - cmCursesMainForm* cm = static_cast<cmCursesMainForm*>(vp); - if (!cm) { - return; - } char tmp[1024]; const char* cmsg = tmp; if (prog >= 0) { @@ -519,8 +515,8 @@ void cmCursesMainForm::UpdateProgress(const char* msg, float prog, void* vp) } else { cmsg = msg; } - cm->UpdateStatusBar(cmsg); - cm->PrintKeys(1); + this->UpdateStatusBar(cmsg); + this->PrintKeys(1); curses_move(1, 1); touchwin(stdscr); refresh(); @@ -536,8 +532,8 @@ int cmCursesMainForm::Configure(int noconfigure) this->PrintKeys(1); touchwin(stdscr); refresh(); - this->CMakeInstance->SetProgressCallback(cmCursesMainForm::UpdateProgress, - this); + this->CMakeInstance->SetProgressCallback( + [this](const char* msg, float prog) { this->UpdateProgress(msg, prog); }); // always save the current gui values to disk this->FillCacheManagerFromUI(); @@ -560,7 +556,7 @@ int cmCursesMainForm::Configure(int noconfigure) } else { retVal = this->CMakeInstance->Configure(); } - this->CMakeInstance->SetProgressCallback(nullptr, nullptr); + this->CMakeInstance->SetProgressCallback(nullptr); keypad(stdscr, true); /* Use key symbols as KEY_DOWN */ @@ -606,8 +602,8 @@ int cmCursesMainForm::Generate() this->PrintKeys(1); touchwin(stdscr); refresh(); - this->CMakeInstance->SetProgressCallback(cmCursesMainForm::UpdateProgress, - this); + this->CMakeInstance->SetProgressCallback( + [this](const char* msg, float prog) { this->UpdateProgress(msg, prog); }); // Get rid of previous errors this->Errors = std::vector<std::string>(); @@ -615,7 +611,7 @@ int cmCursesMainForm::Generate() // run the generate process int retVal = this->CMakeInstance->Generate(); - this->CMakeInstance->SetProgressCallback(nullptr, nullptr); + this->CMakeInstance->SetProgressCallback(nullptr); keypad(stdscr, true); /* Use key symbols as KEY_DOWN */ if (retVal != 0 || !this->Errors.empty()) { diff --git a/Source/CursesDialog/cmCursesMainForm.h b/Source/CursesDialog/cmCursesMainForm.h index 824025b..88864bc 100644 --- a/Source/CursesDialog/cmCursesMainForm.h +++ b/Source/CursesDialog/cmCursesMainForm.h @@ -101,8 +101,7 @@ public: /** * Progress callback */ - static void UpdateProgressOld(const char* msg, float prog, void*); - static void UpdateProgress(const char* msg, float prog, void*); + void UpdateProgress(const char* msg, float prog); protected: // Copy the cache values from the user interface to the actual diff --git a/Source/QtDialog/FirstConfigure.cxx b/Source/QtDialog/FirstConfigure.cxx index ae5179c..f28e1a8 100644 --- a/Source/QtDialog/FirstConfigure.cxx +++ b/Source/QtDialog/FirstConfigure.cxx @@ -86,9 +86,7 @@ QFrame* StartCompilerSetup::CreatePlatformWidgets() return frame; } -StartCompilerSetup::~StartCompilerSetup() -{ -} +StartCompilerSetup::~StartCompilerSetup() = default; void StartCompilerSetup::setGenerators( std::vector<cmake::GeneratorInfo> const& gens) @@ -237,9 +235,7 @@ NativeCompilerSetup::NativeCompilerSetup(QWidget* p) this->setupUi(c); } -NativeCompilerSetup::~NativeCompilerSetup() -{ -} +NativeCompilerSetup::~NativeCompilerSetup() = default; QString NativeCompilerSetup::getCCompiler() const { @@ -301,9 +297,7 @@ CrossCompilerSetup::CrossCompilerSetup(QWidget* p) this->registerField("systemName*", this->systemName); } -CrossCompilerSetup::~CrossCompilerSetup() -{ -} +CrossCompilerSetup::~CrossCompilerSetup() = default; QString CrossCompilerSetup::getCCompiler() const { @@ -414,9 +408,7 @@ ToolchainCompilerSetup::ToolchainCompilerSetup(QWidget* p) l->addWidget(this->ToolchainFile); } -ToolchainCompilerSetup::~ToolchainCompilerSetup() -{ -} +ToolchainCompilerSetup::~ToolchainCompilerSetup() = default; QString ToolchainCompilerSetup::toolchainFile() const { @@ -446,9 +438,7 @@ FirstConfigure::FirstConfigure() this->setPage(ToolchainSetup, this->mToolchainCompilerSetupPage); } -FirstConfigure::~FirstConfigure() -{ -} +FirstConfigure::~FirstConfigure() = default; void FirstConfigure::setGenerators( std::vector<cmake::GeneratorInfo> const& gens) diff --git a/Source/QtDialog/QCMake.cxx b/Source/QtDialog/QCMake.cxx index 2eecce6..065d610 100644 --- a/Source/QtDialog/QCMake.cxx +++ b/Source/QtDialog/QCMake.cxx @@ -23,16 +23,26 @@ QCMake::QCMake(QObject* p) cmSystemTools::DisableRunCommandOutput(); cmSystemTools::SetRunCommandHideConsole(true); - cmSystemTools::SetMessageCallback(QCMake::messageCallback, this); - cmSystemTools::SetStdoutCallback(QCMake::stdoutCallback, this); - cmSystemTools::SetStderrCallback(QCMake::stderrCallback, this); + + cmSystemTools::SetMessageCallback( + [this](const char* msg, const char* title) { + this->messageCallback(msg, title); + }); + cmSystemTools::SetStdoutCallback( + [this](const char* msg, size_t len) { this->stdoutCallback(msg, len); }); + cmSystemTools::SetStderrCallback( + [this](const char* msg, size_t len) { this->stderrCallback(msg, len); }); this->CMakeInstance = new cmake(cmake::RoleProject, cmState::Project); this->CMakeInstance->SetCMakeEditCommand( cmSystemTools::GetCMakeGUICommand()); - this->CMakeInstance->SetProgressCallback(QCMake::progressCallback, this); + this->CMakeInstance->SetProgressCallback( + [this](const char* msg, float percent) { + this->progressCallback(msg, percent); + }); - cmSystemTools::SetInterruptCallback(QCMake::interruptCallback, this); + cmSystemTools::SetInterruptCallback( + [this] { return this->interruptCallback(); }); std::vector<cmake::GeneratorInfo> generators; this->CMakeInstance->GetRegisteredGenerators( @@ -330,46 +340,40 @@ void QCMake::interrupt() this->InterruptFlag.ref(); } -bool QCMake::interruptCallback(void* cd) +bool QCMake::interruptCallback() { - QCMake* self = reinterpret_cast<QCMake*>(cd); #if QT_VERSION < QT_VERSION_CHECK(5, 0, 0) - return self->InterruptFlag; + return this->InterruptFlag; #else - return self->InterruptFlag.load(); + return this->InterruptFlag.load(); #endif } -void QCMake::progressCallback(const char* msg, float percent, void* cd) +void QCMake::progressCallback(const char* msg, float percent) { - QCMake* self = reinterpret_cast<QCMake*>(cd); if (percent >= 0) { - emit self->progressChanged(QString::fromLocal8Bit(msg), percent); + emit this->progressChanged(QString::fromLocal8Bit(msg), percent); } else { - emit self->outputMessage(QString::fromLocal8Bit(msg)); + emit this->outputMessage(QString::fromLocal8Bit(msg)); } QCoreApplication::processEvents(); } -void QCMake::messageCallback(const char* msg, const char* /*title*/, - bool& /*stop*/, void* cd) +void QCMake::messageCallback(const char* msg, const char* /*title*/) { - QCMake* self = reinterpret_cast<QCMake*>(cd); - emit self->errorMessage(QString::fromLocal8Bit(msg)); + emit this->errorMessage(QString::fromLocal8Bit(msg)); QCoreApplication::processEvents(); } -void QCMake::stdoutCallback(const char* msg, size_t len, void* cd) +void QCMake::stdoutCallback(const char* msg, size_t len) { - QCMake* self = reinterpret_cast<QCMake*>(cd); - emit self->outputMessage(QString::fromLocal8Bit(msg, int(len))); + emit this->outputMessage(QString::fromLocal8Bit(msg, int(len))); QCoreApplication::processEvents(); } -void QCMake::stderrCallback(const char* msg, size_t len, void* cd) +void QCMake::stderrCallback(const char* msg, size_t len) { - QCMake* self = reinterpret_cast<QCMake*>(cd); - emit self->outputMessage(QString::fromLocal8Bit(msg, int(len))); + emit this->outputMessage(QString::fromLocal8Bit(msg, int(len))); QCoreApplication::processEvents(); } diff --git a/Source/QtDialog/QCMake.h b/Source/QtDialog/QCMake.h index c84da58..4f22505 100644 --- a/Source/QtDialog/QCMake.h +++ b/Source/QtDialog/QCMake.h @@ -167,12 +167,12 @@ signals: protected: cmake* CMakeInstance; - static bool interruptCallback(void*); - static void progressCallback(const char* msg, float percent, void* cd); - static void messageCallback(const char* msg, const char* title, bool&, - void* cd); - static void stdoutCallback(const char* msg, size_t len, void* cd); - static void stderrCallback(const char* msg, size_t len, void* cd); + bool interruptCallback(); + void progressCallback(const char* msg, float percent); + void messageCallback(const char* msg, const char* title); + void stdoutCallback(const char* msg, size_t len); + void stderrCallback(const char* msg, size_t len); + bool WarnUninitializedMode; bool WarnUnusedMode; bool WarnUnusedAllMode; diff --git a/Source/QtDialog/QCMakeCacheView.cxx b/Source/QtDialog/QCMakeCacheView.cxx index 821c3f4..78a2710 100644 --- a/Source/QtDialog/QCMakeCacheView.cxx +++ b/Source/QtDialog/QCMakeCacheView.cxx @@ -186,9 +186,7 @@ QCMakeCacheModel::QCMakeCacheModel(QObject* p) this->setHorizontalHeaderLabels(labels); } -QCMakeCacheModel::~QCMakeCacheModel() -{ -} +QCMakeCacheModel::~QCMakeCacheModel() = default; static uint qHash(const QCMakeProperty& p) { diff --git a/Source/cmBase32.cxx b/Source/cmBase32.cxx index 1dac212..80ada47 100644 --- a/Source/cmBase32.cxx +++ b/Source/cmBase32.cxx @@ -34,13 +34,9 @@ void Base32Encode5(const unsigned char src[5], char dst[8]) // -- Class methods -cmBase32Encoder::cmBase32Encoder() -{ -} +cmBase32Encoder::cmBase32Encoder() = default; -cmBase32Encoder::~cmBase32Encoder() -{ -} +cmBase32Encoder::~cmBase32Encoder() = default; std::string cmBase32Encoder::encodeString(const unsigned char* input, size_t len, bool padding) diff --git a/Source/cmCPluginAPI.cxx b/Source/cmCPluginAPI.cxx index 811af56..c0088ac 100644 --- a/Source/cmCPluginAPI.cxx +++ b/Source/cmCPluginAPI.cxx @@ -474,7 +474,6 @@ int CCONV cmGetTotalArgumentSize(int argc, char** argv) // API for source files. struct cmCPluginAPISourceFile { - cmCPluginAPISourceFile() {} cmSourceFile* RealSourceFile = nullptr; std::string SourceName; std::string SourceExtension; diff --git a/Source/cmCTest.h b/Source/cmCTest.h index a82f400..92a02c3 100644 --- a/Source/cmCTest.h +++ b/Source/cmCTest.h @@ -57,8 +57,6 @@ public: /** Representation of one part. */ struct PartInfo { - PartInfo() {} - void SetName(const std::string& name) { this->Name = name; } const std::string& GetName() const { return this->Name; } diff --git a/Source/cmCacheManager.h b/Source/cmCacheManager.h index b39856e..0c70ed2 100644 --- a/Source/cmCacheManager.h +++ b/Source/cmCacheManager.h @@ -42,7 +42,6 @@ private: void AppendProperty(const std::string& property, const char* value, bool asString = false); bool Initialized = false; - CacheEntry() {} }; public: diff --git a/Source/cmCallVisualStudioMacro.cxx b/Source/cmCallVisualStudioMacro.cxx index ecfcfb9..ee5feee 100644 --- a/Source/cmCallVisualStudioMacro.cxx +++ b/Source/cmCallVisualStudioMacro.cxx @@ -46,7 +46,7 @@ static bool LogErrorsAsMessages; << std::endl; \ _hresult_oss.flags(std::ios::dec); \ _hresult_oss << __FILE__ << "(" << __LINE__ << ")"; \ - cmSystemTools::Message(_hresult_oss.str().c_str()); \ + cmSystemTools::Message(_hresult_oss.str()); \ } \ } @@ -446,7 +446,7 @@ int cmCallVisualStudioMacro::CallMacro(const std::string& slnFile, if (err && LogErrorsAsMessages) { std::ostringstream oss; oss << "cmCallVisualStudioMacro::CallMacro failed, err = " << err; - cmSystemTools::Message(oss.str().c_str()); + cmSystemTools::Message(oss.str()); } return 0; diff --git a/Source/cmCommand.h b/Source/cmCommand.h index dfc3e78..07333bb 100644 --- a/Source/cmCommand.h +++ b/Source/cmCommand.h @@ -30,12 +30,12 @@ public: /** * Construct the command. By default it has no makefile. */ - cmCommand() {} + cmCommand() = default; /** * Need virtual destructor to destroy real command type. */ - virtual ~cmCommand() {} + virtual ~cmCommand() = default; /** * Specify the makefile. diff --git a/Source/cmCommandArgumentsHelper.h b/Source/cmCommandArgumentsHelper.h index c68e64c..9579861 100644 --- a/Source/cmCommandArgumentsHelper.h +++ b/Source/cmCommandArgumentsHelper.h @@ -39,7 +39,7 @@ class cmCommandArgument public: cmCommandArgument(cmCommandArgumentsHelper* args, const char* key, cmCommandArgumentGroup* group = nullptr); - virtual ~cmCommandArgument() {} + virtual ~cmCommandArgument() = default; /// this argument may follow after arg. 0 means it comes first. void Follows(const cmCommandArgument* arg); @@ -172,8 +172,6 @@ class cmCommandArgumentGroup friend class cmCommandArgument; public: - cmCommandArgumentGroup() {} - /// All members of this group may follow the given argument void Follows(const cmCommandArgument* arg); diff --git a/Source/cmCommonTargetGenerator.cxx b/Source/cmCommonTargetGenerator.cxx index a1df271..66250f3 100644 --- a/Source/cmCommonTargetGenerator.cxx +++ b/Source/cmCommonTargetGenerator.cxx @@ -29,9 +29,7 @@ cmCommonTargetGenerator::cmCommonTargetGenerator(cmGeneratorTarget* gt) { } -cmCommonTargetGenerator::~cmCommonTargetGenerator() -{ -} +cmCommonTargetGenerator::~cmCommonTargetGenerator() = default; std::string const& cmCommonTargetGenerator::GetConfigName() const { @@ -198,7 +196,7 @@ std::string cmCommonTargetGenerator::GetManifests() manifests.reserve(manifest_srcs.size()); for (cmSourceFile const* manifest_src : manifest_srcs) { manifests.push_back(this->LocalCommonGenerator->ConvertToOutputFormat( - this->LocalCommonGenerator->ConvertToRelativePath( + this->LocalCommonGenerator->MaybeConvertToRelativePath( this->LocalCommonGenerator->GetWorkingDirectory(), manifest_src->GetFullPath()), cmOutputConverter::SHELL)); diff --git a/Source/cmComputeComponentGraph.cxx b/Source/cmComputeComponentGraph.cxx index 5820df6..113463f 100644 --- a/Source/cmComputeComponentGraph.cxx +++ b/Source/cmComputeComponentGraph.cxx @@ -18,9 +18,7 @@ cmComputeComponentGraph::cmComputeComponentGraph(Graph const& input) this->TransferEdges(); } -cmComputeComponentGraph::~cmComputeComponentGraph() -{ -} +cmComputeComponentGraph::~cmComputeComponentGraph() = default; void cmComputeComponentGraph::Tarjan() { diff --git a/Source/cmComputeLinkDepends.h b/Source/cmComputeLinkDepends.h index 32a2a62..252f874 100644 --- a/Source/cmComputeLinkDepends.h +++ b/Source/cmComputeLinkDepends.h @@ -38,14 +38,6 @@ public: cmGeneratorTarget const* Target = nullptr; bool IsSharedDep = false; bool IsFlag = false; - LinkEntry() {} - LinkEntry(LinkEntry const& r) - : Item(r.Item) - , Target(r.Target) - , IsSharedDep(r.IsSharedDep) - , IsFlag(r.IsFlag) - { - } }; typedef std::vector<LinkEntry> EntryVector; diff --git a/Source/cmComputeLinkInformation.cxx b/Source/cmComputeLinkInformation.cxx index c68bb21..3d61665 100644 --- a/Source/cmComputeLinkInformation.cxx +++ b/Source/cmComputeLinkInformation.cxx @@ -1282,7 +1282,7 @@ void cmComputeLinkInformation::DropDirectoryItem(std::string const& item) << "\" requests linking to directory \"" << item << "\". " << "Targets may link only to libraries. " << "CMake is dropping the item."; - cmSystemTools::Message(e.str().c_str()); + cmSystemTools::Message(e.str()); } void cmComputeLinkInformation::ComputeFrameworkInfo() diff --git a/Source/cmComputeLinkInformation.h b/Source/cmComputeLinkInformation.h index 61fcf03..863639c 100644 --- a/Source/cmComputeLinkInformation.h +++ b/Source/cmComputeLinkInformation.h @@ -31,7 +31,7 @@ public: struct Item { - Item() {} + Item() = default; Item(std::string v, bool p, cmGeneratorTarget const* target = nullptr) : Value(std::move(v)) , IsPath(p) diff --git a/Source/cmComputeTargetDepends.cxx b/Source/cmComputeTargetDepends.cxx index 1d20cff..9b7b02f 100644 --- a/Source/cmComputeTargetDepends.cxx +++ b/Source/cmComputeTargetDepends.cxx @@ -103,9 +103,7 @@ cmComputeTargetDepends::cmComputeTargetDepends(cmGlobalGenerator* gg) cm->GetState()->GetGlobalPropertyAsBool("GLOBAL_DEPENDS_NO_CYCLES"); } -cmComputeTargetDepends::~cmComputeTargetDepends() -{ -} +cmComputeTargetDepends::~cmComputeTargetDepends() = default; bool cmComputeTargetDepends::Compute() { diff --git a/Source/cmConnection.cxx b/Source/cmConnection.cxx index 50e1936..166426b 100644 --- a/Source/cmConnection.cxx +++ b/Source/cmConnection.cxx @@ -127,9 +127,7 @@ void cmEventBasedConnection::OnDisconnect(int onerror) } } -cmConnection::~cmConnection() -{ -} +cmConnection::~cmConnection() = default; bool cmConnection::OnConnectionShuttingDown() { diff --git a/Source/cmConnection.h b/Source/cmConnection.h index ce2d2dc..3a7f1b9 100644 --- a/Source/cmConnection.h +++ b/Source/cmConnection.h @@ -63,7 +63,7 @@ class cmConnection CM_DISABLE_COPY(cmConnection) public: - cmConnection() {} + cmConnection() = default; virtual void WriteData(const std::string& data) = 0; diff --git a/Source/cmDefinitions.h b/Source/cmDefinitions.h index b2794fa..6c252be 100644 --- a/Source/cmDefinitions.h +++ b/Source/cmDefinitions.h @@ -47,7 +47,7 @@ private: typedef std::string std_string; public: - Def() {} + Def() = default; Def(const char* v) : std_string(v ? v : "") , Exists(v ? true : false) diff --git a/Source/cmDepends.cxx b/Source/cmDepends.cxx index 976ba57..7d1d316 100644 --- a/Source/cmDepends.cxx +++ b/Source/cmDepends.cxx @@ -156,8 +156,8 @@ bool cmDepends::CheckDependencies( // * if the depender does not exist, but the dependee is newer than the // depends file bool regenerate = false; - const char* dependee = this->Dependee + 1; - const char* depender = this->Depender; + const std::string dependee(this->Dependee + 1); + const std::string depender(this->Depender); if (currentDependencies != nullptr) { currentDependencies->push_back(dependee); } @@ -195,8 +195,8 @@ bool cmDepends::CheckDependencies( // The dependee exists, but the depender doesn't. Regenerate if the // internalDepends file is older than the dependee. int result = 0; - if ((!this->FileComparison->FileTimeCompare( - internalDependsFileName.c_str(), dependee, &result) || + if ((!this->FileComparison->FileTimeCompare(internalDependsFileName, + dependee, &result) || result < 0)) { // The depends-file is older than the dependee. regenerate = true; diff --git a/Source/cmDependsC.cxx b/Source/cmDependsC.cxx index f6ac4f2..b1630f9 100644 --- a/Source/cmDependsC.cxx +++ b/Source/cmDependsC.cxx @@ -19,9 +19,7 @@ #define INCLUDE_REGEX_COMPLAIN_MARKER "#IncludeRegexComplain: " #define INCLUDE_REGEX_TRANSFORM_MARKER "#IncludeRegexTransform: " -cmDependsC::cmDependsC() -{ -} +cmDependsC::cmDependsC() = default; cmDependsC::cmDependsC( cmLocalGenerator* lg, const std::string& targetDir, const std::string& lang, @@ -100,7 +98,8 @@ bool cmDependsC::WriteDependencies(const std::set<std::string>& sources, // Compute a path to the object file to write to the internal depend file. // Any existing content of the internal depend file has already been // loaded in ValidDeps with this path as a key. - std::string obj_i = this->LocalGenerator->ConvertToRelativePath(binDir, obj); + std::string obj_i = + this->LocalGenerator->MaybeConvertToRelativePath(binDir, obj); if (this->ValidDeps != nullptr) { std::map<std::string, DependencyVector>::const_iterator tmpIt = @@ -234,7 +233,8 @@ bool cmDependsC::WriteDependencies(const std::set<std::string>& sources, for (std::string const& dep : dependencies) { makeDepends << obj_m << ": " << cmSystemTools::ConvertToOutputPath( - this->LocalGenerator->ConvertToRelativePath(binDir, dep)) + this->LocalGenerator->MaybeConvertToRelativePath(binDir, + dep)) << std::endl; internalDepends << " " << dep << std::endl; } @@ -268,8 +268,7 @@ void cmDependsC::ReadCacheFile() haveFileName = true; int newer = 0; cmFileTimeComparison comp; - bool res = comp.FileTimeCompare(this->CacheFileName.c_str(), - line.c_str(), &newer); + bool res = comp.FileTimeCompare(this->CacheFileName, line, &newer); if (res && newer == 1) // cache is newer than the parsed file { diff --git a/Source/cmDependsC.h b/Source/cmDependsC.h index af2b06e..411458a 100644 --- a/Source/cmDependsC.h +++ b/Source/cmDependsC.h @@ -75,7 +75,6 @@ public: struct cmIncludeLines { - cmIncludeLines() {} std::vector<UnscannedEntry> UnscannedEntries; bool Used = false; }; diff --git a/Source/cmDependsFortran.cxx b/Source/cmDependsFortran.cxx index 6c5f647..cae3ff6 100644 --- a/Source/cmDependsFortran.cxx +++ b/Source/cmDependsFortran.cxx @@ -68,9 +68,7 @@ public: } }; -cmDependsFortran::cmDependsFortran() -{ -} +cmDependsFortran::cmDependsFortran() = default; cmDependsFortran::cmDependsFortran(cmLocalGenerator* lg) : cmDepends(lg) diff --git a/Source/cmDependsJava.cxx b/Source/cmDependsJava.cxx index b44b3a2..2485e15 100644 --- a/Source/cmDependsJava.cxx +++ b/Source/cmDependsJava.cxx @@ -4,13 +4,9 @@ #include "cmSystemTools.h" -cmDependsJava::cmDependsJava() -{ -} +cmDependsJava::cmDependsJava() = default; -cmDependsJava::~cmDependsJava() -{ -} +cmDependsJava::~cmDependsJava() = default; bool cmDependsJava::WriteDependencies(const std::set<std::string>& sources, const std::string& /*obj*/, diff --git a/Source/cmDocumentation.h b/Source/cmDocumentation.h index b2ff01a..cf74b80 100644 --- a/Source/cmDocumentation.h +++ b/Source/cmDocumentation.h @@ -115,7 +115,6 @@ private: struct RequestedHelpItem { - RequestedHelpItem() {} cmDocumentationEnums::Type HelpType = None; std::string Filename; std::string Argument; diff --git a/Source/cmDocumentationEntry.h b/Source/cmDocumentationEntry.h index ca323cc..afbca5e 100644 --- a/Source/cmDocumentationEntry.h +++ b/Source/cmDocumentationEntry.h @@ -13,7 +13,7 @@ struct cmDocumentationEntry std::string Name; std::string Brief; char CustomNamePrefix = ' '; - cmDocumentationEntry() {} + cmDocumentationEntry() = default; cmDocumentationEntry(const char* doc[2]) { if (doc[0]) { diff --git a/Source/cmDocumentationFormatter.cxx b/Source/cmDocumentationFormatter.cxx index e573c04..3e7f989 100644 --- a/Source/cmDocumentationFormatter.cxx +++ b/Source/cmDocumentationFormatter.cxx @@ -11,13 +11,9 @@ #include <string> #include <vector> -cmDocumentationFormatter::cmDocumentationFormatter() -{ -} +cmDocumentationFormatter::cmDocumentationFormatter() = default; -cmDocumentationFormatter::~cmDocumentationFormatter() -{ -} +cmDocumentationFormatter::~cmDocumentationFormatter() = default; void cmDocumentationFormatter::PrintFormatted(std::ostream& os, const char* text) diff --git a/Source/cmDynamicLoader.cxx b/Source/cmDynamicLoader.cxx index 7da6ff5..0549cf9 100644 --- a/Source/cmDynamicLoader.cxx +++ b/Source/cmDynamicLoader.cxx @@ -24,9 +24,7 @@ private: cmDynamicLoaderCache* cmDynamicLoaderCache::Instance = nullptr; -cmDynamicLoaderCache::~cmDynamicLoaderCache() -{ -} +cmDynamicLoaderCache::~cmDynamicLoaderCache() = default; void cmDynamicLoaderCache::CacheFile(const char* path, cmsys::DynamicLoader::LibraryHandle p) diff --git a/Source/cmDynamicLoader.h b/Source/cmDynamicLoader.h index 61d3b46..e9fe97a 100644 --- a/Source/cmDynamicLoader.h +++ b/Source/cmDynamicLoader.h @@ -28,8 +28,8 @@ public: static void FlushCache(); protected: - cmDynamicLoader() {} - ~cmDynamicLoader() {} + cmDynamicLoader() = default; + ~cmDynamicLoader() = default; }; #endif diff --git a/Source/cmExecutionStatus.h b/Source/cmExecutionStatus.h index 1946231..56199dd 100644 --- a/Source/cmExecutionStatus.h +++ b/Source/cmExecutionStatus.h @@ -11,8 +11,6 @@ class cmExecutionStatus { public: - cmExecutionStatus() {} - void Clear() { this->ReturnInvoked = false; diff --git a/Source/cmExpandedCommandArgument.cxx b/Source/cmExpandedCommandArgument.cxx index 00848a6..43f648b 100644 --- a/Source/cmExpandedCommandArgument.cxx +++ b/Source/cmExpandedCommandArgument.cxx @@ -4,9 +4,7 @@ #include <utility> -cmExpandedCommandArgument::cmExpandedCommandArgument() -{ -} +cmExpandedCommandArgument::cmExpandedCommandArgument() = default; cmExpandedCommandArgument::cmExpandedCommandArgument(std::string value, bool quoted) diff --git a/Source/cmExportFileGenerator.h b/Source/cmExportFileGenerator.h index 41c6538..747503e 100644 --- a/Source/cmExportFileGenerator.h +++ b/Source/cmExportFileGenerator.h @@ -42,7 +42,7 @@ class cmExportFileGenerator { public: cmExportFileGenerator(); - virtual ~cmExportFileGenerator() {} + virtual ~cmExportFileGenerator() = default; /** Set the full path to the export file to generate. */ void SetExportFile(const char* mainFile); diff --git a/Source/cmExprParserHelper.cxx b/Source/cmExprParserHelper.cxx index 8d3dad7..80c78a3 100644 --- a/Source/cmExprParserHelper.cxx +++ b/Source/cmExprParserHelper.cxx @@ -18,9 +18,7 @@ cmExprParserHelper::cmExprParserHelper() this->Result = 0; } -cmExprParserHelper::~cmExprParserHelper() -{ -} +cmExprParserHelper::~cmExprParserHelper() = default; int cmExprParserHelper::ParseString(const char* str, int verb) { diff --git a/Source/cmExternalMakefileProjectGenerator.cxx b/Source/cmExternalMakefileProjectGenerator.cxx index 150995f..ac54811 100644 --- a/Source/cmExternalMakefileProjectGenerator.cxx +++ b/Source/cmExternalMakefileProjectGenerator.cxx @@ -41,9 +41,7 @@ cmExternalMakefileProjectGeneratorFactory:: } cmExternalMakefileProjectGeneratorFactory:: - ~cmExternalMakefileProjectGeneratorFactory() -{ -} + ~cmExternalMakefileProjectGeneratorFactory() = default; std::string cmExternalMakefileProjectGeneratorFactory::GetName() const { diff --git a/Source/cmExternalMakefileProjectGenerator.h b/Source/cmExternalMakefileProjectGenerator.h index 492987d..4438f28 100644 --- a/Source/cmExternalMakefileProjectGenerator.h +++ b/Source/cmExternalMakefileProjectGenerator.h @@ -26,7 +26,7 @@ class cmMakefile; class cmExternalMakefileProjectGenerator { public: - virtual ~cmExternalMakefileProjectGenerator() {} + virtual ~cmExternalMakefileProjectGenerator() = default; virtual void EnableLanguage(std::vector<std::string> const& languages, cmMakefile*, bool optional); diff --git a/Source/cmExtraCodeBlocksGenerator.cxx b/Source/cmExtraCodeBlocksGenerator.cxx index d70352f..397508c 100644 --- a/Source/cmExtraCodeBlocksGenerator.cxx +++ b/Source/cmExtraCodeBlocksGenerator.cxx @@ -32,9 +32,7 @@ Discussion: http://forums.codeblocks.org/index.php/topic,6789.0.html */ -cmExtraCodeBlocksGenerator::cmExtraCodeBlocksGenerator() -{ -} +cmExtraCodeBlocksGenerator::cmExtraCodeBlocksGenerator() = default; cmExternalMakefileProjectGeneratorFactory* cmExtraCodeBlocksGenerator::GetFactory() diff --git a/Source/cmExtraEclipseCDT4Generator.cxx b/Source/cmExtraEclipseCDT4Generator.cxx index 5833631..30067b7 100644 --- a/Source/cmExtraEclipseCDT4Generator.cxx +++ b/Source/cmExtraEclipseCDT4Generator.cxx @@ -899,7 +899,7 @@ void cmExtraEclipseCDT4Generator::CreateCProjectFile() const for (cmLocalGenerator* lgen : this->GlobalGenerator->GetLocalGenerators()) { const std::vector<cmGeneratorTarget*>& targets = lgen->GetGeneratorTargets(); - std::string subdir = lgen->ConvertToRelativePath( + std::string subdir = lgen->MaybeConvertToRelativePath( this->HomeOutputDirectory, lgen->GetCurrentBinaryDirectory()); if (subdir == ".") { subdir.clear(); diff --git a/Source/cmExtraKateGenerator.cxx b/Source/cmExtraKateGenerator.cxx index a9ed7fe..e28a865 100644 --- a/Source/cmExtraKateGenerator.cxx +++ b/Source/cmExtraKateGenerator.cxx @@ -16,9 +16,7 @@ #include <string.h> #include <vector> -cmExtraKateGenerator::cmExtraKateGenerator() -{ -} +cmExtraKateGenerator::cmExtraKateGenerator() = default; cmExternalMakefileProjectGeneratorFactory* cmExtraKateGenerator::GetFactory() { diff --git a/Source/cmFLTKWrapUICommand.cxx b/Source/cmFLTKWrapUICommand.cxx index effb446..4b14d26 100644 --- a/Source/cmFLTKWrapUICommand.cxx +++ b/Source/cmFLTKWrapUICommand.cxx @@ -117,7 +117,7 @@ void cmFLTKWrapUICommand::FinalPass() msg += ". The problem was found while processing the source directory: "; msg += this->Makefile->GetCurrentSourceDirectory(); msg += ". This FLTK_WRAP_UI call will be ignored."; - cmSystemTools::Message(msg.c_str(), "Warning"); + cmSystemTools::Message(msg, "Warning"); return; } } diff --git a/Source/cmFileCommand.cxx b/Source/cmFileCommand.cxx index afb0b2a..0f911c1 100644 --- a/Source/cmFileCommand.cxx +++ b/Source/cmFileCommand.cxx @@ -1079,7 +1079,7 @@ struct cmFileCopier , Doing(DoingNone) { } - virtual ~cmFileCopier() {} + virtual ~cmFileCopier() = default; bool Run(std::vector<std::string> const& args); @@ -1102,7 +1102,6 @@ protected: { bool Exclude = false; mode_t Permissions = 0; - MatchProperties() {} }; struct MatchRule { @@ -3759,8 +3758,7 @@ bool cmFileCommand::HandleCreateLinkCommand( // Check if copy-on-error is enabled in the arguments. if (!completed && copyOnErrorArg.IsEnabled()) { - completed = - cmSystemTools::cmCopyFile(fileName.c_str(), newFileName.c_str()); + completed = cmSystemTools::cmCopyFile(fileName, newFileName); if (!completed) { result = "Copy failed: " + cmSystemTools::GetLastSystemError(); } diff --git a/Source/cmFileLockPool.cxx b/Source/cmFileLockPool.cxx index 5dc9243..d700a79 100644 --- a/Source/cmFileLockPool.cxx +++ b/Source/cmFileLockPool.cxx @@ -8,9 +8,7 @@ #include "cmFileLock.h" #include "cmFileLockResult.h" -cmFileLockPool::cmFileLockPool() -{ -} +cmFileLockPool::cmFileLockPool() = default; cmFileLockPool::~cmFileLockPool() { @@ -111,9 +109,7 @@ bool cmFileLockPool::IsAlreadyLocked(const std::string& filename) const return this->ProcessScope.IsAlreadyLocked(filename); } -cmFileLockPool::ScopePool::ScopePool() -{ -} +cmFileLockPool::ScopePool::ScopePool() = default; cmFileLockPool::ScopePool::~ScopePool() { diff --git a/Source/cmFileLockUnix.cxx b/Source/cmFileLockUnix.cxx index 9b653e8..1bf5013 100644 --- a/Source/cmFileLockUnix.cxx +++ b/Source/cmFileLockUnix.cxx @@ -8,9 +8,7 @@ #include <stdio.h> // SEEK_SET #include <unistd.h> -cmFileLock::cmFileLock() -{ -} +cmFileLock::cmFileLock() = default; cmFileLockResult cmFileLock::Release() { diff --git a/Source/cmFileMonitor.cxx b/Source/cmFileMonitor.cxx index b36ac78..56ee739 100644 --- a/Source/cmFileMonitor.cxx +++ b/Source/cmFileMonitor.cxx @@ -19,7 +19,6 @@ void on_fs_close(uv_handle_t* handle); class cmIBaseWatcher { public: - cmIBaseWatcher() = default; virtual ~cmIBaseWatcher() = default; virtual void Trigger(const std::string& pathSegment, int events, @@ -150,11 +149,6 @@ public: p->AddChildWatcher(ps, this); } - ~cmRealDirectoryWatcher() override - { - // Handle is freed via uv_handle_close callback! - } - void StartWatching() final { if (!this->Handle) { diff --git a/Source/cmFilePathChecksum.cxx b/Source/cmFilePathChecksum.cxx index f84360e..2cffa7c 100644 --- a/Source/cmFilePathChecksum.cxx +++ b/Source/cmFilePathChecksum.cxx @@ -9,9 +9,7 @@ #include <vector> -cmFilePathChecksum::cmFilePathChecksum() -{ -} +cmFilePathChecksum::cmFilePathChecksum() = default; cmFilePathChecksum::cmFilePathChecksum(std::string const& currentSrcDir, std::string const& currentBinDir, diff --git a/Source/cmFileTimeComparison.cxx b/Source/cmFileTimeComparison.cxx index 8f6993d..8b3911e 100644 --- a/Source/cmFileTimeComparison.cxx +++ b/Source/cmFileTimeComparison.cxx @@ -21,9 +21,10 @@ class cmFileTimeComparisonInternal { public: // Internal comparison method. - inline bool FileTimeCompare(const char* f1, const char* f2, int* result); + inline bool FileTimeCompare(const std::string& f1, const std::string& f2, + int* result); - bool FileTimesDiffer(const char* f1, const char* f2); + bool FileTimesDiffer(const std::string& f1, const std::string& f2); private: typedef std::unordered_map<std::string, cmFileTimeComparison_Type> @@ -31,14 +32,14 @@ private: FileStatsMap Files; // Internal methods to lookup and compare modification times. - inline bool Stat(const char* fname, cmFileTimeComparison_Type* st); + inline bool Stat(const std::string& fname, cmFileTimeComparison_Type* st); inline int Compare(cmFileTimeComparison_Type* st1, cmFileTimeComparison_Type* st2); inline bool TimesDiffer(cmFileTimeComparison_Type* st1, cmFileTimeComparison_Type* st2); }; -bool cmFileTimeComparisonInternal::Stat(const char* fname, +bool cmFileTimeComparisonInternal::Stat(const std::string& fname, cmFileTimeComparison_Type* st) { // Use the stored time if available. @@ -51,7 +52,7 @@ bool cmFileTimeComparisonInternal::Stat(const char* fname, #if !defined(_WIN32) || defined(__CYGWIN__) // POSIX version. Use the stat function. - int res = ::stat(fname, st); + int res = ::stat(fname.c_str(), st); if (res != 0) { return false; } @@ -83,13 +84,14 @@ cmFileTimeComparison::~cmFileTimeComparison() delete this->Internals; } -bool cmFileTimeComparison::FileTimeCompare(const char* f1, const char* f2, - int* result) +bool cmFileTimeComparison::FileTimeCompare(const std::string& f1, + const std::string& f2, int* result) { return this->Internals->FileTimeCompare(f1, f2, result); } -bool cmFileTimeComparison::FileTimesDiffer(const char* f1, const char* f2) +bool cmFileTimeComparison::FileTimesDiffer(const std::string& f1, + const std::string& f2) { return this->Internals->FileTimesDiffer(f1, f2); } @@ -199,8 +201,9 @@ bool cmFileTimeComparisonInternal::TimesDiffer(cmFileTimeComparison_Type* s1, #endif } -bool cmFileTimeComparisonInternal::FileTimeCompare(const char* f1, - const char* f2, int* result) +bool cmFileTimeComparisonInternal::FileTimeCompare(const std::string& f1, + const std::string& f2, + int* result) { // Get the modification time for each file. cmFileTimeComparison_Type s1; @@ -215,8 +218,8 @@ bool cmFileTimeComparisonInternal::FileTimeCompare(const char* f1, return false; } -bool cmFileTimeComparisonInternal::FileTimesDiffer(const char* f1, - const char* f2) +bool cmFileTimeComparisonInternal::FileTimesDiffer(const std::string& f1, + const std::string& f2) { // Get the modification time for each file. cmFileTimeComparison_Type s1; diff --git a/Source/cmFileTimeComparison.h b/Source/cmFileTimeComparison.h index 114989b..5f74e34 100644 --- a/Source/cmFileTimeComparison.h +++ b/Source/cmFileTimeComparison.h @@ -5,6 +5,8 @@ #include "cmConfigure.h" // IWYU pragma: keep +#include <string> + class cmFileTimeComparisonInternal; /** \class cmFileTimeComparison @@ -24,13 +26,14 @@ public: * When true is returned, result has -1, 0, +1 for * f1 older, same, or newer than f2. */ - bool FileTimeCompare(const char* f1, const char* f2, int* result); + bool FileTimeCompare(const std::string& f1, const std::string& f2, + int* result); /** * Compare file modification times. Return true unless both files * exist and have modification times less than 1 second apart. */ - bool FileTimesDiffer(const char* f1, const char* f2); + bool FileTimesDiffer(const std::string& f1, const std::string& f2); protected: cmFileTimeComparisonInternal* Internals; diff --git a/Source/cmFindCommon.cxx b/Source/cmFindCommon.cxx index 39051b9..78be64e 100644 --- a/Source/cmFindCommon.cxx +++ b/Source/cmFindCommon.cxx @@ -48,9 +48,7 @@ cmFindCommon::cmFindCommon() this->InitializeSearchPathGroups(); } -cmFindCommon::~cmFindCommon() -{ -} +cmFindCommon::~cmFindCommon() = default; void cmFindCommon::InitializeSearchPathGroups() { diff --git a/Source/cmFindLibraryCommand.cxx b/Source/cmFindLibraryCommand.cxx index bcf876d..73d602d 100644 --- a/Source/cmFindLibraryCommand.cxx +++ b/Source/cmFindLibraryCommand.cxx @@ -202,7 +202,6 @@ struct cmFindLibraryHelper bool TryRaw = false; std::string Raw; cmsys::RegularExpression Regex; - Name() {} }; std::vector<Name> Names; diff --git a/Source/cmFindPackageCommand.cxx b/Source/cmFindPackageCommand.cxx index bec2af9..f9ac310 100644 --- a/Source/cmFindPackageCommand.cxx +++ b/Source/cmFindPackageCommand.cxx @@ -1671,7 +1671,7 @@ void cmFindPackageCommand::StoreVersionFound() class cmFileListGeneratorBase { public: - virtual ~cmFileListGeneratorBase() {} + virtual ~cmFileListGeneratorBase() = default; protected: bool Consider(std::string const& fullPath, cmFileList& listing); @@ -1688,8 +1688,7 @@ private: class cmFileList { public: - cmFileList() {} - virtual ~cmFileList() {} + virtual ~cmFileList() = default; cmFileList& operator/(cmFileListGeneratorBase const& rhs) { if (this->Last) { diff --git a/Source/cmFunctionBlocker.h b/Source/cmFunctionBlocker.h index b3450b3..cd6b05d 100644 --- a/Source/cmFunctionBlocker.h +++ b/Source/cmFunctionBlocker.h @@ -26,7 +26,7 @@ public: return false; } - virtual ~cmFunctionBlocker() {} + virtual ~cmFunctionBlocker() = default; /** Set/Get the context in which this blocker is created. */ void SetStartingContext(cmListFileContext const& lfc) diff --git a/Source/cmFunctionCommand.cxx b/Source/cmFunctionCommand.cxx index 67c9e9a..264a338 100644 --- a/Source/cmFunctionCommand.cxx +++ b/Source/cmFunctionCommand.cxx @@ -14,11 +14,6 @@ class cmFunctionHelperCommand : public cmCommand { public: - cmFunctionHelperCommand() {} - - ///! clean up any memory allocated by the function - ~cmFunctionHelperCommand() override {} - /** * This is a virtual constructor for the command. */ diff --git a/Source/cmFunctionCommand.h b/Source/cmFunctionCommand.h index 3352b92..8b37df0 100644 --- a/Source/cmFunctionCommand.h +++ b/Source/cmFunctionCommand.h @@ -18,15 +18,13 @@ class cmMakefile; class cmFunctionFunctionBlocker : public cmFunctionBlocker { public: - cmFunctionFunctionBlocker() { this->Depth = 0; } - ~cmFunctionFunctionBlocker() override {} bool IsFunctionBlocked(const cmListFileFunction&, cmMakefile& mf, cmExecutionStatus&) override; bool ShouldRemove(const cmListFileFunction&, cmMakefile& mf) override; std::vector<std::string> Args; std::vector<cmListFileFunction> Functions; - int Depth; + int Depth = 0; }; /// Starts function() ... endfunction() block diff --git a/Source/cmGeneratedFileStream.cxx b/Source/cmGeneratedFileStream.cxx index eef5dc0..4fe1587 100644 --- a/Source/cmGeneratedFileStream.cxx +++ b/Source/cmGeneratedFileStream.cxx @@ -102,9 +102,7 @@ void cmGeneratedFileStream::SetCompressionExtraExtension(bool ext) this->CompressExtraExtension = ext; } -cmGeneratedFileStreamBase::cmGeneratedFileStreamBase() -{ -} +cmGeneratedFileStreamBase::cmGeneratedFileStreamBase() = default; cmGeneratedFileStreamBase::cmGeneratedFileStreamBase(std::string const& name) { diff --git a/Source/cmGeneratorExpression.cxx b/Source/cmGeneratorExpression.cxx index f3f9771..175a26d 100644 --- a/Source/cmGeneratorExpression.cxx +++ b/Source/cmGeneratorExpression.cxx @@ -33,9 +33,7 @@ std::unique_ptr<cmCompiledGeneratorExpression> cmGeneratorExpression::Parse( return this->Parse(std::string(input ? input : "")); } -cmGeneratorExpression::~cmGeneratorExpression() -{ -} +cmGeneratorExpression::~cmGeneratorExpression() = default; const std::string& cmCompiledGeneratorExpression::Evaluate( cmLocalGenerator* lg, const std::string& config, bool quiet, diff --git a/Source/cmGeneratorExpressionEvaluator.h b/Source/cmGeneratorExpressionEvaluator.h index 0561799..0f553f2 100644 --- a/Source/cmGeneratorExpressionEvaluator.h +++ b/Source/cmGeneratorExpressionEvaluator.h @@ -16,8 +16,8 @@ struct cmGeneratorExpressionNode; struct cmGeneratorExpressionEvaluator { - cmGeneratorExpressionEvaluator() {} - virtual ~cmGeneratorExpressionEvaluator() {} + cmGeneratorExpressionEvaluator() = default; + virtual ~cmGeneratorExpressionEvaluator() = default; enum Type { diff --git a/Source/cmGeneratorExpressionLexer.cxx b/Source/cmGeneratorExpressionLexer.cxx index dd1e243..a7f090a 100644 --- a/Source/cmGeneratorExpressionLexer.cxx +++ b/Source/cmGeneratorExpressionLexer.cxx @@ -2,9 +2,7 @@ file Copyright.txt or https://cmake.org/licensing for details. */ #include "cmGeneratorExpressionLexer.h" -cmGeneratorExpressionLexer::cmGeneratorExpressionLexer() -{ -} +cmGeneratorExpressionLexer::cmGeneratorExpressionLexer() = default; static void InsertText(const char* upto, const char* c, std::vector<cmGeneratorExpressionToken>& result) diff --git a/Source/cmGeneratorExpressionNode.cxx b/Source/cmGeneratorExpressionNode.cxx index 6a3f73d..eb66ed5 100644 --- a/Source/cmGeneratorExpressionNode.cxx +++ b/Source/cmGeneratorExpressionNode.cxx @@ -56,7 +56,7 @@ std::string cmGeneratorExpressionNode::EvaluateDependentExpression( static const struct ZeroNode : public cmGeneratorExpressionNode { - ZeroNode() {} + ZeroNode() {} // NOLINT(modernize-use-equals-default) bool GeneratesContent() const override { return false; } @@ -74,7 +74,7 @@ static const struct ZeroNode : public cmGeneratorExpressionNode static const struct OneNode : public cmGeneratorExpressionNode { - OneNode() {} + OneNode() {} // NOLINT(modernize-use-equals-default) bool AcceptsArbitraryContentParameter() const override { return true; } @@ -127,7 +127,7 @@ BOOLEAN_OP_NODE(orNode, OR, 0, 1) static const struct NotNode : public cmGeneratorExpressionNode { - NotNode() {} + NotNode() {} // NOLINT(modernize-use-equals-default) std::string Evaluate( const std::vector<std::string>& parameters, @@ -147,7 +147,7 @@ static const struct NotNode : public cmGeneratorExpressionNode static const struct BoolNode : public cmGeneratorExpressionNode { - BoolNode() {} + BoolNode() {} // NOLINT(modernize-use-equals-default) int NumExpectedParameters() const override { return 1; } @@ -163,7 +163,7 @@ static const struct BoolNode : public cmGeneratorExpressionNode static const struct IfNode : public cmGeneratorExpressionNode { - IfNode() {} + IfNode() {} // NOLINT(modernize-use-equals-default) int NumExpectedParameters() const override { return 3; } @@ -184,7 +184,7 @@ static const struct IfNode : public cmGeneratorExpressionNode static const struct StrEqualNode : public cmGeneratorExpressionNode { - StrEqualNode() {} + StrEqualNode() {} // NOLINT(modernize-use-equals-default) int NumExpectedParameters() const override { return 2; } @@ -200,7 +200,7 @@ static const struct StrEqualNode : public cmGeneratorExpressionNode static const struct EqualNode : public cmGeneratorExpressionNode { - EqualNode() {} + EqualNode() {} // NOLINT(modernize-use-equals-default) int NumExpectedParameters() const override { return 2; } @@ -278,7 +278,7 @@ static const struct EqualNode : public cmGeneratorExpressionNode static const struct InListNode : public cmGeneratorExpressionNode { - InListNode() {} + InListNode() {} // NOLINT(modernize-use-equals-default) int NumExpectedParameters() const override { return 2; } @@ -328,7 +328,7 @@ static const struct InListNode : public cmGeneratorExpressionNode static const struct TargetExistsNode : public cmGeneratorExpressionNode { - TargetExistsNode() {} + TargetExistsNode() {} // NOLINT(modernize-use-equals-default) int NumExpectedParameters() const override { return 1; } @@ -359,7 +359,7 @@ static const struct TargetExistsNode : public cmGeneratorExpressionNode static const struct TargetNameIfExistsNode : public cmGeneratorExpressionNode { - TargetNameIfExistsNode() {} + TargetNameIfExistsNode() {} // NOLINT(modernize-use-equals-default) int NumExpectedParameters() const override { return 1; } @@ -393,7 +393,7 @@ static const struct TargetNameIfExistsNode : public cmGeneratorExpressionNode struct GenexEvaluator : public cmGeneratorExpressionNode { - GenexEvaluator() {} + GenexEvaluator() {} // NOLINT(modernize-use-equals-default) protected: std::string EvaluateExpression( @@ -430,7 +430,7 @@ protected: static const struct TargetGenexEvalNode : public GenexEvaluator { - TargetGenexEvalNode() {} + TargetGenexEvalNode() {} // NOLINT(modernize-use-equals-default) int NumExpectedParameters() const override { return 2; } @@ -476,7 +476,7 @@ static const struct TargetGenexEvalNode : public GenexEvaluator static const struct GenexEvalNode : public GenexEvaluator { - GenexEvalNode() {} + GenexEvalNode() {} // NOLINT(modernize-use-equals-default) int NumExpectedParameters() const override { return 1; } @@ -500,7 +500,7 @@ static const struct GenexEvalNode : public GenexEvaluator static const struct LowerCaseNode : public cmGeneratorExpressionNode { - LowerCaseNode() {} + LowerCaseNode() {} // NOLINT(modernize-use-equals-default) bool AcceptsArbitraryContentParameter() const override { return true; } @@ -516,7 +516,7 @@ static const struct LowerCaseNode : public cmGeneratorExpressionNode static const struct UpperCaseNode : public cmGeneratorExpressionNode { - UpperCaseNode() {} + UpperCaseNode() {} // NOLINT(modernize-use-equals-default) bool AcceptsArbitraryContentParameter() const override { return true; } @@ -532,7 +532,7 @@ static const struct UpperCaseNode : public cmGeneratorExpressionNode static const struct MakeCIdentifierNode : public cmGeneratorExpressionNode { - MakeCIdentifierNode() {} + MakeCIdentifierNode() {} // NOLINT(modernize-use-equals-default) bool AcceptsArbitraryContentParameter() const override { return true; } @@ -548,7 +548,7 @@ static const struct MakeCIdentifierNode : public cmGeneratorExpressionNode static const struct Angle_RNode : public cmGeneratorExpressionNode { - Angle_RNode() {} + Angle_RNode() {} // NOLINT(modernize-use-equals-default) int NumExpectedParameters() const override { return 0; } @@ -564,7 +564,7 @@ static const struct Angle_RNode : public cmGeneratorExpressionNode static const struct CommaNode : public cmGeneratorExpressionNode { - CommaNode() {} + CommaNode() {} // NOLINT(modernize-use-equals-default) int NumExpectedParameters() const override { return 0; } @@ -580,7 +580,7 @@ static const struct CommaNode : public cmGeneratorExpressionNode static const struct SemicolonNode : public cmGeneratorExpressionNode { - SemicolonNode() {} + SemicolonNode() {} // NOLINT(modernize-use-equals-default) int NumExpectedParameters() const override { return 0; } @@ -596,7 +596,7 @@ static const struct SemicolonNode : public cmGeneratorExpressionNode struct CompilerIdNode : public cmGeneratorExpressionNode { - CompilerIdNode() {} + CompilerIdNode() {} // NOLINT(modernize-use-equals-default) int NumExpectedParameters() const override { return OneOrZeroParameters; } @@ -650,7 +650,7 @@ struct CompilerIdNode : public cmGeneratorExpressionNode static const struct CCompilerIdNode : public CompilerIdNode { - CCompilerIdNode() {} + CCompilerIdNode() {} // NOLINT(modernize-use-equals-default) std::string Evaluate( const std::vector<std::string>& parameters, @@ -672,7 +672,7 @@ static const struct CCompilerIdNode : public CompilerIdNode static const struct CXXCompilerIdNode : public CompilerIdNode { - CXXCompilerIdNode() {} + CXXCompilerIdNode() {} // NOLINT(modernize-use-equals-default) std::string Evaluate( const std::vector<std::string>& parameters, @@ -694,7 +694,7 @@ static const struct CXXCompilerIdNode : public CompilerIdNode static const struct FortranCompilerIdNode : public CompilerIdNode { - FortranCompilerIdNode() {} + FortranCompilerIdNode() {} // NOLINT(modernize-use-equals-default) std::string Evaluate( const std::vector<std::string>& parameters, @@ -716,7 +716,7 @@ static const struct FortranCompilerIdNode : public CompilerIdNode struct CompilerVersionNode : public cmGeneratorExpressionNode { - CompilerVersionNode() {} + CompilerVersionNode() {} // NOLINT(modernize-use-equals-default) int NumExpectedParameters() const override { return OneOrZeroParameters; } @@ -753,7 +753,7 @@ struct CompilerVersionNode : public cmGeneratorExpressionNode static const struct CCompilerVersionNode : public CompilerVersionNode { - CCompilerVersionNode() {} + CCompilerVersionNode() {} // NOLINT(modernize-use-equals-default) std::string Evaluate( const std::vector<std::string>& parameters, @@ -775,7 +775,7 @@ static const struct CCompilerVersionNode : public CompilerVersionNode static const struct CxxCompilerVersionNode : public CompilerVersionNode { - CxxCompilerVersionNode() {} + CxxCompilerVersionNode() {} // NOLINT(modernize-use-equals-default) std::string Evaluate( const std::vector<std::string>& parameters, @@ -797,7 +797,7 @@ static const struct CxxCompilerVersionNode : public CompilerVersionNode static const struct FortranCompilerVersionNode : public CompilerVersionNode { - FortranCompilerVersionNode() {} + FortranCompilerVersionNode() {} // NOLINT(modernize-use-equals-default) std::string Evaluate( const std::vector<std::string>& parameters, @@ -819,7 +819,7 @@ static const struct FortranCompilerVersionNode : public CompilerVersionNode struct PlatformIdNode : public cmGeneratorExpressionNode { - PlatformIdNode() {} + PlatformIdNode() {} // NOLINT(modernize-use-equals-default) int NumExpectedParameters() const override { return OneOrZeroParameters; } @@ -848,7 +848,7 @@ struct PlatformIdNode : public cmGeneratorExpressionNode static const struct VersionGreaterNode : public cmGeneratorExpressionNode { - VersionGreaterNode() {} + VersionGreaterNode() {} // NOLINT(modernize-use-equals-default) int NumExpectedParameters() const override { return 2; } @@ -868,7 +868,7 @@ static const struct VersionGreaterNode : public cmGeneratorExpressionNode static const struct VersionGreaterEqNode : public cmGeneratorExpressionNode { - VersionGreaterEqNode() {} + VersionGreaterEqNode() {} // NOLINT(modernize-use-equals-default) int NumExpectedParameters() const override { return 2; } @@ -888,7 +888,7 @@ static const struct VersionGreaterEqNode : public cmGeneratorExpressionNode static const struct VersionLessNode : public cmGeneratorExpressionNode { - VersionLessNode() {} + VersionLessNode() {} // NOLINT(modernize-use-equals-default) int NumExpectedParameters() const override { return 2; } @@ -908,7 +908,7 @@ static const struct VersionLessNode : public cmGeneratorExpressionNode static const struct VersionLessEqNode : public cmGeneratorExpressionNode { - VersionLessEqNode() {} + VersionLessEqNode() {} // NOLINT(modernize-use-equals-default) int NumExpectedParameters() const override { return 2; } @@ -928,7 +928,7 @@ static const struct VersionLessEqNode : public cmGeneratorExpressionNode static const struct VersionEqualNode : public cmGeneratorExpressionNode { - VersionEqualNode() {} + VersionEqualNode() {} // NOLINT(modernize-use-equals-default) int NumExpectedParameters() const override { return 2; } @@ -948,7 +948,7 @@ static const struct VersionEqualNode : public cmGeneratorExpressionNode static const struct LinkOnlyNode : public cmGeneratorExpressionNode { - LinkOnlyNode() {} + LinkOnlyNode() {} // NOLINT(modernize-use-equals-default) std::string Evaluate( const std::vector<std::string>& parameters, @@ -970,7 +970,7 @@ static const struct LinkOnlyNode : public cmGeneratorExpressionNode static const struct ConfigurationNode : public cmGeneratorExpressionNode { - ConfigurationNode() {} + ConfigurationNode() {} // NOLINT(modernize-use-equals-default) int NumExpectedParameters() const override { return 0; } @@ -987,7 +987,7 @@ static const struct ConfigurationNode : public cmGeneratorExpressionNode static const struct ConfigurationTestNode : public cmGeneratorExpressionNode { - ConfigurationTestNode() {} + ConfigurationTestNode() {} // NOLINT(modernize-use-equals-default) int NumExpectedParameters() const override { return OneOrZeroParameters; } @@ -1046,7 +1046,7 @@ static const struct ConfigurationTestNode : public cmGeneratorExpressionNode static const struct JoinNode : public cmGeneratorExpressionNode { - JoinNode() {} + JoinNode() {} // NOLINT(modernize-use-equals-default) int NumExpectedParameters() const override { return 2; } @@ -1066,7 +1066,7 @@ static const struct JoinNode : public cmGeneratorExpressionNode static const struct CompileLanguageNode : public cmGeneratorExpressionNode { - CompileLanguageNode() {} + CompileLanguageNode() {} // NOLINT(modernize-use-equals-default) int NumExpectedParameters() const override { return OneOrZeroParameters; } @@ -1146,7 +1146,7 @@ std::string getLinkedTargetsContent( static const struct TargetPropertyNode : public cmGeneratorExpressionNode { - TargetPropertyNode() {} + TargetPropertyNode() {} // NOLINT(modernize-use-equals-default) // This node handles errors on parameter count itself. int NumExpectedParameters() const override { return OneOrMoreParameters; } @@ -1442,7 +1442,7 @@ static const struct TargetPropertyNode : public cmGeneratorExpressionNode static const struct TargetNameNode : public cmGeneratorExpressionNode { - TargetNameNode() {} + TargetNameNode() {} // NOLINT(modernize-use-equals-default) bool GeneratesContent() const override { return true; } @@ -1464,7 +1464,7 @@ static const struct TargetNameNode : public cmGeneratorExpressionNode static const struct TargetObjectsNode : public cmGeneratorExpressionNode { - TargetObjectsNode() {} + TargetObjectsNode() {} // NOLINT(modernize-use-equals-default) std::string Evaluate( const std::vector<std::string>& parameters, @@ -1546,7 +1546,7 @@ static const struct TargetObjectsNode : public cmGeneratorExpressionNode static const struct CompileFeaturesNode : public cmGeneratorExpressionNode { - CompileFeaturesNode() {} + CompileFeaturesNode() {} // NOLINT(modernize-use-equals-default) int NumExpectedParameters() const override { return OneOrMoreParameters; } @@ -1671,7 +1671,7 @@ cmPolicies::PolicyID policyForString(const char* policy_id) static const struct TargetPolicyNode : public cmGeneratorExpressionNode { - TargetPolicyNode() {} + TargetPolicyNode() {} // NOLINT(modernize-use-equals-default) int NumExpectedParameters() const override { return 1; } @@ -1732,7 +1732,7 @@ static const struct TargetPolicyNode : public cmGeneratorExpressionNode static const struct InstallPrefixNode : public cmGeneratorExpressionNode { - InstallPrefixNode() {} + InstallPrefixNode() {} // NOLINT(modernize-use-equals-default) bool GeneratesContent() const override { return true; } int NumExpectedParameters() const override { return 0; } @@ -1953,7 +1953,7 @@ struct TargetFilesystemArtifactResultGetter<ArtifactPathTag> template <typename ArtifactT, typename ComponentT> struct TargetFilesystemArtifact : public cmGeneratorExpressionNode { - TargetFilesystemArtifact() {} + TargetFilesystemArtifact() {} // NOLINT(modernize-use-equals-default) int NumExpectedParameters() const override { return 1; } @@ -2009,7 +2009,9 @@ struct TargetFilesystemArtifact : public cmGeneratorExpressionNode template <typename ArtifactT> struct TargetFilesystemArtifactNodeGroup { - TargetFilesystemArtifactNodeGroup() {} + TargetFilesystemArtifactNodeGroup() // NOLINT(modernize-use-equals-default) + { + } TargetFilesystemArtifact<ArtifactT, ArtifactPathTag> File; TargetFilesystemArtifact<ArtifactT, ArtifactNameTag> FileName; @@ -2037,7 +2039,7 @@ static const TargetFilesystemArtifact<ArtifactBundleContentDirTag, static const struct ShellPathNode : public cmGeneratorExpressionNode { - ShellPathNode() {} + ShellPathNode() {} // NOLINT(modernize-use-equals-default) std::string Evaluate( const std::vector<std::string>& parameters, diff --git a/Source/cmGeneratorExpressionNode.h b/Source/cmGeneratorExpressionNode.h index ece1c11..3dbfc6e 100644 --- a/Source/cmGeneratorExpressionNode.h +++ b/Source/cmGeneratorExpressionNode.h @@ -22,7 +22,7 @@ struct cmGeneratorExpressionNode OneOrMoreParameters = -1, OneOrZeroParameters = -2 }; - virtual ~cmGeneratorExpressionNode() {} + virtual ~cmGeneratorExpressionNode() = default; virtual bool GeneratesContent() const { return true; } diff --git a/Source/cmGeneratorTarget.h b/Source/cmGeneratorTarget.h index d9221f0..d72e051 100644 --- a/Source/cmGeneratorTarget.h +++ b/Source/cmGeneratorTarget.h @@ -111,7 +111,6 @@ public: std::set<std::string> ExpectedXamlHeaders; std::set<std::string> ExpectedXamlSources; bool Initialized = false; - KindedSources() {} }; /** Get all sources needed for a configuration with kinds assigned. */ @@ -562,7 +561,6 @@ public: }; struct SourceFileFlags { - SourceFileFlags() {} SourceFileType Type = SourceFileTypeNormal; const char* MacFolder = nullptr; // location inside Mac content folders }; @@ -750,7 +748,6 @@ private: struct CompatibleInterfaces : public CompatibleInterfacesBase { - CompatibleInterfaces() {} bool Done = false; }; mutable std::map<std::string, CompatibleInterfaces> CompatibleInterfacesMap; @@ -764,7 +761,6 @@ private: struct LinkImplClosure : public std::vector<cmGeneratorTarget const*> { - LinkImplClosure() {} bool Done = false; }; mutable std::map<std::string, LinkImplClosure> LinkImplClosureMap; @@ -784,7 +780,6 @@ private: // Cache import information from properties for each configuration. struct ImportInfo { - ImportInfo() {} bool NoSOName = false; ManagedType Managed = Native; unsigned int Multiplicity = 0; diff --git a/Source/cmGhsMultiTargetGenerator.cxx b/Source/cmGhsMultiTargetGenerator.cxx index 19605e4..04a8b3c 100644 --- a/Source/cmGhsMultiTargetGenerator.cxx +++ b/Source/cmGhsMultiTargetGenerator.cxx @@ -67,7 +67,7 @@ void cmGhsMultiTargetGenerator::Generate() case cmStateEnums::SHARED_LIBRARY: { std::string msg = "add_library(<name> SHARED ...) not supported: "; msg += this->Name; - cmSystemTools::Message(msg.c_str()); + cmSystemTools::Message(msg); return; } case cmStateEnums::OBJECT_LIBRARY: { @@ -84,13 +84,13 @@ void cmGhsMultiTargetGenerator::Generate() case cmStateEnums::MODULE_LIBRARY: { std::string msg = "add_library(<name> MODULE ...) not supported: "; msg += this->Name; - cmSystemTools::Message(msg.c_str()); + cmSystemTools::Message(msg); return; } case cmStateEnums::UTILITY: { std::string msg = "add_custom_target(<name> ...) not supported: "; msg += this->Name; - cmSystemTools::Message(msg.c_str()); + cmSystemTools::Message(msg); return; } default: @@ -150,7 +150,8 @@ void cmGhsMultiTargetGenerator::WriteTargetSpecifics(std::ostream& fout, if (this->TagType != GhsMultiGpj::SUBPROJECT) { // set target binary file destination outpath = this->GeneratorTarget->GetDirectory(config); - outpath = this->LocalGenerator->ConvertToRelativePath(rootpath, outpath); + outpath = + this->LocalGenerator->MaybeConvertToRelativePath(rootpath, outpath); fout << " :binDirRelative=\"" << outpath << "\"" << std::endl; fout << " -o \"" << this->TargetNameReal << "\"" << std::endl; } @@ -550,7 +551,7 @@ void cmGhsMultiTargetGenerator::WriteReferences(std::ostream& fout) std::string tpath = t->LocalGenerator->GetCurrentBinaryDirectory(); std::string rootpath = this->LocalGenerator->GetCurrentBinaryDirectory(); std::string outpath = - this->LocalGenerator->ConvertToRelativePath(rootpath, tpath) + "/" + + this->LocalGenerator->MaybeConvertToRelativePath(rootpath, tpath) + "/" + tname + "REF" + cmGlobalGhsMultiGenerator::FILE_EXTENSION; fout << outpath; diff --git a/Source/cmGlobVerificationManager.h b/Source/cmGlobVerificationManager.h index c293a76..f7146be 100644 --- a/Source/cmGlobVerificationManager.h +++ b/Source/cmGlobVerificationManager.h @@ -21,9 +21,6 @@ */ class cmGlobVerificationManager { -public: - cmGlobVerificationManager() {} - protected: ///! Save verification script for given makefile. ///! Saves to output <path>/<CMakeFilesDirectory>/VerifyGlobs.cmake @@ -73,7 +70,6 @@ private: bool Initialized = false; std::vector<std::string> Files; std::vector<std::pair<std::string, cmListFileBacktrace>> Backtraces; - CacheEntryValue() {} }; typedef std::map<CacheEntryKey, CacheEntryValue> CacheEntryMap; diff --git a/Source/cmGlobalBorlandMakefileGenerator.cxx b/Source/cmGlobalBorlandMakefileGenerator.cxx index 56714b1..c2eb583 100644 --- a/Source/cmGlobalBorlandMakefileGenerator.cxx +++ b/Source/cmGlobalBorlandMakefileGenerator.cxx @@ -54,7 +54,7 @@ void cmGlobalBorlandMakefileGenerator::GetDocumentation( } void cmGlobalBorlandMakefileGenerator::GenerateBuildCommand( - std::vector<std::string>& makeCommand, const std::string& makeProgram, + GeneratedMakeCommand& makeCommand, const std::string& makeProgram, const std::string& projectName, const std::string& projectDir, const std::string& targetName, const std::string& config, bool fast, int /*jobs*/, bool verbose, std::vector<std::string> const& makeOptions) diff --git a/Source/cmGlobalBorlandMakefileGenerator.h b/Source/cmGlobalBorlandMakefileGenerator.h index 27de6cc..ca04b7b 100644 --- a/Source/cmGlobalBorlandMakefileGenerator.h +++ b/Source/cmGlobalBorlandMakefileGenerator.h @@ -46,7 +46,7 @@ public: bool AllowDeleteOnError() const override { return false; } protected: - void GenerateBuildCommand(std::vector<std::string>& makeCommand, + void GenerateBuildCommand(GeneratedMakeCommand& makeCommand, const std::string& makeProgram, const std::string& projectName, const std::string& projectDir, diff --git a/Source/cmGlobalCommonGenerator.cxx b/Source/cmGlobalCommonGenerator.cxx index 3b7de4b..bf992b4 100644 --- a/Source/cmGlobalCommonGenerator.cxx +++ b/Source/cmGlobalCommonGenerator.cxx @@ -9,6 +9,4 @@ cmGlobalCommonGenerator::cmGlobalCommonGenerator(cmake* cm) { } -cmGlobalCommonGenerator::~cmGlobalCommonGenerator() -{ -} +cmGlobalCommonGenerator::~cmGlobalCommonGenerator() = default; diff --git a/Source/cmGlobalGenerator.cxx b/Source/cmGlobalGenerator.cxx index ccf7c73..386a3f7 100644 --- a/Source/cmGlobalGenerator.cxx +++ b/Source/cmGlobalGenerator.cxx @@ -33,7 +33,6 @@ #include "cmMSVC60LinkLineComputer.h" #include "cmMakefile.h" #include "cmMessageType.h" -#include "cmOutputConverter.h" #include "cmPolicies.h" #include "cmSourceFile.h" #include "cmState.h" @@ -1060,7 +1059,7 @@ void cmGlobalGenerator::SetLanguageEnabledMaps(const std::string& l, if (preference < 0) { std::string msg = linkerPrefVar; msg += " is negative, adjusting it to 0"; - cmSystemTools::Message(msg.c_str(), "Warning"); + cmSystemTools::Message(msg, "Warning"); preference = 0; } @@ -1754,14 +1753,13 @@ int cmGlobalGenerator::TryCompile(int jobs, const std::string& srcdir, } void cmGlobalGenerator::GenerateBuildCommand( - std::vector<std::string>& makeCommand, const std::string& /*unused*/, + GeneratedMakeCommand& makeCommand, const std::string& /*unused*/, const std::string& /*unused*/, const std::string& /*unused*/, const std::string& /*unused*/, const std::string& /*unused*/, bool /*unused*/, int /*unused*/, bool /*unused*/, std::vector<std::string> const& /*unused*/) { - makeCommand.emplace_back( - "cmGlobalGenerator::GenerateBuildCommand not implemented"); + makeCommand.add("cmGlobalGenerator::GenerateBuildCommand not implemented"); } void cmGlobalGenerator::PrintBuildCommandAdvice(std::ostream& /*os*/, @@ -1805,31 +1803,29 @@ int cmGlobalGenerator::Build(int jobs, const std::string& /*unused*/, std::string outputBuffer; std::string* outputPtr = &outputBuffer; - std::vector<std::string> makeCommand; + GeneratedMakeCommand makeCommand; this->GenerateBuildCommand(makeCommand, makeCommandCSTR, projectName, bindir, target, config, fast, jobs, verbose, nativeOptions); - // Workaround to convince VCExpress.exe to produce output. + // Workaround to convince some commands to produce output. if (outputflag == cmSystemTools::OUTPUT_PASSTHROUGH && - !makeCommand.empty() && - cmSystemTools::LowerCase( - cmSystemTools::GetFilenameName(makeCommand[0])) == "vcexpress.exe") { + makeCommand.RequiresOutputForward) { outputflag = cmSystemTools::OUTPUT_FORWARD; } // should we do a clean first? if (clean) { - std::vector<std::string> cleanCommand; + GeneratedMakeCommand cleanCommand; this->GenerateBuildCommand(cleanCommand, makeCommandCSTR, projectName, bindir, "clean", config, fast, jobs, verbose); output += "\nRun Clean Command:"; - output += cmSystemTools::PrintSingleCommand(cleanCommand); + output += cleanCommand.printable(); output += "\n"; - if (!cmSystemTools::RunSingleCommand(cleanCommand, outputPtr, outputPtr, - &retVal, nullptr, outputflag, - timeout)) { + if (!cmSystemTools::RunSingleCommand(cleanCommand.PrimaryCommand, + outputPtr, outputPtr, &retVal, + nullptr, outputflag, timeout)) { cmSystemTools::SetRunCommandHideConsole(hideconsole); cmSystemTools::Error("Generator: execution of make clean failed."); output += *outputPtr; @@ -1841,13 +1837,13 @@ int cmGlobalGenerator::Build(int jobs, const std::string& /*unused*/, } // now build - std::string makeCommandStr = cmSystemTools::PrintSingleCommand(makeCommand); - output += "\nRun Build Command:"; + std::string makeCommandStr = makeCommand.printable(); + output += "\nRun Build Command(s):"; output += makeCommandStr; output += "\n"; - if (!cmSystemTools::RunSingleCommand(makeCommand, outputPtr, outputPtr, - &retVal, nullptr, outputflag, + if (!cmSystemTools::RunSingleCommand(makeCommand.PrimaryCommand, outputPtr, + outputPtr, &retVal, nullptr, outputflag, timeout)) { cmSystemTools::SetRunCommandHideConsole(hideconsole); cmSystemTools::Error( @@ -2794,8 +2790,9 @@ void cmGlobalGenerator::AddRuleHash(const std::vector<std::string>& outputs, } // Shorten the output name (in expected use case). - cmOutputConverter converter(this->GetMakefiles()[0]->GetStateSnapshot()); - std::string fname = converter.ConvertToRelativePath( + cmStateDirectory cmDir = + this->GetMakefiles()[0]->GetStateSnapshot().GetDirectory(); + std::string fname = cmDir.ConvertToRelPathIfNotContained( this->GetMakefiles()[0]->GetState()->GetBinaryDirectory(), outputs[0]); // Associate the hash with this output. diff --git a/Source/cmGlobalGenerator.h b/Source/cmGlobalGenerator.h index 84ec7a9..ac01326 100644 --- a/Source/cmGlobalGenerator.h +++ b/Source/cmGlobalGenerator.h @@ -41,6 +41,54 @@ class cmSourceFile; class cmStateDirectory; class cmake; +namespace detail { +inline void AppendStrs(std::vector<std::string>&) +{ +} +template <typename T, typename... Ts> +inline void AppendStrs(std::vector<std::string>& command, T&& s, Ts&&... ts) +{ + command.emplace_back(std::forward<T>(s)); + AppendStrs(command, std::forward<Ts>(ts)...); +} + +struct GeneratedMakeCommand +{ + // Add each argument as a separate element to the vector + template <typename... T> + void add(T&&... args) + { + // iterate the args and append each one + AppendStrs(PrimaryCommand, std::forward<T>(args)...); + } + + // Add each value in the iterators as a separate element to the vector + void add(std::vector<std::string>::const_iterator start, + std::vector<std::string>::const_iterator end) + { + PrimaryCommand.insert(PrimaryCommand.end(), start, end); + } + + std::string printable() const + { + std::size_t size = PrimaryCommand.size(); + for (auto&& i : PrimaryCommand) { + size += i.size(); + } + std::string buffer; + buffer.reserve(size); + for (auto&& i : PrimaryCommand) { + buffer.append(i); + buffer.append(1, ' '); + } + return buffer; + } + + std::vector<std::string> PrimaryCommand; + bool RequiresOutputForward = false; +}; +} + /** \class cmGlobalGenerator * \brief Responsible for overseeing the generation process for the entire tree * @@ -182,8 +230,12 @@ public: virtual bool Open(const std::string& bindir, const std::string& projectName, bool dryRun); + struct GeneratedMakeCommand final : public detail::GeneratedMakeCommand + { + }; + virtual void GenerateBuildCommand( - std::vector<std::string>& makeCommand, const std::string& makeProgram, + GeneratedMakeCommand& makeCommand, const std::string& makeProgram, const std::string& projectName, const std::string& projectDir, const std::string& targetName, const std::string& config, bool fast, int jobs, bool verbose, @@ -481,7 +533,6 @@ protected: std::vector<std::string> Depends; std::string WorkingDir; bool UsesTerminal = false; - GlobalTargetInfo() {} }; void CreateDefaultGlobalTargets(std::vector<GlobalTargetInfo>& targets); @@ -610,7 +661,6 @@ private: long LastDiskTime = -1; std::set<std::string> All; std::set<std::string> Generated; - DirectoryContent() {} }; std::map<std::string, DirectoryContent> DirectoryContentMap; diff --git a/Source/cmGlobalGeneratorFactory.h b/Source/cmGlobalGeneratorFactory.h index d4f772b..bb5f74c 100644 --- a/Source/cmGlobalGeneratorFactory.h +++ b/Source/cmGlobalGeneratorFactory.h @@ -20,7 +20,7 @@ struct cmDocumentationEntry; class cmGlobalGeneratorFactory { public: - virtual ~cmGlobalGeneratorFactory() {} + virtual ~cmGlobalGeneratorFactory() = default; /** Create a GlobalGenerator */ virtual cmGlobalGenerator* CreateGlobalGenerator(const std::string& n, diff --git a/Source/cmGlobalGhsMultiGenerator.cxx b/Source/cmGlobalGhsMultiGenerator.cxx index 7963c8a..45fa052 100644 --- a/Source/cmGlobalGhsMultiGenerator.cxx +++ b/Source/cmGlobalGhsMultiGenerator.cxx @@ -70,7 +70,7 @@ bool cmGlobalGhsMultiGenerator::SetGeneratorToolset(std::string const& ts, "Green Hills MULTI: -T <toolset> not specified; defaulting to \""; message += tsp; message += "\""; - cmSystemTools::Message(message.c_str()); + cmSystemTools::Message(message); /* store the full toolset for later use * -- already done if -T<toolset> was specified @@ -297,7 +297,7 @@ void cmGlobalGhsMultiGenerator::WriteSubProjects( if (projName && projType) { cmLocalGenerator* lg = target->GetLocalGenerator(); std::string dir = lg->GetCurrentBinaryDirectory(); - dir = root->ConvertToRelativePath(rootBinaryDir, dir.c_str()); + dir = root->MaybeConvertToRelativePath(rootBinaryDir, dir.c_str()); if (dir == ".") { dir.clear(); } else { @@ -370,25 +370,23 @@ void cmGlobalGhsMultiGenerator::OutputTopLevelProject( } void cmGlobalGhsMultiGenerator::GenerateBuildCommand( - std::vector<std::string>& makeCommand, const std::string& makeProgram, + GeneratedMakeCommand& makeCommand, const std::string& makeProgram, const std::string& projectName, const std::string& projectDir, const std::string& targetName, const std::string& /*config*/, bool /*fast*/, int jobs, bool /*verbose*/, std::vector<std::string> const& makeOptions) { const char* gbuild = this->CMakeInstance->GetCacheDefinition("CMAKE_MAKE_PROGRAM"); - makeCommand.push_back( - this->SelectMakeProgram(makeProgram, (std::string)gbuild)); + makeCommand.add(this->SelectMakeProgram(makeProgram, (std::string)gbuild)); if (jobs != cmake::NO_BUILD_PARALLEL_LEVEL) { - makeCommand.push_back("-parallel"); + makeCommand.add("-parallel"); if (jobs != cmake::DEFAULT_BUILD_PARALLEL_LEVEL) { - makeCommand.push_back(std::to_string(jobs)); + makeCommand.add(std::to_string(jobs)); } } - makeCommand.insert(makeCommand.end(), makeOptions.begin(), - makeOptions.end()); + makeCommand.add(makeOptions.begin(), makeOptions.end()); /* determine which top-project file to use */ std::string proj = projectName + ".top" + FILE_EXTENSION; @@ -401,16 +399,15 @@ void cmGlobalGhsMultiGenerator::GenerateBuildCommand( } } - makeCommand.push_back("-top"); - makeCommand.push_back(proj); + makeCommand.add("-top", proj); if (!targetName.empty()) { if (targetName == "clean") { - makeCommand.push_back("-clean"); + makeCommand.add("-clean"); } else { if (targetName.compare(targetName.size() - 4, 4, ".gpj") == 0) { - makeCommand.push_back(targetName); + makeCommand.add(targetName); } else { - makeCommand.push_back(targetName + ".gpj"); + makeCommand.add(targetName + ".gpj"); } } } diff --git a/Source/cmGlobalGhsMultiGenerator.h b/Source/cmGlobalGhsMultiGenerator.h index 9332567..bc2b199 100644 --- a/Source/cmGlobalGhsMultiGenerator.h +++ b/Source/cmGlobalGhsMultiGenerator.h @@ -88,7 +88,7 @@ public: protected: void Generate() override; - void GenerateBuildCommand(std::vector<std::string>& makeCommand, + void GenerateBuildCommand(GeneratedMakeCommand& makeCommand, const std::string& makeProgram, const std::string& projectName, const std::string& projectDir, diff --git a/Source/cmGlobalJOMMakefileGenerator.cxx b/Source/cmGlobalJOMMakefileGenerator.cxx index 9c805a8..2b7f486 100644 --- a/Source/cmGlobalJOMMakefileGenerator.cxx +++ b/Source/cmGlobalJOMMakefileGenerator.cxx @@ -55,7 +55,7 @@ void cmGlobalJOMMakefileGenerator::PrintCompilerAdvice( } void cmGlobalJOMMakefileGenerator::GenerateBuildCommand( - std::vector<std::string>& makeCommand, const std::string& makeProgram, + GeneratedMakeCommand& makeCommand, const std::string& makeProgram, const std::string& projectName, const std::string& projectDir, const std::string& targetName, const std::string& config, bool fast, int jobs, bool verbose, std::vector<std::string> const& makeOptions) diff --git a/Source/cmGlobalJOMMakefileGenerator.h b/Source/cmGlobalJOMMakefileGenerator.h index bcf46d0..aa8b5fb 100644 --- a/Source/cmGlobalJOMMakefileGenerator.h +++ b/Source/cmGlobalJOMMakefileGenerator.h @@ -40,7 +40,7 @@ public: bool optional) override; protected: - void GenerateBuildCommand(std::vector<std::string>& makeCommand, + void GenerateBuildCommand(GeneratedMakeCommand& makeCommand, const std::string& makeProgram, const std::string& projectName, const std::string& projectDir, diff --git a/Source/cmGlobalNMakeMakefileGenerator.cxx b/Source/cmGlobalNMakeMakefileGenerator.cxx index 5235be7..ffe95f9 100644 --- a/Source/cmGlobalNMakeMakefileGenerator.cxx +++ b/Source/cmGlobalNMakeMakefileGenerator.cxx @@ -55,7 +55,7 @@ void cmGlobalNMakeMakefileGenerator::PrintCompilerAdvice( } void cmGlobalNMakeMakefileGenerator::GenerateBuildCommand( - std::vector<std::string>& makeCommand, const std::string& makeProgram, + GeneratedMakeCommand& makeCommand, const std::string& makeProgram, const std::string& projectName, const std::string& projectDir, const std::string& targetName, const std::string& config, bool fast, int /*jobs*/, bool verbose, std::vector<std::string> const& makeOptions) diff --git a/Source/cmGlobalNMakeMakefileGenerator.h b/Source/cmGlobalNMakeMakefileGenerator.h index 62dea6e..06c48e2 100644 --- a/Source/cmGlobalNMakeMakefileGenerator.h +++ b/Source/cmGlobalNMakeMakefileGenerator.h @@ -45,7 +45,7 @@ public: bool optional) override; protected: - void GenerateBuildCommand(std::vector<std::string>& makeCommand, + void GenerateBuildCommand(GeneratedMakeCommand& makeCommand, const std::string& makeProgram, const std::string& projectName, const std::string& projectDir, diff --git a/Source/cmGlobalNinjaGenerator.cxx b/Source/cmGlobalNinjaGenerator.cxx index 23dbd76..4fd0673 100644 --- a/Source/cmGlobalNinjaGenerator.cxx +++ b/Source/cmGlobalNinjaGenerator.cxx @@ -673,31 +673,28 @@ void cmGlobalNinjaGenerator::EnableLanguage( // Called by: // cmGlobalGenerator::Build() void cmGlobalNinjaGenerator::GenerateBuildCommand( - std::vector<std::string>& makeCommand, const std::string& makeProgram, + GeneratedMakeCommand& makeCommand, const std::string& makeProgram, const std::string& /*projectName*/, const std::string& /*projectDir*/, const std::string& targetName, const std::string& /*config*/, bool /*fast*/, int jobs, bool verbose, std::vector<std::string> const& makeOptions) { - makeCommand.push_back(this->SelectMakeProgram(makeProgram)); + makeCommand.add(this->SelectMakeProgram(makeProgram)); if (verbose) { - makeCommand.emplace_back("-v"); + makeCommand.add("-v"); } if ((jobs != cmake::NO_BUILD_PARALLEL_LEVEL) && (jobs != cmake::DEFAULT_BUILD_PARALLEL_LEVEL)) { - makeCommand.emplace_back("-j"); - makeCommand.push_back(std::to_string(jobs)); + makeCommand.add("-j", std::to_string(jobs)); } - makeCommand.insert(makeCommand.end(), makeOptions.begin(), - makeOptions.end()); + makeCommand.add(makeOptions.begin(), makeOptions.end()); if (!targetName.empty()) { if (targetName == "clean") { - makeCommand.emplace_back("-t"); - makeCommand.emplace_back("clean"); + makeCommand.add("-t", "clean"); } else { - makeCommand.push_back(targetName); + makeCommand.add(targetName); } } } @@ -861,7 +858,7 @@ std::string const& cmGlobalNinjaGenerator::ConvertToNinjaPath( cmLocalNinjaGenerator* ng = static_cast<cmLocalNinjaGenerator*>(this->LocalGenerators[0]); std::string const& bin_dir = ng->GetState()->GetBinaryDirectory(); - std::string convPath = ng->ConvertToRelativePath(bin_dir, path); + std::string convPath = ng->MaybeConvertToRelativePath(bin_dir, path); convPath = this->NinjaOutputPath(convPath); #ifdef _WIN32 std::replace(convPath.begin(), convPath.end(), '/', '\\'); diff --git a/Source/cmGlobalNinjaGenerator.h b/Source/cmGlobalNinjaGenerator.h index f1ab852..b3aa88f 100644 --- a/Source/cmGlobalNinjaGenerator.h +++ b/Source/cmGlobalNinjaGenerator.h @@ -183,8 +183,6 @@ public: return new cmGlobalGeneratorSimpleFactory<cmGlobalNinjaGenerator>(); } - ~cmGlobalNinjaGenerator() override {} - cmLocalGenerator* CreateLocalGenerator(cmMakefile* mf) override; std::string GetName() const override @@ -202,7 +200,7 @@ public: void EnableLanguage(std::vector<std::string> const& languages, cmMakefile* mf, bool optional) override; - void GenerateBuildCommand(std::vector<std::string>& makeCommand, + void GenerateBuildCommand(GeneratedMakeCommand& makeCommand, const std::string& makeProgram, const std::string& projectName, const std::string& projectDir, diff --git a/Source/cmGlobalUnixMakefileGenerator3.cxx b/Source/cmGlobalUnixMakefileGenerator3.cxx index 792adc0..dac6ea6 100644 --- a/Source/cmGlobalUnixMakefileGenerator3.cxx +++ b/Source/cmGlobalUnixMakefileGenerator3.cxx @@ -325,7 +325,8 @@ void cmGlobalUnixMakefileGenerator3::WriteMainCMakefile() << "set(CMAKE_MAKEFILE_DEPENDS\n" << " \"CMakeCache.txt\"\n"; for (std::string const& f : lfiles) { - cmakefileStream << " \"" << lg->ConvertToRelativePath(currentBinDir, f) + cmakefileStream << " \"" + << lg->MaybeConvertToRelativePath(currentBinDir, f) << "\"\n"; } cmakefileStream << " )\n\n"; @@ -339,9 +340,11 @@ void cmGlobalUnixMakefileGenerator3::WriteMainCMakefile() cmakefileStream << "# The corresponding makefile is:\n" << "set(CMAKE_MAKEFILE_OUTPUTS\n" << " \"" - << lg->ConvertToRelativePath(currentBinDir, makefileName) + << lg->MaybeConvertToRelativePath(currentBinDir, + makefileName) << "\"\n" - << " \"" << lg->ConvertToRelativePath(currentBinDir, check) + << " \"" + << lg->MaybeConvertToRelativePath(currentBinDir, check) << "\"\n"; cmakefileStream << " )\n\n"; @@ -354,7 +357,8 @@ void cmGlobalUnixMakefileGenerator3::WriteMainCMakefile() const std::vector<std::string>& outfiles = lg->GetMakefile()->GetOutputFiles(); for (std::string const& outfile : outfiles) { - cmakefileStream << " \"" << lg->ConvertToRelativePath(binDir, outfile) + cmakefileStream << " \"" + << lg->MaybeConvertToRelativePath(binDir, outfile) << "\"\n"; } @@ -365,7 +369,8 @@ void cmGlobalUnixMakefileGenerator3::WriteMainCMakefile() tmpStr = lg->GetCurrentBinaryDirectory(); tmpStr += "/CMakeFiles"; tmpStr += "/CMakeDirectoryInformation.cmake"; - cmakefileStream << " \"" << lg->ConvertToRelativePath(binDir, tmpStr) + cmakefileStream << " \"" + << lg->MaybeConvertToRelativePath(binDir, tmpStr) << "\"\n"; } cmakefileStream << " )\n\n"; @@ -474,7 +479,7 @@ void cmGlobalUnixMakefileGenerator3::WriteDirectoryRules2( // Begin the directory-level rules section. std::string dir = - cmSystemTools::ConvertToOutputPath(lg->ConvertToRelativePath( + cmSystemTools::ConvertToOutputPath(lg->MaybeConvertToRelativePath( lg->GetBinaryDirectory(), lg->GetCurrentBinaryDirectory())); lg->WriteDivider(ruleFileStream); ruleFileStream << "# Directory level rules for directory " << dir << "\n\n"; @@ -490,10 +495,10 @@ void cmGlobalUnixMakefileGenerator3::WriteDirectoryRules2( } void cmGlobalUnixMakefileGenerator3::GenerateBuildCommand( - std::vector<std::string>& makeCommand, const std::string& makeProgram, + GeneratedMakeCommand& makeCommand, const std::string& makeProgram, const std::string& /*projectName*/, const std::string& /*projectDir*/, const std::string& targetName, const std::string& /*config*/, bool fast, - int jobs, bool /*verbose*/, std::vector<std::string> const& makeOptions) + int jobs, bool verbose, std::vector<std::string> const& makeOptions) { std::unique_ptr<cmMakefile> mfu; cmMakefile* mf; @@ -510,27 +515,33 @@ void cmGlobalUnixMakefileGenerator3::GenerateBuildCommand( mf = mfu.get(); } - makeCommand.push_back(this->SelectMakeProgram(makeProgram)); + // Make it possible to set verbosity also from command line + if (verbose) { + makeCommand.add(cmSystemTools::GetCMakeCommand()); + makeCommand.add("-E"); + makeCommand.add("env"); + makeCommand.add("VERBOSE=1"); + } + makeCommand.add(this->SelectMakeProgram(makeProgram)); if (jobs != cmake::NO_BUILD_PARALLEL_LEVEL) { - makeCommand.emplace_back("-j"); + makeCommand.add("-j"); if (jobs != cmake::DEFAULT_BUILD_PARALLEL_LEVEL) { - makeCommand.push_back(std::to_string(jobs)); + makeCommand.add(std::to_string(jobs)); } } - makeCommand.insert(makeCommand.end(), makeOptions.begin(), - makeOptions.end()); + makeCommand.add(makeOptions.begin(), makeOptions.end()); if (!targetName.empty()) { std::string tname = targetName; if (fast) { tname += "/fast"; } - cmOutputConverter conv(mf->GetStateSnapshot()); tname = - conv.ConvertToRelativePath(mf->GetState()->GetBinaryDirectory(), tname); + mf->GetStateSnapshot().GetDirectory().ConvertToRelPathIfNotContained( + mf->GetState()->GetBinaryDirectory(), tname); cmSystemTools::ConvertToOutputSlashes(tname); - makeCommand.push_back(std::move(tname)); + makeCommand.add(std::move(tname)); } } diff --git a/Source/cmGlobalUnixMakefileGenerator3.h b/Source/cmGlobalUnixMakefileGenerator3.h index 6199586..8a80acc 100644 --- a/Source/cmGlobalUnixMakefileGenerator3.h +++ b/Source/cmGlobalUnixMakefileGenerator3.h @@ -127,7 +127,7 @@ public: std::string GetEmptyRuleHackDepends() { return this->EmptyRuleHackDepends; } // change the build command for speed - void GenerateBuildCommand(std::vector<std::string>& makeCommand, + void GenerateBuildCommand(GeneratedMakeCommand& makeCommand, const std::string& makeProgram, const std::string& projectName, const std::string& projectDir, @@ -217,7 +217,6 @@ protected: // Store per-target progress counters. struct TargetProgress { - TargetProgress() {} unsigned long NumberOfActions = 0; std::string VariableFile; std::vector<unsigned long> Marks; diff --git a/Source/cmGlobalVisualStudio10Generator.cxx b/Source/cmGlobalVisualStudio10Generator.cxx index 99e9173..07656ed 100644 --- a/Source/cmGlobalVisualStudio10Generator.cxx +++ b/Source/cmGlobalVisualStudio10Generator.cxx @@ -879,7 +879,7 @@ bool cmGlobalVisualStudio10Generator::FindVCTargetsPath(cmMakefile* mf) } void cmGlobalVisualStudio10Generator::GenerateBuildCommand( - std::vector<std::string>& makeCommand, const std::string& makeProgram, + GeneratedMakeCommand& makeCommand, const std::string& makeProgram, const std::string& projectName, const std::string& projectDir, const std::string& targetName, const std::string& config, bool fast, int jobs, bool verbose, std::vector<std::string> const& makeOptions) @@ -894,6 +894,10 @@ void cmGlobalVisualStudio10Generator::GenerateBuildCommand( bool useDevEnv = (makeProgramLower.find("devenv") != std::string::npos || makeProgramLower.find("vcexpress") != std::string::npos); + // Workaround to convince VCExpress.exe to produce output. + makeCommand.RequiresOutputForward = + (makeProgramLower.find("vcexpress") != std::string::npos); + // MSBuild is preferred (and required for VS Express), but if the .sln has // an Intel Fortran .vfproj then we have to use devenv. Parse it to find out. cmSlnData slnData; @@ -927,7 +931,7 @@ void cmGlobalVisualStudio10Generator::GenerateBuildCommand( return; } - makeCommand.push_back(makeProgramSelected); + makeCommand.add(makeProgramSelected); std::string realTarget = targetName; // msbuild.exe CxxOnly.sln /t:Build /p:Configuration=Debug /target:ALL_BUILD @@ -936,8 +940,8 @@ void cmGlobalVisualStudio10Generator::GenerateBuildCommand( realTarget = "ALL_BUILD"; } if (realTarget == "clean") { - makeCommand.push_back(std::string(projectName) + ".sln"); - makeCommand.push_back("/t:Clean"); + makeCommand.add(std::string(projectName) + ".sln"); + makeCommand.add("/t:Clean"); } else { std::string targetProject(realTarget); targetProject += ".vcxproj"; @@ -949,7 +953,7 @@ void cmGlobalVisualStudio10Generator::GenerateBuildCommand( cmSystemTools::ConvertToUnixSlashes(targetProject); } } - makeCommand.push_back(targetProject); + makeCommand.add(std::move(targetProject)); } std::string configArg = "/p:Configuration="; if (!config.empty()) { @@ -957,23 +961,26 @@ void cmGlobalVisualStudio10Generator::GenerateBuildCommand( } else { configArg += "Debug"; } - makeCommand.push_back(configArg); - makeCommand.push_back("/p:Platform=" + this->GetPlatformName()); - makeCommand.push_back(std::string("/p:VisualStudioVersion=") + - this->GetIDEVersion()); + makeCommand.add(configArg); + makeCommand.add(std::string("/p:Platform=") + this->GetPlatformName()); + makeCommand.add(std::string("/p:VisualStudioVersion=") + + this->GetIDEVersion()); if (jobs != cmake::NO_BUILD_PARALLEL_LEVEL) { if (jobs == cmake::DEFAULT_BUILD_PARALLEL_LEVEL) { - makeCommand.push_back("/m"); + makeCommand.add("/m"); } else { - makeCommand.push_back(std::string("/m:") + std::to_string(jobs)); + makeCommand.add(std::string("/m:") + std::to_string(jobs)); } // Having msbuild.exe and cl.exe using multiple jobs is discouraged - makeCommand.push_back("/p:CL_MPCount=1"); + makeCommand.add("/p:CL_MPCount=1"); } - makeCommand.insert(makeCommand.end(), makeOptions.begin(), - makeOptions.end()); + // Respect the verbosity: 'n' normal will show build commands + // 'm' minimal only the build step's title + makeCommand.add(std::string("/v:") + ((verbose) ? "n" : "m")); + + makeCommand.add(makeOptions.begin(), makeOptions.end()); } bool cmGlobalVisualStudio10Generator::Find64BitTools(cmMakefile* mf) diff --git a/Source/cmGlobalVisualStudio10Generator.h b/Source/cmGlobalVisualStudio10Generator.h index f496357..3ef7abf 100644 --- a/Source/cmGlobalVisualStudio10Generator.h +++ b/Source/cmGlobalVisualStudio10Generator.h @@ -22,7 +22,7 @@ public: bool SetGeneratorPlatform(std::string const& p, cmMakefile* mf) override; bool SetGeneratorToolset(std::string const& ts, cmMakefile* mf) override; - void GenerateBuildCommand(std::vector<std::string>& makeCommand, + void GenerateBuildCommand(GeneratedMakeCommand& makeCommand, const std::string& makeProgram, const std::string& projectName, const std::string& projectDir, diff --git a/Source/cmGlobalVisualStudio7Generator.cxx b/Source/cmGlobalVisualStudio7Generator.cxx index cae46e1..d457f60 100644 --- a/Source/cmGlobalVisualStudio7Generator.cxx +++ b/Source/cmGlobalVisualStudio7Generator.cxx @@ -191,7 +191,7 @@ const char* cmGlobalVisualStudio7Generator::ExternalProjectType( return "8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942"; } void cmGlobalVisualStudio7Generator::GenerateBuildCommand( - std::vector<std::string>& makeCommand, const std::string& makeProgram, + GeneratedMakeCommand& makeCommand, const std::string& makeProgram, const std::string& projectName, const std::string& /*projectDir*/, const std::string& targetName, const std::string& config, bool /*fast*/, int /*jobs*/, bool /*verbose*/, std::vector<std::string> const& makeOptions) @@ -209,35 +209,25 @@ void cmGlobalVisualStudio7Generator::GenerateBuildCommand( makeProgramSelected = this->GetDevEnvCommand(); } - makeCommand.push_back(makeProgramSelected); + // Workaround to convince VCExpress.exe to produce output. + makeCommand.RequiresOutputForward = + (makeProgramLower.find("vcexpress") != std::string::npos); - makeCommand.push_back(std::string(projectName) + ".sln"); + makeCommand.add(makeProgramSelected); + + makeCommand.add(std::string(projectName) + ".sln"); std::string realTarget = targetName; bool clean = false; if (realTarget == "clean") { clean = true; realTarget = "ALL_BUILD"; } - if (clean) { - makeCommand.push_back("/clean"); - } else { - makeCommand.push_back("/build"); - } - - if (!config.empty()) { - makeCommand.push_back(config); - } else { - makeCommand.push_back("Debug"); - } - makeCommand.push_back("/project"); - if (!realTarget.empty()) { - makeCommand.push_back(realTarget); - } else { - makeCommand.push_back("ALL_BUILD"); - } - makeCommand.insert(makeCommand.end(), makeOptions.begin(), - makeOptions.end()); + makeCommand.add((clean ? "/clean" : "/build")); + makeCommand.add((config.empty() ? "Debug" : config)); + makeCommand.add("/project"); + makeCommand.add((realTarget.empty() ? "ALL_BUILD" : realTarget)); + makeCommand.add(makeOptions.begin(), makeOptions.end()); } ///! Create a local generator appropriate to this Global Generator @@ -367,7 +357,7 @@ void cmGlobalVisualStudio7Generator::WriteTargetsToSolution( if (vcprojName) { cmLocalGenerator* lg = target->GetLocalGenerator(); std::string dir = lg->GetCurrentBinaryDirectory(); - dir = root->ConvertToRelativePath(rootBinaryDir, dir.c_str()); + dir = root->MaybeConvertToRelativePath(rootBinaryDir, dir.c_str()); if (dir == ".") { dir.clear(); // msbuild cannot handle ".\" prefix } diff --git a/Source/cmGlobalVisualStudio7Generator.h b/Source/cmGlobalVisualStudio7Generator.h index d2a2a38..3f1c173 100644 --- a/Source/cmGlobalVisualStudio7Generator.h +++ b/Source/cmGlobalVisualStudio7Generator.h @@ -52,7 +52,7 @@ public: * Try running cmake and building a file. This is used for dynamically * loaded commands, not as part of the usual build process. */ - void GenerateBuildCommand(std::vector<std::string>& makeCommand, + void GenerateBuildCommand(GeneratedMakeCommand& makeCommand, const std::string& makeProgram, const std::string& projectName, const std::string& projectDir, diff --git a/Source/cmGlobalVisualStudioGenerator.cxx b/Source/cmGlobalVisualStudioGenerator.cxx index cbea3dd..77be592 100644 --- a/Source/cmGlobalVisualStudioGenerator.cxx +++ b/Source/cmGlobalVisualStudioGenerator.cxx @@ -262,13 +262,12 @@ void cmGlobalVisualStudioGenerator::ConfigureCMakeVisualStudioMacros() // purposes but newer versions distributed with CMake will replace // older versions in user directories. int res; - if (!cmSystemTools::FileTimeCompare(src.c_str(), dst.c_str(), &res) || - res > 0) { - if (!cmSystemTools::CopyFileAlways(src.c_str(), dst.c_str())) { + if (!cmSystemTools::FileTimeCompare(src, dst, &res) || res > 0) { + if (!cmSystemTools::CopyFileAlways(src, dst)) { std::ostringstream oss; oss << "Could not copy from: " << src << std::endl; oss << " to: " << dst << std::endl; - cmSystemTools::Message(oss.str().c_str(), "Warning"); + cmSystemTools::Message(oss.str(), "Warning"); } } @@ -783,7 +782,7 @@ void RegisterVisualStudioMacros(const std::string& macrosFile, << "CMake needs to register Visual Studio macros when its macros" << " file is updated or when it detects that its current macros file" << " is no longer registered with Visual Studio." << std::endl; - cmSystemTools::Message(oss.str().c_str(), "Warning"); + cmSystemTools::Message(oss.str(), "Warning"); // Count them again now that the warning is over. In the case of a GUI // warning, the user may have gone to close Visual Studio and then come diff --git a/Source/cmGlobalWatcomWMakeGenerator.cxx b/Source/cmGlobalWatcomWMakeGenerator.cxx index 558ef15..c02c471 100644 --- a/Source/cmGlobalWatcomWMakeGenerator.cxx +++ b/Source/cmGlobalWatcomWMakeGenerator.cxx @@ -51,7 +51,7 @@ void cmGlobalWatcomWMakeGenerator::GetDocumentation( } void cmGlobalWatcomWMakeGenerator::GenerateBuildCommand( - std::vector<std::string>& makeCommand, const std::string& makeProgram, + GeneratedMakeCommand& makeCommand, const std::string& makeProgram, const std::string& projectName, const std::string& projectDir, const std::string& targetName, const std::string& config, bool fast, int /*jobs*/, bool verbose, std::vector<std::string> const& makeOptions) diff --git a/Source/cmGlobalWatcomWMakeGenerator.h b/Source/cmGlobalWatcomWMakeGenerator.h index 0d10d58..6680b19 100644 --- a/Source/cmGlobalWatcomWMakeGenerator.h +++ b/Source/cmGlobalWatcomWMakeGenerator.h @@ -50,7 +50,7 @@ public: bool AllowDeleteOnError() const override { return false; } protected: - void GenerateBuildCommand(std::vector<std::string>& makeCommand, + void GenerateBuildCommand(GeneratedMakeCommand& makeCommand, const std::string& makeProgram, const std::string& projectName, const std::string& projectDir, diff --git a/Source/cmGlobalXCodeGenerator.cxx b/Source/cmGlobalXCodeGenerator.cxx index 0d70a0e..6d15b8c 100644 --- a/Source/cmGlobalXCodeGenerator.cxx +++ b/Source/cmGlobalXCodeGenerator.cxx @@ -339,20 +339,22 @@ bool cmGlobalXCodeGenerator::Open(const std::string& bindir, } void cmGlobalXCodeGenerator::GenerateBuildCommand( - std::vector<std::string>& makeCommand, const std::string& makeProgram, + GeneratedMakeCommand& makeCommand, const std::string& makeProgram, const std::string& projectName, const std::string& /*projectDir*/, const std::string& targetName, const std::string& config, bool /*fast*/, int jobs, bool /*verbose*/, std::vector<std::string> const& makeOptions) { // now build the test - makeCommand.emplace_back( + makeCommand.add( this->SelectMakeProgram(makeProgram, this->GetXcodeBuildCommand())); - makeCommand.emplace_back("-project"); - std::string projectArg = projectName; - projectArg += ".xcode"; - projectArg += "proj"; - makeCommand.emplace_back(projectArg); + if (!projectName.empty()) { + makeCommand.add("-project"); + std::string projectArg = projectName; + projectArg += ".xcode"; + projectArg += "proj"; + makeCommand.add(projectArg); + } bool clean = false; std::string realTarget = targetName; @@ -360,29 +362,22 @@ void cmGlobalXCodeGenerator::GenerateBuildCommand( clean = true; realTarget = "ALL_BUILD"; } - if (clean) { - makeCommand.emplace_back("clean"); - } else { - makeCommand.emplace_back("build"); - } - makeCommand.emplace_back("-target"); - if (!realTarget.empty()) { - makeCommand.emplace_back(realTarget); - } else { - makeCommand.emplace_back("ALL_BUILD"); - } - makeCommand.emplace_back("-configuration"); - makeCommand.emplace_back(!config.empty() ? config : "Debug"); + + makeCommand.add((clean ? "clean" : "build")); + makeCommand.add("-target", (realTarget.empty() ? "ALL_BUILD" : realTarget)); + makeCommand.add("-configuration", (config.empty() ? "Debug" : config)); if (jobs != cmake::NO_BUILD_PARALLEL_LEVEL) { - makeCommand.emplace_back("-jobs"); + makeCommand.add("-jobs"); if (jobs != cmake::DEFAULT_BUILD_PARALLEL_LEVEL) { - makeCommand.emplace_back(std::to_string(jobs)); + makeCommand.add(std::to_string(jobs)); } } - makeCommand.insert(makeCommand.end(), makeOptions.begin(), - makeOptions.end()); + if (this->XcodeVersion >= 70) { + makeCommand.add("-hideShellScriptEnvironment"); + } + makeCommand.add(makeOptions.begin(), makeOptions.end()); } ///! Create a local generator appropriate to this Global Generator @@ -3581,7 +3576,7 @@ std::string cmGlobalXCodeGenerator::RelativeToSource(const char* p) std::string cmGlobalXCodeGenerator::RelativeToBinary(const char* p) { - return this->CurrentLocalGenerator->ConvertToRelativePath( + return this->CurrentLocalGenerator->MaybeConvertToRelativePath( cmSystemTools::JoinPath(this->ProjectOutputDirectoryComponents), p); } diff --git a/Source/cmGlobalXCodeGenerator.h b/Source/cmGlobalXCodeGenerator.h index 9b0d4fe..92ff258 100644 --- a/Source/cmGlobalXCodeGenerator.h +++ b/Source/cmGlobalXCodeGenerator.h @@ -66,7 +66,7 @@ public: * Try running cmake and building a file. This is used for dynalically * loaded commands, not as part of the usual build process. */ - void GenerateBuildCommand(std::vector<std::string>& makeCommand, + void GenerateBuildCommand(GeneratedMakeCommand& makeCommand, const std::string& makeProgram, const std::string& projectName, const std::string& projectDir, diff --git a/Source/cmIfCommand.h b/Source/cmIfCommand.h index e3d30dd..d34ed02 100644 --- a/Source/cmIfCommand.h +++ b/Source/cmIfCommand.h @@ -19,13 +19,6 @@ class cmMakefile; class cmIfFunctionBlocker : public cmFunctionBlocker { public: - cmIfFunctionBlocker() - { - this->HasRun = false; - this->ElseSeen = false; - this->ScopeDepth = 0; - } - ~cmIfFunctionBlocker() override {} bool IsFunctionBlocked(const cmListFileFunction& lff, cmMakefile& mf, cmExecutionStatus&) override; bool ShouldRemove(const cmListFileFunction& lff, cmMakefile& mf) override; @@ -33,9 +26,9 @@ public: std::vector<cmListFileArgument> Args; std::vector<cmListFileFunction> Functions; bool IsBlocking; - bool HasRun; - bool ElseSeen; - unsigned int ScopeDepth; + bool HasRun = false; + bool ElseSeen = false; + unsigned int ScopeDepth = 0; }; /// Starts an if block diff --git a/Source/cmInstallCommand.cxx b/Source/cmInstallCommand.cxx index c6f4064..8ef6441 100644 --- a/Source/cmInstallCommand.cxx +++ b/Source/cmInstallCommand.cxx @@ -712,7 +712,7 @@ bool cmInstallCommand::HandleTargetsMode(std::vector<std::string> const& args) std::ostringstream e; e << "INSTALL TARGETS - target " << target.GetName() << " has " << "RESOURCE files but no RESOURCE DESTINATION."; - cmSystemTools::Message(e.str().c_str(), "Warning"); + cmSystemTools::Message(e.str(), "Warning"); } } } diff --git a/Source/cmInstallCommandArguments.cxx b/Source/cmInstallCommandArguments.cxx index 4f872f4..155f055 100644 --- a/Source/cmInstallCommandArguments.cxx +++ b/Source/cmInstallCommandArguments.cxx @@ -206,9 +206,7 @@ bool cmInstallCommandArguments::CheckPermissions( return false; } -cmInstallCommandIncludesArgument::cmInstallCommandIncludesArgument() -{ -} +cmInstallCommandIncludesArgument::cmInstallCommandIncludesArgument() = default; const std::vector<std::string>& cmInstallCommandIncludesArgument::GetIncludeDirs() const diff --git a/Source/cmInstallDirectoryGenerator.cxx b/Source/cmInstallDirectoryGenerator.cxx index c9b50a3..a88c7af 100644 --- a/Source/cmInstallDirectoryGenerator.cxx +++ b/Source/cmInstallDirectoryGenerator.cxx @@ -39,9 +39,7 @@ cmInstallDirectoryGenerator::cmInstallDirectoryGenerator( } } -cmInstallDirectoryGenerator::~cmInstallDirectoryGenerator() -{ -} +cmInstallDirectoryGenerator::~cmInstallDirectoryGenerator() = default; void cmInstallDirectoryGenerator::Compute(cmLocalGenerator* lg) { diff --git a/Source/cmInstallFilesGenerator.cxx b/Source/cmInstallFilesGenerator.cxx index 68e3f86..07094cb 100644 --- a/Source/cmInstallFilesGenerator.cxx +++ b/Source/cmInstallFilesGenerator.cxx @@ -38,9 +38,7 @@ cmInstallFilesGenerator::cmInstallFilesGenerator( } } -cmInstallFilesGenerator::~cmInstallFilesGenerator() -{ -} +cmInstallFilesGenerator::~cmInstallFilesGenerator() = default; void cmInstallFilesGenerator::Compute(cmLocalGenerator* lg) { diff --git a/Source/cmInstallGenerator.cxx b/Source/cmInstallGenerator.cxx index 2b23658..d139190 100644 --- a/Source/cmInstallGenerator.cxx +++ b/Source/cmInstallGenerator.cxx @@ -18,9 +18,7 @@ cmInstallGenerator::cmInstallGenerator( { } -cmInstallGenerator::~cmInstallGenerator() -{ -} +cmInstallGenerator::~cmInstallGenerator() = default; bool cmInstallGenerator::HaveInstall() { diff --git a/Source/cmInstallScriptGenerator.cxx b/Source/cmInstallScriptGenerator.cxx index 12e87c7..a513958 100644 --- a/Source/cmInstallScriptGenerator.cxx +++ b/Source/cmInstallScriptGenerator.cxx @@ -27,9 +27,7 @@ cmInstallScriptGenerator::cmInstallScriptGenerator(const char* script, } } -cmInstallScriptGenerator::~cmInstallScriptGenerator() -{ -} +cmInstallScriptGenerator::~cmInstallScriptGenerator() = default; void cmInstallScriptGenerator::Compute(cmLocalGenerator* lg) { diff --git a/Source/cmInstallSubdirectoryGenerator.cxx b/Source/cmInstallSubdirectoryGenerator.cxx index ca9f134..ad7121f 100644 --- a/Source/cmInstallSubdirectoryGenerator.cxx +++ b/Source/cmInstallSubdirectoryGenerator.cxx @@ -20,9 +20,7 @@ cmInstallSubdirectoryGenerator::cmInstallSubdirectoryGenerator( { } -cmInstallSubdirectoryGenerator::~cmInstallSubdirectoryGenerator() -{ -} +cmInstallSubdirectoryGenerator::~cmInstallSubdirectoryGenerator() = default; bool cmInstallSubdirectoryGenerator::HaveInstall() { diff --git a/Source/cmInstallTargetGenerator.cxx b/Source/cmInstallTargetGenerator.cxx index d1d4316..10df70b 100644 --- a/Source/cmInstallTargetGenerator.cxx +++ b/Source/cmInstallTargetGenerator.cxx @@ -38,9 +38,7 @@ cmInstallTargetGenerator::cmInstallTargetGenerator( this->NamelinkMode = NamelinkModeNone; } -cmInstallTargetGenerator::~cmInstallTargetGenerator() -{ -} +cmInstallTargetGenerator::~cmInstallTargetGenerator() = default; void cmInstallTargetGenerator::GenerateScript(std::ostream& os) { @@ -51,7 +49,7 @@ void cmInstallTargetGenerator::GenerateScript(std::ostream& os) << "\" has EXCLUDE_FROM_ALL set and will not be built by default " << "but an install rule has been provided for it. CMake does " << "not define behavior for this case."; - cmSystemTools::Message(msg.str().c_str(), "Warning"); + cmSystemTools::Message(msg.str(), "Warning"); } // Perform the main install script generation. diff --git a/Source/cmInstalledFile.cxx b/Source/cmInstalledFile.cxx index 9f61e5b..537b4ec 100644 --- a/Source/cmInstalledFile.cxx +++ b/Source/cmInstalledFile.cxx @@ -9,18 +9,14 @@ #include <utility> -cmInstalledFile::cmInstalledFile() -{ -} +cmInstalledFile::cmInstalledFile() = default; cmInstalledFile::~cmInstalledFile() { delete NameExpression; } -cmInstalledFile::Property::Property() -{ -} +cmInstalledFile::Property::Property() = default; cmInstalledFile::Property::~Property() { diff --git a/Source/cmLinkItem.cxx b/Source/cmLinkItem.cxx index b035c8c..9b03ad0 100644 --- a/Source/cmLinkItem.cxx +++ b/Source/cmLinkItem.cxx @@ -6,9 +6,7 @@ #include <utility> // IWYU pragma: keep -cmLinkItem::cmLinkItem() -{ -} +cmLinkItem::cmLinkItem() = default; cmLinkItem::cmLinkItem(std::string n, cmListFileBacktrace bt) : String(std::move(n)) diff --git a/Source/cmLinkItem.h b/Source/cmLinkItem.h index d2459db..5b635b5 100644 --- a/Source/cmLinkItem.h +++ b/Source/cmLinkItem.h @@ -77,13 +77,10 @@ struct cmLinkInterface : public cmLinkInterfaceLibraries std::vector<cmLinkItem> WrongConfigLibraries; bool ImplementationIsInterface = false; - - cmLinkInterface() {} }; struct cmOptionalLinkInterface : public cmLinkInterface { - cmOptionalLinkInterface() {} bool LibrariesDone = false; bool AllDone = false; bool Exists = false; @@ -105,7 +102,6 @@ struct cmLinkImplementation : public cmLinkImplementationLibraries // Cache link implementation computation from each configuration. struct cmOptionalLinkImplementation : public cmLinkImplementation { - cmOptionalLinkImplementation() {} bool LibrariesDone = false; bool LanguagesDone = false; bool HadHeadSensitiveCondition = false; diff --git a/Source/cmLinkLineComputer.cxx b/Source/cmLinkLineComputer.cxx index 6643990..2a8bee6 100644 --- a/Source/cmLinkLineComputer.cxx +++ b/Source/cmLinkLineComputer.cxx @@ -23,9 +23,7 @@ cmLinkLineComputer::cmLinkLineComputer(cmOutputConverter* outputConverter, { } -cmLinkLineComputer::~cmLinkLineComputer() -{ -} +cmLinkLineComputer::~cmLinkLineComputer() = default; void cmLinkLineComputer::SetUseWatcomQuote(bool useWatcomQuote) { diff --git a/Source/cmLinkLineDeviceComputer.cxx b/Source/cmLinkLineDeviceComputer.cxx index a93ec12..a403dc9 100644 --- a/Source/cmLinkLineDeviceComputer.cxx +++ b/Source/cmLinkLineDeviceComputer.cxx @@ -21,9 +21,7 @@ cmLinkLineDeviceComputer::cmLinkLineDeviceComputer( { } -cmLinkLineDeviceComputer::~cmLinkLineDeviceComputer() -{ -} +cmLinkLineDeviceComputer::~cmLinkLineDeviceComputer() = default; static bool cmLinkItemValidForDevice(std::string const& item) { diff --git a/Source/cmListCommand.cxx b/Source/cmListCommand.cxx index b24c5ba..297babf 100644 --- a/Source/cmListCommand.cxx +++ b/Source/cmListCommand.cxx @@ -426,7 +426,7 @@ public: class TransformSelector { public: - virtual ~TransformSelector() {} + virtual ~TransformSelector() = default; std::string Tag; @@ -580,7 +580,7 @@ private: class TransformAction { public: - virtual ~TransformAction() {} + virtual ~TransformAction() = default; virtual std::string Transform(const std::string& input) = 0; }; diff --git a/Source/cmListFileCache.cxx b/Source/cmListFileCache.cxx index cc2c09f..f855119 100644 --- a/Source/cmListFileCache.cxx +++ b/Source/cmListFileCache.cxx @@ -5,8 +5,8 @@ #include "cmListFileLexer.h" #include "cmMessageType.h" #include "cmMessenger.h" -#include "cmOutputConverter.h" #include "cmState.h" +#include "cmStateDirectory.h" #include "cmSystemTools.h" #include <assert.h> @@ -390,9 +390,8 @@ void cmListFileBacktrace::PrintTitle(std::ostream& out) const } cmListFileContext lfc = this->TopEntry->Context; cmStateSnapshot bottom = this->GetBottom(); - cmOutputConverter converter(bottom); if (!bottom.GetState()->GetIsInTryCompile()) { - lfc.FilePath = converter.ConvertToRelativePath( + lfc.FilePath = bottom.GetDirectory().ConvertToRelPathIfNotContained( bottom.GetState()->GetSourceDirectory(), lfc.FilePath); } out << (lfc.Line ? " at " : " in ") << lfc; @@ -409,7 +408,6 @@ void cmListFileBacktrace::PrintCallStack(std::ostream& out) const bool first = true; cmStateSnapshot bottom = this->GetBottom(); - cmOutputConverter converter(bottom); for (Entry const* cur = this->TopEntry->Parent.get(); !cur->IsBottom(); cur = cur->Parent.get()) { if (cur->Context.Name.empty()) { @@ -423,7 +421,7 @@ void cmListFileBacktrace::PrintCallStack(std::ostream& out) const } cmListFileContext lfc = cur->Context; if (!bottom.GetState()->GetIsInTryCompile()) { - lfc.FilePath = converter.ConvertToRelativePath( + lfc.FilePath = bottom.GetDirectory().ConvertToRelPathIfNotContained( bottom.GetState()->GetSourceDirectory(), lfc.FilePath); } out << " " << lfc << "\n"; diff --git a/Source/cmListFileCache.h b/Source/cmListFileCache.h index 529c389..9457415 100644 --- a/Source/cmListFileCache.h +++ b/Source/cmListFileCache.h @@ -29,12 +29,12 @@ struct cmCommandContext { std::string Lower; std::string Original; - cmCommandName() {} + cmCommandName() = default; cmCommandName(std::string const& name) { *this = name; } cmCommandName& operator=(std::string const& name); } Name; long Line = 0; - cmCommandContext() {} + cmCommandContext() = default; cmCommandContext(const char* name, int line) : Name(name) , Line(line) @@ -50,7 +50,7 @@ struct cmListFileArgument Quoted, Bracket }; - cmListFileArgument() {} + cmListFileArgument() = default; cmListFileArgument(std::string v, Delimiter d, long line) : Value(std::move(v)) , Delim(d) @@ -73,7 +73,6 @@ public: std::string Name; std::string FilePath; long Line = 0; - cmListFileContext() {} static cmListFileContext FromCommandContext(cmCommandContext const& lfcc, std::string const& fileName) @@ -110,15 +109,6 @@ public: // indicated by the given valid snapshot. cmListFileBacktrace(cmStateSnapshot const& snapshot); - // Backtraces may be copied, moved, and assigned as values. - cmListFileBacktrace(cmListFileBacktrace const&) = default; - cmListFileBacktrace(cmListFileBacktrace&&) // NOLINT(clang-tidy) - noexcept = default; - cmListFileBacktrace& operator=(cmListFileBacktrace const&) = default; - cmListFileBacktrace& operator=(cmListFileBacktrace&&) // NOLINT(clang-tidy) - noexcept = default; - ~cmListFileBacktrace() = default; - cmStateSnapshot GetBottom() const; // Get a backtrace with the given file scope added to the top. diff --git a/Source/cmLocalCommonGenerator.cxx b/Source/cmLocalCommonGenerator.cxx index c6d2c58..75ad2a6 100644 --- a/Source/cmLocalCommonGenerator.cxx +++ b/Source/cmLocalCommonGenerator.cxx @@ -26,9 +26,7 @@ cmLocalCommonGenerator::cmLocalCommonGenerator(cmGlobalGenerator* gg, } } -cmLocalCommonGenerator::~cmLocalCommonGenerator() -{ -} +cmLocalCommonGenerator::~cmLocalCommonGenerator() = default; std::string cmLocalCommonGenerator::GetTargetFortranFlags( cmGeneratorTarget const* target, std::string const& config) @@ -46,7 +44,7 @@ std::string cmLocalCommonGenerator::GetTargetFortranFlags( target->GetFortranModuleDirectory(this->WorkingDirectory); if (!mod_dir.empty()) { mod_dir = this->ConvertToOutputFormat( - this->ConvertToRelativePath(this->WorkingDirectory, mod_dir), + this->MaybeConvertToRelativePath(this->WorkingDirectory, mod_dir), cmOutputConverter::SHELL); } else { mod_dir = diff --git a/Source/cmLocalGenerator.cxx b/Source/cmLocalGenerator.cxx index 1122924..252aa4c 100644 --- a/Source/cmLocalGenerator.cxx +++ b/Source/cmLocalGenerator.cxx @@ -316,7 +316,7 @@ void cmLocalGenerator::GenerateTestFiles() for (cmStateSnapshot const& i : children) { // TODO: Use add_subdirectory instead? std::string outP = i.GetDirectory().GetCurrentBinary(); - outP = this->ConvertToRelativePath(parentBinDir, outP); + outP = this->MaybeConvertToRelativePath(parentBinDir, outP); outP = cmOutputConverter::EscapeForCMake(outP); fout << "subdirs(" << outP << ")" << std::endl; } @@ -2321,7 +2321,7 @@ std::string cmLocalGenerator::ConstructComment( std::string currentBinaryDir = this->GetCurrentBinaryDirectory(); for (std::string const& o : ccg.GetOutputs()) { comment += sep; - comment += this->ConvertToRelativePath(currentBinaryDir, o); + comment += this->MaybeConvertToRelativePath(currentBinaryDir, o); sep = ", "; } return comment; @@ -2578,15 +2578,15 @@ std::string cmLocalGenerator::GetObjectFileNameWithoutTarget( std::string const& fullPath = source.GetFullPath(); // Try referencing the source relative to the source tree. - std::string relFromSource = - this->ConvertToRelativePath(this->GetCurrentSourceDirectory(), fullPath); + std::string relFromSource = this->MaybeConvertToRelativePath( + this->GetCurrentSourceDirectory(), fullPath); assert(!relFromSource.empty()); bool relSource = !cmSystemTools::FileIsFullPath(relFromSource); bool subSource = relSource && relFromSource[0] != '.'; // Try referencing the source relative to the binary tree. - std::string relFromBinary = - this->ConvertToRelativePath(this->GetCurrentBinaryDirectory(), fullPath); + std::string relFromBinary = this->MaybeConvertToRelativePath( + this->GetCurrentBinaryDirectory(), fullPath); assert(!relFromBinary.empty()); bool relBinary = !cmSystemTools::FileIsFullPath(relFromBinary); bool subBinary = relBinary && relFromBinary[0] != '.'; @@ -2685,6 +2685,13 @@ std::string const& cmLocalGenerator::GetCurrentSourceDirectory() const return this->StateSnapshot.GetDirectory().GetCurrentSource(); } +std::string cmLocalGenerator::MaybeConvertToRelativePath( + std::string const& local_path, std::string const& remote_path) const +{ + return this->StateSnapshot.GetDirectory().ConvertToRelPathIfNotContained( + local_path, remote_path); +} + std::string cmLocalGenerator::GetTargetDirectory( const cmGeneratorTarget* /*unused*/) const { @@ -2771,7 +2778,7 @@ bool cmLocalGenerator::CheckDefinition(std::string const& define) const << "CMake is dropping a preprocessor definition: " << define << "\n" << "Consider defining the macro in a (configured) header file.\n"; /* clang-format on */ - cmSystemTools::Message(e.str().c_str()); + cmSystemTools::Message(e.str()); return false; } } @@ -2786,7 +2793,7 @@ bool cmLocalGenerator::CheckDefinition(std::string const& define) const << "CMake is dropping a preprocessor definition: " << define << "\n" << "Consider defining the macro in a (configured) header file.\n"; /* clang-format on */ - cmSystemTools::Message(e.str().c_str()); + cmSystemTools::Message(e.str()); return false; } diff --git a/Source/cmLocalGenerator.h b/Source/cmLocalGenerator.h index 7cc7e37..f9839f6 100644 --- a/Source/cmLocalGenerator.h +++ b/Source/cmLocalGenerator.h @@ -326,6 +326,16 @@ public: std::string const& GetCurrentSourceDirectory() const; /** + * Convert the given remote path to a relative path with respect to + * the given local path. Both paths must use forward slashes and not + * already be escaped or quoted. + * The conversion is skipped if the paths are not both in the source + * or both in the binary tree. + */ + std::string MaybeConvertToRelativePath(std::string const& local_path, + std::string const& remote_path) const; + + /** * Generate a macOS application bundle Info.plist file. */ void GenerateAppleInfoPList(cmGeneratorTarget* target, diff --git a/Source/cmLocalNinjaGenerator.cxx b/Source/cmLocalNinjaGenerator.cxx index 4b9837c..c0afc25 100644 --- a/Source/cmLocalNinjaGenerator.cxx +++ b/Source/cmLocalNinjaGenerator.cxx @@ -46,15 +46,13 @@ cmLocalNinjaGenerator::CreateRulePlaceholderExpander() const return ret; } -cmLocalNinjaGenerator::~cmLocalNinjaGenerator() -{ -} +cmLocalNinjaGenerator::~cmLocalNinjaGenerator() = default; void cmLocalNinjaGenerator::Generate() { // Compute the path to use when referencing the current output // directory from the top output directory. - this->HomeRelativeOutputPath = this->ConvertToRelativePath( + this->HomeRelativeOutputPath = this->MaybeConvertToRelativePath( this->GetBinaryDirectory(), this->GetCurrentBinaryDirectory()); if (this->HomeRelativeOutputPath == ".") { this->HomeRelativeOutputPath.clear(); @@ -139,7 +137,8 @@ std::string cmLocalNinjaGenerator::ConvertToIncludeReference( format); } return this->ConvertToOutputFormat( - this->ConvertToRelativePath(this->GetBinaryDirectory(), path), format); + this->MaybeConvertToRelativePath(this->GetBinaryDirectory(), path), + format); } // Private methods. @@ -582,8 +581,8 @@ std::string cmLocalNinjaGenerator::MakeCustomLauncher( if (!outputs.empty()) { output = outputs[0]; if (ccg.GetWorkingDirectory().empty()) { - output = - this->ConvertToRelativePath(this->GetCurrentBinaryDirectory(), output); + output = this->MaybeConvertToRelativePath( + this->GetCurrentBinaryDirectory(), output); } output = this->ConvertToOutputFormat(output, cmOutputConverter::SHELL); } diff --git a/Source/cmLocalUnixMakefileGenerator3.cxx b/Source/cmLocalUnixMakefileGenerator3.cxx index 7cb98b9..d6f71d3 100644 --- a/Source/cmLocalUnixMakefileGenerator3.cxx +++ b/Source/cmLocalUnixMakefileGenerator3.cxx @@ -98,9 +98,7 @@ cmLocalUnixMakefileGenerator3::cmLocalUnixMakefileGenerator3( this->BorlandMakeCurlyHack = false; } -cmLocalUnixMakefileGenerator3::~cmLocalUnixMakefileGenerator3() -{ -} +cmLocalUnixMakefileGenerator3::~cmLocalUnixMakefileGenerator3() = default; void cmLocalUnixMakefileGenerator3::Generate() { @@ -1278,8 +1276,7 @@ bool cmLocalUnixMakefileGenerator3::UpdateDependencies( this->GlobalGenerator->GetCMakeInstance()->GetFileComparison(); { int result; - if (!ftc->FileTimeCompare(internalDependFile.c_str(), tgtInfo.c_str(), - &result) || + if (!ftc->FileTimeCompare(internalDependFile, tgtInfo, &result) || result < 0) { if (verbose) { std::ostringstream msg; @@ -1299,8 +1296,7 @@ bool cmLocalUnixMakefileGenerator3::UpdateDependencies( dirInfoFile += "/CMakeDirectoryInformation.cmake"; { int result; - if (!ftc->FileTimeCompare(internalDependFile.c_str(), dirInfoFile.c_str(), - &result) || + if (!ftc->FileTimeCompare(internalDependFile, dirInfoFile, &result) || result < 0) { if (verbose) { std::ostringstream msg; @@ -2081,12 +2077,3 @@ void cmLocalUnixMakefileGenerator3::CreateCDCommand( [&prefix](std::string const& s) { return prefix + s; }); } } - -std::string cmLocalUnixMakefileGenerator3::MaybeConvertToRelativePath( - std::string const& base, std::string const& path) -{ - if (!this->GetStateSnapshot().GetDirectory().ContainsBoth(base, path)) { - return path; - } - return cmSystemTools::ForceToRelativePath(base, path); -} diff --git a/Source/cmLocalUnixMakefileGenerator3.h b/Source/cmLocalUnixMakefileGenerator3.h index 1e1c59e..ced2dbd 100644 --- a/Source/cmLocalUnixMakefileGenerator3.h +++ b/Source/cmLocalUnixMakefileGenerator3.h @@ -184,9 +184,6 @@ public: // Eclipse generator. void GetIndividualFileTargets(std::vector<std::string>& targets); - std::string MaybeConvertToRelativePath(std::string const& base, - std::string const& path); - protected: void WriteLocalMakefile(); @@ -255,7 +252,7 @@ private: { cmGeneratorTarget* Target = nullptr; std::string Language; - LocalObjectEntry() {} + LocalObjectEntry() = default; LocalObjectEntry(cmGeneratorTarget* t, std::string lang) : Target(t) , Language(std::move(lang)) @@ -267,7 +264,6 @@ private: bool HasSourceExtension = false; bool HasPreprocessRule = false; bool HasAssembleRule = false; - LocalObjectInfo() {} }; void GetLocalObjectFiles( std::map<std::string, LocalObjectInfo>& localObjectFiles); diff --git a/Source/cmLocalVisualStudio7Generator.cxx b/Source/cmLocalVisualStudio7Generator.cxx index 9ea8c2e..7019552 100644 --- a/Source/cmLocalVisualStudio7Generator.cxx +++ b/Source/cmLocalVisualStudio7Generator.cxx @@ -803,8 +803,8 @@ void cmLocalVisualStudio7Generator::WriteConfiguration( target->GetProperty("Fortran_MODULE_DIRECTORY"); std::string modDir; if (target_mod_dir) { - modDir = this->ConvertToRelativePath(this->GetCurrentBinaryDirectory(), - target_mod_dir); + modDir = this->MaybeConvertToRelativePath( + this->GetCurrentBinaryDirectory(), target_mod_dir); } else { modDir = "."; } @@ -1306,7 +1306,7 @@ void cmLocalVisualStudio7GeneratorInternals::OutputLibraries( for (ItemVector::const_iterator l = libs.begin(); l != libs.end(); ++l) { if (l->IsPath) { std::string rel = - lg->ConvertToRelativePath(currentBinDir, l->Value.c_str()); + lg->MaybeConvertToRelativePath(currentBinDir, l->Value.c_str()); fout << lg->ConvertToXMLOutputPath(rel.c_str()) << " "; } else if (!l->Target || l->Target->GetType() != cmStateEnums::INTERFACE_LIBRARY) { @@ -1332,7 +1332,7 @@ void cmLocalVisualStudio7GeneratorInternals::OutputObjects( i != objs.end(); ++i) { if (!(*i)->GetObjectLibrary().empty()) { std::string const& objFile = (*i)->GetFullPath(); - std::string rel = lg->ConvertToRelativePath(currentBinDir, objFile); + std::string rel = lg->MaybeConvertToRelativePath(currentBinDir, objFile); fout << sep << lg->ConvertToXMLOutputPath(rel.c_str()); sep = " "; } @@ -1358,7 +1358,7 @@ void cmLocalVisualStudio7Generator::OutputLibraryDirectories( // Switch to a relative path specification if it is shorter. if (cmSystemTools::FileIsFullPath(dir.c_str())) { std::string rel = - this->ConvertToRelativePath(currentBinDir, dir.c_str()); + this->MaybeConvertToRelativePath(currentBinDir, dir.c_str()); if (rel.size() < dir.size()) { dir = rel; } diff --git a/Source/cmLocalVisualStudioGenerator.cxx b/Source/cmLocalVisualStudioGenerator.cxx index 2237da7..660729c 100644 --- a/Source/cmLocalVisualStudioGenerator.cxx +++ b/Source/cmLocalVisualStudioGenerator.cxx @@ -210,9 +210,10 @@ std::string cmLocalVisualStudioGenerator::ConstructScript( } if (workingDirectory.empty()) { - script += this->ConvertToOutputFormat( - this->ConvertToRelativePath(this->GetCurrentBinaryDirectory(), cmd), - cmOutputConverter::SHELL); + script += + this->ConvertToOutputFormat(this->MaybeConvertToRelativePath( + this->GetCurrentBinaryDirectory(), cmd), + cmOutputConverter::SHELL); } else { script += this->ConvertToOutputFormat(cmd.c_str(), SHELL); } diff --git a/Source/cmLocalXCodeGenerator.cxx b/Source/cmLocalXCodeGenerator.cxx index 92c958d..9c36627 100644 --- a/Source/cmLocalXCodeGenerator.cxx +++ b/Source/cmLocalXCodeGenerator.cxx @@ -19,9 +19,7 @@ cmLocalXCodeGenerator::cmLocalXCodeGenerator(cmGlobalGenerator* gg, this->EmitUniversalBinaryFlags = false; } -cmLocalXCodeGenerator::~cmLocalXCodeGenerator() -{ -} +cmLocalXCodeGenerator::~cmLocalXCodeGenerator() = default; std::string cmLocalXCodeGenerator::GetTargetDirectory( cmGeneratorTarget const*) const diff --git a/Source/cmMachO.cxx b/Source/cmMachO.cxx index 7368812..d4af1e0 100644 --- a/Source/cmMachO.cxx +++ b/Source/cmMachO.cxx @@ -91,7 +91,7 @@ public: : Swap(_swap) { } - virtual ~cmMachOHeaderAndLoadCommands() {} + virtual ~cmMachOHeaderAndLoadCommands() = default; virtual bool read_mach_o(cmsys::ifstream& fin) = 0; diff --git a/Source/cmMacroCommand.cxx b/Source/cmMacroCommand.cxx index 411c0c3..7279d5f 100644 --- a/Source/cmMacroCommand.cxx +++ b/Source/cmMacroCommand.cxx @@ -17,11 +17,6 @@ class cmMacroHelperCommand : public cmCommand { public: - cmMacroHelperCommand() {} - - ///! clean up any memory allocated by the macro - ~cmMacroHelperCommand() override {} - /** * This is a virtual constructor for the command. */ diff --git a/Source/cmMacroCommand.h b/Source/cmMacroCommand.h index d967388..b54ed66 100644 --- a/Source/cmMacroCommand.h +++ b/Source/cmMacroCommand.h @@ -18,15 +18,13 @@ class cmMakefile; class cmMacroFunctionBlocker : public cmFunctionBlocker { public: - cmMacroFunctionBlocker() { this->Depth = 0; } - ~cmMacroFunctionBlocker() override {} bool IsFunctionBlocked(const cmListFileFunction&, cmMakefile& mf, cmExecutionStatus&) override; bool ShouldRemove(const cmListFileFunction&, cmMakefile& mf) override; std::vector<std::string> Args; std::vector<cmListFileFunction> Functions; - int Depth; + int Depth = 0; }; /// Starts macro() ... endmacro() block diff --git a/Source/cmMakefile.cxx b/Source/cmMakefile.cxx index b59a733..ab139c0 100644 --- a/Source/cmMakefile.cxx +++ b/Source/cmMakefile.cxx @@ -322,7 +322,7 @@ void cmMakefile::PrintCommandTrace(const cmListFileFunction& lff) const msg << " "; } msg << ")"; - cmSystemTools::Message(msg.str().c_str()); + cmSystemTools::Message(msg.str()); } // Helper class to make sure the call stack is valid. @@ -1622,7 +1622,7 @@ void cmMakefile::ConfigureSubDirectory(cmMakefile* mf) if (this->GetCMakeInstance()->GetDebugOutput()) { std::string msg = " Entering "; msg += currentStart; - cmSystemTools::Message(msg.c_str()); + cmSystemTools::Message(msg); } std::string const currentStartFile = currentStart + "/CMakeLists.txt"; @@ -1665,7 +1665,7 @@ void cmMakefile::ConfigureSubDirectory(cmMakefile* mf) if (this->GetCMakeInstance()->GetDebugOutput()) { std::string msg = " Returning to "; msg += this->GetCurrentSourceDirectory(); - cmSystemTools::Message(msg.c_str()); + cmSystemTools::Message(msg); } } @@ -2738,7 +2738,6 @@ typedef enum } t_domain; struct t_lookup { - t_lookup() {} t_domain domain = NORMAL; size_t loc = 0; }; @@ -3750,8 +3749,7 @@ int cmMakefile::ConfigureFile(const char* infile, const char* outfile, } if (copyonly) { - if (!cmSystemTools::CopyFileIfDifferent(sinfile.c_str(), - soutfile.c_str())) { + if (!cmSystemTools::CopyFileIfDifferent(sinfile, soutfile)) { return 0; } } else { @@ -3802,8 +3800,7 @@ int cmMakefile::ConfigureFile(const char* infile, const char* outfile, // close the files before attempting to copy fin.close(); fout.close(); - if (!cmSystemTools::CopyFileIfDifferent(tempOutputFile.c_str(), - soutfile.c_str())) { + if (!cmSystemTools::CopyFileIfDifferent(tempOutputFile, soutfile)) { res = 0; } else { cmSystemTools::SetPermissions(soutfile, perm); diff --git a/Source/cmMakefileTargetGenerator.cxx b/Source/cmMakefileTargetGenerator.cxx index 0fad233..af34169 100644 --- a/Source/cmMakefileTargetGenerator.cxx +++ b/Source/cmMakefileTargetGenerator.cxx @@ -403,7 +403,7 @@ void cmMakefileTargetGenerator::WriteObjectRuleFiles( err << "Warning: Source file \"" << source.GetFullPath() << "\" is listed multiple times for target \"" << this->GeneratorTarget->GetName() << "\"."; - cmSystemTools::Message(err.str().c_str(), "Warning"); + cmSystemTools::Message(err.str(), "Warning"); return; } diff --git a/Source/cmMessageCommand.cxx b/Source/cmMessageCommand.cxx index 4c26c66..95f5fcb 100644 --- a/Source/cmMessageCommand.cxx +++ b/Source/cmMessageCommand.cxx @@ -70,7 +70,7 @@ bool cmMessageCommand::InitialPass(std::vector<std::string> const& args, if (status) { this->Makefile->DisplayStatus(message.c_str(), -1); } else { - cmSystemTools::Message(message.c_str()); + cmSystemTools::Message(message); } } if (fatal) { diff --git a/Source/cmMessenger.cxx b/Source/cmMessenger.cxx index 3d788f6..1d790e2 100644 --- a/Source/cmMessenger.cxx +++ b/Source/cmMessenger.cxx @@ -124,9 +124,9 @@ void displayMessage(MessageType t, std::ostringstream& msg) if (t == MessageType::FATAL_ERROR || t == MessageType::INTERNAL_ERROR || t == MessageType::DEPRECATION_ERROR || t == MessageType::AUTHOR_ERROR) { cmSystemTools::SetErrorOccured(); - cmSystemTools::Message(msg.str().c_str(), "Error"); + cmSystemTools::Message(msg.str(), "Error"); } else { - cmSystemTools::Message(msg.str().c_str(), "Warning"); + cmSystemTools::Message(msg.str(), "Warning"); } } diff --git a/Source/cmNewLineStyle.cxx b/Source/cmNewLineStyle.cxx index 12c18ee..3f6523e 100644 --- a/Source/cmNewLineStyle.cxx +++ b/Source/cmNewLineStyle.cxx @@ -4,9 +4,7 @@ #include <stddef.h> -cmNewLineStyle::cmNewLineStyle() -{ -} +cmNewLineStyle::cmNewLineStyle() = default; bool cmNewLineStyle::IsValid() const { diff --git a/Source/cmNinjaUtilityTargetGenerator.cxx b/Source/cmNinjaUtilityTargetGenerator.cxx index 5057dc4..95fcf66 100644 --- a/Source/cmNinjaUtilityTargetGenerator.cxx +++ b/Source/cmNinjaUtilityTargetGenerator.cxx @@ -26,9 +26,7 @@ cmNinjaUtilityTargetGenerator::cmNinjaUtilityTargetGenerator( { } -cmNinjaUtilityTargetGenerator::~cmNinjaUtilityTargetGenerator() -{ -} +cmNinjaUtilityTargetGenerator::~cmNinjaUtilityTargetGenerator() = default; void cmNinjaUtilityTargetGenerator::Generate() { diff --git a/Source/cmOSXBundleGenerator.h b/Source/cmOSXBundleGenerator.h index ba5bee0..3dea6cc 100644 --- a/Source/cmOSXBundleGenerator.h +++ b/Source/cmOSXBundleGenerator.h @@ -31,7 +31,7 @@ public: struct MacOSXContentGeneratorType { - virtual ~MacOSXContentGeneratorType() {} + virtual ~MacOSXContentGeneratorType() = default; virtual void operator()(cmSourceFile const& source, const char* pkgloc) = 0; }; diff --git a/Source/cmOrderDirectories.cxx b/Source/cmOrderDirectories.cxx index 961e2b2..2c28fc0 100644 --- a/Source/cmOrderDirectories.cxx +++ b/Source/cmOrderDirectories.cxx @@ -48,7 +48,7 @@ public: this->FileName = cmSystemTools::GetFilenameName(file); } } - virtual ~cmOrderDirectoriesConstraint() {} + virtual ~cmOrderDirectoriesConstraint() = default; void AddDirectory() { diff --git a/Source/cmOutputConverter.cxx b/Source/cmOutputConverter.cxx index 011c7d8..7d88b08 100644 --- a/Source/cmOutputConverter.cxx +++ b/Source/cmOutputConverter.cxx @@ -10,7 +10,6 @@ #include <vector> #include "cmState.h" -#include "cmStateDirectory.h" #include "cmSystemTools.h" cmOutputConverter::cmOutputConverter(cmStateSnapshot const& snapshot) @@ -72,17 +71,6 @@ std::string cmOutputConverter::ConvertDirectorySeparatorsForShell( return result; } -std::string cmOutputConverter::ConvertToRelativePath( - std::string const& local_path, std::string const& remote_path) const -{ - if (!this->StateSnapshot.GetDirectory().ContainsBoth(local_path, - remote_path)) { - return remote_path; - } - - return cmSystemTools::ForceToRelativePath(local_path, remote_path); -} - static bool cmOutputConverterIsShellOperator(const std::string& str) { static std::set<std::string> shellOperators; diff --git a/Source/cmOutputConverter.h b/Source/cmOutputConverter.h index 5a4f879..6438c7b 100644 --- a/Source/cmOutputConverter.h +++ b/Source/cmOutputConverter.h @@ -91,16 +91,6 @@ public: }; static FortranFormat GetFortranFormat(const char* value); - /** - * Convert the given remote path to a relative path with respect to - * the given local path. Both paths must use forward slashes and not - * already be escaped or quoted. - * The conversion is skipped if the paths are not both in the source - * or both in the binary tree. - */ - std::string ConvertToRelativePath(std::string const& local_path, - std::string const& remote_path) const; - private: cmState* GetState() const; diff --git a/Source/cmOutputRequiredFilesCommand.cxx b/Source/cmOutputRequiredFilesCommand.cxx index ff1e027..46d04a6 100644 --- a/Source/cmOutputRequiredFilesCommand.cxx +++ b/Source/cmOutputRequiredFilesCommand.cxx @@ -28,7 +28,7 @@ public: * Construct with dependency generation marked not done; instance * not placed in cmMakefile's list. */ - cmDependInformation() {} + cmDependInformation() = default; /** * The set of files on which this one depends. diff --git a/Source/cmProcessOutput.cxx b/Source/cmProcessOutput.cxx index e4ca426..e80ea5c 100644 --- a/Source/cmProcessOutput.cxx +++ b/Source/cmProcessOutput.cxx @@ -48,9 +48,7 @@ cmProcessOutput::cmProcessOutput(Encoding encoding, unsigned int maxSize) #endif } -cmProcessOutput::~cmProcessOutput() -{ -} +cmProcessOutput::~cmProcessOutput() = default; bool cmProcessOutput::DecodeText(std::string raw, std::string& decoded, size_t id) diff --git a/Source/cmProcessTools.h b/Source/cmProcessTools.h index da3693d..7616316 100644 --- a/Source/cmProcessTools.h +++ b/Source/cmProcessTools.h @@ -34,7 +34,7 @@ public: return this->Process(data, static_cast<int>(strlen(data))); } - virtual ~OutputParser() {} + virtual ~OutputParser() = default; protected: /** Implement in a subclass to process a chunk of data. It should diff --git a/Source/cmQtAutoGenGlobalInitializer.cxx b/Source/cmQtAutoGenGlobalInitializer.cxx index 431c5bc..95a297c 100644 --- a/Source/cmQtAutoGenGlobalInitializer.cxx +++ b/Source/cmQtAutoGenGlobalInitializer.cxx @@ -129,9 +129,7 @@ cmQtAutoGenGlobalInitializer::cmQtAutoGenGlobalInitializer( } } -cmQtAutoGenGlobalInitializer::~cmQtAutoGenGlobalInitializer() -{ -} +cmQtAutoGenGlobalInitializer::~cmQtAutoGenGlobalInitializer() = default; void cmQtAutoGenGlobalInitializer::GetOrCreateGlobalTarget( cmLocalGenerator* localGen, std::string const& name, diff --git a/Source/cmQtAutoGenInitializer.h b/Source/cmQtAutoGenInitializer.h index eefbaf0..10f0bf3 100644 --- a/Source/cmQtAutoGenInitializer.h +++ b/Source/cmQtAutoGenInitializer.h @@ -26,9 +26,6 @@ public: class Qrc { public: - Qrc() {} - - public: std::string LockFile; std::string QrcFile; std::string QrcName; diff --git a/Source/cmQtAutoGenerator.h b/Source/cmQtAutoGenerator.h index 75143f5..2b9cbc6 100644 --- a/Source/cmQtAutoGenerator.h +++ b/Source/cmQtAutoGenerator.h @@ -206,9 +206,6 @@ public: bool MergedOutput = false; }; - // -- Constructor - ReadOnlyProcessT() = default; - // -- Const accessors const SetupT& Setup() const { return Setup_; } ProcessResultT* Result() const { return Setup_.Result; } diff --git a/Source/cmQtAutoGeneratorMocUic.cxx b/Source/cmQtAutoGeneratorMocUic.cxx index 068f65c..bc496ac 100644 --- a/Source/cmQtAutoGeneratorMocUic.cxx +++ b/Source/cmQtAutoGeneratorMocUic.cxx @@ -1144,9 +1144,7 @@ cmQtAutoGeneratorMocUic::cmQtAutoGeneratorMocUic() UVRequest().init(*UVLoop(), &cmQtAutoGeneratorMocUic::UVPollStage, this); } -cmQtAutoGeneratorMocUic::~cmQtAutoGeneratorMocUic() -{ -} +cmQtAutoGeneratorMocUic::~cmQtAutoGeneratorMocUic() = default; bool cmQtAutoGeneratorMocUic::Init(cmMakefile* makefile) { diff --git a/Source/cmQtAutoGeneratorRcc.cxx b/Source/cmQtAutoGeneratorRcc.cxx index 87c8d18..43ff172 100644 --- a/Source/cmQtAutoGeneratorRcc.cxx +++ b/Source/cmQtAutoGeneratorRcc.cxx @@ -20,9 +20,7 @@ cmQtAutoGeneratorRcc::cmQtAutoGeneratorRcc() UVRequest().init(*UVLoop(), &cmQtAutoGeneratorRcc::UVPollStage, this); } -cmQtAutoGeneratorRcc::~cmQtAutoGeneratorRcc() -{ -} +cmQtAutoGeneratorRcc::~cmQtAutoGeneratorRcc() = default; bool cmQtAutoGeneratorRcc::Init(cmMakefile* makefile) { diff --git a/Source/cmScriptGenerator.cxx b/Source/cmScriptGenerator.cxx index ae0a158..9182b41 100644 --- a/Source/cmScriptGenerator.cxx +++ b/Source/cmScriptGenerator.cxx @@ -16,9 +16,7 @@ cmScriptGenerator::cmScriptGenerator(std::string config_var, { } -cmScriptGenerator::~cmScriptGenerator() -{ -} +cmScriptGenerator::~cmScriptGenerator() = default; void cmScriptGenerator::Generate( std::ostream& os, const std::string& config, diff --git a/Source/cmScriptGenerator.h b/Source/cmScriptGenerator.h index 725cbc6..5792ba8 100644 --- a/Source/cmScriptGenerator.h +++ b/Source/cmScriptGenerator.h @@ -12,7 +12,7 @@ class cmScriptGeneratorIndent { public: - cmScriptGeneratorIndent() {} + cmScriptGeneratorIndent() = default; cmScriptGeneratorIndent(int level) : Level(level) { diff --git a/Source/cmSearchPath.cxx b/Source/cmSearchPath.cxx index 5dd4413..0f51e0e 100644 --- a/Source/cmSearchPath.cxx +++ b/Source/cmSearchPath.cxx @@ -16,9 +16,7 @@ cmSearchPath::cmSearchPath(cmFindCommon* findCmd) { } -cmSearchPath::~cmSearchPath() -{ -} +cmSearchPath::~cmSearchPath() = default; void cmSearchPath::ExtractWithout(const std::set<std::string>& ignore, std::vector<std::string>& outPaths, diff --git a/Source/cmServer.cxx b/Source/cmServer.cxx index f7d3879..e740c05 100644 --- a/Source/cmServer.cxx +++ b/Source/cmServer.cxx @@ -96,11 +96,16 @@ void cmServer::ProcessRequest(cmConnection* connection, return; } - cmSystemTools::SetMessageCallback(reportMessage, - const_cast<cmServerRequest*>(&request)); + cmSystemTools::SetMessageCallback( + [&request](const char* msg, const char* title) { + reportMessage(msg, title, request); + }); + if (this->Protocol) { this->Protocol->CMakeInstance()->SetProgressCallback( - reportProgress, const_cast<cmServerRequest*>(&request)); + [&request](const char* msg, float prog) { + reportProgress(msg, prog, request); + }); this->WriteResponse(connection, this->Protocol->Process(request), debug.get()); } else { @@ -150,28 +155,25 @@ void cmServer::PrintHello(cmConnection* connection) const this->WriteJsonObject(connection, hello, nullptr); } -void cmServer::reportProgress(const char* msg, float progress, void* data) +void cmServer::reportProgress(const char* msg, float progress, + const cmServerRequest& request) { - const cmServerRequest* request = static_cast<const cmServerRequest*>(data); - assert(request); if (progress < 0.0f || progress > 1.0f) { - request->ReportMessage(msg, ""); + request.ReportMessage(msg, ""); } else { - request->ReportProgress(0, static_cast<int>(progress * 1000), 1000, msg); + request.ReportProgress(0, static_cast<int>(progress * 1000), 1000, msg); } } void cmServer::reportMessage(const char* msg, const char* title, - bool& /* cancel */, void* data) + const cmServerRequest& request) { - const cmServerRequest* request = static_cast<const cmServerRequest*>(data); - assert(request); assert(msg); std::string titleString; if (title) { titleString = title; } - request->ReportMessage(std::string(msg), titleString); + request.ReportMessage(std::string(msg), titleString); } cmServerResponse cmServer::SetProtocolVersion(const cmServerRequest& request) diff --git a/Source/cmServer.h b/Source/cmServer.h index ca37ce2..bedf97f 100644 --- a/Source/cmServer.h +++ b/Source/cmServer.h @@ -118,9 +118,10 @@ public: void OnConnected(cmConnection* connection) override; private: - static void reportProgress(const char* msg, float progress, void* data); - static void reportMessage(const char* msg, const char* title, bool& cancel, - void* data); + static void reportProgress(const char* msg, float progress, + const cmServerRequest& request); + static void reportMessage(const char* msg, const char* title, + const cmServerRequest& request); // Handle requests: cmServerResponse SetProtocolVersion(const cmServerRequest& request); diff --git a/Source/cmServerConnection.cxx b/Source/cmServerConnection.cxx index 5caa019..844a858 100644 --- a/Source/cmServerConnection.cxx +++ b/Source/cmServerConnection.cxx @@ -119,9 +119,7 @@ cmServerStdIoConnection::cmServerStdIoConnection() { } -cmConnectionBufferStrategy::~cmConnectionBufferStrategy() -{ -} +cmConnectionBufferStrategy::~cmConnectionBufferStrategy() = default; void cmConnectionBufferStrategy::clear() { diff --git a/Source/cmSourceFileLocation.cxx b/Source/cmSourceFileLocation.cxx index 3dab638..13d2d7e 100644 --- a/Source/cmSourceFileLocation.cxx +++ b/Source/cmSourceFileLocation.cxx @@ -11,9 +11,7 @@ #include <assert.h> -cmSourceFileLocation::cmSourceFileLocation() -{ -} +cmSourceFileLocation::cmSourceFileLocation() = default; cmSourceFileLocation::cmSourceFileLocation(const cmSourceFileLocation& loc) : Makefile(loc.Makefile) diff --git a/Source/cmStateDirectory.cxx b/Source/cmStateDirectory.cxx index 40f694c..6752743 100644 --- a/Source/cmStateDirectory.cxx +++ b/Source/cmStateDirectory.cxx @@ -155,6 +155,15 @@ bool cmStateDirectory::ContainsBoth(std::string const& local_path, return bothInBinary || bothInSource; } +std::string cmStateDirectory::ConvertToRelPathIfNotContained( + std::string const& local_path, std::string const& remote_path) const +{ + if (!this->ContainsBoth(local_path, remote_path)) { + return remote_path; + } + return cmSystemTools::ForceToRelativePath(local_path, remote_path); +} + cmStateDirectory::cmStateDirectory( cmLinkedTree<cmStateDetail::BuildsystemDirectoryStateType>::iterator iter, const cmStateSnapshot& snapshot) diff --git a/Source/cmStateDirectory.h b/Source/cmStateDirectory.h index c4b18ad..6956594 100644 --- a/Source/cmStateDirectory.h +++ b/Source/cmStateDirectory.h @@ -35,6 +35,9 @@ public: bool ContainsBoth(std::string const& local_path, std::string const& remote_path) const; + std::string ConvertToRelPathIfNotContained( + std::string const& local_path, std::string const& remote_path) const; + cmStringRange GetIncludeDirectoriesEntries() const; cmBacktraceRange GetIncludeDirectoriesEntryBacktraces() const; void AppendIncludeDirectoriesEntry(std::string const& vec, diff --git a/Source/cmStringReplaceHelper.h b/Source/cmStringReplaceHelper.h index 5cebde7..b3e4704 100644 --- a/Source/cmStringReplaceHelper.h +++ b/Source/cmStringReplaceHelper.h @@ -48,7 +48,7 @@ private: : Number(n) { } - RegexReplacement() {} + RegexReplacement() = default; int Number; std::string Value; diff --git a/Source/cmSystemTools.cxx b/Source/cmSystemTools.cxx index a16460f..a9cf0c6 100644 --- a/Source/cmSystemTools.cxx +++ b/Source/cmSystemTools.cxx @@ -76,6 +76,15 @@ # include <malloc.h> /* for malloc/free on QNX */ #endif +namespace { + +cmSystemTools::InterruptCallback s_InterruptCallback; +cmSystemTools::MessageCallback s_MessageCallback; +cmSystemTools::OutputCallback s_StderrCallback; +cmSystemTools::OutputCallback s_StdoutCallback; + +} // namespace + static bool cm_isspace(char c) { return ((c & 0x80) == 0) && isspace(c); @@ -161,15 +170,6 @@ bool cmSystemTools::s_FatalErrorOccured = false; bool cmSystemTools::s_DisableMessages = false; bool cmSystemTools::s_ForceUnixPaths = false; -cmSystemTools::MessageCallback cmSystemTools::s_MessageCallback; -cmSystemTools::OutputCallback cmSystemTools::s_StdoutCallback; -cmSystemTools::OutputCallback cmSystemTools::s_StderrCallback; -cmSystemTools::InterruptCallback cmSystemTools::s_InterruptCallback; -void* cmSystemTools::s_MessageCallbackClientData; -void* cmSystemTools::s_StdoutCallbackClientData; -void* cmSystemTools::s_StderrCallbackClientData; -void* cmSystemTools::s_InterruptCallbackClientData; - // replace replace with with as many times as it shows up in source. // write the result into source. #if defined(_WIN32) && !defined(__CYGWIN__) @@ -267,52 +267,48 @@ void cmSystemTools::Error(const char* m1, const char* m2, const char* m3, message += m4; } cmSystemTools::s_ErrorOccured = true; - cmSystemTools::Message(message.c_str(), "Error"); + cmSystemTools::Message(message, "Error"); } void cmSystemTools::Error(const std::string& m) { std::string message = "CMake Error: " + m; cmSystemTools::s_ErrorOccured = true; - cmSystemTools::Message(message.c_str(), "Error"); + cmSystemTools::Message(message, "Error"); } -void cmSystemTools::SetInterruptCallback(InterruptCallback f, void* clientData) +void cmSystemTools::SetInterruptCallback(InterruptCallback f) { - s_InterruptCallback = f; - s_InterruptCallbackClientData = clientData; + s_InterruptCallback = std::move(f); } bool cmSystemTools::GetInterruptFlag() { if (s_InterruptCallback) { - return (*s_InterruptCallback)(s_InterruptCallbackClientData); + return s_InterruptCallback(); } return false; } -void cmSystemTools::SetMessageCallback(MessageCallback f, void* clientData) +void cmSystemTools::SetMessageCallback(MessageCallback f) { - s_MessageCallback = f; - s_MessageCallbackClientData = clientData; + s_MessageCallback = std::move(f); } -void cmSystemTools::SetStdoutCallback(OutputCallback f, void* clientData) +void cmSystemTools::SetStdoutCallback(OutputCallback f) { - s_StdoutCallback = f; - s_StdoutCallbackClientData = clientData; + s_StdoutCallback = std::move(f); } -void cmSystemTools::SetStderrCallback(OutputCallback f, void* clientData) +void cmSystemTools::SetStderrCallback(OutputCallback f) { - s_StderrCallback = f; - s_StderrCallbackClientData = clientData; + s_StderrCallback = std::move(f); } void cmSystemTools::Stderr(const std::string& s) { if (s_StderrCallback) { - (*s_StderrCallback)(s.c_str(), s.length(), s_StderrCallbackClientData); + s_StderrCallback(s.c_str(), s.length()); } else { std::cerr << s << std::flush; } @@ -321,7 +317,7 @@ void cmSystemTools::Stderr(const std::string& s) void cmSystemTools::Stdout(const std::string& s) { if (s_StdoutCallback) { - (*s_StdoutCallback)(s.c_str(), s.length(), s_StdoutCallbackClientData); + s_StdoutCallback(s.c_str(), s.length()); } else { std::cout << s << std::flush; } @@ -333,8 +329,7 @@ void cmSystemTools::Message(const char* m1, const char* title) return; } if (s_MessageCallback) { - (*s_MessageCallback)(m1, title, s_DisableMessages, - s_MessageCallbackClientData); + s_MessageCallback(m1, title); return; } std::cerr << m1 << std::endl << std::flush; @@ -940,17 +935,12 @@ std::string cmSystemTools::FileExistsInParentDirectories(const char* fname, return ""; } -bool cmSystemTools::cmCopyFile(const char* source, const char* destination) +bool cmSystemTools::cmCopyFile(const std::string& source, + const std::string& destination) { return Superclass::CopyFileAlways(source, destination); } -bool cmSystemTools::CopyFileIfDifferent(const char* source, - const char* destination) -{ - return Superclass::CopyFileIfDifferent(source, destination); -} - #ifdef _WIN32 cmSystemTools::WindowsFileRetry cmSystemTools::GetWindowsFileRetry() { diff --git a/Source/cmSystemTools.h b/Source/cmSystemTools.h index b30e4f7..990c932 100644 --- a/Source/cmSystemTools.h +++ b/Source/cmSystemTools.h @@ -10,6 +10,7 @@ #include "cmProcessOutput.h" #include "cmsys/Process.h" #include "cmsys/SystemTools.hxx" // IWYU pragma: export +#include <functional> #include <stddef.h> #include <string> #include <vector> @@ -55,15 +56,13 @@ public: */ static std::string TrimWhitespace(const std::string& s); - typedef void (*MessageCallback)(const char*, const char*, bool&, void*); + using MessageCallback = std::function<void(const char*, const char*)>; /** * Set the function used by GUIs to display error messages * Function gets passed: message as a const char*, - * title as a const char*, and a reference to bool that when - * set to false, will disable further messages (cancel). + * title as a const char*. */ - static void SetMessageCallback(MessageCallback f, - void* clientData = nullptr); + static void SetMessageCallback(MessageCallback f); /** * Display an error message. @@ -76,20 +75,23 @@ public: * Display a message. */ static void Message(const char* m, const char* title = nullptr); + static void Message(const std::string& m, const char* title = nullptr) + { + Message(m.c_str(), title); + } - typedef void (*OutputCallback)(const char*, size_t length, void*); + using OutputCallback = std::function<void(const char*, size_t)>; ///! Send a string to stdout static void Stdout(const std::string& s); - static void SetStdoutCallback(OutputCallback, void* clientData = nullptr); + static void SetStdoutCallback(OutputCallback f); ///! Send a string to stderr static void Stderr(const std::string& s); - static void SetStderrCallback(OutputCallback, void* clientData = nullptr); + static void SetStderrCallback(OutputCallback f); - typedef bool (*InterruptCallback)(void*); - static void SetInterruptCallback(InterruptCallback f, - void* clientData = nullptr); + using InterruptCallback = std::function<bool()>; + static void SetInterruptCallback(InterruptCallback f); static bool GetInterruptFlag(); ///! Return true if there was an error at any point. @@ -175,8 +177,8 @@ public: std::vector<std::string>& files, int type = 0); ///! Copy a file. - static bool cmCopyFile(const char* source, const char* destination); - static bool CopyFileIfDifferent(const char* source, const char* destination); + static bool cmCopyFile(const std::string& source, + const std::string& destination); /** Rename a file or directory within a single disk volume (atomic if possible). */ @@ -544,14 +546,6 @@ private: static bool s_FatalErrorOccured; static bool s_DisableMessages; static bool s_DisableRunCommandOutput; - static MessageCallback s_MessageCallback; - static OutputCallback s_StdoutCallback; - static OutputCallback s_StderrCallback; - static InterruptCallback s_InterruptCallback; - static void* s_MessageCallbackClientData; - static void* s_StdoutCallbackClientData; - static void* s_StderrCallbackClientData; - static void* s_InterruptCallbackClientData; }; #endif diff --git a/Source/cmTarget.cxx b/Source/cmTarget.cxx index fe48934..93cdd46 100644 --- a/Source/cmTarget.cxx +++ b/Source/cmTarget.cxx @@ -19,7 +19,6 @@ #include "cmMakefile.h" #include "cmMessageType.h" #include "cmMessenger.h" -#include "cmOutputConverter.h" #include "cmProperty.h" #include "cmSourceFile.h" #include "cmSourceFileLocation.h" @@ -747,11 +746,12 @@ void cmTarget::GetTllSignatureTraces(std::ostream& s, TLLSignature sig) const const char* sigString = (sig == cmTarget::KeywordTLLSignature ? "keyword" : "plain"); s << "The uses of the " << sigString << " signature are here:\n"; - cmOutputConverter converter(this->GetMakefile()->GetStateSnapshot()); + cmStateDirectory cmDir = + this->GetMakefile()->GetStateSnapshot().GetDirectory(); for (auto const& cmd : this->TLLCommands) { if (cmd.first == sig) { cmListFileContext lfc = cmd.second; - lfc.FilePath = converter.ConvertToRelativePath( + lfc.FilePath = cmDir.ConvertToRelPathIfNotContained( this->Makefile->GetState()->GetSourceDirectory(), lfc.FilePath); s << " * " << lfc << std::endl; } diff --git a/Source/cmTest.cxx b/Source/cmTest.cxx index 4d0cbaa..7d45cf5 100644 --- a/Source/cmTest.cxx +++ b/Source/cmTest.cxx @@ -14,9 +14,7 @@ cmTest::cmTest(cmMakefile* mf) this->OldStyle = true; } -cmTest::~cmTest() -{ -} +cmTest::~cmTest() = default; cmListFileBacktrace const& cmTest::GetBacktrace() const { diff --git a/Source/cmTestGenerator.cxx b/Source/cmTestGenerator.cxx index 6032701..5102613 100644 --- a/Source/cmTestGenerator.cxx +++ b/Source/cmTestGenerator.cxx @@ -26,9 +26,7 @@ cmTestGenerator::cmTestGenerator( this->LG = nullptr; } -cmTestGenerator::~cmTestGenerator() -{ -} +cmTestGenerator::~cmTestGenerator() = default; void cmTestGenerator::Compute(cmLocalGenerator* lg) { diff --git a/Source/cmTimestamp.h b/Source/cmTimestamp.h index 2f75acb..d5fbdfd 100644 --- a/Source/cmTimestamp.h +++ b/Source/cmTimestamp.h @@ -15,8 +15,6 @@ class cmTimestamp { public: - cmTimestamp() {} - std::string CurrentTime(const std::string& formatString, bool utcFlag); std::string FileModificationTime(const char* path, diff --git a/Source/cmUVHandlePtr.h b/Source/cmUVHandlePtr.h index 73ee334..d42969e 100644 --- a/Source/cmUVHandlePtr.h +++ b/Source/cmUVHandlePtr.h @@ -86,8 +86,8 @@ public: } // Dtor and ctor need to be inline defined like this for default ctors and - // dtors to work. - uv_handle_ptr_base_() {} + // dtors to work. Some compilers do not like '= default' here. + uv_handle_ptr_base_() {} // NOLINT(modernize-use-equals-default) uv_handle_ptr_base_(std::nullptr_t) {} ~uv_handle_ptr_base_() { reset(); } diff --git a/Source/cmUseMangledMesaCommand.cxx b/Source/cmUseMangledMesaCommand.cxx index 01ef5cb..9648b21 100644 --- a/Source/cmUseMangledMesaCommand.cxx +++ b/Source/cmUseMangledMesaCommand.cxx @@ -100,6 +100,6 @@ void cmUseMangledMesaCommand::CopyAndFullPathMesaHeader(const char* source, // close the files before attempting to copy fin.close(); fout.close(); - cmSystemTools::CopyFileIfDifferent(tempOutputFile.c_str(), outFile.c_str()); + cmSystemTools::CopyFileIfDifferent(tempOutputFile, outFile); cmSystemTools::RemoveFile(tempOutputFile); } diff --git a/Source/cmUtilitySourceCommand.cxx b/Source/cmUtilitySourceCommand.cxx index f374626..231bca4 100644 --- a/Source/cmUtilitySourceCommand.cxx +++ b/Source/cmUtilitySourceCommand.cxx @@ -40,7 +40,7 @@ bool cmUtilitySourceCommand::InitialPass(std::vector<std::string> const& args, msg += ". If your intention is to run this executable, you need to " "preload the cache with the full path to a version of that " "program, which runs on this build machine."; - cmSystemTools::Message(msg.c_str(), "Warning"); + cmSystemTools::Message(msg, "Warning"); } } else { cmState* state = this->Makefile->GetState(); diff --git a/Source/cmVSSetupHelper.h b/Source/cmVSSetupHelper.h index 4748a7a..1bda54a 100644 --- a/Source/cmVSSetupHelper.h +++ b/Source/cmVSSetupHelper.h @@ -112,8 +112,6 @@ struct VSInstanceInfo bool IsWin10SDKInstalled = false; bool IsWin81SDKInstalled = false; - VSInstanceInfo() = default; - std::string GetInstallLocation() const; }; diff --git a/Source/cmVariableWatch.cxx b/Source/cmVariableWatch.cxx index bd5d19c..3df1420 100644 --- a/Source/cmVariableWatch.cxx +++ b/Source/cmVariableWatch.cxx @@ -19,13 +19,9 @@ const char* cmVariableWatch::GetAccessAsString(int access_type) return cmVariableWatchAccessStrings[access_type]; } -cmVariableWatch::cmVariableWatch() -{ -} +cmVariableWatch::cmVariableWatch() = default; -cmVariableWatch::~cmVariableWatch() -{ -} +cmVariableWatch::~cmVariableWatch() = default; bool cmVariableWatch::AddWatch(const std::string& variable, WatchMethod method, void* client_data /*=0*/, diff --git a/Source/cmVariableWatch.h b/Source/cmVariableWatch.h index 2f444ed..5855fed 100644 --- a/Source/cmVariableWatch.h +++ b/Source/cmVariableWatch.h @@ -66,7 +66,6 @@ protected: WatchMethod Method = nullptr; void* ClientData = nullptr; DeleteData DeleteDataCall = nullptr; - Pair() {} ~Pair() { if (this->DeleteDataCall && this->ClientData) { diff --git a/Source/cmVariableWatchCommand.cxx b/Source/cmVariableWatchCommand.cxx index 975d6e4..5fe55bd 100644 --- a/Source/cmVariableWatchCommand.cxx +++ b/Source/cmVariableWatchCommand.cxx @@ -84,9 +84,7 @@ static void deleteVariableWatchCallbackData(void* client_data) delete data; } -cmVariableWatchCommand::cmVariableWatchCommand() -{ -} +cmVariableWatchCommand::cmVariableWatchCommand() = default; cmVariableWatchCommand::~cmVariableWatchCommand() { diff --git a/Source/cmVisualStudio10TargetGenerator.cxx b/Source/cmVisualStudio10TargetGenerator.cxx index ac4a4f5..9d7dd07 100644 --- a/Source/cmVisualStudio10TargetGenerator.cxx +++ b/Source/cmVisualStudio10TargetGenerator.cxx @@ -3584,8 +3584,8 @@ bool cmVisualStudio10TargetGenerator::ComputeLibOptions( this->LocalGenerator->GetCurrentBinaryDirectory(); for (cmComputeLinkInformation::Item const& l : libs) { if (l.IsPath && cmVS10IsTargetsFile(l.Value)) { - std::string path = - this->LocalGenerator->ConvertToRelativePath(currentBinDir, l.Value); + std::string path = this->LocalGenerator->MaybeConvertToRelativePath( + currentBinDir, l.Value); ConvertToWindowsSlash(path); this->AddTargetsFileAndConfigPair(path, config); } @@ -3668,8 +3668,8 @@ void cmVisualStudio10TargetGenerator::AddLibraries( } if (l.IsPath) { - std::string path = - this->LocalGenerator->ConvertToRelativePath(currentBinDir, l.Value); + std::string path = this->LocalGenerator->MaybeConvertToRelativePath( + currentBinDir, l.Value); ConvertToWindowsSlash(path); if (cmVS10IsTargetsFile(l.Value)) { vsTargetVec.push_back(path); diff --git a/Source/cm_codecvt.cxx b/Source/cm_codecvt.cxx index 9519f91..821c112 100644 --- a/Source/cm_codecvt.cxx +++ b/Source/cm_codecvt.cxx @@ -38,9 +38,7 @@ codecvt::codecvt(Encoding e) } } -codecvt::~codecvt() -{ -} +codecvt::~codecvt() = default; bool codecvt::do_always_noconv() const throw() { diff --git a/Source/cmake.cxx b/Source/cmake.cxx index 744b8fc..2b627ff 100644 --- a/Source/cmake.cxx +++ b/Source/cmake.cxx @@ -157,8 +157,6 @@ cmake::cmake(Role role, cmState::Mode mode) #endif this->GlobalGenerator = nullptr; - this->ProgressCallback = nullptr; - this->ProgressCallbackClientData = nullptr; this->CurrentWorkingMode = NORMAL_MODE; #ifdef CMAKE_BUILD_WITH_CMAKE @@ -1252,7 +1250,7 @@ int cmake::HandleDeleteCacheVariables(const std::string& var) for (SaveCacheEntry const& i : saved) { this->AddCacheEntry(i.key, i.value.c_str(), i.help.c_str(), i.type); } - cmSystemTools::Message(warning.str().c_str()); + cmSystemTools::Message(warning.str()); // avoid reconfigure if there were errors if (!cmSystemTools::GetErrorOccuredFlag()) { // re-run configure @@ -1922,17 +1920,15 @@ bool cmake::DeleteCache(const std::string& path) return this->State->DeleteCache(path); } -void cmake::SetProgressCallback(ProgressCallbackType f, void* cd) +void cmake::SetProgressCallback(ProgressCallbackType f) { - this->ProgressCallback = f; - this->ProgressCallbackClientData = cd; + this->ProgressCallback = std::move(f); } void cmake::UpdateProgress(const char* msg, float prog) { if (this->ProgressCallback && !this->State->GetIsInTryCompile()) { - (*this->ProgressCallback)(msg, prog, this->ProgressCallbackClientData); - return; + this->ProgressCallback(msg, prog); } } @@ -2146,8 +2142,7 @@ int cmake::CheckBuildSystem() std::string dep_newest = *dep++; for (; dep != depends.end(); ++dep) { int result = 0; - if (this->FileComparison->FileTimeCompare(dep_newest.c_str(), dep->c_str(), - &result)) { + if (this->FileComparison->FileTimeCompare(dep_newest, *dep, &result)) { if (result < 0) { dep_newest = *dep; } @@ -2166,8 +2161,7 @@ int cmake::CheckBuildSystem() std::string out_oldest = *out++; for (; out != outputs.end(); ++out) { int result = 0; - if (this->FileComparison->FileTimeCompare(out_oldest.c_str(), out->c_str(), - &result)) { + if (this->FileComparison->FileTimeCompare(out_oldest, *out, &result)) { if (result > 0) { out_oldest = *out; } @@ -2184,8 +2178,8 @@ int cmake::CheckBuildSystem() // If any output is older than any dependency then rerun. { int result = 0; - if (!this->FileComparison->FileTimeCompare(out_oldest.c_str(), - dep_newest.c_str(), &result) || + if (!this->FileComparison->FileTimeCompare(out_oldest, dep_newest, + &result) || result < 0) { if (verbose) { std::ostringstream msg; @@ -2360,7 +2354,7 @@ int cmake::GetSystemInformation(std::vector<std::string>& args) outFile += "/CMakeLists.txt"; // Copy file - if (!cmSystemTools::cmCopyFile(inFile.c_str(), outFile.c_str())) { + if (!cmSystemTools::cmCopyFile(inFile, outFile)) { std::cerr << "Error copying file \"" << inFile << "\" to \"" << outFile << "\".\n"; return 1; @@ -2446,8 +2440,7 @@ static bool cmakeCheckStampFile(const std::string& stampName, bool verbose) while (cmSystemTools::GetLineFromStream(fin, dep)) { int result; if (!dep.empty() && dep[0] != '#' && - (!ftc.FileTimeCompare(stampDepends.c_str(), dep.c_str(), &result) || - result < 0)) { + (!ftc.FileTimeCompare(stampDepends, dep, &result) || result < 0)) { // The stamp depends file is older than this dependency. The // build system is really out of date. std::cout << "CMake is re-running because " << stampName @@ -2540,7 +2533,8 @@ cmMessenger* cmake::GetMessenger() const int cmake::Build(int jobs, const std::string& dir, const std::string& target, const std::string& config, - const std::vector<std::string>& nativeOptions, bool clean) + const std::vector<std::string>& nativeOptions, bool clean, + bool verbose) { this->SetHomeDirectory(""); @@ -2593,11 +2587,11 @@ int cmake::Build(int jobs, const std::string& dir, const std::string& target, return 1; } projName = cachedProjectName; - bool verbose = false; + const char* cachedVerbose = this->State->GetCacheEntryValue("CMAKE_VERBOSE_MAKEFILE"); - if (cachedVerbose) { - verbose = cmSystemTools::IsOn(cachedVerbose); + if (cmSystemTools::IsOn(cachedVerbose)) { + verbose = true; } #ifdef CMAKE_HAVE_VS_GENERATORS diff --git a/Source/cmake.h b/Source/cmake.h index 0f53d28..afd4117 100644 --- a/Source/cmake.h +++ b/Source/cmake.h @@ -5,6 +5,7 @@ #include "cmConfigure.h" // IWYU pragma: keep +#include <functional> #include <map> #include <memory> // IWYU pragma: keep #include <set> @@ -271,7 +272,7 @@ public: ///! Parse command line arguments that might set cache values bool SetCacheArgs(const std::vector<std::string>&); - typedef void (*ProgressCallbackType)(const char* msg, float progress, void*); + using ProgressCallbackType = std::function<void(const char*, float)>; /** * Set the function used by GUIs to receive progress updates * Function gets passed: message as a const char*, a progress @@ -279,7 +280,7 @@ public: * number provided may be negative in cases where a message is * to be displayed without any progress percentage. */ - void SetProgressCallback(ProgressCallbackType f, void* clientData = nullptr); + void SetProgressCallback(ProgressCallbackType f); ///! this is called by generators to update the progress void UpdateProgress(const char* msg, float prog); @@ -424,7 +425,8 @@ public: ///! run the --build option int Build(int jobs, const std::string& dir, const std::string& target, const std::string& config, - const std::vector<std::string>& nativeOptions, bool clean); + const std::vector<std::string>& nativeOptions, bool clean, + bool verbose); ///! run the --open option bool Open(const std::string& dir, bool dryRun); @@ -484,7 +486,6 @@ protected: private: ProgressCallbackType ProgressCallback; - void* ProgressCallbackClientData; bool InTryCompile; WorkingMode CurrentWorkingMode; bool DebugOutput; diff --git a/Source/cmakemain.cxx b/Source/cmakemain.cxx index 0c25498..890b74e 100644 --- a/Source/cmakemain.cxx +++ b/Source/cmakemain.cxx @@ -68,6 +68,8 @@ static const char* cmDocumentationUsageNote[][2] = { " --clean-first = Build target 'clean' first, then build.\n" \ " (To clean only, use --target 'clean'.)\n" \ " --use-stderr = Ignored. Behavior is default in CMake >= 3.0.\n" \ + " -v --verbose = Enable verbose output - if supported - including\n" \ + " the build commands to be executed. \n" \ " -- = Pass remaining options to the native tool.\n" static const char* cmDocumentationOptions[][2] = { @@ -115,9 +117,8 @@ int do_cmake(int ac, char const* const* av); static int do_build(int ac, char const* const* av); static int do_open(int ac, char const* const* av); -static cmMakefile* cmakemainGetMakefile(void* clientdata) +static cmMakefile* cmakemainGetMakefile(cmake* cm) { - cmake* cm = static_cast<cmake*>(clientdata); if (cm && cm->GetDebugOutput()) { cmGlobalGenerator* gg = cm->GetGlobalGenerator(); if (gg) { @@ -127,10 +128,10 @@ static cmMakefile* cmakemainGetMakefile(void* clientdata) return nullptr; } -static std::string cmakemainGetStack(void* clientdata) +static std::string cmakemainGetStack(cmake* cm) { std::string msg; - cmMakefile* mf = cmakemainGetMakefile(clientdata); + cmMakefile* mf = cmakemainGetMakefile(cm); if (mf) { msg = mf->FormatListFileStack(); if (!msg.empty()) { @@ -142,15 +143,14 @@ static std::string cmakemainGetStack(void* clientdata) } static void cmakemainMessageCallback(const char* m, const char* /*unused*/, - bool& /*unused*/, void* clientdata) + cmake* cm) { - std::cerr << m << cmakemainGetStack(clientdata) << std::endl << std::flush; + std::cerr << m << cmakemainGetStack(cm) << std::endl << std::flush; } -static void cmakemainProgressCallback(const char* m, float prog, - void* clientdata) +static void cmakemainProgressCallback(const char* m, float prog, cmake* cm) { - cmMakefile* mf = cmakemainGetMakefile(clientdata); + cmMakefile* mf = cmakemainGetMakefile(cm); std::string dir; if ((mf) && (strstr(m, "Configuring") == m) && (prog < 0)) { dir = " "; @@ -161,8 +161,7 @@ static void cmakemainProgressCallback(const char* m, float prog, } if ((prog < 0) || (!dir.empty())) { - std::cout << "-- " << m << dir << cmakemainGetStack(clientdata) - << std::endl; + std::cout << "-- " << m << dir << cmakemainGetStack(cm) << std::endl; } std::cout.flush(); @@ -320,8 +319,12 @@ int do_cmake(int ac, char const* const* av) cmake cm(role, mode); cm.SetHomeDirectory(""); cm.SetHomeOutputDirectory(""); - cmSystemTools::SetMessageCallback(cmakemainMessageCallback, &cm); - cm.SetProgressCallback(cmakemainProgressCallback, &cm); + cmSystemTools::SetMessageCallback([&cm](const char* msg, const char* title) { + cmakemainMessageCallback(msg, title, &cm); + }); + cm.SetProgressCallback([&cm](const char* msg, float prog) { + cmakemainProgressCallback(msg, prog, &cm); + }); cm.SetWorkingMode(workingMode); int res = cm.Run(args, view_only); @@ -395,6 +398,7 @@ static int do_build(int ac, char const* const* av) std::string dir; std::vector<std::string> nativeOptions; bool clean = false; + bool verbose = cmSystemTools::HasEnv("VERBOSE"); bool hasTarget = false; enum Doing @@ -435,6 +439,10 @@ static int do_build(int ac, char const* const* av) } else if (strcmp(av[i], "--clean-first") == 0) { clean = true; doing = DoingNone; + } else if ((strcmp(av[i], "--verbose") == 0) || + (strcmp(av[i], "-v") == 0)) { + verbose = true; + doing = DoingNone; } else if (strcmp(av[i], "--use-stderr") == 0) { /* tolerate legacy option */ } else if (strcmp(av[i], "--") == 0) { @@ -491,9 +499,13 @@ static int do_build(int ac, char const* const* av) } cmake cm(cmake::RoleInternal, cmState::Unknown); - cmSystemTools::SetMessageCallback(cmakemainMessageCallback, &cm); - cm.SetProgressCallback(cmakemainProgressCallback, &cm); - return cm.Build(jobs, dir, target, config, nativeOptions, clean); + cmSystemTools::SetMessageCallback([&cm](const char* msg, const char* title) { + cmakemainMessageCallback(msg, title, &cm); + }); + cm.SetProgressCallback([&cm](const char* msg, float prog) { + cmakemainProgressCallback(msg, prog, &cm); + }); + return cm.Build(jobs, dir, target, config, nativeOptions, clean, verbose); #endif } @@ -529,8 +541,12 @@ static int do_open(int ac, char const* const* av) } cmake cm(cmake::RoleInternal, cmState::Unknown); - cmSystemTools::SetMessageCallback(cmakemainMessageCallback, &cm); - cm.SetProgressCallback(cmakemainProgressCallback, &cm); + cmSystemTools::SetMessageCallback([&cm](const char* msg, const char* title) { + cmakemainMessageCallback(msg, title, &cm); + }); + cm.SetProgressCallback([&cm](const char* msg, float prog) { + cmakemainProgressCallback(msg, prog, &cm); + }); return cm.Open(dir, false) ? 0 : 1; #endif } diff --git a/Source/cmcmd.cxx b/Source/cmcmd.cxx index 0ad9b88..d20c5d2 100644 --- a/Source/cmcmd.cxx +++ b/Source/cmcmd.cxx @@ -482,8 +482,7 @@ int cmcmd::ExecuteCMakeCommand(std::vector<std::string>& args) // If error occurs we want to continue copying next files. bool return_value = false; for (std::string::size_type cc = 2; cc < args.size() - 1; cc++) { - if (!cmSystemTools::cmCopyFile(args[cc].c_str(), - args.back().c_str())) { + if (!cmSystemTools::cmCopyFile(args[cc], args.back())) { std::cerr << "Error copying file \"" << args[cc] << "\" to \"" << args.back() << "\".\n"; return_value = true; @@ -505,8 +504,7 @@ int cmcmd::ExecuteCMakeCommand(std::vector<std::string>& args) // If error occurs we want to continue copying next files. bool return_value = false; for (std::string::size_type cc = 2; cc < args.size() - 1; cc++) { - if (!cmSystemTools::CopyFileIfDifferent(args[cc].c_str(), - args.back().c_str())) { + if (!cmSystemTools::CopyFileIfDifferent(args[cc], args.back())) { std::cerr << "Error copying file (if different) from \"" << args[cc] << "\" to \"" << args.back() << "\".\n"; return_value = true; @@ -1304,7 +1302,7 @@ bool cmcmd::SymlinkInternal(std::string const& file, std::string const& link) cmSystemTools::RemoveFile(link); } #if defined(_WIN32) && !defined(__CYGWIN__) - return cmSystemTools::CopyFileAlways(file.c_str(), link.c_str()); + return cmSystemTools::CopyFileAlways(file, link); #else std::string linktext = cmSystemTools::GetFilenameName(file); return cmSystemTools::CreateSymlink(linktext, link); @@ -1361,8 +1359,8 @@ static void cmcmdProgressReport(std::string const& dir, std::string const& num) int cmcmd::ExecuteEchoColor(std::vector<std::string>& args) { // The arguments are - // argv[0] == <cmake-executable> - // argv[1] == cmake_echo_color + // args[0] == <cmake-executable> + // args[1] == cmake_echo_color bool enabled = true; int color = cmsysTerminal_Color_Normal; @@ -1419,10 +1417,10 @@ int cmcmd::ExecuteEchoColor(std::vector<std::string>& args) int cmcmd::ExecuteLinkScript(std::vector<std::string>& args) { // The arguments are - // argv[0] == <cmake-executable> - // argv[1] == cmake_link_script - // argv[2] == <link-script-name> - // argv[3] == --verbose=? + // args[0] == <cmake-executable> + // args[1] == cmake_link_script + // args[2] == <link-script-name> + // args[3] == --verbose=? bool verbose = false; if (args.size() >= 4) { if (args[3].find("--verbose=") == 0) { diff --git a/Tests/CMakeLists.txt b/Tests/CMakeLists.txt index 0c6eabc..ed98d97 100644 --- a/Tests/CMakeLists.txt +++ b/Tests/CMakeLists.txt @@ -1704,18 +1704,37 @@ ${CMake_BINARY_DIR}/bin/cmake -DDIR=dev -P ${CMake_SOURCE_DIR}/Utilities/Release DEPENDS ExternalProjectUpdateSetup ) # do each of the tutorial steps - foreach(STP RANGE 1 7) - add_test(TutorialStep${STP} ${CMAKE_CTEST_COMMAND} + function(add_tutorial_test step_name use_mymath) + set(tutorial_test_name Tutorial${step_name}) + set(tutorial_build_dir "${CMake_BINARY_DIR}/Tests/Tutorial/${step_name}") + if (use_mymath) + set(tutorial_build_options "") + else() + set(tutorial_test_name ${tutorial_test_name}_MYMATH) + set(tutorial_build_dir "${tutorial_build_dir}_MYMATH") + set(tutorial_build_options -DUSE_MYMATH:BOOL=OFF) + endif() + add_test(${tutorial_test_name} ${CMAKE_CTEST_COMMAND} --build-and-test - "${CMake_SOURCE_DIR}/Tests/Tutorial/Step${STP}" - "${CMake_BINARY_DIR}/Tests/Tutorial/Step${STP}" - --build-two-config + "${CMake_SOURCE_DIR}/Tests/Tutorial/${step_name}" + ${tutorial_build_dir}_Build ${build_generator_args} --build-project Tutorial - --build-options ${build_options} + --build-options ${build_options} ${tutorial_build_options} --test-command Tutorial 25.0) - endforeach() - list(APPEND TEST_BUILD_DIRS "${CMake_BINARY_DIR}/Tests/Tutorial") + list(APPEND TEST_BUILD_DIRS "${CMake_BINARY_DIR}/${tutorial_build_dir}_Build") + endfunction() + + if(NOT CMake_TEST_EXTERNAL_CMAKE) + foreach(STP RANGE 1 11) + add_tutorial_test(Step${STP} TRUE) + endforeach() + add_tutorial_test(Complete TRUE) + foreach(STP RANGE 3 11) + add_tutorial_test(Step${STP} FALSE) + endforeach() + add_tutorial_test(Complete FALSE) + endif() add_test(testing ${CMAKE_CTEST_COMMAND} -C \${CTEST_CONFIGURATION_TYPE} --build-and-test diff --git a/Tests/ExternalProjectLocal/CMakeLists.txt b/Tests/ExternalProjectLocal/CMakeLists.txt index 55fd713..1075a9d 100644 --- a/Tests/ExternalProjectLocal/CMakeLists.txt +++ b/Tests/ExternalProjectLocal/CMakeLists.txt @@ -20,71 +20,55 @@ set(binary_base "${base}/Build") set_property(DIRECTORY PROPERTY EP_BASE ${base}) set_property(DIRECTORY PROPERTY EP_STEP_TARGETS configure build test) -if(NOT DEFINED can_build_tutorial_step5) - set(can_build_tutorial_step5 1) - - # The ExternalProject builds of Tutorial Step5 cannot be built - # correctly 2nd and later times in an in-source build... - # (because the CMakeCache.txt from the real in-source build of - # the Tests/Tutorial/Step5 directory gets copied when we do - # the "source directory copy" step... but it still refers to - # its original path which yields a configure error.) So: - # - if("${CMAKE_SOURCE_DIR}" STREQUAL "${CMAKE_BINARY_DIR}") - set(can_build_tutorial_step5 0) - endif() -endif() # Local DIR: # -if(can_build_tutorial_step5) - set(proj TutorialStep5-Local) - ExternalProject_Add(${proj} - URL "${CMAKE_CURRENT_SOURCE_DIR}/../Tutorial/Step5" - CMAKE_CACHE_ARGS -DCMAKE_INSTALL_PREFIX:PATH=<INSTALL_DIR> - CMAKE_ARGS -G ${CMAKE_GENERATOR} <SOURCE_DIR> - TEST_BEFORE_INSTALL 1 - LOG_INSTALL 1 - ) - set_property(TARGET ${proj} PROPERTY FOLDER "Local") - ExternalProject_Get_Property(${proj} install_dir) - set(TutorialStep5_install_dir ${install_dir}) - - set(proj TutorialStep5-Local-TestAfterInstall) - ExternalProject_Add(${proj} - URL "${CMAKE_CURRENT_SOURCE_DIR}/../Tutorial/Step5" - CMAKE_ARGS -DCMAKE_INSTALL_PREFIX:PATH=<INSTALL_DIR> -G ${CMAKE_GENERATOR} <SOURCE_DIR> - CMAKE_CACHE_DEFAULT_ARGS -DUSE_MYMATH:BOOL=OFF - TEST_AFTER_INSTALL 1 - LOG_TEST 1 - ) - set_property(TARGET ${proj} PROPERTY FOLDER "Local") - - set(proj TutorialStep5-Local-TestExcludeFromMainBefore) - ExternalProject_Add(${proj} - URL "${CMAKE_CURRENT_SOURCE_DIR}/../Tutorial/Step5" - CMAKE_ARGS -DCMAKE_INSTALL_PREFIX:PATH=<INSTALL_DIR> -G ${CMAKE_GENERATOR} <SOURCE_DIR> - CMAKE_CACHE_DEFAULT_ARGS -DUSE_MYMATH:BOOL=OFF - TEST_BEFORE_INSTALL 1 - TEST_EXCLUDE_FROM_MAIN 1 - STEP_TARGETS test - LOG_TEST 1 - ) - set_property(TARGET ${proj} PROPERTY FOLDER "Local") - - set(proj TutorialStep5-Local-TestExcludeFromMainAfter) - ExternalProject_Add(${proj} - URL "${CMAKE_CURRENT_SOURCE_DIR}/../Tutorial/Step5" - CMAKE_ARGS -DCMAKE_INSTALL_PREFIX:PATH=<INSTALL_DIR> -G ${CMAKE_GENERATOR} <SOURCE_DIR> - CMAKE_CACHE_DEFAULT_ARGS -DUSE_MYMATH:BOOL=OFF - TEST_AFTER_INSTALL 1 - TEST_EXCLUDE_FROM_MAIN 1 - STEP_TARGETS test - LOG_TEST 1 - ) - set_property(TARGET ${proj} PROPERTY FOLDER "Local") +set(proj TutorialStep5-Local) +ExternalProject_Add(${proj} +URL "${CMAKE_CURRENT_SOURCE_DIR}/Step5" +CMAKE_CACHE_ARGS -DCMAKE_INSTALL_PREFIX:PATH=<INSTALL_DIR> +CMAKE_ARGS -G ${CMAKE_GENERATOR} <SOURCE_DIR> +TEST_BEFORE_INSTALL 1 +LOG_INSTALL 1 +) +set_property(TARGET ${proj} PROPERTY FOLDER "Local") +ExternalProject_Get_Property(${proj} install_dir) +set(TutorialStep5_install_dir ${install_dir}) + +set(proj TutorialStep5-Local-TestAfterInstall) +ExternalProject_Add(${proj} +URL "${CMAKE_CURRENT_SOURCE_DIR}/Step5" +CMAKE_ARGS -DCMAKE_INSTALL_PREFIX:PATH=<INSTALL_DIR> -G ${CMAKE_GENERATOR} <SOURCE_DIR> +CMAKE_CACHE_DEFAULT_ARGS -DUSE_MYMATH:BOOL=OFF +TEST_AFTER_INSTALL 1 +LOG_TEST 1 +) +set_property(TARGET ${proj} PROPERTY FOLDER "Local") + +set(proj TutorialStep5-Local-TestExcludeFromMainBefore) +ExternalProject_Add(${proj} +URL "${CMAKE_CURRENT_SOURCE_DIR}/Step5" +CMAKE_ARGS -DCMAKE_INSTALL_PREFIX:PATH=<INSTALL_DIR> -G ${CMAKE_GENERATOR} <SOURCE_DIR> +CMAKE_CACHE_DEFAULT_ARGS -DUSE_MYMATH:BOOL=OFF +TEST_BEFORE_INSTALL 1 +TEST_EXCLUDE_FROM_MAIN 1 +STEP_TARGETS test +LOG_TEST 1 +) +set_property(TARGET ${proj} PROPERTY FOLDER "Local") + +set(proj TutorialStep5-Local-TestExcludeFromMainAfter) +ExternalProject_Add(${proj} +URL "${CMAKE_CURRENT_SOURCE_DIR}/Step5" +CMAKE_ARGS -DCMAKE_INSTALL_PREFIX:PATH=<INSTALL_DIR> -G ${CMAKE_GENERATOR} <SOURCE_DIR> +CMAKE_CACHE_DEFAULT_ARGS -DUSE_MYMATH:BOOL=OFF +TEST_AFTER_INSTALL 1 +TEST_EXCLUDE_FROM_MAIN 1 +STEP_TARGETS test +LOG_TEST 1 +) +set_property(TARGET ${proj} PROPERTY FOLDER "Local") -endif() # Local TAR: @@ -209,12 +193,10 @@ enable_testing() # # BuildTree tests: # -if(can_build_tutorial_step5) - add_test(TutorialStep5-Local-BuildTreeTest - "${binary_base}/TutorialStep5-Local/Tutorial" 42) - set_property(TEST TutorialStep5-Local-BuildTreeTest - APPEND PROPERTY LABELS Step5 BuildTree) -endif() +add_test(TutorialStep5-Local-BuildTreeTest +"${binary_base}/TutorialStep5-Local/Tutorial" 42) +set_property(TEST TutorialStep5-Local-BuildTreeTest +APPEND PROPERTY LABELS Step5 BuildTree) add_test(TutorialStep1-LocalTAR-BuildTreeTest "${binary_base}/TutorialStep1-LocalTAR/EP-Tutorial" 36) @@ -234,12 +216,7 @@ add_test(TutorialStep1-LocalNoDirTGZ-BuildTreeTest # InstallTree tests: # -if(can_build_tutorial_step5) - add_test(TutorialStep5-InstallTreeTest - "${TutorialStep5_install_dir}/bin/Tutorial" 49) - set_property(TEST TutorialStep5-InstallTreeTest - APPEND PROPERTY LABELS Step5 InstallTree) -endif() - - -message(STATUS "can_build_tutorial_step5='${can_build_tutorial_step5}'") +add_test(TutorialStep5-InstallTreeTest +"${TutorialStep5_install_dir}/bin/Tutorial" 49) +set_property(TEST TutorialStep5-InstallTreeTest +APPEND PROPERTY LABELS Step5 InstallTree) diff --git a/Tests/ExternalProjectLocal/Step5/CMakeLists.txt b/Tests/ExternalProjectLocal/Step5/CMakeLists.txt new file mode 100644 index 0000000..93b3880 --- /dev/null +++ b/Tests/ExternalProjectLocal/Step5/CMakeLists.txt @@ -0,0 +1,71 @@ +cmake_minimum_required (VERSION 2.6) +project (Tutorial) + +# The version number. +set (Tutorial_VERSION_MAJOR 1) +set (Tutorial_VERSION_MINOR 0) + +# does this system provide the log and exp functions? +include (${CMAKE_ROOT}/Modules/CheckFunctionExists.cmake) +check_function_exists (log HAVE_LOG) +check_function_exists (exp HAVE_EXP) + +# should we use our own math functions +option(USE_MYMATH "Use tutorial provided math implementation" ON) + +# configure a header file to pass some of the CMake settings +# to the source code +configure_file ( + "${PROJECT_SOURCE_DIR}/TutorialConfig.h.in" + "${PROJECT_BINARY_DIR}/TutorialConfig.h" + ) + +# add the binary tree to the search path for include files +# so that we will find TutorialConfig.h +include_directories ("${PROJECT_BINARY_DIR}") + +# add the MathFunctions library? +if (USE_MYMATH) + include_directories ("${PROJECT_SOURCE_DIR}/MathFunctions") + add_subdirectory (MathFunctions) + set (EXTRA_LIBS ${EXTRA_LIBS} MathFunctions) +endif () + +# add the executable +add_executable (Tutorial tutorial.cxx) +target_link_libraries (Tutorial ${EXTRA_LIBS}) + +# add the install targets +install (TARGETS Tutorial DESTINATION bin) +install (FILES "${PROJECT_BINARY_DIR}/TutorialConfig.h" + DESTINATION include) + +# enable testing +enable_testing () + +# does the application run +add_test (TutorialRuns Tutorial 25) + +# does the usage message work? +add_test (TutorialUsage Tutorial) +set_tests_properties (TutorialUsage + PROPERTIES + PASS_REGULAR_EXPRESSION "Usage:.*number" + ) + +#define a macro to simplify adding tests +macro (do_test arg result) + add_test (TutorialComp${arg} Tutorial ${arg}) + set_tests_properties (TutorialComp${arg} + PROPERTIES PASS_REGULAR_EXPRESSION ${result} + ) +endmacro () + +# do a bunch of result based tests +do_test (4 "4 is 2") +do_test (9 "9 is 3") +do_test (5 "5 is 2.236") +do_test (7 "7 is 2.645") +do_test (25 "25 is 5") +do_test (-25 "-25 is 0") +do_test (0.0001 "0.0001 is 0.01") diff --git a/Tests/ExternalProjectLocal/Step5/MathFunctions/CMakeLists.txt b/Tests/ExternalProjectLocal/Step5/MathFunctions/CMakeLists.txt new file mode 100644 index 0000000..453a463 --- /dev/null +++ b/Tests/ExternalProjectLocal/Step5/MathFunctions/CMakeLists.txt @@ -0,0 +1,17 @@ +# first we add the executable that generates the table +# add the binary tree directory to the search path for include files +include_directories( ${CMAKE_CURRENT_BINARY_DIR} ) + +add_executable(MakeTable MakeTable.cxx ) +# add the command to generate the source code +add_custom_command ( + OUTPUT ${CMAKE_CURRENT_BINARY_DIR}/Table.h + COMMAND MakeTable ${CMAKE_CURRENT_BINARY_DIR}/Table.h + DEPENDS MakeTable + ) + +# add the main library +add_library(MathFunctions mysqrt.cxx ${CMAKE_CURRENT_BINARY_DIR}/Table.h ) + +install (TARGETS MathFunctions DESTINATION bin) +install (FILES MathFunctions.h DESTINATION include) diff --git a/Tests/ExternalProjectLocal/Step5/MathFunctions/MakeTable.cxx b/Tests/ExternalProjectLocal/Step5/MathFunctions/MakeTable.cxx new file mode 100644 index 0000000..cebd50f --- /dev/null +++ b/Tests/ExternalProjectLocal/Step5/MathFunctions/MakeTable.cxx @@ -0,0 +1,32 @@ +// A simple program that builds a sqrt table +#include <math.h> +#include <stdio.h> + +int main(int argc, char* argv[]) +{ + int i; + double result; + + // make sure we have enough arguments + if (argc < 2) { + return 1; + } + + // open the output file + FILE* fout = fopen(argv[1], "w"); + if (!fout) { + return 1; + } + + // create a source file with a table of square roots + fprintf(fout, "double sqrtTable[] = {\n"); + for (i = 0; i < 10; ++i) { + result = sqrt(static_cast<double>(i)); + fprintf(fout, "%g,\n", result); + } + + // close the table with a zero + fprintf(fout, "0};\n"); + fclose(fout); + return 0; +} diff --git a/Tests/ExternalProjectLocal/Step5/MathFunctions/MathFunctions.h b/Tests/ExternalProjectLocal/Step5/MathFunctions/MathFunctions.h new file mode 100644 index 0000000..cd36bcc --- /dev/null +++ b/Tests/ExternalProjectLocal/Step5/MathFunctions/MathFunctions.h @@ -0,0 +1 @@ +double mysqrt(double x); diff --git a/Tests/ExternalProjectLocal/Step5/MathFunctions/mysqrt.cxx b/Tests/ExternalProjectLocal/Step5/MathFunctions/mysqrt.cxx new file mode 100644 index 0000000..458ed63 --- /dev/null +++ b/Tests/ExternalProjectLocal/Step5/MathFunctions/mysqrt.cxx @@ -0,0 +1,40 @@ +#include "MathFunctions.h" +#include "TutorialConfig.h" +#include <stdio.h> + +// include the generated table +#include "Table.h" + +#include <math.h> + +// a hack square root calculation using simple operations +double mysqrt(double x) +{ + if (x <= 0) { + return 0; + } + + double result; + + // if we have both log and exp then use them + double delta; + + // use the table to help find an initial value + result = x; + if (x >= 1 && x < 10) { + result = sqrtTable[static_cast<int>(x)]; + } + + // do ten iterations + int i; + for (i = 0; i < 10; ++i) { + if (result <= 0) { + result = 0.1; + } + delta = x - (result * result); + result = result + 0.5 * delta / result; + fprintf(stdout, "Computing sqrt of %g to be %g\n", x, result); + } + + return result; +} diff --git a/Tests/ExternalProjectLocal/Step5/TutorialConfig.h.in b/Tests/ExternalProjectLocal/Step5/TutorialConfig.h.in new file mode 100644 index 0000000..e97ce24 --- /dev/null +++ b/Tests/ExternalProjectLocal/Step5/TutorialConfig.h.in @@ -0,0 +1,8 @@ +// the configured options and settings for Tutorial +#define Tutorial_VERSION_MAJOR @Tutorial_VERSION_MAJOR@ +#define Tutorial_VERSION_MINOR @Tutorial_VERSION_MINOR@ +#cmakedefine USE_MYMATH + +// does the platform provide exp and log functions? +#cmakedefine HAVE_LOG +#cmakedefine HAVE_EXP diff --git a/Tests/ExternalProjectLocal/Step5/tutorial.cxx b/Tests/ExternalProjectLocal/Step5/tutorial.cxx new file mode 100644 index 0000000..37f6ac4 --- /dev/null +++ b/Tests/ExternalProjectLocal/Step5/tutorial.cxx @@ -0,0 +1,33 @@ +// A simple program that computes the square root of a number +#include "TutorialConfig.h" +#include <math.h> +#include <stdio.h> +#include <stdlib.h> + +#ifdef USE_MYMATH +# include "MathFunctions.h" +#endif + +int main(int argc, char* argv[]) +{ + if (argc < 2) { + fprintf(stdout, "%s Version %d.%d\n", argv[0], Tutorial_VERSION_MAJOR, + Tutorial_VERSION_MINOR); + fprintf(stdout, "Usage: %s number\n", argv[0]); + return 1; + } + + double inputValue = atof(argv[1]); + double outputValue = 0; + + if (inputValue >= 0) { +#ifdef USE_MYMATH + outputValue = mysqrt(inputValue); +#else + outputValue = sqrt(inputValue); +#endif + } + + fprintf(stdout, "The square root of %g is %g\n", inputValue, outputValue); + return 0; +} diff --git a/Tests/RunCMake/CMakeLists.txt b/Tests/RunCMake/CMakeLists.txt index e6c90b4..2de90e7 100644 --- a/Tests/RunCMake/CMakeLists.txt +++ b/Tests/RunCMake/CMakeLists.txt @@ -123,7 +123,7 @@ if(NOT CMAKE_GENERATOR MATCHES "Visual Studio|Xcode") add_RunCMake_test(CMP0065) endif() if(CMAKE_GENERATOR MATCHES "Make") - add_RunCMake_test(Make) + add_RunCMake_test(Make -DMAKE_IS_GNU=${MAKE_IS_GNU}) endif() if(CMAKE_GENERATOR STREQUAL "Ninja") set(Ninja_ARGS diff --git a/Tests/RunCMake/Make/RunCMakeTest.cmake b/Tests/RunCMake/Make/RunCMakeTest.cmake index 3b2b8f5..82db6b7 100644 --- a/Tests/RunCMake/Make/RunCMakeTest.cmake +++ b/Tests/RunCMake/Make/RunCMakeTest.cmake @@ -16,5 +16,22 @@ run_TargetMessages(OFF) run_TargetMessages(VAR-ON -DCMAKE_TARGET_MESSAGES=ON) run_TargetMessages(VAR-OFF -DCMAKE_TARGET_MESSAGES=OFF) +function(run_VerboseBuild) + run_cmake(VerboseBuild) + set(RunCMake_TEST_NO_CLEAN 1) + set(RunCMake_TEST_BINARY_DIR ${RunCMake_BINARY_DIR}/VerboseBuild-build) + if(RunCMake_GENERATOR STREQUAL "Watcom WMake") + # wmake does not actually show the verbose output. + set(RunCMake-stdout-file VerboseBuild-build-watcom-stdout.txt) + endif() + run_cmake_command(VerboseBuild-build ${CMAKE_COMMAND} --build . -v --clean-first) + unset(RunCMake-stdout-file) + if(MAKE_IS_GNU) + set(RunCMake-stdout-file VerboseBuild-nowork-gnu-stdout.txt) + endif() + run_cmake_command(VerboseBuild-nowork ${CMAKE_COMMAND} --build . --verbose) +endfunction() +run_VerboseBuild() + run_cmake(CustomCommandDepfile-ERROR) run_cmake(IncludeRegexSubdir) diff --git a/Tests/RunCMake/Make/VerboseBuild-build-stdout.txt b/Tests/RunCMake/Make/VerboseBuild-build-stdout.txt new file mode 100644 index 0000000..884bf95 --- /dev/null +++ b/Tests/RunCMake/Make/VerboseBuild-build-stdout.txt @@ -0,0 +1 @@ +.*DEFINE_FOR_VERBOSE_DETECTION.*hello.dir.* diff --git a/Tests/RunCMake/Make/VerboseBuild-build-watcom-stdout.txt b/Tests/RunCMake/Make/VerboseBuild-build-watcom-stdout.txt new file mode 100644 index 0000000..9c558e3 --- /dev/null +++ b/Tests/RunCMake/Make/VerboseBuild-build-watcom-stdout.txt @@ -0,0 +1 @@ +. diff --git a/Tests/RunCMake/Make/VerboseBuild-nowork-gnu-stdout.txt b/Tests/RunCMake/Make/VerboseBuild-nowork-gnu-stdout.txt new file mode 100644 index 0000000..3e65cd9 --- /dev/null +++ b/Tests/RunCMake/Make/VerboseBuild-nowork-gnu-stdout.txt @@ -0,0 +1 @@ +.*Nothing to be done for.*hello.* diff --git a/Tests/RunCMake/Make/VerboseBuild.cmake b/Tests/RunCMake/Make/VerboseBuild.cmake new file mode 100644 index 0000000..70a971d --- /dev/null +++ b/Tests/RunCMake/Make/VerboseBuild.cmake @@ -0,0 +1,8 @@ +enable_language(C) + +# Make sure compile command is not hidden in a temp file. +string(REPLACE "${CMAKE_START_TEMP_FILE}" "" CMAKE_C_COMPILE_OBJECT "${CMAKE_C_COMPILE_OBJECT}") +string(REPLACE "${CMAKE_END_TEMP_FILE}" "" CMAKE_C_COMPILE_OBJECT "${CMAKE_C_COMPILE_OBJECT}") + +add_executable(hello hello.c) +target_compile_definitions(hello PRIVATE "DEFINE_FOR_VERBOSE_DETECTION") diff --git a/Tests/RunCMake/Make/hello.c b/Tests/RunCMake/Make/hello.c new file mode 100644 index 0000000..aac8b4e --- /dev/null +++ b/Tests/RunCMake/Make/hello.c @@ -0,0 +1,7 @@ +#include <stdio.h> + +int main(void) +{ + printf("Hello world!\n"); + return 0; +} diff --git a/Tests/RunCMake/Ninja/RunCMakeTest.cmake b/Tests/RunCMake/Ninja/RunCMakeTest.cmake index 9e1e9a5..8fa650a 100644 --- a/Tests/RunCMake/Ninja/RunCMakeTest.cmake +++ b/Tests/RunCMake/Ninja/RunCMakeTest.cmake @@ -30,6 +30,15 @@ function(run_NoWorkToDo) endfunction() run_NoWorkToDo() +function(run_VerboseBuild) + run_cmake(VerboseBuild) + set(RunCMake_TEST_NO_CLEAN 1) + set(RunCMake_TEST_BINARY_DIR ${RunCMake_BINARY_DIR}/VerboseBuild-build) + run_cmake_command(VerboseBuild-build ${CMAKE_COMMAND} --build . -v --clean-first) + run_cmake_command(VerboseBuild-nowork ${CMAKE_COMMAND} --build . --verbose) +endfunction() +run_VerboseBuild() + function(run_CMP0058 case) # Use a single build tree for a few tests without cleaning. set(RunCMake_TEST_BINARY_DIR ${RunCMake_BINARY_DIR}/CMP0058-${case}-build) diff --git a/Tests/RunCMake/Ninja/VerboseBuild-build-stdout.txt b/Tests/RunCMake/Ninja/VerboseBuild-build-stdout.txt new file mode 100644 index 0000000..884bf95 --- /dev/null +++ b/Tests/RunCMake/Ninja/VerboseBuild-build-stdout.txt @@ -0,0 +1 @@ +.*DEFINE_FOR_VERBOSE_DETECTION.*hello.dir.* diff --git a/Tests/RunCMake/Ninja/VerboseBuild-nowork-stdout.txt b/Tests/RunCMake/Ninja/VerboseBuild-nowork-stdout.txt new file mode 100644 index 0000000..60a9228 --- /dev/null +++ b/Tests/RunCMake/Ninja/VerboseBuild-nowork-stdout.txt @@ -0,0 +1 @@ +^ninja: no work to do diff --git a/Tests/RunCMake/Ninja/VerboseBuild.cmake b/Tests/RunCMake/Ninja/VerboseBuild.cmake new file mode 100644 index 0000000..424e54e --- /dev/null +++ b/Tests/RunCMake/Ninja/VerboseBuild.cmake @@ -0,0 +1,3 @@ +enable_language(C) +add_executable(hello hello.c) +target_compile_definitions(hello PRIVATE "DEFINE_FOR_VERBOSE_DETECTION") diff --git a/Tests/Tutorial/Complete/CMakeLists.txt b/Tests/Tutorial/Complete/CMakeLists.txt new file mode 100644 index 0000000..9658e65 --- /dev/null +++ b/Tests/Tutorial/Complete/CMakeLists.txt @@ -0,0 +1,116 @@ +cmake_minimum_required(VERSION 3.3) +project(Tutorial) + +# control where the static and shared libraries are built so that on windows +# we don't need to tinker with the path to run the executable +set(CMAKE_ARCHIVE_OUTPUT_DIRECTORY "${PROJECT_BINARY_DIR}") +set(CMAKE_LIBRARY_OUTPUT_DIRECTORY "${PROJECT_BINARY_DIR}") +set(CMAKE_RUNTIME_OUTPUT_DIRECTORY "${PROJECT_BINARY_DIR}") + +set(CMAKE_CXX_STANDARD 11) +set(CMAKE_CXX_STANDARD_REQUIRED True) + +option(BUILD_SHARED_LIBS "Build using shared libraries" ON) + +# the version number. +set(Tutorial_VERSION_MAJOR 1) +set(Tutorial_VERSION_MINOR 0) + +if(APPLE) + set(CMAKE_INSTALL_RPATH "@executable_path/../lib") +elseif(UNIX) + set(CMAKE_INSTALL_RPATH "$ORIGIN/../lib") +endif() + +# configure a header file to pass the version number only +configure_file( + "${PROJECT_SOURCE_DIR}/TutorialConfig.h.in" + "${PROJECT_BINARY_DIR}/TutorialConfig.h" + ) + +# add the MathFunctions library +add_subdirectory(MathFunctions) + +# add the executable +add_executable(Tutorial tutorial.cxx) +target_link_libraries(Tutorial MathFunctions) + +# add the binary tree to the search path for include files +# so that we will find TutorialConfig.h +target_include_directories(Tutorial PUBLIC + "${PROJECT_BINARY_DIR}" + ) + +# add the install targets +install(TARGETS Tutorial DESTINATION bin) +install(FILES "${PROJECT_BINARY_DIR}/TutorialConfig.h" + DESTINATION include + ) + +# enable testing +enable_testing() + +# does the application run +add_test(NAME Runs COMMAND Tutorial 25) + +# does the usage message work? +add_test(NAME Usage COMMAND Tutorial) +set_tests_properties(Usage + PROPERTIES PASS_REGULAR_EXPRESSION "Usage:.*number" + ) + +# define a function to simplify adding tests +function(do_test target arg result) + add_test(NAME Comp${arg} COMMAND ${target} ${arg}) + set_tests_properties(Comp${arg} + PROPERTIES PASS_REGULAR_EXPRESSION ${result} + ) +endfunction(do_test) + +# do a bunch of result based tests +do_test(Tutorial 4 "4 is 2") +do_test(Tutorial 9 "9 is 3") +do_test(Tutorial 5 "5 is 2.236") +do_test(Tutorial 7 "7 is 2.645") +do_test(Tutorial 25 "25 is 5") +do_test(Tutorial -25 "-25 is [-nan|nan|0]") +do_test(Tutorial 0.0001 "0.0001 is 0.01") + +include(InstallRequiredSystemLibraries) +set(CPACK_RESOURCE_FILE_LICENSE "${CMAKE_CURRENT_SOURCE_DIR}/License.txt") +set(CPACK_PACKAGE_VERSION_MAJOR "${Tutorial_VERSION_MAJOR}") +set(CPACK_PACKAGE_VERSION_MINOR "${Tutorial_VERSION_MINOR}") +include(CPack) + +# install the configuration targets +install(EXPORT MathFunctionsTargets + FILE MathFunctionsTargets.cmake + DESTINATION lib/cmake/MathFunctions +) + +include(CMakePackageConfigHelpers) +# generate the config file that is includes the exports +configure_package_config_file(${CMAKE_CURRENT_SOURCE_DIR}/Config.cmake.in + "${CMAKE_CURRENT_BINARY_DIR}/MathFunctionsConfig.cmake" + INSTALL_DESTINATION "lib/cmake/example" + NO_SET_AND_CHECK_MACRO + NO_CHECK_REQUIRED_COMPONENTS_MACRO + ) +# generate the version file for the config file +write_basic_package_version_file( + "${CMAKE_CURRENT_BINARY_DIR}/MathFunctionsConfigVersion.cmake" + VERSION "${Tutorial_VERSION_MAJOR}.${Tutorial_VERSION_MINOR}" + COMPATIBILITY AnyNewerVersion +) + +# install the configuration file +install(FILES + ${CMAKE_CURRENT_BINARY_DIR}/MathFunctionsConfig.cmake + DESTINATION lib/cmake/MathFunctions + ) + +# generate the export targets for the build tree +# needs to be after the install(TARGETS ) command +export(EXPORT MathFunctionsTargets + FILE "${CMAKE_CURRENT_BINARY_DIR}/MathFunctionsTargets.cmake" +) diff --git a/Tests/Tutorial/Complete/Config.cmake.in b/Tests/Tutorial/Complete/Config.cmake.in new file mode 100644 index 0000000..17cbabd --- /dev/null +++ b/Tests/Tutorial/Complete/Config.cmake.in @@ -0,0 +1,4 @@ + +@PACKAGE_INIT@ + +include ( "${CMAKE_CURRENT_LIST_DIR}/MathFunctionsTargets.cmake" ) diff --git a/Tests/Tutorial/Step6/License.txt b/Tests/Tutorial/Complete/License.txt index 673d724..c62d00b 100644 --- a/Tests/Tutorial/Step6/License.txt +++ b/Tests/Tutorial/Complete/License.txt @@ -1,2 +1,2 @@ This is the open source License.txt file introduced in -CMake/Tests/Tutorial/Step6... +CMake/Tutorial/Step7... diff --git a/Tests/Tutorial/Complete/MathFunctions/CMakeLists.txt b/Tests/Tutorial/Complete/MathFunctions/CMakeLists.txt new file mode 100644 index 0000000..161ad64 --- /dev/null +++ b/Tests/Tutorial/Complete/MathFunctions/CMakeLists.txt @@ -0,0 +1,68 @@ + +# add the library that runs +add_library(MathFunctions MathFunctions.cxx) + +# state that anybody linking to us needs to include the current source dir +# to find MathFunctions.h, while we don't. +target_include_directories(MathFunctions + INTERFACE + $<BUILD_INTERFACE:${CMAKE_CURRENT_SOURCE_DIR}> + $<INSTALL_INTERFACE:include> + ) + +# should we use our own math functions +option(USE_MYMATH "Use tutorial provided math implementation" ON) +if(USE_MYMATH) + + # does this system provide the log and exp functions? + include(CheckSymbolExists) + set(CMAKE_REQUIRED_LIBRARIES "m") + check_symbol_exists(log "math.h" HAVE_LOG) + check_symbol_exists(exp "math.h" HAVE_EXP) + + # first we add the executable that generates the table + add_executable(MakeTable MakeTable.cxx) + + # add the command to generate the source code + add_custom_command( + OUTPUT ${CMAKE_CURRENT_BINARY_DIR}/Table.h + COMMAND MakeTable ${CMAKE_CURRENT_BINARY_DIR}/Table.h + DEPENDS MakeTable + ) + + # library that just does sqrt + add_library(SqrtLibrary STATIC + mysqrt.cxx + ${CMAKE_CURRENT_BINARY_DIR}/Table.h + ) + + # state that we depend on our binary dir to find Table.h + target_include_directories(SqrtLibrary PRIVATE + ${CMAKE_CURRENT_BINARY_DIR} + ) + + set_target_properties(SqrtLibrary PROPERTIES + POSITION_INDEPENDENT_CODE ${BUILD_SHARED_LIBS} + ) + + target_compile_definitions(SqrtLibrary PRIVATE + "$<$<BOOL:${HAVE_LOG}>:HAVE_LOG>" + "$<$<BOOL:${HAVE_EXP}>:HAVE_EXP>" + ) + target_link_libraries(MathFunctions PRIVATE SqrtLibrary) +endif() + +target_compile_definitions(MathFunctions PRIVATE "$<$<BOOL:${USE_MYMATH}>:USE_MYMATH>") + +# define the symbol stating we are using the declspec(dllexport) when +# building on windows +target_compile_definitions(MathFunctions PRIVATE "EXPORTING_MYMATH") + +# setup the version numbering +set_property(TARGET MathFunctions PROPERTY VERSION "1.0.0") +set_property(TARGET MathFunctions PROPERTY SOVERSION "1") + +install(TARGETS MathFunctions + DESTINATION lib + EXPORT MathFunctionsTargets) +install(FILES MathFunctions.h DESTINATION include) diff --git a/Tests/Tutorial/Complete/MathFunctions/MakeTable.cxx b/Tests/Tutorial/Complete/MathFunctions/MakeTable.cxx new file mode 100644 index 0000000..ee58556 --- /dev/null +++ b/Tests/Tutorial/Complete/MathFunctions/MakeTable.cxx @@ -0,0 +1,25 @@ +// A simple program that builds a sqrt table +#include <cmath> +#include <fstream> +#include <iostream> + +int main(int argc, char* argv[]) +{ + // make sure we have enough arguments + if (argc < 2) { + return 1; + } + + std::ofstream fout(argv[1], std::ios_base::out); + const bool fileOpen = fout.is_open(); + if (fileOpen) { + fout << "double sqrtTable[] = {" << std::endl; + for (int i = 0; i < 10; ++i) { + fout << sqrt(static_cast<double>(i)) << "," << std::endl; + } + // close the table with a zero + fout << "0};" << std::endl; + fout.close(); + } + return fileOpen ? 0 : 1; // return 0 if wrote the file +} diff --git a/Tests/Tutorial/Complete/MathFunctions/MathFunctions.cxx b/Tests/Tutorial/Complete/MathFunctions/MathFunctions.cxx new file mode 100644 index 0000000..5351184 --- /dev/null +++ b/Tests/Tutorial/Complete/MathFunctions/MathFunctions.cxx @@ -0,0 +1,18 @@ + +#include "MathFunctions.h" +#include <cmath> + +#ifdef USE_MYMATH +# include "mysqrt.h" +#endif + +namespace mathfunctions { +double sqrt(double x) +{ +#ifdef USE_MYMATH + return detail::mysqrt(x); +#else + return std::sqrt(x); +#endif +} +} diff --git a/Tests/Tutorial/Complete/MathFunctions/MathFunctions.h b/Tests/Tutorial/Complete/MathFunctions/MathFunctions.h new file mode 100644 index 0000000..3fb547b --- /dev/null +++ b/Tests/Tutorial/Complete/MathFunctions/MathFunctions.h @@ -0,0 +1,14 @@ + +#if defined(_WIN32) +# if defined(EXPORTING_MYMATH) +# define DECLSPEC __declspec(dllexport) +# else +# define DECLSPEC __declspec(dllimport) +# endif +#else // non windows +# define DECLSPEC +#endif + +namespace mathfunctions { +double DECLSPEC sqrt(double x); +} diff --git a/Tests/Tutorial/Complete/MathFunctions/mysqrt.cxx b/Tests/Tutorial/Complete/MathFunctions/mysqrt.cxx new file mode 100644 index 0000000..96d9421 --- /dev/null +++ b/Tests/Tutorial/Complete/MathFunctions/mysqrt.cxx @@ -0,0 +1,45 @@ +#include "MathFunctions.h" +#include <iostream> + +// include the generated table +#include "Table.h" + +#include <cmath> + +namespace mathfunctions { +namespace detail { +// a hack square root calculation using simple operations +double mysqrt(double x) +{ + if (x <= 0) { + return 0; + } + + // if we have both log and exp then use them +#if defined(HAVE_LOG) && defined(HAVE_EXP) + double result = exp(log(x) * 0.5); + std::cout << "Computing sqrt of " << x << " to be " << result << " using log" + << std::endl; +#else + // use the table to help find an initial value + double result = x; + if (x >= 1 && x < 10) { + result = sqrtTable[static_cast<int>(x)]; + } + + // if we have both log and exp then use them + + // do ten iterations + for (int i = 0; i < 10; ++i) { + if (result <= 0) { + result = 0.1; + } + double delta = x - (result * result); + result = result + 0.5 * delta / result; + std::cout << "Computing sqrt of " << x << " to be " << result << std::endl; + } +#endif + return result; +} +} +} diff --git a/Tests/Tutorial/Complete/MathFunctions/mysqrt.h b/Tests/Tutorial/Complete/MathFunctions/mysqrt.h new file mode 100644 index 0000000..e1c42ef --- /dev/null +++ b/Tests/Tutorial/Complete/MathFunctions/mysqrt.h @@ -0,0 +1,6 @@ + +namespace mathfunctions { +namespace detail { +double mysqrt(double x); +} +} diff --git a/Tests/Tutorial/Complete/TutorialConfig.h.in b/Tests/Tutorial/Complete/TutorialConfig.h.in new file mode 100644 index 0000000..8cd2fc9 --- /dev/null +++ b/Tests/Tutorial/Complete/TutorialConfig.h.in @@ -0,0 +1,3 @@ +// the configured version number +#define Tutorial_VERSION_MAJOR @Tutorial_VERSION_MAJOR@ +#define Tutorial_VERSION_MINOR @Tutorial_VERSION_MINOR@ diff --git a/Tests/Tutorial/Complete/tutorial.cxx b/Tests/Tutorial/Complete/tutorial.cxx new file mode 100644 index 0000000..443d195 --- /dev/null +++ b/Tests/Tutorial/Complete/tutorial.cxx @@ -0,0 +1,25 @@ +// A simple program that computes the square root of a number +#include <iostream> +#include <sstream> +#include <string> + +#include "MathFunctions.h" +#include "TutorialConfig.h" + +int main(int argc, char* argv[]) +{ + if (argc < 2) { + std::cout << argv[0] << " Version " << Tutorial_VERSION_MAJOR << "." + << Tutorial_VERSION_MAJOR << std::endl; + std::cout << "Usage: " << argv[0] << " number" << std::endl; + return 1; + } + + double inputValue = std::stod(argv[1]); + + const double outputValue = mathfunctions::sqrt(inputValue); + + std::cout << "The square root of " << inputValue << " is " << outputValue + << std::endl; + return 0; +} diff --git a/Tests/Tutorial/Consumer/CMakeLists.txt b/Tests/Tutorial/Consumer/CMakeLists.txt new file mode 100644 index 0000000..4033b4d --- /dev/null +++ b/Tests/Tutorial/Consumer/CMakeLists.txt @@ -0,0 +1,51 @@ +cmake_minimum_required(VERSION 3.3) + +if(NOT DEFINED CMAKE_CXX_STANDARD) + set(CMAKE_CXX_STANDARD 11) + set(CMAKE_CXX_STANDARD_REQUIRED True) +endif() + + +function(find_external_dependency name) + set(${name}_ROOT "" CACHE PATH "Root directory to find ${name}") + mark_as_advanced(${name}_DIR) + find_package(${name} PATHS ${${name}_ROOT} REQUIRED) +endfunction() + + +project(Consumer) + +find_external_dependency(MathFunctions) + +add_library(consumer consumer.cxx) +target_link_libraries(consumer PUBLIC MathFunctions) + +# install the consumer library +install(TARGETS consumer DESTINATION bin EXPORT ConsumerTargets) + +# install the configuration targets +install(EXPORT ConsumerTargets + FILE ConsumerTargets.cmake + DESTINATION lib/cmake/Consumer +) + +include(CMakePackageConfigHelpers) +# generate the config file that is includes the exports +configure_package_config_file(${CMAKE_CURRENT_SOURCE_DIR}/Config.cmake.in + "${CMAKE_CURRENT_BINARY_DIR}/ConsumerConfig.cmake" + INSTALL_DESTINATION "lib/cmake/example" + NO_SET_AND_CHECK_MACRO + NO_CHECK_REQUIRED_COMPONENTS_MACRO + ) + +# install the configuration file +install(FILES + ${CMAKE_CURRENT_BINARY_DIR}/ConsumerConfig.cmake + DESTINATION lib/cmake/Consumer + ) + +# generate the export targets for the build tree +# needs to be after the install(TARGETS ) command +export(EXPORT ConsumerTargets + FILE "${CMAKE_CURRENT_BINARY_DIR}/ConsumerTargets.cmake" +) diff --git a/Tests/Tutorial/Consumer/Config.cmake.in b/Tests/Tutorial/Consumer/Config.cmake.in new file mode 100644 index 0000000..0b3f1e4 --- /dev/null +++ b/Tests/Tutorial/Consumer/Config.cmake.in @@ -0,0 +1,14 @@ + +@PACKAGE_INIT@ + +include(CMakeFindDependencyMacro) + +function(find_external_dependency name) + set(${name}_ROOT "" CACHE PATH "Root directory to find ${name}") + mark_as_advanced(${name}_DIR) + find_dependency(${name} PATHS ${${name}_ROOT} REQUIRED) +endfunction() + +find_external_dependency(MathFunctions) + +include ( "${CMAKE_CURRENT_LIST_DIR}/ConsumerTargets.cmake" ) diff --git a/Tests/Tutorial/Consumer/consumer.cxx b/Tests/Tutorial/Consumer/consumer.cxx new file mode 100644 index 0000000..ae7877b --- /dev/null +++ b/Tests/Tutorial/Consumer/consumer.cxx @@ -0,0 +1,11 @@ +// A simple function that computes the square root of a number +#include <iostream> +#include <sstream> +#include <string> + +#include "MathFunctions.h" + +double string_square_root(std::string const& value) +{ + return mathfunctions::sqrt(std::stod(value)); +} diff --git a/Tests/Tutorial/Consumer/directions.txt b/Tests/Tutorial/Consumer/directions.txt new file mode 100644 index 0000000..6a70aab --- /dev/null +++ b/Tests/Tutorial/Consumer/directions.txt @@ -0,0 +1,6 @@ +# Import a CMake Project# + +This examples shows how a project can find other CMake packages that +generated Config.cmake files. + +It also shows how to state a projects external dependencies when generating a Config.cmake. diff --git a/Tests/Tutorial/MultiPackage/CMakeLists.txt b/Tests/Tutorial/MultiPackage/CMakeLists.txt new file mode 100644 index 0000000..067e807 --- /dev/null +++ b/Tests/Tutorial/MultiPackage/CMakeLists.txt @@ -0,0 +1,109 @@ +cmake_minimum_required(VERSION 3.3) +project(Tutorial) + +# control how we mark up Debug libraries compared to Release libraries +set(CMAKE_DEBUG_POSTFIX "-d") + +# control where the static and shared libraries are built so that on windows +# we don't need to tinker with the path to run the executable +set(CMAKE_ARCHIVE_OUTPUT_DIRECTORY "${PROJECT_BINARY_DIR}") +set(CMAKE_LIBRARY_OUTPUT_DIRECTORY "${PROJECT_BINARY_DIR}") + +option(BUILD_SHARED_LIBS "Build using shared libraries" ON) + +# the version number. +set(Tutorial_VERSION_MAJOR 1) +set(Tutorial_VERSION_MINOR 0) + +# configure a header file to pass the version number only +configure_file( + "${PROJECT_SOURCE_DIR}/TutorialConfig.h.in" + "${PROJECT_BINARY_DIR}/TutorialConfig.h" + ) + +# add the MathFunctions library +add_subdirectory(MathFunctions) + +# add the executable +add_executable(Tutorial tutorial.cxx) +target_link_libraries(Tutorial MathFunctions) + +# add the binary tree to the search path for include files +# so that we will find TutorialConfig.h +target_include_directories(Tutorial PUBLIC + "${PROJECT_BINARY_DIR}" + ) + +# add the install targets +install(TARGETS Tutorial DESTINATION bin) +install(FILES "${PROJECT_BINARY_DIR}/TutorialConfig.h" + DESTINATION include + ) + +# enable testing +enable_testing() + +# does the application run +add_test(NAME Runs COMMAND Tutorial 25) + +# does the usage message work? +add_test(NAME Usage COMMAND Tutorial) +set_tests_properties(Usage + PROPERTIES PASS_REGULAR_EXPRESSION "Usage:.*number" + ) + +# define a function to simplify adding tests +function(do_test target arg result) + add_test(NAME Comp${arg} COMMAND ${target} ${arg}) + set_tests_properties(Comp${arg} + PROPERTIES PASS_REGULAR_EXPRESSION ${result} + ) +endfunction(do_test) + +# do a bunch of result based tests +do_test(Tutorial 4 "4 is 2") +do_test(Tutorial 9 "9 is 3") +do_test(Tutorial 5 "5 is 2.236") +do_test(Tutorial 7 "7 is 2.645") +do_test(Tutorial 25 "25 is 5") +do_test(Tutorial -25 "-25 is [-nan|nan|0]") +do_test(Tutorial 0.0001 "0.0001 is 0.01") + +include(InstallRequiredSystemLibraries) +set(CPACK_RESOURCE_FILE_LICENSE "${CMAKE_CURRENT_SOURCE_DIR}/License.txt") +set(CPACK_PACKAGE_VERSION_MAJOR "${Tutorial_VERSION_MAJOR}") +set(CPACK_PACKAGE_VERSION_MINOR "${Tutorial_VERSION_MINOR}") +include(CPack) + +# install the configuration targets +install(EXPORT MathFunctionsTargets + FILE MathFunctionsTargets.cmake + DESTINATION lib/cmake/MathFunctions +) + +include(CMakePackageConfigHelpers) +# generate the config file that is includes the exports +configure_package_config_file(${CMAKE_CURRENT_SOURCE_DIR}/Config.cmake.in + "${CMAKE_CURRENT_BINARY_DIR}/MathFunctionsConfig.cmake" + INSTALL_DESTINATION "lib/cmake/example" + NO_SET_AND_CHECK_MACRO + NO_CHECK_REQUIRED_COMPONENTS_MACRO + ) +# generate the version file for the config file +write_basic_package_version_file( + "${CMAKE_CURRENT_BINARY_DIR}/MathFunctionsConfigVersion.cmake" + VERSION "${Tutorial_VERSION_MAJOR}.${Tutorial_VERSION_MINOR}" + COMPATIBILITY AnyNewerVersion +) + +# install the configuration file +install(FILES + ${CMAKE_CURRENT_BINARY_DIR}/MathFunctionsConfig.cmake + DESTINATION lib/cmake/MathFunctions + ) + +# generate the export targets for the build tree +# needs to be after the install(TARGETS ) command +export(EXPORT MathFunctionsTargets + FILE "${CMAKE_CURRENT_BINARY_DIR}/MathFunctionsTargets.cmake" +) diff --git a/Tests/Tutorial/MultiPackage/Config.cmake.in b/Tests/Tutorial/MultiPackage/Config.cmake.in new file mode 100644 index 0000000..17cbabd --- /dev/null +++ b/Tests/Tutorial/MultiPackage/Config.cmake.in @@ -0,0 +1,4 @@ + +@PACKAGE_INIT@ + +include ( "${CMAKE_CURRENT_LIST_DIR}/MathFunctionsTargets.cmake" ) diff --git a/Tests/Tutorial/MultiPackage/License.txt b/Tests/Tutorial/MultiPackage/License.txt new file mode 100644 index 0000000..c62d00b --- /dev/null +++ b/Tests/Tutorial/MultiPackage/License.txt @@ -0,0 +1,2 @@ +This is the open source License.txt file introduced in +CMake/Tutorial/Step7... diff --git a/Tests/Tutorial/MultiPackage/MathFunctions/CMakeLists.txt b/Tests/Tutorial/MultiPackage/MathFunctions/CMakeLists.txt new file mode 100644 index 0000000..161ad64 --- /dev/null +++ b/Tests/Tutorial/MultiPackage/MathFunctions/CMakeLists.txt @@ -0,0 +1,68 @@ + +# add the library that runs +add_library(MathFunctions MathFunctions.cxx) + +# state that anybody linking to us needs to include the current source dir +# to find MathFunctions.h, while we don't. +target_include_directories(MathFunctions + INTERFACE + $<BUILD_INTERFACE:${CMAKE_CURRENT_SOURCE_DIR}> + $<INSTALL_INTERFACE:include> + ) + +# should we use our own math functions +option(USE_MYMATH "Use tutorial provided math implementation" ON) +if(USE_MYMATH) + + # does this system provide the log and exp functions? + include(CheckSymbolExists) + set(CMAKE_REQUIRED_LIBRARIES "m") + check_symbol_exists(log "math.h" HAVE_LOG) + check_symbol_exists(exp "math.h" HAVE_EXP) + + # first we add the executable that generates the table + add_executable(MakeTable MakeTable.cxx) + + # add the command to generate the source code + add_custom_command( + OUTPUT ${CMAKE_CURRENT_BINARY_DIR}/Table.h + COMMAND MakeTable ${CMAKE_CURRENT_BINARY_DIR}/Table.h + DEPENDS MakeTable + ) + + # library that just does sqrt + add_library(SqrtLibrary STATIC + mysqrt.cxx + ${CMAKE_CURRENT_BINARY_DIR}/Table.h + ) + + # state that we depend on our binary dir to find Table.h + target_include_directories(SqrtLibrary PRIVATE + ${CMAKE_CURRENT_BINARY_DIR} + ) + + set_target_properties(SqrtLibrary PROPERTIES + POSITION_INDEPENDENT_CODE ${BUILD_SHARED_LIBS} + ) + + target_compile_definitions(SqrtLibrary PRIVATE + "$<$<BOOL:${HAVE_LOG}>:HAVE_LOG>" + "$<$<BOOL:${HAVE_EXP}>:HAVE_EXP>" + ) + target_link_libraries(MathFunctions PRIVATE SqrtLibrary) +endif() + +target_compile_definitions(MathFunctions PRIVATE "$<$<BOOL:${USE_MYMATH}>:USE_MYMATH>") + +# define the symbol stating we are using the declspec(dllexport) when +# building on windows +target_compile_definitions(MathFunctions PRIVATE "EXPORTING_MYMATH") + +# setup the version numbering +set_property(TARGET MathFunctions PROPERTY VERSION "1.0.0") +set_property(TARGET MathFunctions PROPERTY SOVERSION "1") + +install(TARGETS MathFunctions + DESTINATION lib + EXPORT MathFunctionsTargets) +install(FILES MathFunctions.h DESTINATION include) diff --git a/Tests/Tutorial/MultiPackage/MathFunctions/MakeTable.cxx b/Tests/Tutorial/MultiPackage/MathFunctions/MakeTable.cxx new file mode 100644 index 0000000..ee58556 --- /dev/null +++ b/Tests/Tutorial/MultiPackage/MathFunctions/MakeTable.cxx @@ -0,0 +1,25 @@ +// A simple program that builds a sqrt table +#include <cmath> +#include <fstream> +#include <iostream> + +int main(int argc, char* argv[]) +{ + // make sure we have enough arguments + if (argc < 2) { + return 1; + } + + std::ofstream fout(argv[1], std::ios_base::out); + const bool fileOpen = fout.is_open(); + if (fileOpen) { + fout << "double sqrtTable[] = {" << std::endl; + for (int i = 0; i < 10; ++i) { + fout << sqrt(static_cast<double>(i)) << "," << std::endl; + } + // close the table with a zero + fout << "0};" << std::endl; + fout.close(); + } + return fileOpen ? 0 : 1; // return 0 if wrote the file +} diff --git a/Tests/Tutorial/MultiPackage/MathFunctions/MathFunctions.cxx b/Tests/Tutorial/MultiPackage/MathFunctions/MathFunctions.cxx new file mode 100644 index 0000000..5351184 --- /dev/null +++ b/Tests/Tutorial/MultiPackage/MathFunctions/MathFunctions.cxx @@ -0,0 +1,18 @@ + +#include "MathFunctions.h" +#include <cmath> + +#ifdef USE_MYMATH +# include "mysqrt.h" +#endif + +namespace mathfunctions { +double sqrt(double x) +{ +#ifdef USE_MYMATH + return detail::mysqrt(x); +#else + return std::sqrt(x); +#endif +} +} diff --git a/Tests/Tutorial/MultiPackage/MathFunctions/MathFunctions.h b/Tests/Tutorial/MultiPackage/MathFunctions/MathFunctions.h new file mode 100644 index 0000000..3fb547b --- /dev/null +++ b/Tests/Tutorial/MultiPackage/MathFunctions/MathFunctions.h @@ -0,0 +1,14 @@ + +#if defined(_WIN32) +# if defined(EXPORTING_MYMATH) +# define DECLSPEC __declspec(dllexport) +# else +# define DECLSPEC __declspec(dllimport) +# endif +#else // non windows +# define DECLSPEC +#endif + +namespace mathfunctions { +double DECLSPEC sqrt(double x); +} diff --git a/Tests/Tutorial/MultiPackage/MathFunctions/mysqrt.cxx b/Tests/Tutorial/MultiPackage/MathFunctions/mysqrt.cxx new file mode 100644 index 0000000..96d9421 --- /dev/null +++ b/Tests/Tutorial/MultiPackage/MathFunctions/mysqrt.cxx @@ -0,0 +1,45 @@ +#include "MathFunctions.h" +#include <iostream> + +// include the generated table +#include "Table.h" + +#include <cmath> + +namespace mathfunctions { +namespace detail { +// a hack square root calculation using simple operations +double mysqrt(double x) +{ + if (x <= 0) { + return 0; + } + + // if we have both log and exp then use them +#if defined(HAVE_LOG) && defined(HAVE_EXP) + double result = exp(log(x) * 0.5); + std::cout << "Computing sqrt of " << x << " to be " << result << " using log" + << std::endl; +#else + // use the table to help find an initial value + double result = x; + if (x >= 1 && x < 10) { + result = sqrtTable[static_cast<int>(x)]; + } + + // if we have both log and exp then use them + + // do ten iterations + for (int i = 0; i < 10; ++i) { + if (result <= 0) { + result = 0.1; + } + double delta = x - (result * result); + result = result + 0.5 * delta / result; + std::cout << "Computing sqrt of " << x << " to be " << result << std::endl; + } +#endif + return result; +} +} +} diff --git a/Tests/Tutorial/MultiPackage/MathFunctions/mysqrt.h b/Tests/Tutorial/MultiPackage/MathFunctions/mysqrt.h new file mode 100644 index 0000000..e1c42ef --- /dev/null +++ b/Tests/Tutorial/MultiPackage/MathFunctions/mysqrt.h @@ -0,0 +1,6 @@ + +namespace mathfunctions { +namespace detail { +double mysqrt(double x); +} +} diff --git a/Tests/Tutorial/MultiPackage/MultiCPackConfig.cmake b/Tests/Tutorial/MultiPackage/MultiCPackConfig.cmake new file mode 100644 index 0000000..403b633 --- /dev/null +++ b/Tests/Tutorial/MultiPackage/MultiCPackConfig.cmake @@ -0,0 +1,7 @@ + +include("release/CPackConfig.cmake") + +set(CPACK_INSTALL_CMAKE_PROJECTS + "debug;Tutorial;ALL;/" + "release;Tutorial;ALL;/" + ) diff --git a/Tests/Tutorial/MultiPackage/TutorialConfig.h.in b/Tests/Tutorial/MultiPackage/TutorialConfig.h.in new file mode 100644 index 0000000..8cd2fc9 --- /dev/null +++ b/Tests/Tutorial/MultiPackage/TutorialConfig.h.in @@ -0,0 +1,3 @@ +// the configured version number +#define Tutorial_VERSION_MAJOR @Tutorial_VERSION_MAJOR@ +#define Tutorial_VERSION_MINOR @Tutorial_VERSION_MINOR@ diff --git a/Tests/Tutorial/MultiPackage/directions.txt b/Tests/Tutorial/MultiPackage/directions.txt new file mode 100644 index 0000000..c3102bb --- /dev/null +++ b/Tests/Tutorial/MultiPackage/directions.txt @@ -0,0 +1,34 @@ +# Packaging Debug and Release # + +By default CMake is model is that a build directory only contains a single +configuration, be it Debug, Release, MinSizeRel, or RelWithDebInfo. + +But it is possible to setup CPack to bundle multiple build directories at the same +time to build a package that contains multiple configurations of the same project. + +First we need to ahead and construct a directory called 'multi_config' this +will contain all the builds that we want to package together. + +Second create a 'debug' and 'release' directory underneath 'multi_config'. At +the end you should have a layout that looks like: + +─ multi_config + ├── debug + └── release + +Now we need to setup debug and release builds, which would roughly entail +the following: + + cd debug + cmake -DCMAKE_BUILD_TYPE=Debug ../../MultiPackage/ + cmake --build . + cd ../release + cmake -DCMAKE_BUILD_TYPE=Release ../../MultiPackage/ + cmake --build . + cd .. + + +Now that both the debug and release builds are complete we can now use +the custom MultiCPackConfig to package both builds into a single release. + + cpack --config ../../MultiPackage/MultiCPackConfig.cmake diff --git a/Tests/Tutorial/MultiPackage/tutorial.cxx b/Tests/Tutorial/MultiPackage/tutorial.cxx new file mode 100644 index 0000000..443d195 --- /dev/null +++ b/Tests/Tutorial/MultiPackage/tutorial.cxx @@ -0,0 +1,25 @@ +// A simple program that computes the square root of a number +#include <iostream> +#include <sstream> +#include <string> + +#include "MathFunctions.h" +#include "TutorialConfig.h" + +int main(int argc, char* argv[]) +{ + if (argc < 2) { + std::cout << argv[0] << " Version " << Tutorial_VERSION_MAJOR << "." + << Tutorial_VERSION_MAJOR << std::endl; + std::cout << "Usage: " << argv[0] << " number" << std::endl; + return 1; + } + + double inputValue = std::stod(argv[1]); + + const double outputValue = mathfunctions::sqrt(inputValue); + + std::cout << "The square root of " << inputValue << " is " << outputValue + << std::endl; + return 0; +} diff --git a/Tests/Tutorial/Readme.txt b/Tests/Tutorial/Readme.txt new file mode 100644 index 0000000..74eb01a --- /dev/null +++ b/Tests/Tutorial/Readme.txt @@ -0,0 +1,16 @@ + +Step 0: A Starting Point +Step 1: Configure a File and C++11 Controls +Step 2: Adding a Library +Step 3: Usage Requirements for Library +Step 4: Installing and Testing +Step 5: System Introspection +Step 6: Custom Command and Generated File +Step 7: Building an Installer +Step 8: CDash submission +Step 9: Mixing Static and Shared +Step 10: Generator Expressions +Step 11: Adding Export Configuration +Complete: End result of Step 11 +Consumer: Example of Import Packages +MultiPackage: How to package Debug and Release versions diff --git a/Tests/Tutorial/Step1/CMakeLists.txt b/Tests/Tutorial/Step1/CMakeLists.txt index e461d3c..141f0c2 100644 --- a/Tests/Tutorial/Step1/CMakeLists.txt +++ b/Tests/Tutorial/Step1/CMakeLists.txt @@ -1,20 +1,3 @@ -cmake_minimum_required (VERSION 2.6) -project (Tutorial) +project(Tutorial) -# The version number. -set (Tutorial_VERSION_MAJOR 1) -set (Tutorial_VERSION_MINOR 0) - -# configure a header file to pass some of the CMake settings -# to the source code -configure_file ( - "${PROJECT_SOURCE_DIR}/TutorialConfig.h.in" - "${PROJECT_BINARY_DIR}/TutorialConfig.h" - ) - -# add the binary tree to the search path for include files -# so that we will find TutorialConfig.h -include_directories("${PROJECT_BINARY_DIR}") - -# add the executable add_executable(Tutorial tutorial.cxx) diff --git a/Tests/Tutorial/Step1/directions.txt b/Tests/Tutorial/Step1/directions.txt new file mode 100644 index 0000000..827d775 --- /dev/null +++ b/Tests/Tutorial/Step1/directions.txt @@ -0,0 +1,95 @@ +# Adding a Version Number and Configured Header File # + +The first feature we will add is to provide our executable and project with a +version number. While we could do this exclusively in the source code, using +CMakeLists provides more flexibility. + +To add a version number we modify the CMakeLists file as follows: + + cmake_minimum_required(VERSION 3.3) + project(Tutorial) + + # the version number. + set(Tutorial_VERSION_MAJOR 1) + set(Tutorial_VERSION_MINOR 0) + + # configure a header file to pass some of the CMake settings + # to the source code + configure_file( + "${PROJECT_SOURCE_DIR}/TutorialConfig.h.in" + "${PROJECT_BINARY_DIR}/TutorialConfig.h" + ) + + # add the executable + add_executable(Tutorial tutorial.cxx) + + # add the binary tree to the search path for include files + # so that we will find TutorialConfig.h + target_include_directories(Tutorial PUBLIC + "${PROJECT_BINARY_DIR}" + ) + + +We then create a TutorialConfig.h.in file in the source tree with the +following contents: + + // the configured options and settings for Tutorial + #define Tutorial_VERSION_MAJOR @Tutorial_VERSION_MAJOR@ + #define Tutorial_VERSION_MINOR @Tutorial_VERSION_MINOR@ + +When CMake configures this header file the values for @Tutorial_VERSION_MAJOR@ +and @Tutorial_VERSION_MINOR@ will be replaced by the values from the CMakeLists +file. Next we modify tutorial.cxx to include the configured header file and to +make use of the version numbers. The resulting source code is listed below. + + // A simple program that computes the square root of a number + #include <cmath> + #include <iostream> + #include <string> + #include <sstream> + + #include "TutorialConfig.h" + + int main (int argc, char *argv[]) + { + if (argc < 2) { + std::cout << argv[0] << " Version " + << Tutorial_VERSION_MAJOR << "." << Tutorial_VERSION_MINOR + << std::endl; + std::cout << "Usage: " << argv[0] << " number" << std::endl; + return 1; + } + + double inputValue = atof(argv[1]); + + double outputValue = sqrt(inputValue); + std::cout << "The square root of " + << inputValue << " is " << outputValue << std::endl; + return 0; + } + +# Adding C++11 support # + +Let's add some C++11 features to our project. We will need to explicitly state +in the CMake code that it should use the correct flags. The easiest way to +enable C++11 support for CMake is by using the CMAKE_CXX_STANDARD +and CMAKE_CXX_STANDARD_REQUIRED variables. + +First, replace `atof` with `std::stod` in tutorial.cxx. + +Then, add the CMAKE_CXX_STANDARD and CMAKE_CXX_STANDARD_REQUIRED variables to +the CMakeLists file. The STANADARD value should be set to 11, and REQUIRED +should be set to True. + + +# Build and Test # + +Run cmake or cmake-gui to configure the project and then build it with your +chosen build tool + +cd to the directory where Tutorial was built (likely the make directory or +a Debug or Release build configuration subdirectory) and run these commands: + + Tutorial 4294967296 + Tutorial 10 + Tutorial diff --git a/Tests/Tutorial/Step1/tutorial.cxx b/Tests/Tutorial/Step1/tutorial.cxx index 7a13376..f8dd0c6 100644 --- a/Tests/Tutorial/Step1/tutorial.cxx +++ b/Tests/Tutorial/Step1/tutorial.cxx @@ -1,19 +1,20 @@ // A simple program that computes the square root of a number -#include "TutorialConfig.h" -#include <math.h> -#include <stdio.h> -#include <stdlib.h> +#include <cmath> +#include <cstdlib> +#include <iostream> +#include <string> int main(int argc, char* argv[]) { if (argc < 2) { - fprintf(stdout, "%s Version %d.%d\n", argv[0], Tutorial_VERSION_MAJOR, - Tutorial_VERSION_MINOR); - fprintf(stdout, "Usage: %s number\n", argv[0]); + std::cout << "Usage: " << argv[0] << " number" << std::endl; return 1; } + double inputValue = atof(argv[1]); + double outputValue = sqrt(inputValue); - fprintf(stdout, "The square root of %g is %g\n", inputValue, outputValue); + std::cout << "The square root of " << inputValue << " is " << outputValue + << std::endl; return 0; } diff --git a/Tests/Tutorial/Step10/CMakeLists.txt b/Tests/Tutorial/Step10/CMakeLists.txt new file mode 100644 index 0000000..b1d46c4 --- /dev/null +++ b/Tests/Tutorial/Step10/CMakeLists.txt @@ -0,0 +1,77 @@ +cmake_minimum_required(VERSION 3.3) +project(Tutorial) + +# control where the static and shared libraries are built so that on windows +# we don't need to tinker with the path to run the executable +set(CMAKE_ARCHIVE_OUTPUT_DIRECTORY "${PROJECT_BINARY_DIR}") +set(CMAKE_LIBRARY_OUTPUT_DIRECTORY "${PROJECT_BINARY_DIR}") +set(CMAKE_RUNTIME_OUTPUT_DIRECTORY "${PROJECT_BINARY_DIR}") + +set(CMAKE_CXX_STANDARD 11) +set(CMAKE_CXX_STANDARD_REQUIRED True) + +option(BUILD_SHARED_LIBS "Build using shared libraries" ON) + +# the version number. +set(Tutorial_VERSION_MAJOR 1) +set(Tutorial_VERSION_MINOR 0) + +# configure a header file to pass the version number only +configure_file( + "${PROJECT_SOURCE_DIR}/TutorialConfig.h.in" + "${PROJECT_BINARY_DIR}/TutorialConfig.h" + ) + +# add the MathFunctions library +add_subdirectory(MathFunctions) + +# add the executable +add_executable(Tutorial tutorial.cxx) +target_link_libraries(Tutorial MathFunctions) + +# add the binary tree to the search path for include files +# so that we will find TutorialConfig.h +target_include_directories(Tutorial PUBLIC + "${PROJECT_BINARY_DIR}" + ) + +# add the install targets +install(TARGETS Tutorial DESTINATION bin) +install(FILES "${PROJECT_BINARY_DIR}/TutorialConfig.h" + DESTINATION include + ) + +# enable testing +enable_testing() + +# does the application run +add_test(NAME Runs COMMAND Tutorial 25) + +# does the usage message work? +add_test(NAME Usage COMMAND Tutorial) +set_tests_properties(Usage + PROPERTIES PASS_REGULAR_EXPRESSION "Usage:.*number" + ) + +# define a function to simplify adding tests +function(do_test target arg result) + add_test(NAME Comp${arg} COMMAND ${target} ${arg}) + set_tests_properties(Comp${arg} + PROPERTIES PASS_REGULAR_EXPRESSION ${result} + ) +endfunction(do_test) + +# do a bunch of result based tests +do_test(Tutorial 4 "4 is 2") +do_test(Tutorial 9 "9 is 3") +do_test(Tutorial 5 "5 is 2.236") +do_test(Tutorial 7 "7 is 2.645") +do_test(Tutorial 25 "25 is 5") +do_test(Tutorial -25 "-25 is [-nan|nan|0]") +do_test(Tutorial 0.0001 "0.0001 is 0.01") + +include(InstallRequiredSystemLibraries) +set(CPACK_RESOURCE_FILE_LICENSE "${CMAKE_CURRENT_SOURCE_DIR}/License.txt") +set(CPACK_PACKAGE_VERSION_MAJOR "${Tutorial_VERSION_MAJOR}") +set(CPACK_PACKAGE_VERSION_MINOR "${Tutorial_VERSION_MINOR}") +include(CPack) diff --git a/Tests/Tutorial/Step10/License.txt b/Tests/Tutorial/Step10/License.txt new file mode 100644 index 0000000..c62d00b --- /dev/null +++ b/Tests/Tutorial/Step10/License.txt @@ -0,0 +1,2 @@ +This is the open source License.txt file introduced in +CMake/Tutorial/Step7... diff --git a/Tests/Tutorial/Step10/MathFunctions/CMakeLists.txt b/Tests/Tutorial/Step10/MathFunctions/CMakeLists.txt new file mode 100644 index 0000000..7a23505 --- /dev/null +++ b/Tests/Tutorial/Step10/MathFunctions/CMakeLists.txt @@ -0,0 +1,61 @@ + +# add the library that runs +add_library(MathFunctions MathFunctions.cxx) + +# state that anybody linking to us needs to include the current source dir +# to find MathFunctions.h, while we don't. +target_include_directories(MathFunctions + INTERFACE ${CMAKE_CURRENT_SOURCE_DIR} + ) + +# should we use our own math functions +option(USE_MYMATH "Use tutorial provided math implementation" ON) +if(USE_MYMATH) + + # does this system provide the log and exp functions? + include(CheckSymbolExists) + set(CMAKE_REQUIRED_LIBRARIES "m") + check_symbol_exists(log "math.h" HAVE_LOG) + check_symbol_exists(exp "math.h" HAVE_EXP) + + # first we add the executable that generates the table + add_executable(MakeTable MakeTable.cxx) + + # add the command to generate the source code + add_custom_command( + OUTPUT ${CMAKE_CURRENT_BINARY_DIR}/Table.h + COMMAND MakeTable ${CMAKE_CURRENT_BINARY_DIR}/Table.h + DEPENDS MakeTable + ) + + # library that just does sqrt + add_library(SqrtLibrary STATIC + mysqrt.cxx + ${CMAKE_CURRENT_BINARY_DIR}/Table.h + ) + + # state that we depend on our binary dir to find Table.h + target_include_directories(SqrtLibrary PRIVATE + ${CMAKE_CURRENT_BINARY_DIR} + ) + + # state that SqrtLibrary need PIC when the default is shared libraries + set_target_properties(SqrtLibrary PROPERTIES + POSITION_INDEPENDENT_CODE ${BUILD_SHARED_LIBS} + ) + + target_compile_definitions(MathFunctions PRIVATE "USE_MYMATH") + if(HAVE_LOG AND HAVE_EXP) + target_compile_definitions(SqrtLibrary + PRIVATE "HAVE_LOG" "HAVE_EXP") + endif() + + target_link_libraries(MathFunctions PRIVATE SqrtLibrary) +endif() + +# define the symbol stating we are using the declspec(dllexport) when +# building on windows +target_compile_definitions(MathFunctions PRIVATE "EXPORTING_MYMATH") + +install(TARGETS MathFunctions DESTINATION lib) +install(FILES MathFunctions.h DESTINATION include) diff --git a/Tests/Tutorial/Step10/MathFunctions/MakeTable.cxx b/Tests/Tutorial/Step10/MathFunctions/MakeTable.cxx new file mode 100644 index 0000000..ee58556 --- /dev/null +++ b/Tests/Tutorial/Step10/MathFunctions/MakeTable.cxx @@ -0,0 +1,25 @@ +// A simple program that builds a sqrt table +#include <cmath> +#include <fstream> +#include <iostream> + +int main(int argc, char* argv[]) +{ + // make sure we have enough arguments + if (argc < 2) { + return 1; + } + + std::ofstream fout(argv[1], std::ios_base::out); + const bool fileOpen = fout.is_open(); + if (fileOpen) { + fout << "double sqrtTable[] = {" << std::endl; + for (int i = 0; i < 10; ++i) { + fout << sqrt(static_cast<double>(i)) << "," << std::endl; + } + // close the table with a zero + fout << "0};" << std::endl; + fout.close(); + } + return fileOpen ? 0 : 1; // return 0 if wrote the file +} diff --git a/Tests/Tutorial/Step10/MathFunctions/MathFunctions.cxx b/Tests/Tutorial/Step10/MathFunctions/MathFunctions.cxx new file mode 100644 index 0000000..5351184 --- /dev/null +++ b/Tests/Tutorial/Step10/MathFunctions/MathFunctions.cxx @@ -0,0 +1,18 @@ + +#include "MathFunctions.h" +#include <cmath> + +#ifdef USE_MYMATH +# include "mysqrt.h" +#endif + +namespace mathfunctions { +double sqrt(double x) +{ +#ifdef USE_MYMATH + return detail::mysqrt(x); +#else + return std::sqrt(x); +#endif +} +} diff --git a/Tests/Tutorial/Step10/MathFunctions/MathFunctions.h b/Tests/Tutorial/Step10/MathFunctions/MathFunctions.h new file mode 100644 index 0000000..3fb547b --- /dev/null +++ b/Tests/Tutorial/Step10/MathFunctions/MathFunctions.h @@ -0,0 +1,14 @@ + +#if defined(_WIN32) +# if defined(EXPORTING_MYMATH) +# define DECLSPEC __declspec(dllexport) +# else +# define DECLSPEC __declspec(dllimport) +# endif +#else // non windows +# define DECLSPEC +#endif + +namespace mathfunctions { +double DECLSPEC sqrt(double x); +} diff --git a/Tests/Tutorial/Step10/MathFunctions/mysqrt.cxx b/Tests/Tutorial/Step10/MathFunctions/mysqrt.cxx new file mode 100644 index 0000000..96d9421 --- /dev/null +++ b/Tests/Tutorial/Step10/MathFunctions/mysqrt.cxx @@ -0,0 +1,45 @@ +#include "MathFunctions.h" +#include <iostream> + +// include the generated table +#include "Table.h" + +#include <cmath> + +namespace mathfunctions { +namespace detail { +// a hack square root calculation using simple operations +double mysqrt(double x) +{ + if (x <= 0) { + return 0; + } + + // if we have both log and exp then use them +#if defined(HAVE_LOG) && defined(HAVE_EXP) + double result = exp(log(x) * 0.5); + std::cout << "Computing sqrt of " << x << " to be " << result << " using log" + << std::endl; +#else + // use the table to help find an initial value + double result = x; + if (x >= 1 && x < 10) { + result = sqrtTable[static_cast<int>(x)]; + } + + // if we have both log and exp then use them + + // do ten iterations + for (int i = 0; i < 10; ++i) { + if (result <= 0) { + result = 0.1; + } + double delta = x - (result * result); + result = result + 0.5 * delta / result; + std::cout << "Computing sqrt of " << x << " to be " << result << std::endl; + } +#endif + return result; +} +} +} diff --git a/Tests/Tutorial/Step10/MathFunctions/mysqrt.h b/Tests/Tutorial/Step10/MathFunctions/mysqrt.h new file mode 100644 index 0000000..e1c42ef --- /dev/null +++ b/Tests/Tutorial/Step10/MathFunctions/mysqrt.h @@ -0,0 +1,6 @@ + +namespace mathfunctions { +namespace detail { +double mysqrt(double x); +} +} diff --git a/Tests/Tutorial/Step10/TutorialConfig.h.in b/Tests/Tutorial/Step10/TutorialConfig.h.in new file mode 100644 index 0000000..8cd2fc9 --- /dev/null +++ b/Tests/Tutorial/Step10/TutorialConfig.h.in @@ -0,0 +1,3 @@ +// the configured version number +#define Tutorial_VERSION_MAJOR @Tutorial_VERSION_MAJOR@ +#define Tutorial_VERSION_MINOR @Tutorial_VERSION_MINOR@ diff --git a/Tests/Tutorial/Step10/directions.txt b/Tests/Tutorial/Step10/directions.txt new file mode 100644 index 0000000..5317b54 --- /dev/null +++ b/Tests/Tutorial/Step10/directions.txt @@ -0,0 +1,38 @@ +# Adding Generator Expressions # + +Generator expressions are evaluated during build system generation to produce +information specific to each build configuration. + +Generator expressions are allowed in the context of many target properties, such +as LINK_LIBRARIES, INCLUDE_DIRECTORIES, COMPILE_DEFINITIONS and others. They may +also be used when using commands to populate those properties, such as +target_link_libraries(), target_include_directories(), +target_compile_definitions() and others. + +Generator expressions may to used to enable conditional linking, conditional +definitions used when compiling, and conditional include directories and more. +The conditions may be based on the build configuration, target properties, +platform information or any other queryable information. + +There are different types of generator expressions including Logical, +Informational, and Output expressions. + +Logical expressions are used to create conditional output. The basic expressions +are the 0 and 1 expressions. A "$<0:...>" results in the empty string, and +"$<1:...>" results in the content of "...". They can also be nested. +For example: + + if(HAVE_LOG AND HAVE_EXP) + target_compile_definitions(SqrtLibrary + PRIVATE "HAVE_LOG" "HAVE_EXP") + endif() + +Can be rewritten with generator expressions: + + target_compile_definitions(SqrtLibrary PRIVATE + "$<$<BOOL:${HAVE_LOG}>:HAVE_LOG>" + "$<$<BOOL:${HAVE_EXP}>:HAVE_EXP>" + ) + +Note that "${HAVE_LOG}" is evaluated at CMake configure time while +"$<$<BOOL:${HAVE_LOG}>:HAVE_LOG>" is evaluated at build system generation time. diff --git a/Tests/Tutorial/Step10/tutorial.cxx b/Tests/Tutorial/Step10/tutorial.cxx new file mode 100644 index 0000000..443d195 --- /dev/null +++ b/Tests/Tutorial/Step10/tutorial.cxx @@ -0,0 +1,25 @@ +// A simple program that computes the square root of a number +#include <iostream> +#include <sstream> +#include <string> + +#include "MathFunctions.h" +#include "TutorialConfig.h" + +int main(int argc, char* argv[]) +{ + if (argc < 2) { + std::cout << argv[0] << " Version " << Tutorial_VERSION_MAJOR << "." + << Tutorial_VERSION_MAJOR << std::endl; + std::cout << "Usage: " << argv[0] << " number" << std::endl; + return 1; + } + + double inputValue = std::stod(argv[1]); + + const double outputValue = mathfunctions::sqrt(inputValue); + + std::cout << "The square root of " << inputValue << " is " << outputValue + << std::endl; + return 0; +} diff --git a/Tests/Tutorial/Step11/CMakeLists.txt b/Tests/Tutorial/Step11/CMakeLists.txt new file mode 100644 index 0000000..b1d46c4 --- /dev/null +++ b/Tests/Tutorial/Step11/CMakeLists.txt @@ -0,0 +1,77 @@ +cmake_minimum_required(VERSION 3.3) +project(Tutorial) + +# control where the static and shared libraries are built so that on windows +# we don't need to tinker with the path to run the executable +set(CMAKE_ARCHIVE_OUTPUT_DIRECTORY "${PROJECT_BINARY_DIR}") +set(CMAKE_LIBRARY_OUTPUT_DIRECTORY "${PROJECT_BINARY_DIR}") +set(CMAKE_RUNTIME_OUTPUT_DIRECTORY "${PROJECT_BINARY_DIR}") + +set(CMAKE_CXX_STANDARD 11) +set(CMAKE_CXX_STANDARD_REQUIRED True) + +option(BUILD_SHARED_LIBS "Build using shared libraries" ON) + +# the version number. +set(Tutorial_VERSION_MAJOR 1) +set(Tutorial_VERSION_MINOR 0) + +# configure a header file to pass the version number only +configure_file( + "${PROJECT_SOURCE_DIR}/TutorialConfig.h.in" + "${PROJECT_BINARY_DIR}/TutorialConfig.h" + ) + +# add the MathFunctions library +add_subdirectory(MathFunctions) + +# add the executable +add_executable(Tutorial tutorial.cxx) +target_link_libraries(Tutorial MathFunctions) + +# add the binary tree to the search path for include files +# so that we will find TutorialConfig.h +target_include_directories(Tutorial PUBLIC + "${PROJECT_BINARY_DIR}" + ) + +# add the install targets +install(TARGETS Tutorial DESTINATION bin) +install(FILES "${PROJECT_BINARY_DIR}/TutorialConfig.h" + DESTINATION include + ) + +# enable testing +enable_testing() + +# does the application run +add_test(NAME Runs COMMAND Tutorial 25) + +# does the usage message work? +add_test(NAME Usage COMMAND Tutorial) +set_tests_properties(Usage + PROPERTIES PASS_REGULAR_EXPRESSION "Usage:.*number" + ) + +# define a function to simplify adding tests +function(do_test target arg result) + add_test(NAME Comp${arg} COMMAND ${target} ${arg}) + set_tests_properties(Comp${arg} + PROPERTIES PASS_REGULAR_EXPRESSION ${result} + ) +endfunction(do_test) + +# do a bunch of result based tests +do_test(Tutorial 4 "4 is 2") +do_test(Tutorial 9 "9 is 3") +do_test(Tutorial 5 "5 is 2.236") +do_test(Tutorial 7 "7 is 2.645") +do_test(Tutorial 25 "25 is 5") +do_test(Tutorial -25 "-25 is [-nan|nan|0]") +do_test(Tutorial 0.0001 "0.0001 is 0.01") + +include(InstallRequiredSystemLibraries) +set(CPACK_RESOURCE_FILE_LICENSE "${CMAKE_CURRENT_SOURCE_DIR}/License.txt") +set(CPACK_PACKAGE_VERSION_MAJOR "${Tutorial_VERSION_MAJOR}") +set(CPACK_PACKAGE_VERSION_MINOR "${Tutorial_VERSION_MINOR}") +include(CPack) diff --git a/Tests/Tutorial/Step11/License.txt b/Tests/Tutorial/Step11/License.txt new file mode 100644 index 0000000..c62d00b --- /dev/null +++ b/Tests/Tutorial/Step11/License.txt @@ -0,0 +1,2 @@ +This is the open source License.txt file introduced in +CMake/Tutorial/Step7... diff --git a/Tests/Tutorial/Step11/MathFunctions/CMakeLists.txt b/Tests/Tutorial/Step11/MathFunctions/CMakeLists.txt new file mode 100644 index 0000000..760d6a5 --- /dev/null +++ b/Tests/Tutorial/Step11/MathFunctions/CMakeLists.txt @@ -0,0 +1,60 @@ + +# add the library that runs +add_library(MathFunctions MathFunctions.cxx) + +# state that anybody linking to us needs to include the current source dir +# to find MathFunctions.h, while we don't. +target_include_directories(MathFunctions + INTERFACE ${CMAKE_CURRENT_SOURCE_DIR} + ) + +# should we use our own math functions +option(USE_MYMATH "Use tutorial provided math implementation" ON) +if(USE_MYMATH) + + # does this system provide the log and exp functions? + include(CheckSymbolExists) + set(CMAKE_REQUIRED_LIBRARIES "m") + check_symbol_exists(log "math.h" HAVE_LOG) + check_symbol_exists(exp "math.h" HAVE_EXP) + + # first we add the executable that generates the table + add_executable(MakeTable MakeTable.cxx) + + # add the command to generate the source code + add_custom_command( + OUTPUT ${CMAKE_CURRENT_BINARY_DIR}/Table.h + COMMAND MakeTable ${CMAKE_CURRENT_BINARY_DIR}/Table.h + DEPENDS MakeTable + ) + + # library that just does sqrt + add_library(SqrtLibrary STATIC + mysqrt.cxx + ${CMAKE_CURRENT_BINARY_DIR}/Table.h + ) + + # state that we depend on our binary dir to find Table.h + target_include_directories(SqrtLibrary PRIVATE + ${CMAKE_CURRENT_BINARY_DIR} + ) + + set_target_properties(SqrtLibrary PROPERTIES + POSITION_INDEPENDENT_CODE ${BUILD_SHARED_LIBS} + ) + + target_compile_definitions(SqrtLibrary PRIVATE + "$<$<BOOL:${HAVE_LOG}>:HAVE_LOG>" + "$<$<BOOL:${HAVE_EXP}>:HAVE_EXP>" + ) + target_link_libraries(MathFunctions PRIVATE SqrtLibrary) +endif() + +target_compile_definitions(MathFunctions PRIVATE "$<$<BOOL:${USE_MYMATH}>:USE_MYMATH>") + +# define the symbol stating we are using the declspec(dllexport) when +#building on windows +target_compile_definitions(MathFunctions PRIVATE "EXPORTING_MYMATH") + +install(TARGETS MathFunctions DESTINATION lib) +install(FILES MathFunctions.h DESTINATION include) diff --git a/Tests/Tutorial/Step11/MathFunctions/MakeTable.cxx b/Tests/Tutorial/Step11/MathFunctions/MakeTable.cxx new file mode 100644 index 0000000..ee58556 --- /dev/null +++ b/Tests/Tutorial/Step11/MathFunctions/MakeTable.cxx @@ -0,0 +1,25 @@ +// A simple program that builds a sqrt table +#include <cmath> +#include <fstream> +#include <iostream> + +int main(int argc, char* argv[]) +{ + // make sure we have enough arguments + if (argc < 2) { + return 1; + } + + std::ofstream fout(argv[1], std::ios_base::out); + const bool fileOpen = fout.is_open(); + if (fileOpen) { + fout << "double sqrtTable[] = {" << std::endl; + for (int i = 0; i < 10; ++i) { + fout << sqrt(static_cast<double>(i)) << "," << std::endl; + } + // close the table with a zero + fout << "0};" << std::endl; + fout.close(); + } + return fileOpen ? 0 : 1; // return 0 if wrote the file +} diff --git a/Tests/Tutorial/Step11/MathFunctions/MathFunctions.cxx b/Tests/Tutorial/Step11/MathFunctions/MathFunctions.cxx new file mode 100644 index 0000000..5351184 --- /dev/null +++ b/Tests/Tutorial/Step11/MathFunctions/MathFunctions.cxx @@ -0,0 +1,18 @@ + +#include "MathFunctions.h" +#include <cmath> + +#ifdef USE_MYMATH +# include "mysqrt.h" +#endif + +namespace mathfunctions { +double sqrt(double x) +{ +#ifdef USE_MYMATH + return detail::mysqrt(x); +#else + return std::sqrt(x); +#endif +} +} diff --git a/Tests/Tutorial/Step11/MathFunctions/MathFunctions.h b/Tests/Tutorial/Step11/MathFunctions/MathFunctions.h new file mode 100644 index 0000000..3fb547b --- /dev/null +++ b/Tests/Tutorial/Step11/MathFunctions/MathFunctions.h @@ -0,0 +1,14 @@ + +#if defined(_WIN32) +# if defined(EXPORTING_MYMATH) +# define DECLSPEC __declspec(dllexport) +# else +# define DECLSPEC __declspec(dllimport) +# endif +#else // non windows +# define DECLSPEC +#endif + +namespace mathfunctions { +double DECLSPEC sqrt(double x); +} diff --git a/Tests/Tutorial/Step11/MathFunctions/mysqrt.cxx b/Tests/Tutorial/Step11/MathFunctions/mysqrt.cxx new file mode 100644 index 0000000..96d9421 --- /dev/null +++ b/Tests/Tutorial/Step11/MathFunctions/mysqrt.cxx @@ -0,0 +1,45 @@ +#include "MathFunctions.h" +#include <iostream> + +// include the generated table +#include "Table.h" + +#include <cmath> + +namespace mathfunctions { +namespace detail { +// a hack square root calculation using simple operations +double mysqrt(double x) +{ + if (x <= 0) { + return 0; + } + + // if we have both log and exp then use them +#if defined(HAVE_LOG) && defined(HAVE_EXP) + double result = exp(log(x) * 0.5); + std::cout << "Computing sqrt of " << x << " to be " << result << " using log" + << std::endl; +#else + // use the table to help find an initial value + double result = x; + if (x >= 1 && x < 10) { + result = sqrtTable[static_cast<int>(x)]; + } + + // if we have both log and exp then use them + + // do ten iterations + for (int i = 0; i < 10; ++i) { + if (result <= 0) { + result = 0.1; + } + double delta = x - (result * result); + result = result + 0.5 * delta / result; + std::cout << "Computing sqrt of " << x << " to be " << result << std::endl; + } +#endif + return result; +} +} +} diff --git a/Tests/Tutorial/Step11/MathFunctions/mysqrt.h b/Tests/Tutorial/Step11/MathFunctions/mysqrt.h new file mode 100644 index 0000000..e1c42ef --- /dev/null +++ b/Tests/Tutorial/Step11/MathFunctions/mysqrt.h @@ -0,0 +1,6 @@ + +namespace mathfunctions { +namespace detail { +double mysqrt(double x); +} +} diff --git a/Tests/Tutorial/Step11/TutorialConfig.h.in b/Tests/Tutorial/Step11/TutorialConfig.h.in new file mode 100644 index 0000000..8cd2fc9 --- /dev/null +++ b/Tests/Tutorial/Step11/TutorialConfig.h.in @@ -0,0 +1,3 @@ +// the configured version number +#define Tutorial_VERSION_MAJOR @Tutorial_VERSION_MAJOR@ +#define Tutorial_VERSION_MINOR @Tutorial_VERSION_MINOR@ diff --git a/Tests/Tutorial/Step11/directions.txt b/Tests/Tutorial/Step11/directions.txt new file mode 100644 index 0000000..ebb5def --- /dev/null +++ b/Tests/Tutorial/Step11/directions.txt @@ -0,0 +1,104 @@ +# Adding Export Configuration # + +During Step 4 of the tutorial we added the ability for CMake to install the +library and headers of the project. During Step 7 we added the ability +to package up this information so it could be distributed to other people. + +The next step is to add the necessary information so that other CMake projects +can use our project, be it from a build directory, a local install or when +packaged. + +The first step is to update our install(TARGETS) commands to not only specify +a DESTINATION but also an EXPORT. The EXPORT keyword generates and installs a +CMake file containing code to import all targets listed in the install command +from the installation tree. So let's go ahead and explicitly EXPORT the +MathFunctions library by updating the install command in +MathFunctions/CMakeLists.txt to look like: + + install(TARGETS MathFunctions DESTINATION lib EXPORT MathFunctionsTargets) + +Now that we have MathFunctions being exported, we also need to explicitly install +the generated MathFunctionsTargets.cmake file. This is done by adding +the following to the bottom of the top-level CMakeLists.txt: + + # install the configuration targets + install(EXPORT MathFunctionsTargets + FILE MathFunctionsTargets.cmake + DESTINATION lib/cmake/MathFunctions + ) + +At this point you should try and run CMake. If everything is setup properly +you will see that CMake will generate an error that looks like: + + Target "MathFunctions" INTERFACE_INCLUDE_DIRECTORIES property contains + path: + + "/Users/robert/Documents/CMakeClass/Tutorial/Step11/MathFunctions" + + which is prefixed in the source directory. + +What CMake is trying to say is that during generating the export information +it will export a path that is intrinsically tied to the current machine and +will not be valid on other machines. The solution to this is to update the +MathFunctions target_include_directories to understand that it needs different +INTERFACE locations when being used from within the build directory and from an +install / package. This means converting the target_include_directories +call for MathFunctions to look like: + + target_include_directories(MathFunctions + INTERFACE + $<BUILD_INTERFACE:${CMAKE_CURRENT_SOURCE_DIR}> + $<INSTALL_INTERFACE:include> + ) + +Once this has been updated, we can re-run CMake and see verify that it doesn't +warn anymore. + +At this point, we have CMake properly packaging the target information that is +required but we will still need to generate a MathFunctionsConfig.cmake, so +that the CMake find_package command can find our project. So let's go ahead and +add a new file to the top-level of the project called Config.cmake.in with the +following contents: + + @PACKAGE_INIT@ + + include ( "${CMAKE_CURRENT_LIST_DIR}/MathFunctionsTargets.cmake" ) + +Then, to properly configure and install that file, add the following to the +bottom of the top-level CMakeLists: + + include(CMakePackageConfigHelpers) + # generate the config file that is includes the exports + configure_package_config_file(${CMAKE_CURRENT_SOURCE_DIR}/Config.cmake.in + "${CMAKE_CURRENT_BINARY_DIR}/MathFunctionsConfig.cmake" + INSTALL_DESTINATION "lib/cmake/example" + NO_SET_AND_CHECK_MACRO + NO_CHECK_REQUIRED_COMPONENTS_MACRO + ) + # generate the version file for the config file + write_basic_package_version_file( + "${CMAKE_CURRENT_BINARY_DIR}/MathFunctionsConfigVersion.cmake" + VERSION "${Tutorial_VERSION_MAJOR}.${Tutorial_VERSION_MINOR}" + COMPATIBILITY AnyNewerVersion + ) + + # install the configuration file + install(FILES + ${CMAKE_CURRENT_BINARY_DIR}/MathFunctionsConfig.cmake + DESTINATION lib/cmake/MathFunctions + ) + +At this point, we have generated a relocatable CMake Configuration for our project +that can be used after the project has been installed or packaged. If we want +our project to also be used from a build directory we only have to add +the following to the bottom of the top level CMakeLists: + + # generate the export targets for the build tree + # needs to be after the install(TARGETS ) command + export(EXPORT MathFunctionsTargets + FILE "${CMAKE_CURRENT_BINARY_DIR}/MathFunctionsTargets.cmake" + ) + +With this export call we now generate a Targets.cmake, allowing the configured +MathFunctionsConfig.cmake in the build directory to be used by other projects, +without needing it to be installed. diff --git a/Tests/Tutorial/Step11/tutorial.cxx b/Tests/Tutorial/Step11/tutorial.cxx new file mode 100644 index 0000000..3768855 --- /dev/null +++ b/Tests/Tutorial/Step11/tutorial.cxx @@ -0,0 +1,25 @@ +// A simple program that computes the square root of a number +#include <cmath> +#include <iostream> +#include <string> + +#include "MathFunctions.h" +#include "TutorialConfig.h" + +int main(int argc, char* argv[]) +{ + if (argc < 2) { + std::cout << argv[0] << " Version " << Tutorial_VERSION_MAJOR << "." + << Tutorial_VERSION_MAJOR << std::endl; + std::cout << "Usage: " << argv[0] << " number" << std::endl; + return 1; + } + + double inputValue = std::stod(argv[1]); + + const double outputValue = mathfunctions::sqrt(inputValue); + + std::cout << "The square root of " << inputValue << " is " << outputValue + << std::endl; + return 0; +} diff --git a/Tests/Tutorial/Step2/CMakeLists.txt b/Tests/Tutorial/Step2/CMakeLists.txt index cf1d30e..48afaa3 100644 --- a/Tests/Tutorial/Step2/CMakeLists.txt +++ b/Tests/Tutorial/Step2/CMakeLists.txt @@ -1,31 +1,25 @@ -cmake_minimum_required (VERSION 2.6) -project (Tutorial) +cmake_minimum_required(VERSION 3.3) +project(Tutorial) -# The version number. -set (Tutorial_VERSION_MAJOR 1) -set (Tutorial_VERSION_MINOR 0) +set(CMAKE_CXX_STANDARD 11) +set(CMAKE_CXX_STANDARD_REQUIRED True) -# should we use our own math functions -option(USE_MYMATH "Use tutorial provided math implementation" ON) +# the version number. +set(Tutorial_VERSION_MAJOR 1) +set(Tutorial_VERSION_MINOR 0) # configure a header file to pass some of the CMake settings # to the source code -configure_file ( +configure_file( "${PROJECT_SOURCE_DIR}/TutorialConfig.h.in" "${PROJECT_BINARY_DIR}/TutorialConfig.h" ) +# add the executable +add_executable(Tutorial tutorial.cxx) + # add the binary tree to the search path for include files # so that we will find TutorialConfig.h -include_directories ("${PROJECT_BINARY_DIR}") - -# add the MathFunctions library? -if (USE_MYMATH) - include_directories ("${PROJECT_SOURCE_DIR}/MathFunctions") - add_subdirectory (MathFunctions) - set (EXTRA_LIBS ${EXTRA_LIBS} MathFunctions) -endif () - -# add the executable -add_executable (Tutorial tutorial.cxx) -target_link_libraries (Tutorial ${EXTRA_LIBS}) +target_include_directories(Tutorial PUBLIC + "${PROJECT_BINARY_DIR}" + ) diff --git a/Tests/Tutorial/Step2/MathFunctions/mysqrt.cxx b/Tests/Tutorial/Step2/MathFunctions/mysqrt.cxx index 2710f92..7d9379e 100644 --- a/Tests/Tutorial/Step2/MathFunctions/mysqrt.cxx +++ b/Tests/Tutorial/Step2/MathFunctions/mysqrt.cxx @@ -1,5 +1,5 @@ #include "MathFunctions.h" -#include <stdio.h> +#include <iostream> // a hack square root calculation using simple operations double mysqrt(double x) @@ -8,19 +8,16 @@ double mysqrt(double x) return 0; } - double result; - double delta; - result = x; + double result = x; // do ten iterations - int i; - for (i = 0; i < 10; ++i) { + for (int i = 0; i < 10; ++i) { if (result <= 0) { result = 0.1; } - delta = x - (result * result); + double delta = x - (result * result); result = result + 0.5 * delta / result; - fprintf(stdout, "Computing sqrt of %g to be %g\n", x, result); + std::cout << "Computing sqrt of " << x << " to be " << result << std::endl; } return result; } diff --git a/Tests/Tutorial/Step2/TutorialConfig.h.in b/Tests/Tutorial/Step2/TutorialConfig.h.in index 25a0602..5395a06 100644 --- a/Tests/Tutorial/Step2/TutorialConfig.h.in +++ b/Tests/Tutorial/Step2/TutorialConfig.h.in @@ -1,5 +1,4 @@ // the configured options and settings for Tutorial #define Tutorial_VERSION_MAJOR @Tutorial_VERSION_MAJOR@ #define Tutorial_VERSION_MINOR @Tutorial_VERSION_MINOR@ -#cmakedefine USE_MYMATH diff --git a/Tests/Tutorial/Step2/directions.txt b/Tests/Tutorial/Step2/directions.txt new file mode 100644 index 0000000..bb6662c --- /dev/null +++ b/Tests/Tutorial/Step2/directions.txt @@ -0,0 +1,102 @@ +# Adding a Library # + +Now we will add a library to our project. This library will contain our own +implementation for computing the square root of a number. The executable can +then use this library instead of the standard square root function provided by +the compiler. + +For this tutorial we will put the library into a subdirectory +called MathFunctions. It will have the following one line CMakeLists file: + + add_library(MathFunctions mysqrt.cxx) + +The source file mysqrt.cxx has one function called mysqrt that provides similar +functionality to the compiler’s sqrt function. To make use of the new library +we add an add_subdirectory call in the top-level CMakeLists file so that the +library will get built. We add the new library to the executable, and add the +MathFunctions as an include directory so that mqsqrt.h header file can be +found. The last few lines of the top-level CMakeLists file now look like: + + + add_subdirectory(MathFunctions) + + #add the executable + add_executable(Tutorial tutorial.cxx) + + target_link_libraries(Tutorial ${EXTRA_LIBS}) + + +Now let us make the MathFunctions library optional. While for the tutorial +there really isn’t any need to do so, but with larger projects this is a common +occurrence. The first step is to add an option to the top-level CMakeLists file. + + option (USE_MYMATH + "Use tutorial provided math implementation" ON) + +This will show up in CMake GUI and ccmake with a default value of ON that can +be changed by the user. This setting will be stored so that the user does not +need to set the value each time they run CMake on this build directory. + +The next change is to make building and linking the MathFunctions library +conditional. To do this we change the top-level CMakeLists file to look like +the following: + + cmake_minimum_required(VERSION 3.3) + project(Tutorial) + + set(CMAKE_CXX_STANDARD 11) + set(CMAKE_CXX_STANDARD_REQUIRED True) + + # the version number. + set(Tutorial_VERSION_MAJOR 1) + set(Tutorial_VERSION_MINOR 0) + + # configure a header file to pass some of the CMake settings + # to the source code + configure_file( + "${PROJECT_SOURCE_DIR}/TutorialConfig.h.in" + "${PROJECT_BINARY_DIR}/TutorialConfig.h" + ) + + # should we use our own math functions + option(USE_MYMATH "Use tutorial provided math implementation" ON) + + # add the MathFunctions library? + if(USE_MYMATH) + add_subdirectory(MathFunctions) + list(APPEND EXTRA_LIBS MathFunctions) + list(APPEND EXTRA_INCLUDES "${PROJECT_SOURCE_DIR}/MathFunctions") + endif(USE_MYMATH) + + # add the executable + add_executable(Tutorial tutorial.cxx) + + target_link_libraries(Tutorial ${EXTRA_LIBS}) + + # add the binary tree to the search path for include files + # so that we will find TutorialConfig.h + target_include_directories(Tutorial PUBLIC + "${PROJECT_BINARY_DIR}" + ${EXTRA_INCLUDES} + ) + +Note the use of the variables EXTRA_LIBS, and EXTRA_INCLUDES to collect +up any optional libraries to later be linked into the executable. This is a +classic approach when dealing with many optional components, we will cover the +modern approach in the next step. For now the corresponding changes to the +source code are fairly straightforward and leave us with: + + #ifdef USE_MYMATH + double outputValue = mysqrt(inputValue); + #else + double outputValue = sqrt(inputValue); + #endif + +Since the source code now requires USE_MYMATH we can add it to the +TutorialConfig.h.in. Simply add the following line: + #cmakedefine USE_MYMATH + +Run cmake or cmake-gui to configure the project and then build it with your +chosen build tool and then run the built Tutorial executable. + +Which function gives better results, Step1’s sqrt or Step2’s mysqrt? diff --git a/Tests/Tutorial/Step2/tutorial.cxx b/Tests/Tutorial/Step2/tutorial.cxx index 37f6ac4..75b7d67 100644 --- a/Tests/Tutorial/Step2/tutorial.cxx +++ b/Tests/Tutorial/Step2/tutorial.cxx @@ -1,33 +1,23 @@ // A simple program that computes the square root of a number -#include "TutorialConfig.h" -#include <math.h> -#include <stdio.h> -#include <stdlib.h> +#include <cmath> +#include <iostream> +#include <string> -#ifdef USE_MYMATH -# include "MathFunctions.h" -#endif +#include "TutorialConfig.h" int main(int argc, char* argv[]) { if (argc < 2) { - fprintf(stdout, "%s Version %d.%d\n", argv[0], Tutorial_VERSION_MAJOR, - Tutorial_VERSION_MINOR); - fprintf(stdout, "Usage: %s number\n", argv[0]); + std::cout << argv[0] << " Version " << Tutorial_VERSION_MAJOR << "." + << Tutorial_VERSION_MAJOR << std::endl; + std::cout << "Usage: " << argv[0] << " number" << std::endl; return 1; } - double inputValue = atof(argv[1]); - double outputValue = 0; - - if (inputValue >= 0) { -#ifdef USE_MYMATH - outputValue = mysqrt(inputValue); -#else - outputValue = sqrt(inputValue); -#endif - } + double inputValue = std::stod(argv[1]); - fprintf(stdout, "The square root of %g is %g\n", inputValue, outputValue); + double outputValue = sqrt(inputValue); + std::cout << "The square root of " << inputValue << " is " << outputValue + << std::endl; return 0; } diff --git a/Tests/Tutorial/Step3/CMakeLists.txt b/Tests/Tutorial/Step3/CMakeLists.txt index 762302b..f904ea7 100644 --- a/Tests/Tutorial/Step3/CMakeLists.txt +++ b/Tests/Tutorial/Step3/CMakeLists.txt @@ -1,68 +1,38 @@ -cmake_minimum_required (VERSION 2.6) -project (Tutorial) +cmake_minimum_required(VERSION 3.3) +project(Tutorial) -# The version number. -set (Tutorial_VERSION_MAJOR 1) -set (Tutorial_VERSION_MINOR 0) +set(CMAKE_CXX_STANDARD 11) +set(CMAKE_CXX_STANDARD_REQUIRED True) # should we use our own math functions option(USE_MYMATH "Use tutorial provided math implementation" ON) +# the version number. +set(Tutorial_VERSION_MAJOR 1) +set(Tutorial_VERSION_MINOR 0) + # configure a header file to pass some of the CMake settings # to the source code -configure_file ( +configure_file( "${PROJECT_SOURCE_DIR}/TutorialConfig.h.in" "${PROJECT_BINARY_DIR}/TutorialConfig.h" ) -# add the binary tree to the search path for include files -# so that we will find TutorialConfig.h -include_directories ("${PROJECT_BINARY_DIR}") - # add the MathFunctions library? -if (USE_MYMATH) - include_directories ("${PROJECT_SOURCE_DIR}/MathFunctions") - add_subdirectory (MathFunctions) - set (EXTRA_LIBS ${EXTRA_LIBS} MathFunctions) -endif () +if(USE_MYMATH) + add_subdirectory(MathFunctions) + list(APPEND EXTRA_LIBS MathFunctions) + list(APPEND EXTRA_INCLUDES "${PROJECT_SOURCE_DIR}/MathFunctions") +endif(USE_MYMATH) # add the executable -add_executable (Tutorial tutorial.cxx) -target_link_libraries (Tutorial ${EXTRA_LIBS}) - -# add the install targets -install (TARGETS Tutorial DESTINATION bin) -install (FILES "${PROJECT_BINARY_DIR}/TutorialConfig.h" - DESTINATION include) - - -# enable testing -enable_testing () - -# does the application run -add_test (TutorialRuns Tutorial 25) +add_executable(Tutorial tutorial.cxx) -# does it sqrt of 25 -add_test (TutorialComp25 Tutorial 25) -set_tests_properties (TutorialComp25 - PROPERTIES PASS_REGULAR_EXPRESSION "25 is 5" - ) - -# does it handle negative numbers -add_test (TutorialNegative Tutorial -25) -set_tests_properties (TutorialNegative - PROPERTIES PASS_REGULAR_EXPRESSION "-25 is 0" - ) - -# does it handle small numbers -add_test (TutorialSmall Tutorial 0.0001) -set_tests_properties (TutorialSmall - PROPERTIES PASS_REGULAR_EXPRESSION "0.0001 is 0.01" - ) +target_link_libraries(Tutorial ${EXTRA_LIBS}) -# does the usage message work? -add_test (TutorialUsage Tutorial) -set_tests_properties (TutorialUsage - PROPERTIES - PASS_REGULAR_EXPRESSION "Usage:.*number" - ) +# add the binary tree to the search path for include files +# so that we will find TutorialConfig.h +target_include_directories(Tutorial PUBLIC + "${PROJECT_BINARY_DIR}" + ${EXTRA_INCLUDES} + ) diff --git a/Tests/Tutorial/Step3/MathFunctions/CMakeLists.txt b/Tests/Tutorial/Step3/MathFunctions/CMakeLists.txt index f386036..8b443a6 100644 --- a/Tests/Tutorial/Step3/MathFunctions/CMakeLists.txt +++ b/Tests/Tutorial/Step3/MathFunctions/CMakeLists.txt @@ -1,4 +1 @@ add_library(MathFunctions mysqrt.cxx) - -install (TARGETS MathFunctions DESTINATION bin) -install (FILES MathFunctions.h DESTINATION include) diff --git a/Tests/Tutorial/Step3/MathFunctions/mysqrt.cxx b/Tests/Tutorial/Step3/MathFunctions/mysqrt.cxx index 2710f92..7d9379e 100644 --- a/Tests/Tutorial/Step3/MathFunctions/mysqrt.cxx +++ b/Tests/Tutorial/Step3/MathFunctions/mysqrt.cxx @@ -1,5 +1,5 @@ #include "MathFunctions.h" -#include <stdio.h> +#include <iostream> // a hack square root calculation using simple operations double mysqrt(double x) @@ -8,19 +8,16 @@ double mysqrt(double x) return 0; } - double result; - double delta; - result = x; + double result = x; // do ten iterations - int i; - for (i = 0; i < 10; ++i) { + for (int i = 0; i < 10; ++i) { if (result <= 0) { result = 0.1; } - delta = x - (result * result); + double delta = x - (result * result); result = result + 0.5 * delta / result; - fprintf(stdout, "Computing sqrt of %g to be %g\n", x, result); + std::cout << "Computing sqrt of " << x << " to be " << result << std::endl; } return result; } diff --git a/Tests/Tutorial/Step3/directions.txt b/Tests/Tutorial/Step3/directions.txt new file mode 100644 index 0000000..54d0318 --- /dev/null +++ b/Tests/Tutorial/Step3/directions.txt @@ -0,0 +1,26 @@ +# Adding Usage Requirements for Library # + +Usage requirements allow for far better control over a library / executable's +link and include line. While also giving more control over the transitive +property of targets inside CMake. The primary commands that leverage usage +requirements are: + + - target_compile_definitions + - target_compile_options + - target_include_directories + - target_link_libraries + +First up is MathFunctions. We first state that anybody linking to MathFunctions +needs to include the current source directory, while MathFunctions itself +doesn't. So this can become an INTERFACE usage requirement. + +Remember INTERFACE means things that consumers require but the producer doesn't. + + target_include_directories(MathFunctions + INTERFACE ${CMAKE_CURRENT_SOURCE_DIR}) + +Now that we've specified usage requirements for MathFunctions we can safely remove +our uses of the EXTRA_INCLUDES variable. + +Run cmake or cmake-gui to configure the project and then build it with your +chosen build tool. diff --git a/Tests/Tutorial/Step3/tutorial.cxx b/Tests/Tutorial/Step3/tutorial.cxx index 37f6ac4..1d5742d 100644 --- a/Tests/Tutorial/Step3/tutorial.cxx +++ b/Tests/Tutorial/Step3/tutorial.cxx @@ -1,8 +1,9 @@ // A simple program that computes the square root of a number +#include <cmath> +#include <iostream> +#include <string> + #include "TutorialConfig.h" -#include <math.h> -#include <stdio.h> -#include <stdlib.h> #ifdef USE_MYMATH # include "MathFunctions.h" @@ -11,23 +12,21 @@ int main(int argc, char* argv[]) { if (argc < 2) { - fprintf(stdout, "%s Version %d.%d\n", argv[0], Tutorial_VERSION_MAJOR, - Tutorial_VERSION_MINOR); - fprintf(stdout, "Usage: %s number\n", argv[0]); + std::cout << argv[0] << " Version " << Tutorial_VERSION_MAJOR << "." + << Tutorial_VERSION_MAJOR << std::endl; + std::cout << "Usage: " << argv[0] << " number" << std::endl; return 1; } - double inputValue = atof(argv[1]); - double outputValue = 0; + double inputValue = std::stod(argv[1]); - if (inputValue >= 0) { #ifdef USE_MYMATH - outputValue = mysqrt(inputValue); + double outputValue = mysqrt(inputValue); #else - outputValue = sqrt(inputValue); + double outputValue = sqrt(inputValue); #endif - } - fprintf(stdout, "The square root of %g is %g\n", inputValue, outputValue); + std::cout << "The square root of " << inputValue << " is " << outputValue + << std::endl; return 0; } diff --git a/Tests/Tutorial/Step4/CMakeLists.txt b/Tests/Tutorial/Step4/CMakeLists.txt index 6994aa1..34eab55 100644 --- a/Tests/Tutorial/Step4/CMakeLists.txt +++ b/Tests/Tutorial/Step4/CMakeLists.txt @@ -1,68 +1,36 @@ -cmake_minimum_required (VERSION 2.6) -project (Tutorial) +cmake_minimum_required(VERSION 3.3) +project(Tutorial) -# The version number. -set (Tutorial_VERSION_MAJOR 1) -set (Tutorial_VERSION_MINOR 0) - -# does this system provide the log and exp functions? -include (${CMAKE_ROOT}/Modules/CheckFunctionExists.cmake) -check_function_exists (log HAVE_LOG) -check_function_exists (exp HAVE_EXP) +set(CMAKE_CXX_STANDARD 11) +set(CMAKE_CXX_STANDARD_REQUIRED True) # should we use our own math functions option(USE_MYMATH "Use tutorial provided math implementation" ON) +# the version number. +set(Tutorial_VERSION_MAJOR 1) +set(Tutorial_VERSION_MINOR 0) + # configure a header file to pass some of the CMake settings # to the source code -configure_file ( +configure_file( "${PROJECT_SOURCE_DIR}/TutorialConfig.h.in" "${PROJECT_BINARY_DIR}/TutorialConfig.h" ) -# add the binary tree to the search path for include files -# so that we will find TutorialConfig.h -include_directories ("${PROJECT_BINARY_DIR}") - # add the MathFunctions library? -if (USE_MYMATH) - include_directories ("${PROJECT_SOURCE_DIR}/MathFunctions") - add_subdirectory (MathFunctions) - set (EXTRA_LIBS ${EXTRA_LIBS} MathFunctions) -endif () +if(USE_MYMATH) + add_subdirectory(MathFunctions) + list(APPEND EXTRA_LIBS MathFunctions) +endif(USE_MYMATH) # add the executable -add_executable (Tutorial tutorial.cxx) -target_link_libraries (Tutorial ${EXTRA_LIBS}) - -# add the install targets -install (TARGETS Tutorial DESTINATION bin) -install (FILES "${PROJECT_BINARY_DIR}/TutorialConfig.h" - DESTINATION include) - -# enable testing -enable_testing () +add_executable(Tutorial tutorial.cxx) -# does the application run -add_test (TutorialRuns Tutorial 25) - -# does the usage message work? -add_test (TutorialUsage Tutorial) -set_tests_properties (TutorialUsage - PROPERTIES - PASS_REGULAR_EXPRESSION "Usage:.*number" - ) - -#define a macro to simplify adding tests -macro (do_test arg result) - add_test (TutorialComp${arg} Tutorial ${arg}) - set_tests_properties (TutorialComp${arg} - PROPERTIES PASS_REGULAR_EXPRESSION ${result} - ) -endmacro () - -# do a bunch of result based tests -do_test (25 "25 is 5") -do_test (-25 "-25 is 0") -do_test (0.0001 "0.0001 is 0.01") +target_link_libraries(Tutorial PUBLIC ${EXTRA_LIBS}) +# add the binary tree to the search path for include files +# so that we will find TutorialConfig.h +target_include_directories(Tutorial PUBLIC + "${PROJECT_BINARY_DIR}" + ) diff --git a/Tests/Tutorial/Step4/MathFunctions/CMakeLists.txt b/Tests/Tutorial/Step4/MathFunctions/CMakeLists.txt index f386036..0515852 100644 --- a/Tests/Tutorial/Step4/MathFunctions/CMakeLists.txt +++ b/Tests/Tutorial/Step4/MathFunctions/CMakeLists.txt @@ -1,4 +1,7 @@ add_library(MathFunctions mysqrt.cxx) -install (TARGETS MathFunctions DESTINATION bin) -install (FILES MathFunctions.h DESTINATION include) +# state that anybody linking to us needs to include the current source dir +# to find MathFunctions.h, while we don't. +target_include_directories(MathFunctions + INTERFACE ${CMAKE_CURRENT_SOURCE_DIR} + ) diff --git a/Tests/Tutorial/Step4/MathFunctions/mysqrt.cxx b/Tests/Tutorial/Step4/MathFunctions/mysqrt.cxx index 6ca264f..7d9379e 100644 --- a/Tests/Tutorial/Step4/MathFunctions/mysqrt.cxx +++ b/Tests/Tutorial/Step4/MathFunctions/mysqrt.cxx @@ -1,8 +1,5 @@ #include "MathFunctions.h" -#include "TutorialConfig.h" -#include <stdio.h> - -#include <math.h> +#include <iostream> // a hack square root calculation using simple operations double mysqrt(double x) @@ -11,26 +8,16 @@ double mysqrt(double x) return 0; } - double result; - -// if we have both log and exp then use them -#if defined(HAVE_LOG) && defined(HAVE_EXP) - result = exp(log(x) * 0.5); - fprintf(stdout, "Computing sqrt of %g to be %g using log\n", x, result); -#else - double delta; - result = x; + double result = x; // do ten iterations - int i; - for (i = 0; i < 10; ++i) { + for (int i = 0; i < 10; ++i) { if (result <= 0) { result = 0.1; } - delta = x - (result * result); + double delta = x - (result * result); result = result + 0.5 * delta / result; - fprintf(stdout, "Computing sqrt of %g to be %g\n", x, result); + std::cout << "Computing sqrt of " << x << " to be " << result << std::endl; } -#endif return result; } diff --git a/Tests/Tutorial/Step4/TutorialConfig.h.in b/Tests/Tutorial/Step4/TutorialConfig.h.in index a091265..25a0602 100644 --- a/Tests/Tutorial/Step4/TutorialConfig.h.in +++ b/Tests/Tutorial/Step4/TutorialConfig.h.in @@ -3,7 +3,3 @@ #define Tutorial_VERSION_MINOR @Tutorial_VERSION_MINOR@ #cmakedefine USE_MYMATH -// does the platform provide exp and log functions? -#cmakedefine HAVE_LOG -#cmakedefine HAVE_EXP - diff --git a/Tests/Tutorial/Step4/directions.txt b/Tests/Tutorial/Step4/directions.txt new file mode 100644 index 0000000..91e4043 --- /dev/null +++ b/Tests/Tutorial/Step4/directions.txt @@ -0,0 +1,72 @@ +# Installing and Testing # + +Now we can start adding testing support and install rules to our project. + +The install rules are fairly simple; for MathFunctions we install the library +and header file, for the application we install the executable and configured +header. + +So to MathFunctions/CMakeLists.txt we add: + + install (TARGETS MathFunctions DESTINATION bin) + install (FILES MathFunctions.h DESTINATION include) + +And the to top-level CMakeLists.txt we add: + + install(TARGETS Tutorial DESTINATION bin) + install(FILES "${PROJECT_BINARY_DIR}/TutorialConfig.h" + DESTINATION include + ) + +That is all that is needed to create a basic local install of the tutorial. + +Run cmake or cmake-gui to configure the project and then build it with your +chosen build tool. Then build the “install” target by typing 'make install' +from the command line or build the INSTALL target from an IDE. This will +install the appropriate header files, libraries, and executables. + +Verify that the installed Tutorial runs. Note: The CMake variable +CMAKE_INSTALL_PREFIX is used to determine the root of where the files will +be installed. + +Next let's test our application. Adding testing is an easy process. At the +end of the top-level CMakeLists file we can add a number of basic tests to +verify that the application is working correctly. + + # enable testing + enable_testing() + + # does the application run + add_test(NAME Runs COMMAND Tutorial 25) + + # does the usage message work? + add_test(NAME Usage COMMAND Tutorial) + set_tests_properties(Usage + PROPERTIES PASS_REGULAR_EXPRESSION "Usage:.*number" + ) + + # define a function to simplify adding tests + function(do_test target arg result) + add_test(NAME Comp${arg} COMMAND ${target} ${arg}) + set_tests_properties(Comp${arg} + PROPERTIES PASS_REGULAR_EXPRESSION ${result} + ) + endfunction(do_test) + + # do a bunch of result based tests + do_test(Tutorial 25 "25 is 5") + do_test(Tutorial -25 "-25 is [-nan|nan|0]") + do_test(Tutorial 0.0001 "0.0001 is 0.01") + +The first test simply verifies that the application runs, does not segfault or +otherwise crash, and has a zero return value. This is the basic form of a CTest +test. + +The Usage test uses a regular expression to verify that the usage message +is printed when an incorrect number of arguments are provided. + +Lastly, we have a function called do_test that simplifies running the +application and verifying that the computed square root is correct for given +input. + +To run tests, cd to the binary directory and run “ctest -N” and “ctest -VV”. diff --git a/Tests/Tutorial/Step4/tutorial.cxx b/Tests/Tutorial/Step4/tutorial.cxx index 37f6ac4..1d5742d 100644 --- a/Tests/Tutorial/Step4/tutorial.cxx +++ b/Tests/Tutorial/Step4/tutorial.cxx @@ -1,8 +1,9 @@ // A simple program that computes the square root of a number +#include <cmath> +#include <iostream> +#include <string> + #include "TutorialConfig.h" -#include <math.h> -#include <stdio.h> -#include <stdlib.h> #ifdef USE_MYMATH # include "MathFunctions.h" @@ -11,23 +12,21 @@ int main(int argc, char* argv[]) { if (argc < 2) { - fprintf(stdout, "%s Version %d.%d\n", argv[0], Tutorial_VERSION_MAJOR, - Tutorial_VERSION_MINOR); - fprintf(stdout, "Usage: %s number\n", argv[0]); + std::cout << argv[0] << " Version " << Tutorial_VERSION_MAJOR << "." + << Tutorial_VERSION_MAJOR << std::endl; + std::cout << "Usage: " << argv[0] << " number" << std::endl; return 1; } - double inputValue = atof(argv[1]); - double outputValue = 0; + double inputValue = std::stod(argv[1]); - if (inputValue >= 0) { #ifdef USE_MYMATH - outputValue = mysqrt(inputValue); + double outputValue = mysqrt(inputValue); #else - outputValue = sqrt(inputValue); + double outputValue = sqrt(inputValue); #endif - } - fprintf(stdout, "The square root of %g is %g\n", inputValue, outputValue); + std::cout << "The square root of " << inputValue << " is " << outputValue + << std::endl; return 0; } diff --git a/Tests/Tutorial/Step5/CMakeLists.txt b/Tests/Tutorial/Step5/CMakeLists.txt index e40b676..63e5410 100644 --- a/Tests/Tutorial/Step5/CMakeLists.txt +++ b/Tests/Tutorial/Step5/CMakeLists.txt @@ -1,72 +1,70 @@ -cmake_minimum_required (VERSION 2.6) -project (Tutorial) +cmake_minimum_required(VERSION 3.3) +project(Tutorial) -# The version number. -set (Tutorial_VERSION_MAJOR 1) -set (Tutorial_VERSION_MINOR 0) - -# does this system provide the log and exp functions? -include (${CMAKE_ROOT}/Modules/CheckFunctionExists.cmake) -check_function_exists (log HAVE_LOG) -check_function_exists (exp HAVE_EXP) +set(CMAKE_CXX_STANDARD 11) +set(CMAKE_CXX_STANDARD_REQUIRED True) # should we use our own math functions option(USE_MYMATH "Use tutorial provided math implementation" ON) +# the version number. +set(Tutorial_VERSION_MAJOR 1) +set(Tutorial_VERSION_MINOR 0) + # configure a header file to pass some of the CMake settings # to the source code -configure_file ( +configure_file( "${PROJECT_SOURCE_DIR}/TutorialConfig.h.in" "${PROJECT_BINARY_DIR}/TutorialConfig.h" ) -# add the binary tree to the search path for include files -# so that we will find TutorialConfig.h -include_directories ("${PROJECT_BINARY_DIR}") - # add the MathFunctions library? -if (USE_MYMATH) - include_directories ("${PROJECT_SOURCE_DIR}/MathFunctions") - add_subdirectory (MathFunctions) - set (EXTRA_LIBS ${EXTRA_LIBS} MathFunctions) -endif () +if(USE_MYMATH) + add_subdirectory(MathFunctions) + list(APPEND EXTRA_LIBS MathFunctions) +endif() # add the executable -add_executable (Tutorial tutorial.cxx) -target_link_libraries (Tutorial ${EXTRA_LIBS}) +add_executable(Tutorial tutorial.cxx) +target_link_libraries(Tutorial PUBLIC ${EXTRA_LIBS}) + +# add the binary tree to the search path for include files +# so that we will find TutorialConfig.h +target_include_directories(Tutorial PUBLIC + "${PROJECT_BINARY_DIR}" + ) # add the install targets -install (TARGETS Tutorial DESTINATION bin) -install (FILES "${PROJECT_BINARY_DIR}/TutorialConfig.h" - DESTINATION include) +install(TARGETS Tutorial DESTINATION bin) +install(FILES "${PROJECT_BINARY_DIR}/TutorialConfig.h" + DESTINATION include + ) # enable testing -enable_testing () +enable_testing() # does the application run -add_test (TutorialRuns Tutorial 25) +add_test(NAME Runs COMMAND Tutorial 25) # does the usage message work? -add_test (TutorialUsage Tutorial) -set_tests_properties (TutorialUsage - PROPERTIES - PASS_REGULAR_EXPRESSION "Usage:.*number" +add_test(NAME Usage COMMAND Tutorial) +set_tests_properties(Usage + PROPERTIES PASS_REGULAR_EXPRESSION "Usage:.*number" ) -#define a macro to simplify adding tests -macro (do_test arg result) - add_test (TutorialComp${arg} Tutorial ${arg}) - set_tests_properties (TutorialComp${arg} +# define a function to simplify adding tests +function(do_test target arg result) + add_test(NAME Comp${arg} COMMAND ${target} ${arg}) + set_tests_properties(Comp${arg} PROPERTIES PASS_REGULAR_EXPRESSION ${result} ) -endmacro () +endfunction(do_test) # do a bunch of result based tests -do_test (4 "4 is 2") -do_test (9 "9 is 3") -do_test (5 "5 is 2.236") -do_test (7 "7 is 2.645") -do_test (25 "25 is 5") -do_test (-25 "-25 is 0") -do_test (0.0001 "0.0001 is 0.01") - +do_test(Tutorial 4 "4 is 2") +do_test(Tutorial 9 "9 is 3") +do_test(Tutorial 5 "5 is 2.236") +do_test(Tutorial 7 "7 is 2.645") +do_test(Tutorial 25 "25 is 5") +do_test(Tutorial -25 "-25 is [-nan|nan|0]") +do_test(Tutorial 0.0001 "0.0001 is 0.01") diff --git a/Tests/Tutorial/Step5/MathFunctions/CMakeLists.txt b/Tests/Tutorial/Step5/MathFunctions/CMakeLists.txt index 453a463..11cf412 100644 --- a/Tests/Tutorial/Step5/MathFunctions/CMakeLists.txt +++ b/Tests/Tutorial/Step5/MathFunctions/CMakeLists.txt @@ -1,17 +1,10 @@ -# first we add the executable that generates the table -# add the binary tree directory to the search path for include files -include_directories( ${CMAKE_CURRENT_BINARY_DIR} ) +add_library(MathFunctions mysqrt.cxx) -add_executable(MakeTable MakeTable.cxx ) -# add the command to generate the source code -add_custom_command ( - OUTPUT ${CMAKE_CURRENT_BINARY_DIR}/Table.h - COMMAND MakeTable ${CMAKE_CURRENT_BINARY_DIR}/Table.h - DEPENDS MakeTable - ) +# state that anybody linking to us needs to include the current source dir +# to find MathFunctions.h, while we don't. +target_include_directories(MathFunctions + INTERFACE ${CMAKE_CURRENT_SOURCE_DIR} + ) -# add the main library -add_library(MathFunctions mysqrt.cxx ${CMAKE_CURRENT_BINARY_DIR}/Table.h ) - -install (TARGETS MathFunctions DESTINATION bin) -install (FILES MathFunctions.h DESTINATION include) +install(TARGETS MathFunctions DESTINATION lib) +install(FILES MathFunctions.h DESTINATION include) diff --git a/Tests/Tutorial/Step5/MathFunctions/MakeTable.cxx b/Tests/Tutorial/Step5/MathFunctions/MakeTable.cxx index cebd50f..ee58556 100644 --- a/Tests/Tutorial/Step5/MathFunctions/MakeTable.cxx +++ b/Tests/Tutorial/Step5/MathFunctions/MakeTable.cxx @@ -1,32 +1,25 @@ // A simple program that builds a sqrt table -#include <math.h> -#include <stdio.h> +#include <cmath> +#include <fstream> +#include <iostream> int main(int argc, char* argv[]) { - int i; - double result; - // make sure we have enough arguments if (argc < 2) { return 1; } - // open the output file - FILE* fout = fopen(argv[1], "w"); - if (!fout) { - return 1; + std::ofstream fout(argv[1], std::ios_base::out); + const bool fileOpen = fout.is_open(); + if (fileOpen) { + fout << "double sqrtTable[] = {" << std::endl; + for (int i = 0; i < 10; ++i) { + fout << sqrt(static_cast<double>(i)) << "," << std::endl; + } + // close the table with a zero + fout << "0};" << std::endl; + fout.close(); } - - // create a source file with a table of square roots - fprintf(fout, "double sqrtTable[] = {\n"); - for (i = 0; i < 10; ++i) { - result = sqrt(static_cast<double>(i)); - fprintf(fout, "%g,\n", result); - } - - // close the table with a zero - fprintf(fout, "0};\n"); - fclose(fout); - return 0; + return fileOpen ? 0 : 1; // return 0 if wrote the file } diff --git a/Tests/Tutorial/Step5/MathFunctions/mysqrt.cxx b/Tests/Tutorial/Step5/MathFunctions/mysqrt.cxx index 458ed63..7d9379e 100644 --- a/Tests/Tutorial/Step5/MathFunctions/mysqrt.cxx +++ b/Tests/Tutorial/Step5/MathFunctions/mysqrt.cxx @@ -1,11 +1,5 @@ #include "MathFunctions.h" -#include "TutorialConfig.h" -#include <stdio.h> - -// include the generated table -#include "Table.h" - -#include <math.h> +#include <iostream> // a hack square root calculation using simple operations double mysqrt(double x) @@ -14,27 +8,16 @@ double mysqrt(double x) return 0; } - double result; - - // if we have both log and exp then use them - double delta; - - // use the table to help find an initial value - result = x; - if (x >= 1 && x < 10) { - result = sqrtTable[static_cast<int>(x)]; - } + double result = x; // do ten iterations - int i; - for (i = 0; i < 10; ++i) { + for (int i = 0; i < 10; ++i) { if (result <= 0) { result = 0.1; } - delta = x - (result * result); + double delta = x - (result * result); result = result + 0.5 * delta / result; - fprintf(stdout, "Computing sqrt of %g to be %g\n", x, result); + std::cout << "Computing sqrt of " << x << " to be " << result << std::endl; } - return result; } diff --git a/Tests/Tutorial/Step5/TutorialConfig.h.in b/Tests/Tutorial/Step5/TutorialConfig.h.in index a091265..25a0602 100644 --- a/Tests/Tutorial/Step5/TutorialConfig.h.in +++ b/Tests/Tutorial/Step5/TutorialConfig.h.in @@ -3,7 +3,3 @@ #define Tutorial_VERSION_MINOR @Tutorial_VERSION_MINOR@ #cmakedefine USE_MYMATH -// does the platform provide exp and log functions? -#cmakedefine HAVE_LOG -#cmakedefine HAVE_EXP - diff --git a/Tests/Tutorial/Step5/directions.txt b/Tests/Tutorial/Step5/directions.txt new file mode 100644 index 0000000..e6f5197 --- /dev/null +++ b/Tests/Tutorial/Step5/directions.txt @@ -0,0 +1,69 @@ +# Adding System Introspection # + +Let us consider adding some code to our project that depends on features the +target platform may not have. For this example, we will add some code that +depends on whether or not the target platform has the log and exp functions. Of +course almost every platform has these functions but for this tutorial assume +that they are not common. + +If the platform has log and exp then we will use them to compute the square +root in the mysqrt function. We first test for the availability of these +functions using the CheckSymbolExists.cmake macro in the top-level CMakeLists +file as follows: + + # does this system provide the log and exp functions? + include(CheckSymbolExists) + set(CMAKE_REQUIRED_LIBRARIES "m") + check_symbol_exists(log "math.h" HAVE_LOG) + check_symbol_exists(exp "math.h" HAVE_EXP) + +Now let's add these defines to TutorialConfig.h.in so that we can use them +from mysqrt.cxx: + + // does the platform provide exp and log functions? + #cmakedefine HAVE_LOG + #cmakedefine HAVE_EXP + +Modify mysqrt.cxx to include math.h. Next, in the mysqrt function we can +provide an alternate implementation based on log and exp if they are available +on the system using the following code: + + // if we have both log and exp then use them + #if defined(HAVE_LOG) && defined (HAVE_EXP) + double result = exp(log(x)*0.5); + std::cout << "Computing sqrt of " << x << " to be " << result << " using log" << std::endl; + #else + ... + +Run cmake or cmake-gui to configure the project and then build it with your +chosen build tool. + +You will notice that even though HAVE_LOG and HAVE_EXP are both defined mysqrt +isn't using them. We should realize quickly that we have forgotten to include +TutorialConfig.h in mysqrt.cxx. We will also need to update +MathFunctions/CMakeLists.txt with where it is located. + +So let's go ahead and update MathFunctions/CMakeLists.txt to look like: + + add_library(MathFunctions mysqrt.cxx) + + target_include_directories(MathFunctions + INTERFACE ${CMAKE_CURRENT_SOURCE_DIR} + PRIVATE ${Tutorial_BINARY_DIR} + ) + + install(TARGETS MathFunctions DESTINATION lib) + install(FILES MathFunctions.h DESTINATION include) + +Now all we need to do is include TutorialConfig.h in mysqrt.cxx + +At this point you should go ahead and build the project again. + +Run the built Tutorial executable. Which function gives better results now, +Step1’s sqrt or Step5’s mysqrt? + +Exercise: Why is it important that we configure TutorialConfig.h.in after the +checks for HAVE_LOG and HAVE_EXP? What would happen if we inverted the two? + +Exercise: Is there a better place for us to save the HAVE_LOG and HAVE_EXP +values other than in TutorialConfig.h? diff --git a/Tests/Tutorial/Step5/tutorial.cxx b/Tests/Tutorial/Step5/tutorial.cxx index 37f6ac4..1d5742d 100644 --- a/Tests/Tutorial/Step5/tutorial.cxx +++ b/Tests/Tutorial/Step5/tutorial.cxx @@ -1,8 +1,9 @@ // A simple program that computes the square root of a number +#include <cmath> +#include <iostream> +#include <string> + #include "TutorialConfig.h" -#include <math.h> -#include <stdio.h> -#include <stdlib.h> #ifdef USE_MYMATH # include "MathFunctions.h" @@ -11,23 +12,21 @@ int main(int argc, char* argv[]) { if (argc < 2) { - fprintf(stdout, "%s Version %d.%d\n", argv[0], Tutorial_VERSION_MAJOR, - Tutorial_VERSION_MINOR); - fprintf(stdout, "Usage: %s number\n", argv[0]); + std::cout << argv[0] << " Version " << Tutorial_VERSION_MAJOR << "." + << Tutorial_VERSION_MAJOR << std::endl; + std::cout << "Usage: " << argv[0] << " number" << std::endl; return 1; } - double inputValue = atof(argv[1]); - double outputValue = 0; + double inputValue = std::stod(argv[1]); - if (inputValue >= 0) { #ifdef USE_MYMATH - outputValue = mysqrt(inputValue); + double outputValue = mysqrt(inputValue); #else - outputValue = sqrt(inputValue); + double outputValue = sqrt(inputValue); #endif - } - fprintf(stdout, "The square root of %g is %g\n", inputValue, outputValue); + std::cout << "The square root of " << inputValue << " is " << outputValue + << std::endl; return 0; } diff --git a/Tests/Tutorial/Step6/CMakeLists.txt b/Tests/Tutorial/Step6/CMakeLists.txt index 0fb7cac..503a312 100644 --- a/Tests/Tutorial/Step6/CMakeLists.txt +++ b/Tests/Tutorial/Step6/CMakeLists.txt @@ -1,78 +1,76 @@ -cmake_minimum_required (VERSION 2.6) -project (Tutorial) +cmake_minimum_required(VERSION 3.3) +project(Tutorial) -# The version number. -set (Tutorial_VERSION_MAJOR 1) -set (Tutorial_VERSION_MINOR 0) +set(CMAKE_CXX_STANDARD 11) +set(CMAKE_CXX_STANDARD_REQUIRED True) + +# the version number. +set(Tutorial_VERSION_MAJOR 1) +set(Tutorial_VERSION_MINOR 0) # does this system provide the log and exp functions? -include (${CMAKE_ROOT}/Modules/CheckFunctionExists.cmake) -check_function_exists (log HAVE_LOG) -check_function_exists (exp HAVE_EXP) +include(CheckSymbolExists) +set(CMAKE_REQUIRED_LIBRARIES "m") +check_symbol_exists(log "math.h" HAVE_LOG) +check_symbol_exists(exp "math.h" HAVE_EXP) # should we use our own math functions option(USE_MYMATH "Use tutorial provided math implementation" ON) # configure a header file to pass some of the CMake settings # to the source code -configure_file ( +configure_file( "${PROJECT_SOURCE_DIR}/TutorialConfig.h.in" "${PROJECT_BINARY_DIR}/TutorialConfig.h" ) -# add the binary tree to the search path for include files -# so that we will find TutorialConfig.h -include_directories ("${PROJECT_BINARY_DIR}") - # add the MathFunctions library? -if (USE_MYMATH) - include_directories ("${PROJECT_SOURCE_DIR}/MathFunctions") - add_subdirectory (MathFunctions) - set (EXTRA_LIBS ${EXTRA_LIBS} MathFunctions) -endif () +if(USE_MYMATH) + add_subdirectory(MathFunctions) + list(APPEND EXTRA_LIBS MathFunctions) +endif() # add the executable -add_executable (Tutorial tutorial.cxx) -target_link_libraries (Tutorial ${EXTRA_LIBS}) +add_executable(Tutorial tutorial.cxx) +target_link_libraries(Tutorial PUBLIC ${EXTRA_LIBS}) + +# add the binary tree to the search path for include files +# so that we will find TutorialConfig.h +target_include_directories(Tutorial PUBLIC + "${PROJECT_BINARY_DIR}" + ) # add the install targets -install (TARGETS Tutorial DESTINATION bin) -install (FILES "${PROJECT_BINARY_DIR}/TutorialConfig.h" - DESTINATION include) +install(TARGETS Tutorial DESTINATION bin) +install(FILES "${PROJECT_BINARY_DIR}/TutorialConfig.h" + DESTINATION include + ) # enable testing -enable_testing () +enable_testing() # does the application run -add_test (TutorialRuns Tutorial 25) +add_test(NAME Runs COMMAND Tutorial 25) # does the usage message work? -add_test (TutorialUsage Tutorial) -set_tests_properties (TutorialUsage - PROPERTIES - PASS_REGULAR_EXPRESSION "Usage:.*number" +add_test(NAME Usage COMMAND Tutorial) +set_tests_properties(Usage + PROPERTIES PASS_REGULAR_EXPRESSION "Usage:.*number" ) -#define a macro to simplify adding tests -macro (do_test arg result) - add_test (TutorialComp${arg} Tutorial ${arg}) - set_tests_properties (TutorialComp${arg} +# define a function to simplify adding tests +function(do_test target arg result) + add_test(NAME Comp${arg} COMMAND ${target} ${arg}) + set_tests_properties(Comp${arg} PROPERTIES PASS_REGULAR_EXPRESSION ${result} ) -endmacro () +endfunction(do_test) # do a bunch of result based tests -do_test (4 "4 is 2") -do_test (9 "9 is 3") -do_test (5 "5 is 2.236") -do_test (7 "7 is 2.645") -do_test (25 "25 is 5") -do_test (-25 "-25 is 0") -do_test (0.0001 "0.0001 is 0.01") - -# build a CPack driven installer package -include (InstallRequiredSystemLibraries) -set (CPACK_RESOURCE_FILE_LICENSE "${CMAKE_CURRENT_SOURCE_DIR}/License.txt") -set (CPACK_PACKAGE_VERSION_MAJOR "${Tutorial_VERSION_MAJOR}") -set (CPACK_PACKAGE_VERSION_MINOR "${Tutorial_VERSION_MINOR}") -include (CPack) +do_test(Tutorial 4 "4 is 2") +do_test(Tutorial 9 "9 is 3") +do_test(Tutorial 5 "5 is 2.236") +do_test(Tutorial 7 "7 is 2.645") +do_test(Tutorial 25 "25 is 5") +do_test(Tutorial -25 "-25 is [-nan|nan|0]") +do_test(Tutorial 0.0001 "0.0001 is 0.01") diff --git a/Tests/Tutorial/Step6/MathFunctions/CMakeLists.txt b/Tests/Tutorial/Step6/MathFunctions/CMakeLists.txt index 70a35f6..2946075 100644 --- a/Tests/Tutorial/Step6/MathFunctions/CMakeLists.txt +++ b/Tests/Tutorial/Step6/MathFunctions/CMakeLists.txt @@ -1,24 +1,14 @@ -# first we add the executable that generates the table -add_executable(MakeTable MakeTable.cxx) - -# add the command to generate the source code -add_custom_command ( - OUTPUT ${CMAKE_CURRENT_BINARY_DIR}/Table.h - DEPENDS MakeTable - COMMAND MakeTable - ARGS ${CMAKE_CURRENT_BINARY_DIR}/Table.h - ) - -set_source_files_properties ( - mysqrt.cxx PROPERTIES - OBJECT_DEPENDS ${CMAKE_CURRENT_BINARY_DIR}/Table.h - ) +add_library(MathFunctions mysqrt.cxx) -# add the binary tree directory to the search path for include files -include_directories( ${CMAKE_CURRENT_BINARY_DIR} ) +# state that anybody linking to us needs to include the current source dir +# to find MathFunctions.h, while we don't. +# state that we depend on Tutorial_BINARY_DIR but consumers don't, as the +# TutorialConfig.h include is an implementation detail -# add the main library -add_library(MathFunctions mysqrt.cxx) +target_include_directories(MathFunctions + INTERFACE ${CMAKE_CURRENT_SOURCE_DIR} + PRIVATE ${Tutorial_BINARY_DIR} + ) -install (TARGETS MathFunctions DESTINATION bin) -install (FILES MathFunctions.h DESTINATION include) +install(TARGETS MathFunctions DESTINATION lib) +install(FILES MathFunctions.h DESTINATION include) diff --git a/Tests/Tutorial/Step6/MathFunctions/MakeTable.cxx b/Tests/Tutorial/Step6/MathFunctions/MakeTable.cxx index cebd50f..ee58556 100644 --- a/Tests/Tutorial/Step6/MathFunctions/MakeTable.cxx +++ b/Tests/Tutorial/Step6/MathFunctions/MakeTable.cxx @@ -1,32 +1,25 @@ // A simple program that builds a sqrt table -#include <math.h> -#include <stdio.h> +#include <cmath> +#include <fstream> +#include <iostream> int main(int argc, char* argv[]) { - int i; - double result; - // make sure we have enough arguments if (argc < 2) { return 1; } - // open the output file - FILE* fout = fopen(argv[1], "w"); - if (!fout) { - return 1; + std::ofstream fout(argv[1], std::ios_base::out); + const bool fileOpen = fout.is_open(); + if (fileOpen) { + fout << "double sqrtTable[] = {" << std::endl; + for (int i = 0; i < 10; ++i) { + fout << sqrt(static_cast<double>(i)) << "," << std::endl; + } + // close the table with a zero + fout << "0};" << std::endl; + fout.close(); } - - // create a source file with a table of square roots - fprintf(fout, "double sqrtTable[] = {\n"); - for (i = 0; i < 10; ++i) { - result = sqrt(static_cast<double>(i)); - fprintf(fout, "%g,\n", result); - } - - // close the table with a zero - fprintf(fout, "0};\n"); - fclose(fout); - return 0; + return fileOpen ? 0 : 1; // return 0 if wrote the file } diff --git a/Tests/Tutorial/Step6/MathFunctions/mysqrt.cxx b/Tests/Tutorial/Step6/MathFunctions/mysqrt.cxx index 458ed63..b9ad20a 100644 --- a/Tests/Tutorial/Step6/MathFunctions/mysqrt.cxx +++ b/Tests/Tutorial/Step6/MathFunctions/mysqrt.cxx @@ -1,11 +1,8 @@ #include "MathFunctions.h" #include "TutorialConfig.h" -#include <stdio.h> +#include <iostream> -// include the generated table -#include "Table.h" - -#include <math.h> +#include <cmath> // a hack square root calculation using simple operations double mysqrt(double x) @@ -14,27 +11,23 @@ double mysqrt(double x) return 0; } - double result; - // if we have both log and exp then use them - double delta; - - // use the table to help find an initial value - result = x; - if (x >= 1 && x < 10) { - result = sqrtTable[static_cast<int>(x)]; - } +#if defined(HAVE_LOG) && defined(HAVE_EXP) + double result = exp(log(x) * 0.5); + std::cout << "Computing sqrt of " << x << " to be " << result << " using log" + << std::endl; +#else + double result = x; // do ten iterations - int i; - for (i = 0; i < 10; ++i) { + for (int i = 0; i < 10; ++i) { if (result <= 0) { result = 0.1; } - delta = x - (result * result); + double delta = x - (result * result); result = result + 0.5 * delta / result; - fprintf(stdout, "Computing sqrt of %g to be %g\n", x, result); + std::cout << "Computing sqrt of " << x << " to be " << result << std::endl; } - +#endif return result; } diff --git a/Tests/Tutorial/Step6/directions.txt b/Tests/Tutorial/Step6/directions.txt new file mode 100644 index 0000000..42b9f06 --- /dev/null +++ b/Tests/Tutorial/Step6/directions.txt @@ -0,0 +1,104 @@ +# Adding a Custom Command and Generated File # + +In this section we will show how you can add a generated source file into the +build process of an application. For this example, we will create a table of +precomputed square roots as part of the build process, and then compile that +table into our application. + +To accomplish this, we first need a program that will generate the table. In the +MathFunctions subdirectory a new source file named MakeTable.cxx will do just that. + + // A simple program that builds a sqrt table + #include <iostream> + #include <fstream> + #include <cmath> + + int main (int argc, char *argv[]) + { + // make sure we have enough arguments + if (argc < 2) { + return 1; + } + + std::ofstream fout(argv[1],std::ios_base::out); + const bool fileOpen = fout.is_open(); + if(fileOpen) { + fout << "double sqrtTable[] = {" << std::endl; + for (int i = 0; i < 10; ++i) { + fout << sqrt(static_cast<double>(i)) << "," << std::endl; + } + // close the table with a zero + fout << "0};" << std::endl; + fout.close(); + } + return fileOpen ? 0 : 1; // return 0 if wrote the file + } + +Note that the table is produced as valid C++ code and that the output filename +is passed in as an argument. + +The next step is to add the appropriate commands to MathFunctions’ CMakeLists +file to build the MakeTable executable and then run it as part of the build +process. A few commands are needed to accomplish this, as shown below: + + # first we add the executable that generates the table + add_executable(MakeTable MakeTable.cxx) + + # add the command to generate the source code + add_custom_command( + OUTPUT ${CMAKE_CURRENT_BINARY_DIR}/Table.h + COMMAND MakeTable ${CMAKE_CURRENT_BINARY_DIR}/Table.h + DEPENDS MakeTable + ) + + # add the main library + add_library(MathFunctions + mysqrt.cxx + ${CMAKE_CURRENT_BINARY_DIR}/Table.h + ) + + target_include_directories(MathFunctions + INTERFACE ${CMAKE_CURRENT_SOURCE_DIR} + PUBLIC ${Tutorial_BINARY_DIR} + # add the binary tree directory to the search path for include files + ${CMAKE_CURRENT_BINARY_DIR} + ) + + install(TARGETS MathFunctions DESTINATION lib) + install(FILES MathFunctions.h DESTINATION include) + +First, the executable for MakeTable is added as any other executable would be +added. Then we add a custom command that specifies how to produce Table.h by +running MakeTable. Next we have to let CMake know that mysqrt.cxx depends on +the generated file Table.h. This is done by adding the generated Table.h to the +list of sources for the library MathFunctions. We also have to add the current +binary directory to the list of include directories so that Table.h can be +found and included by mysqrt.cxx. + +Now let's use the generated table. First, modify mysqrt.cxx to include Table.h. +Next, we can rewrite the mysqrt function to use the table: + + if (x <= 0) { + return 0; + } + + // use the table to help find an initial value + double result = x; + if (x >= 1 && x < 10) { + result = sqrtTable[static_cast<int>(x)]; + } + + // do ten iterations + for (int i = 0; i < 10; ++i) { + if (result <= 0) { + result = 0.1; + } + double delta = x - (result*result); + result = result + 0.5*delta/result; + std::cout << "Computing sqrt of " << x << " to be " << result << std::endl; + } + +Run cmake or cmake-gui to configure the project and then build it with your +chosen build tool. When this project is built it will first build the MakeTable +executable. It will then run MakeTable to produce Table.h. Finally, it will +compile mysqrt.cxx which includes Table.h to produce the MathFunctions library. diff --git a/Tests/Tutorial/Step6/tutorial.cxx b/Tests/Tutorial/Step6/tutorial.cxx index 37f6ac4..1d5742d 100644 --- a/Tests/Tutorial/Step6/tutorial.cxx +++ b/Tests/Tutorial/Step6/tutorial.cxx @@ -1,8 +1,9 @@ // A simple program that computes the square root of a number +#include <cmath> +#include <iostream> +#include <string> + #include "TutorialConfig.h" -#include <math.h> -#include <stdio.h> -#include <stdlib.h> #ifdef USE_MYMATH # include "MathFunctions.h" @@ -11,23 +12,21 @@ int main(int argc, char* argv[]) { if (argc < 2) { - fprintf(stdout, "%s Version %d.%d\n", argv[0], Tutorial_VERSION_MAJOR, - Tutorial_VERSION_MINOR); - fprintf(stdout, "Usage: %s number\n", argv[0]); + std::cout << argv[0] << " Version " << Tutorial_VERSION_MAJOR << "." + << Tutorial_VERSION_MAJOR << std::endl; + std::cout << "Usage: " << argv[0] << " number" << std::endl; return 1; } - double inputValue = atof(argv[1]); - double outputValue = 0; + double inputValue = std::stod(argv[1]); - if (inputValue >= 0) { #ifdef USE_MYMATH - outputValue = mysqrt(inputValue); + double outputValue = mysqrt(inputValue); #else - outputValue = sqrt(inputValue); + double outputValue = sqrt(inputValue); #endif - } - fprintf(stdout, "The square root of %g is %g\n", inputValue, outputValue); + std::cout << "The square root of " << inputValue << " is " << outputValue + << std::endl; return 0; } diff --git a/Tests/Tutorial/Step7/CMakeLists.txt b/Tests/Tutorial/Step7/CMakeLists.txt index d9a92fb..f2d3839 100644 --- a/Tests/Tutorial/Step7/CMakeLists.txt +++ b/Tests/Tutorial/Step7/CMakeLists.txt @@ -1,82 +1,76 @@ -cmake_minimum_required (VERSION 2.6) -project (Tutorial) +cmake_minimum_required(VERSION 3.3) +project(Tutorial) -# The version number. -set (Tutorial_VERSION_MAJOR 1) -set (Tutorial_VERSION_MINOR 0) +set(CMAKE_CXX_STANDARD 11) +set(CMAKE_CXX_STANDARD_REQUIRED True) + +# the version number. +set(Tutorial_VERSION_MAJOR 1) +set(Tutorial_VERSION_MINOR 0) # does this system provide the log and exp functions? -include (${CMAKE_ROOT}/Modules/CheckFunctionExists.cmake) -check_function_exists (log HAVE_LOG) -check_function_exists (exp HAVE_EXP) +include(CheckSymbolExists) +set(CMAKE_REQUIRED_LIBRARIES "m") +check_symbol_exists(log "math.h" HAVE_LOG) +check_symbol_exists(exp "math.h" HAVE_EXP) # should we use our own math functions option(USE_MYMATH "Use tutorial provided math implementation" ON) # configure a header file to pass some of the CMake settings # to the source code -configure_file ( +configure_file( "${PROJECT_SOURCE_DIR}/TutorialConfig.h.in" "${PROJECT_BINARY_DIR}/TutorialConfig.h" ) -# add the binary tree to the search path for include files -# so that we will find TutorialConfig.h -include_directories ("${PROJECT_BINARY_DIR}") - # add the MathFunctions library? -if (USE_MYMATH) - include_directories ("${PROJECT_SOURCE_DIR}/MathFunctions") - add_subdirectory (MathFunctions) - set (EXTRA_LIBS ${EXTRA_LIBS} MathFunctions) -endif () +if(USE_MYMATH) + add_subdirectory(MathFunctions) + list(APPEND EXTRA_LIBS MathFunctions) +endif(USE_MYMATH) # add the executable -add_executable (Tutorial tutorial.cxx) -target_link_libraries (Tutorial ${EXTRA_LIBS}) +add_executable(Tutorial tutorial.cxx) +target_link_libraries(Tutorial PUBLIC ${EXTRA_LIBS}) + +# add the binary tree to the search path for include files +# so that we will find TutorialConfig.h +target_include_directories(Tutorial PUBLIC + "${PROJECT_BINARY_DIR}" + ) # add the install targets -install (TARGETS Tutorial DESTINATION bin) -install (FILES "${PROJECT_BINARY_DIR}/TutorialConfig.h" - DESTINATION include) +install(TARGETS Tutorial DESTINATION bin) +install(FILES "${PROJECT_BINARY_DIR}/TutorialConfig.h" + DESTINATION include + ) # enable testing -enable_testing () +enable_testing() # does the application run -add_test (TutorialRuns Tutorial 25) +add_test(NAME Runs COMMAND Tutorial 25) # does the usage message work? -add_test (TutorialUsage Tutorial) -set_tests_properties (TutorialUsage - PROPERTIES - PASS_REGULAR_EXPRESSION "Usage:.*number" +add_test(NAME Usage COMMAND Tutorial) +set_tests_properties(Usage + PROPERTIES PASS_REGULAR_EXPRESSION "Usage:.*number" ) -#define a macro to simplify adding tests -macro (do_test arg result) - add_test (TutorialComp${arg} Tutorial ${arg}) - set_tests_properties (TutorialComp${arg} +# define a function to simplify adding tests +function(do_test target arg result) + add_test(NAME Comp${arg} COMMAND ${target} ${arg}) + set_tests_properties(Comp${arg} PROPERTIES PASS_REGULAR_EXPRESSION ${result} ) -endmacro () +endfunction(do_test) # do a bunch of result based tests -do_test (4 "4 is 2") -do_test (9 "9 is 3") -do_test (5 "5 is 2.236") -do_test (7 "7 is 2.645") -do_test (25 "25 is 5") -do_test (-25 "-25 is 0") -do_test (0.0001 "0.0001 is 0.01") - -# build a CPack driven installer package -include (InstallRequiredSystemLibraries) -set (CPACK_RESOURCE_FILE_LICENSE "${CMAKE_CURRENT_SOURCE_DIR}/License.txt") -set (CPACK_PACKAGE_VERSION_MAJOR "${Tutorial_VERSION_MAJOR}") -set (CPACK_PACKAGE_VERSION_MINOR "${Tutorial_VERSION_MINOR}") -set (CPACK_PACKAGE_CONTACT "foo@bar.org") -include (CPack) - -# enable dashboard scripting -include (CTest) +do_test(Tutorial 4 "4 is 2") +do_test(Tutorial 9 "9 is 3") +do_test(Tutorial 5 "5 is 2.236") +do_test(Tutorial 7 "7 is 2.645") +do_test(Tutorial 25 "25 is 5") +do_test(Tutorial -25 "-25 is [-nan|nan|0]") +do_test(Tutorial 0.0001 "0.0001 is 0.01") diff --git a/Tests/Tutorial/Step7/License.txt b/Tests/Tutorial/Step7/License.txt index 673d724..c62d00b 100644 --- a/Tests/Tutorial/Step7/License.txt +++ b/Tests/Tutorial/Step7/License.txt @@ -1,2 +1,2 @@ This is the open source License.txt file introduced in -CMake/Tests/Tutorial/Step6... +CMake/Tutorial/Step7... diff --git a/Tests/Tutorial/Step7/MathFunctions/CMakeLists.txt b/Tests/Tutorial/Step7/MathFunctions/CMakeLists.txt index 70a35f6..dc3eb98 100644 --- a/Tests/Tutorial/Step7/MathFunctions/CMakeLists.txt +++ b/Tests/Tutorial/Step7/MathFunctions/CMakeLists.txt @@ -2,23 +2,28 @@ add_executable(MakeTable MakeTable.cxx) # add the command to generate the source code -add_custom_command ( +add_custom_command( OUTPUT ${CMAKE_CURRENT_BINARY_DIR}/Table.h + COMMAND MakeTable ${CMAKE_CURRENT_BINARY_DIR}/Table.h DEPENDS MakeTable - COMMAND MakeTable - ARGS ${CMAKE_CURRENT_BINARY_DIR}/Table.h ) -set_source_files_properties ( - mysqrt.cxx PROPERTIES - OBJECT_DEPENDS ${CMAKE_CURRENT_BINARY_DIR}/Table.h - ) - -# add the binary tree directory to the search path for include files -include_directories( ${CMAKE_CURRENT_BINARY_DIR} ) - # add the main library -add_library(MathFunctions mysqrt.cxx) +add_library(MathFunctions + mysqrt.cxx + ${CMAKE_CURRENT_BINARY_DIR}/Table.h + ) + +# state that anybody linking to us needs to include the current source dir +# to find MathFunctions.h, while we don't. +# state that we depend on Tutorial_BINARY_DIR but consumers don't, as the +# TutorialConfig.h include is an implementation detail +# state that we depend on our binary dir to find Table.h +target_include_directories(MathFunctions + INTERFACE ${CMAKE_CURRENT_SOURCE_DIR} + PRIVATE ${Tutorial_BINARY_DIR} + ${CMAKE_CURRENT_BINARY_DIR} + ) -install (TARGETS MathFunctions DESTINATION bin) -install (FILES MathFunctions.h DESTINATION include) +install(TARGETS MathFunctions DESTINATION lib) +install(FILES MathFunctions.h DESTINATION include) diff --git a/Tests/Tutorial/Step7/MathFunctions/MakeTable.cxx b/Tests/Tutorial/Step7/MathFunctions/MakeTable.cxx index cebd50f..ee58556 100644 --- a/Tests/Tutorial/Step7/MathFunctions/MakeTable.cxx +++ b/Tests/Tutorial/Step7/MathFunctions/MakeTable.cxx @@ -1,32 +1,25 @@ // A simple program that builds a sqrt table -#include <math.h> -#include <stdio.h> +#include <cmath> +#include <fstream> +#include <iostream> int main(int argc, char* argv[]) { - int i; - double result; - // make sure we have enough arguments if (argc < 2) { return 1; } - // open the output file - FILE* fout = fopen(argv[1], "w"); - if (!fout) { - return 1; + std::ofstream fout(argv[1], std::ios_base::out); + const bool fileOpen = fout.is_open(); + if (fileOpen) { + fout << "double sqrtTable[] = {" << std::endl; + for (int i = 0; i < 10; ++i) { + fout << sqrt(static_cast<double>(i)) << "," << std::endl; + } + // close the table with a zero + fout << "0};" << std::endl; + fout.close(); } - - // create a source file with a table of square roots - fprintf(fout, "double sqrtTable[] = {\n"); - for (i = 0; i < 10; ++i) { - result = sqrt(static_cast<double>(i)); - fprintf(fout, "%g,\n", result); - } - - // close the table with a zero - fprintf(fout, "0};\n"); - fclose(fout); - return 0; + return fileOpen ? 0 : 1; // return 0 if wrote the file } diff --git a/Tests/Tutorial/Step7/MathFunctions/mysqrt.cxx b/Tests/Tutorial/Step7/MathFunctions/mysqrt.cxx index 458ed63..5272f56 100644 --- a/Tests/Tutorial/Step7/MathFunctions/mysqrt.cxx +++ b/Tests/Tutorial/Step7/MathFunctions/mysqrt.cxx @@ -1,11 +1,11 @@ #include "MathFunctions.h" #include "TutorialConfig.h" -#include <stdio.h> +#include <iostream> // include the generated table #include "Table.h" -#include <math.h> +#include <cmath> // a hack square root calculation using simple operations double mysqrt(double x) @@ -14,26 +14,20 @@ double mysqrt(double x) return 0; } - double result; - - // if we have both log and exp then use them - double delta; - // use the table to help find an initial value - result = x; + double result = x; if (x >= 1 && x < 10) { result = sqrtTable[static_cast<int>(x)]; } // do ten iterations - int i; - for (i = 0; i < 10; ++i) { + for (int i = 0; i < 10; ++i) { if (result <= 0) { result = 0.1; } - delta = x - (result * result); + double delta = x - (result * result); result = result + 0.5 * delta / result; - fprintf(stdout, "Computing sqrt of %g to be %g\n", x, result); + std::cout << "Computing sqrt of " << x << " to be " << result << std::endl; } return result; diff --git a/Tests/Tutorial/Step7/directions.txt b/Tests/Tutorial/Step7/directions.txt new file mode 100644 index 0000000..7d7c2ea --- /dev/null +++ b/Tests/Tutorial/Step7/directions.txt @@ -0,0 +1,40 @@ +# Building an Installer # + +Next suppose that we want to distribute our project to other people so that they +can use it. We want to provide both binary and source distributions on a variety +of platforms. This is a little different from the install we did previously in +the Installing and Testing section (Step 4), where we were installing the +binaries that we had built from the source code. In this example we will be +building installation packages that support binary installations and package +management features. To accomplish this we will use CPack to create platform +specific installers. Specifically we need to add a few lines to the bottom of +our top-level CMakeLists.txt file. + + include(InstallRequiredSystemLibraries) + set(CPACK_RESOURCE_FILE_LICENSE "${CMAKE_CURRENT_SOURCE_DIR}/License.txt") + set(CPACK_PACKAGE_VERSION_MAJOR "${Tutorial_VERSION_MAJOR}") + set(CPACK_PACKAGE_VERSION_MINOR "${Tutorial_VERSION_MINOR}") + include(CPack) + +That is all there is to it. We start by including InstallRequiredSystemLibraries. +This module will include any runtime libraries that are needed by the project +for the current platform. Next we set some CPack variables to where we have +stored the license and version information for this project. The version +information makes use of the variables we set earlier in this tutorial. Finally +we include the CPack module which will use these variables and some other +properties of the system you are on to setup an installer. + +The next step is to build the project in the usual manner and then run CPack +on it. To build a binary distribution you would run: + + cpack + +To create a source distribution you would type: + + cpack -C CPackSourceConfig.cmake + +Alternatively, run “make package” or right click the Package target and +“Build Project” from an IDE. + +Run the installer executable found in the binary directory. Then run the +installed executable and verify that it works. diff --git a/Tests/Tutorial/Step7/tutorial.cxx b/Tests/Tutorial/Step7/tutorial.cxx index 37f6ac4..1d5742d 100644 --- a/Tests/Tutorial/Step7/tutorial.cxx +++ b/Tests/Tutorial/Step7/tutorial.cxx @@ -1,8 +1,9 @@ // A simple program that computes the square root of a number +#include <cmath> +#include <iostream> +#include <string> + #include "TutorialConfig.h" -#include <math.h> -#include <stdio.h> -#include <stdlib.h> #ifdef USE_MYMATH # include "MathFunctions.h" @@ -11,23 +12,21 @@ int main(int argc, char* argv[]) { if (argc < 2) { - fprintf(stdout, "%s Version %d.%d\n", argv[0], Tutorial_VERSION_MAJOR, - Tutorial_VERSION_MINOR); - fprintf(stdout, "Usage: %s number\n", argv[0]); + std::cout << argv[0] << " Version " << Tutorial_VERSION_MAJOR << "." + << Tutorial_VERSION_MAJOR << std::endl; + std::cout << "Usage: " << argv[0] << " number" << std::endl; return 1; } - double inputValue = atof(argv[1]); - double outputValue = 0; + double inputValue = std::stod(argv[1]); - if (inputValue >= 0) { #ifdef USE_MYMATH - outputValue = mysqrt(inputValue); + double outputValue = mysqrt(inputValue); #else - outputValue = sqrt(inputValue); + double outputValue = sqrt(inputValue); #endif - } - fprintf(stdout, "The square root of %g is %g\n", inputValue, outputValue); + std::cout << "The square root of " << inputValue << " is " << outputValue + << std::endl; return 0; } diff --git a/Tests/Tutorial/Step8/CMakeLists.txt b/Tests/Tutorial/Step8/CMakeLists.txt new file mode 100644 index 0000000..c66bf96 --- /dev/null +++ b/Tests/Tutorial/Step8/CMakeLists.txt @@ -0,0 +1,82 @@ +cmake_minimum_required(VERSION 3.3) +project(Tutorial) + +set(CMAKE_CXX_STANDARD 11) +set(CMAKE_CXX_STANDARD_REQUIRED True) + +# the version number. +set(Tutorial_VERSION_MAJOR 1) +set(Tutorial_VERSION_MINOR 0) + +# does this system provide the log and exp functions? +include(CheckSymbolExists) +set(CMAKE_REQUIRED_LIBRARIES "m") +check_symbol_exists(log "math.h" HAVE_LOG) +check_symbol_exists(exp "math.h" HAVE_EXP) + +# should we use our own math functions +option(USE_MYMATH "Use tutorial provided math implementation" ON) + +# configure a header file to pass some of the CMake settings +# to the source code +configure_file( + "${PROJECT_SOURCE_DIR}/TutorialConfig.h.in" + "${PROJECT_BINARY_DIR}/TutorialConfig.h" + ) + +# add the MathFunctions library? +if(USE_MYMATH) + add_subdirectory(MathFunctions) + list(APPEND EXTRA_LIBS MathFunctions) +endif(USE_MYMATH) + +# add the executable +add_executable(Tutorial tutorial.cxx) +target_link_libraries(Tutorial PUBLIC ${EXTRA_LIBS}) + +# add the binary tree to the search path for include files +# so that we will find TutorialConfig.h +target_include_directories(Tutorial PUBLIC + "${PROJECT_BINARY_DIR}" + ) + +# add the install targets +install(TARGETS Tutorial DESTINATION bin) +install(FILES "${PROJECT_BINARY_DIR}/TutorialConfig.h" + DESTINATION include + ) + +# enable testing +enable_testing() + +# does the application run +add_test(NAME Runs COMMAND Tutorial 25) + +# does the usage message work? +add_test(NAME Usage COMMAND Tutorial) +set_tests_properties(Usage + PROPERTIES PASS_REGULAR_EXPRESSION "Usage:.*number" + ) + +# define a function to simplify adding tests +function(do_test target arg result) +add_test(NAME Comp${arg} COMMAND ${target} ${arg}) + set_tests_properties(Comp${arg} + PROPERTIES PASS_REGULAR_EXPRESSION ${result} + ) +endfunction(do_test) + +# do a bunch of result based tests +do_test(Tutorial 4 "4 is 2") +do_test(Tutorial 9 "9 is 3") +do_test(Tutorial 5 "5 is 2.236") +do_test(Tutorial 7 "7 is 2.645") +do_test(Tutorial 25 "25 is 5") +do_test(Tutorial -25 "-25 is [-nan|nan|0]") +do_test(Tutorial 0.0001 "0.0001 is 0.01") + +include(InstallRequiredSystemLibraries) +set(CPACK_RESOURCE_FILE_LICENSE "${CMAKE_CURRENT_SOURCE_DIR}/License.txt") +set(CPACK_PACKAGE_VERSION_MAJOR "${Tutorial_VERSION_MAJOR}") +set(CPACK_PACKAGE_VERSION_MINOR "${Tutorial_VERSION_MINOR}") +include(CPack) diff --git a/Tests/Tutorial/Step8/License.txt b/Tests/Tutorial/Step8/License.txt new file mode 100644 index 0000000..c62d00b --- /dev/null +++ b/Tests/Tutorial/Step8/License.txt @@ -0,0 +1,2 @@ +This is the open source License.txt file introduced in +CMake/Tutorial/Step7... diff --git a/Tests/Tutorial/Step8/MathFunctions/CMakeLists.txt b/Tests/Tutorial/Step8/MathFunctions/CMakeLists.txt new file mode 100644 index 0000000..dc3eb98 --- /dev/null +++ b/Tests/Tutorial/Step8/MathFunctions/CMakeLists.txt @@ -0,0 +1,29 @@ +# first we add the executable that generates the table +add_executable(MakeTable MakeTable.cxx) + +# add the command to generate the source code +add_custom_command( + OUTPUT ${CMAKE_CURRENT_BINARY_DIR}/Table.h + COMMAND MakeTable ${CMAKE_CURRENT_BINARY_DIR}/Table.h + DEPENDS MakeTable + ) + +# add the main library +add_library(MathFunctions + mysqrt.cxx + ${CMAKE_CURRENT_BINARY_DIR}/Table.h + ) + +# state that anybody linking to us needs to include the current source dir +# to find MathFunctions.h, while we don't. +# state that we depend on Tutorial_BINARY_DIR but consumers don't, as the +# TutorialConfig.h include is an implementation detail +# state that we depend on our binary dir to find Table.h +target_include_directories(MathFunctions + INTERFACE ${CMAKE_CURRENT_SOURCE_DIR} + PRIVATE ${Tutorial_BINARY_DIR} + ${CMAKE_CURRENT_BINARY_DIR} + ) + +install(TARGETS MathFunctions DESTINATION lib) +install(FILES MathFunctions.h DESTINATION include) diff --git a/Tests/Tutorial/Step8/MathFunctions/MakeTable.cxx b/Tests/Tutorial/Step8/MathFunctions/MakeTable.cxx new file mode 100644 index 0000000..ee58556 --- /dev/null +++ b/Tests/Tutorial/Step8/MathFunctions/MakeTable.cxx @@ -0,0 +1,25 @@ +// A simple program that builds a sqrt table +#include <cmath> +#include <fstream> +#include <iostream> + +int main(int argc, char* argv[]) +{ + // make sure we have enough arguments + if (argc < 2) { + return 1; + } + + std::ofstream fout(argv[1], std::ios_base::out); + const bool fileOpen = fout.is_open(); + if (fileOpen) { + fout << "double sqrtTable[] = {" << std::endl; + for (int i = 0; i < 10; ++i) { + fout << sqrt(static_cast<double>(i)) << "," << std::endl; + } + // close the table with a zero + fout << "0};" << std::endl; + fout.close(); + } + return fileOpen ? 0 : 1; // return 0 if wrote the file +} diff --git a/Tests/Tutorial/Step8/MathFunctions/MathFunctions.h b/Tests/Tutorial/Step8/MathFunctions/MathFunctions.h new file mode 100644 index 0000000..cd36bcc --- /dev/null +++ b/Tests/Tutorial/Step8/MathFunctions/MathFunctions.h @@ -0,0 +1 @@ +double mysqrt(double x); diff --git a/Tests/Tutorial/Step8/MathFunctions/mysqrt.cxx b/Tests/Tutorial/Step8/MathFunctions/mysqrt.cxx new file mode 100644 index 0000000..5b862fb --- /dev/null +++ b/Tests/Tutorial/Step8/MathFunctions/mysqrt.cxx @@ -0,0 +1,42 @@ +#include "MathFunctions.h" +#include "TutorialConfig.h" +#include <iostream> + +// include the generated table +#include "Table.h" + +#include <cmath> + +// a hack square root calculation using simple operations +double mysqrt(double x) +{ + if (x <= 0) { + return 0; + } + + // if we have both log and exp then use them +#if defined(HAVE_LOG) && defined(HAVE_EXP) + double result = exp(log(x) * 0.5); + std::cout << "Computing sqrt of " << x << " to be " << result << " using log" + << std::endl; +#else + // use the table to help find an initial value + double result = x; + if (x >= 1 && x < 10) { + result = sqrtTable[static_cast<int>(x)]; + } + + // if we have both log and exp then use them + + // do ten iterations + for (int i = 0; i < 10; ++i) { + if (result <= 0) { + result = 0.1; + } + double delta = x - (result * result); + result = result + 0.5 * delta / result; + std::cout << "Computing sqrt of " << x << " to be " << result << std::endl; + } +#endif + return result; +} diff --git a/Tests/Tutorial/Step8/TutorialConfig.h.in b/Tests/Tutorial/Step8/TutorialConfig.h.in new file mode 100644 index 0000000..e97ce24 --- /dev/null +++ b/Tests/Tutorial/Step8/TutorialConfig.h.in @@ -0,0 +1,8 @@ +// the configured options and settings for Tutorial +#define Tutorial_VERSION_MAJOR @Tutorial_VERSION_MAJOR@ +#define Tutorial_VERSION_MINOR @Tutorial_VERSION_MINOR@ +#cmakedefine USE_MYMATH + +// does the platform provide exp and log functions? +#cmakedefine HAVE_LOG +#cmakedefine HAVE_EXP diff --git a/Tests/Tutorial/Step8/directions.txt b/Tests/Tutorial/Step8/directions.txt new file mode 100644 index 0000000..588d9c6 --- /dev/null +++ b/Tests/Tutorial/Step8/directions.txt @@ -0,0 +1,38 @@ +# Adding Support for a Dashboard # + +Adding support for submitting our test results to a dashboard is very easy. We +already defined a number of tests for our project in the earlier steps of this +tutorial. We just have to run those tests and submit them to a dashboard. To +include support for dashboards we include the CTest module in our top-level +CMakeLists.txt. + +Replace: + # enable testing + enable_testing() + +With: + # enable dashboard scripting + include(CTest) + +The CTest module will automatically call enable_testing(), so +we can remove it from our CMake files. + +We will also need to create a CTestConfig.cmake file where we can specify the +name of the project and where to submit the dashboard. + + set(CTEST_PROJECT_NAME "CMakeTutorial") + set(CTEST_NIGHTLY_START_TIME "01:00:00 UTC") + + set(CTEST_DROP_METHOD "http") + set(CTEST_DROP_SITE "my.cdash.org/") + set(CTEST_DROP_LOCATION "/submit.php?project=CMakeTutorial") + set(CTEST_DROP_SITE_CDASH TRUE) + +CTest will read in this file when it runs. To create a simple dashboard you can +run cmake or cmake-gui to configure the project, but do not build it yet. +Instead, change directory to the binary tree, and then run: + 'ctest [-VV] –D Experimental'. On Windows, build the EXPERIMENTAL target. + +Ctest will build and test the project and submit results to the Kitware public +dashboard. The results of your dashboard will be uploaded to Kitware's public +dashboard here: https://my.cdash.org/index.php?project=CMakeTutorial. diff --git a/Tests/Tutorial/Step8/tutorial.cxx b/Tests/Tutorial/Step8/tutorial.cxx new file mode 100644 index 0000000..1d5742d --- /dev/null +++ b/Tests/Tutorial/Step8/tutorial.cxx @@ -0,0 +1,32 @@ +// A simple program that computes the square root of a number +#include <cmath> +#include <iostream> +#include <string> + +#include "TutorialConfig.h" + +#ifdef USE_MYMATH +# include "MathFunctions.h" +#endif + +int main(int argc, char* argv[]) +{ + if (argc < 2) { + std::cout << argv[0] << " Version " << Tutorial_VERSION_MAJOR << "." + << Tutorial_VERSION_MAJOR << std::endl; + std::cout << "Usage: " << argv[0] << " number" << std::endl; + return 1; + } + + double inputValue = std::stod(argv[1]); + +#ifdef USE_MYMATH + double outputValue = mysqrt(inputValue); +#else + double outputValue = sqrt(inputValue); +#endif + + std::cout << "The square root of " << inputValue << " is " << outputValue + << std::endl; + return 0; +} diff --git a/Tests/Tutorial/Step9/CMakeLists.txt b/Tests/Tutorial/Step9/CMakeLists.txt new file mode 100644 index 0000000..309d513 --- /dev/null +++ b/Tests/Tutorial/Step9/CMakeLists.txt @@ -0,0 +1,81 @@ +cmake_minimum_required(VERSION 3.3) +project(Tutorial) + +set(CMAKE_CXX_STANDARD 11) +set(CMAKE_CXX_STANDARD_REQUIRED True) + +# the version number. +set(Tutorial_VERSION_MAJOR 1) +set(Tutorial_VERSION_MINOR 0) + +# does this system provide the log and exp functions? +include(CheckSymbolExists) +set(CMAKE_REQUIRED_LIBRARIES "m") +check_symbol_exists(log "math.h" HAVE_LOG) +check_symbol_exists(exp "math.h" HAVE_EXP) + +# should we use our own math functions +option(USE_MYMATH "Use tutorial provided math implementation" ON) + +# configure a header file to pass the version number only +configure_file( + "${PROJECT_SOURCE_DIR}/TutorialConfig.h.in" + "${PROJECT_BINARY_DIR}/TutorialConfig.h" + ) + +# add the MathFunctions library? +if(USE_MYMATH) + add_subdirectory(MathFunctions) + list(APPEND EXTRA_LIBS MathFunctions) +endif() + +# add the executable +add_executable(Tutorial tutorial.cxx) +target_link_libraries(Tutorial PUBLIC ${EXTRA_LIBS}) + +# add the binary tree to the search path for include files +# so that we will find TutorialConfig.h +target_include_directories(Tutorial PUBLIC + "${PROJECT_BINARY_DIR}" + ) + +# add the install targets +install(TARGETS Tutorial DESTINATION bin) +install(FILES "${PROJECT_BINARY_DIR}/TutorialConfig.h" + DESTINATION include + ) + +# enable testing +include(CTest) + +# does the application run +add_test(NAME Runs COMMAND Tutorial 25) + +# does the usage message work? +add_test(NAME Usage COMMAND Tutorial) +set_tests_properties(Usage + PROPERTIES PASS_REGULAR_EXPRESSION "Usage:.*number" + ) + +# define a function to simplify adding tests +function(do_test target arg result) + add_test(NAME Comp${arg} COMMAND ${target} ${arg}) + set_tests_properties(Comp${arg} + PROPERTIES PASS_REGULAR_EXPRESSION ${result} + ) +endfunction(do_test) + +# do a bunch of result based tests +do_test(Tutorial 4 "4 is 2") +do_test(Tutorial 9 "9 is 3") +do_test(Tutorial 5 "5 is 2.236") +do_test(Tutorial 7 "7 is 2.645") +do_test(Tutorial 25 "25 is 5") +do_test(Tutorial -25 "-25 is [-nan|nan|0]") +do_test(Tutorial 0.0001 "0.0001 is 0.01") + +include(InstallRequiredSystemLibraries) +set(CPACK_RESOURCE_FILE_LICENSE "${CMAKE_CURRENT_SOURCE_DIR}/License.txt") +set(CPACK_PACKAGE_VERSION_MAJOR "${Tutorial_VERSION_MAJOR}") +set(CPACK_PACKAGE_VERSION_MINOR "${Tutorial_VERSION_MINOR}") +include(CPack) diff --git a/Tests/Tutorial/Step9/CTestConfig.cmake b/Tests/Tutorial/Step9/CTestConfig.cmake new file mode 100644 index 0000000..7a927ac --- /dev/null +++ b/Tests/Tutorial/Step9/CTestConfig.cmake @@ -0,0 +1,15 @@ +## This file should be placed in the root directory of your project. +## Then modify the CMakeLists.txt file in the root directory of your +## project to incorporate the testing dashboard. +## +## # The following are required to submit to the CDash dashboard: +## ENABLE_TESTING() +## INCLUDE(CTest) + +set(CTEST_PROJECT_NAME "CMakeTutorial") +set(CTEST_NIGHTLY_START_TIME "00:00:00 EST") + +set(CTEST_DROP_METHOD "http") +set(CTEST_DROP_SITE "my.cdash.org") +set(CTEST_DROP_LOCATION "/submit.php?project=CMakeTutorial") +set(CTEST_DROP_SITE_CDASH TRUE) diff --git a/Tests/Tutorial/Step9/License.txt b/Tests/Tutorial/Step9/License.txt new file mode 100644 index 0000000..c62d00b --- /dev/null +++ b/Tests/Tutorial/Step9/License.txt @@ -0,0 +1,2 @@ +This is the open source License.txt file introduced in +CMake/Tutorial/Step7... diff --git a/Tests/Tutorial/Step9/MathFunctions/CMakeLists.txt b/Tests/Tutorial/Step9/MathFunctions/CMakeLists.txt new file mode 100644 index 0000000..e651a57 --- /dev/null +++ b/Tests/Tutorial/Step9/MathFunctions/CMakeLists.txt @@ -0,0 +1,35 @@ +# first we add the executable that generates the table +add_executable(MakeTable MakeTable.cxx) + +# add the command to generate the source code +add_custom_command( + OUTPUT ${CMAKE_CURRENT_BINARY_DIR}/Table.h + COMMAND MakeTable ${CMAKE_CURRENT_BINARY_DIR}/Table.h + DEPENDS MakeTable + ) + +# add the main library +add_library(MathFunctions + mysqrt.cxx + ${CMAKE_CURRENT_BINARY_DIR}/Table.h + ) + +# state that anybody linking to us needs to include the current source dir +# to find MathFunctions.h, while we don't. +# state that we depend on our binary dir to find Table.h +target_include_directories(MathFunctions + INTERFACE ${CMAKE_CURRENT_SOURCE_DIR} + PRIVATE ${CMAKE_CURRENT_BINARY_DIR} + ) + +# use compile definitions to state if we have enabled USE_MYMATH +# and that anything that links to use will get this define +target_compile_definitions(MathFunctions INTERFACE "USE_MYMATH") + +if(HAVE_LOG AND HAVE_EXP) + target_compile_definitions(MathFunctions + PRIVATE "HAVE_LOG" "HAVE_EXP") +endif() + +install(TARGETS MathFunctions DESTINATION lib) +install(FILES MathFunctions.h DESTINATION include) diff --git a/Tests/Tutorial/Step9/MathFunctions/MakeTable.cxx b/Tests/Tutorial/Step9/MathFunctions/MakeTable.cxx new file mode 100644 index 0000000..ee58556 --- /dev/null +++ b/Tests/Tutorial/Step9/MathFunctions/MakeTable.cxx @@ -0,0 +1,25 @@ +// A simple program that builds a sqrt table +#include <cmath> +#include <fstream> +#include <iostream> + +int main(int argc, char* argv[]) +{ + // make sure we have enough arguments + if (argc < 2) { + return 1; + } + + std::ofstream fout(argv[1], std::ios_base::out); + const bool fileOpen = fout.is_open(); + if (fileOpen) { + fout << "double sqrtTable[] = {" << std::endl; + for (int i = 0; i < 10; ++i) { + fout << sqrt(static_cast<double>(i)) << "," << std::endl; + } + // close the table with a zero + fout << "0};" << std::endl; + fout.close(); + } + return fileOpen ? 0 : 1; // return 0 if wrote the file +} diff --git a/Tests/Tutorial/Step9/MathFunctions/MathFunctions.cxx b/Tests/Tutorial/Step9/MathFunctions/MathFunctions.cxx new file mode 100644 index 0000000..5351184 --- /dev/null +++ b/Tests/Tutorial/Step9/MathFunctions/MathFunctions.cxx @@ -0,0 +1,18 @@ + +#include "MathFunctions.h" +#include <cmath> + +#ifdef USE_MYMATH +# include "mysqrt.h" +#endif + +namespace mathfunctions { +double sqrt(double x) +{ +#ifdef USE_MYMATH + return detail::mysqrt(x); +#else + return std::sqrt(x); +#endif +} +} diff --git a/Tests/Tutorial/Step9/MathFunctions/MathFunctions.h b/Tests/Tutorial/Step9/MathFunctions/MathFunctions.h new file mode 100644 index 0000000..cd36bcc --- /dev/null +++ b/Tests/Tutorial/Step9/MathFunctions/MathFunctions.h @@ -0,0 +1 @@ +double mysqrt(double x); diff --git a/Tests/Tutorial/Step9/MathFunctions/mysqrt.cxx b/Tests/Tutorial/Step9/MathFunctions/mysqrt.cxx new file mode 100644 index 0000000..8b82141 --- /dev/null +++ b/Tests/Tutorial/Step9/MathFunctions/mysqrt.cxx @@ -0,0 +1,41 @@ +#include "MathFunctions.h" +#include <iostream> + +// include the generated table +#include "Table.h" + +#include <cmath> + +// a hack square root calculation using simple operations +double mysqrt(double x) +{ + if (x <= 0) { + return 0; + } + + // if we have both log and exp then use them +#if defined(HAVE_LOG) && defined(HAVE_EXP) + double result = exp(log(x) * 0.5); + std::cout << "Computing sqrt of " << x << " to be " << result << " using log" + << std::endl; +#else + // use the table to help find an initial value + double result = x; + if (x >= 1 && x < 10) { + result = sqrtTable[static_cast<int>(x)]; + } + + // if we have both log and exp then use them + + // do ten iterations + for (int i = 0; i < 10; ++i) { + if (result <= 0) { + result = 0.1; + } + double delta = x - (result * result); + result = result + 0.5 * delta / result; + std::cout << "Computing sqrt of " << x << " to be " << result << std::endl; + } +#endif + return result; +} diff --git a/Tests/Tutorial/Step9/MathFunctions/mysqrt.h b/Tests/Tutorial/Step9/MathFunctions/mysqrt.h new file mode 100644 index 0000000..e1c42ef --- /dev/null +++ b/Tests/Tutorial/Step9/MathFunctions/mysqrt.h @@ -0,0 +1,6 @@ + +namespace mathfunctions { +namespace detail { +double mysqrt(double x); +} +} diff --git a/Tests/Tutorial/Step9/TutorialConfig.h.in b/Tests/Tutorial/Step9/TutorialConfig.h.in new file mode 100644 index 0000000..8cd2fc9 --- /dev/null +++ b/Tests/Tutorial/Step9/TutorialConfig.h.in @@ -0,0 +1,3 @@ +// the configured version number +#define Tutorial_VERSION_MAJOR @Tutorial_VERSION_MAJOR@ +#define Tutorial_VERSION_MINOR @Tutorial_VERSION_MINOR@ diff --git a/Tests/Tutorial/Step9/directions.txt b/Tests/Tutorial/Step9/directions.txt new file mode 100644 index 0000000..8771637 --- /dev/null +++ b/Tests/Tutorial/Step9/directions.txt @@ -0,0 +1,166 @@ +# Mixing Static and Shared # + +In this section we will show how by using the BUILD_SHARED_LIBS variable we can +control the default behavior of add_library, and allow control over how +libraries without an explicit type ( STATIC/SHARED/MODULE/OBJECT ) are built. + +To accomplish this we need to add BUILD_SHARED_LIBS to the top level +CMakeLists.txt. We use the option command as it allows users to optionally +select if the value should be On or Off. + +Next we are going to refactor MathFunctions to become a real library that +encapsulates using mysqrt or sqrt, instead of requiring the calling code +to do this logic. This will also mean that USE_MYMATH will not control building +MathFuctions, but instead will control the behavior of this library. + +The first step is to update the starting section of the top level CMakeLists.txt +to look like: + + cmake_minimum_required(VERSION 3.3) + project(Tutorial) + + # control where the static and shared libraries are built so that on windows + # we don't need to tinker with the path to run the executable + set(CMAKE_ARCHIVE_OUTPUT_DIRECTORY "${PROJECT_BINARY_DIR}") + set(CMAKE_LIBRARY_OUTPUT_DIRECTORY "${PROJECT_BINARY_DIR}") + + set(CMAKE_CXX_STANDARD 11) + set(CMAKE_CXX_STANDARD_REQUIRED True) + + option(BUILD_SHARED_LIBS "Build using shared libraries" ON) + + # the version number. + set(Tutorial_VERSION_MAJOR 1) + set(Tutorial_VERSION_MINOR 0) + + # configure a header file to pass the version number only + configure_file( + "${PROJECT_SOURCE_DIR}/TutorialConfig.h.in" + "${PROJECT_BINARY_DIR}/TutorialConfig.h" + ) + + # add the MathFunctions library + add_subdirectory(MathFunctions) + + # add the executable + add_executable(Tutorial tutorial.cxx) + target_link_libraries(Tutorial PUBLIC MathFunctions) + +Now that we have made MathFunctions always be used, we will need to update +the logic of that library. So, in MathFunctions/CMakeLists.txt we need to +create a SqrtLibrary that will conditionally be built when USE_MYMATH is +enabled. Now, since this is a tutorial, we are going to explicitly require +that SqrtLibrary is built statically. + +The end result is that MathFunctions/CMakeLists.txt should look like: + + # add the library that runs + add_library(MathFunctions MathFunctions.cxx) + + # state that anybody linking to us needs to include the current source dir + # to find MathFunctions.h, while we don't. + target_include_directories(MathFunctions + INTERFACE ${CMAKE_CURRENT_SOURCE_DIR} + ) + + # should we use our own math functions + option(USE_MYMATH "Use tutorial provided math implementation" ON) + if(USE_MYMATH) + + # does this system provide the log and exp functions? + include(CheckSymbolExists) + set(CMAKE_REQUIRED_LIBRARIES "m") + check_symbol_exists(log "math.h" HAVE_LOG) + check_symbol_exists(exp "math.h" HAVE_EXP) + + # first we add the executable that generates the table + add_executable(MakeTable MakeTable.cxx) + + # add the command to generate the source code + add_custom_command( + OUTPUT ${CMAKE_CURRENT_BINARY_DIR}/Table.h + COMMAND MakeTable ${CMAKE_CURRENT_BINARY_DIR}/Table.h + DEPENDS MakeTable + ) + + # library that just does sqrt + add_library(SqrtLibrary STATIC + mysqrt.cxx + ${CMAKE_CURRENT_BINARY_DIR}/Table.h + ) + + # state that we depend on our binary dir to find Table.h + target_include_directories(SqrtLibrary PRIVATE + ${CMAKE_CURRENT_BINARY_DIR} + ) + + target_compile_definitions(MathFunctions PRIVATE "USE_MYMATH") + if(HAVE_LOG AND HAVE_EXP) + target_compile_definitions(SqrtLibrary + PRIVATE "HAVE_LOG" "HAVE_EXP") + endif() + + target_link_libraries(MathFunctions PRIVATE SqrtLibrary) + endif() + + # define the symbol stating we are using the declspec(dllexport) when + # building on windows + target_compile_definitions(MathFunctions PRIVATE "EXPORTING_MYMATH") + + install(TARGETS MathFunctions DESTINATION lib) + install(FILES MathFunctions.h DESTINATION include) + +Next, update MathFunctions/mysqrt.cxx to use the mathfunctions and detail namespaces: + + #include <iostream> + #include "MathFunctions.h" + + // include the generated table + #include "Table.h" + + #include <cmath> + + namespace mathfunctions { + namespace detail { + // a hack square root calculation using simple operations + double mysqrt(double x) + { + ... + + return result; + } + } + } + +We also need to make some changes in tutorial.cxx, so that it no longer uses USE_MYMATH: +1. Always include MathFunctions.h +2. Always use mathfunctions::sqrt + +Finally, update MathFunctions/MathFunctions.h to use dll export defines: + + #if defined(_WIN32) + #if defined(EXPORTING_MYMATH) + #define DECLSPEC __declspec(dllexport) + #else + #define DECLSPEC __declspec(dllimport) + #endif + #else //non windows + #define DECLSPEC + #endif + + namespace mathfunctions + { + double DECLSPEC sqrt(double x); + } + +At this point, if you build everything, you will notice that linking fails +as we are combining a static library without position enabled code with a +library that has position enabled code. This solution to this is to explicitly +set the POSITION_INDEPENDENT_CODE target property of SqrtLibrary to be True no +matter the build type. + +Exercise: We modified MathFunctions.h to use dll export defines. Using CMake +documentation can you find a helper module to simplify this? + +Exercise: Determine what command is enabling PIC for SqrtLibrary. +What happens if we remove said command? diff --git a/Tests/Tutorial/Step9/tutorial.cxx b/Tests/Tutorial/Step9/tutorial.cxx new file mode 100644 index 0000000..73e67a9 --- /dev/null +++ b/Tests/Tutorial/Step9/tutorial.cxx @@ -0,0 +1,33 @@ +// A simple program that computes the square root of a number +#include <cmath> +#include <iostream> +#include <sstream> +#include <string> + +#include "TutorialConfig.h" + +#ifdef USE_MYMATH +# include "MathFunctions.h" +#endif + +int main(int argc, char* argv[]) +{ + if (argc < 2) { + std::cout << argv[0] << " Version " << Tutorial_VERSION_MAJOR << "." + << Tutorial_VERSION_MAJOR << std::endl; + std::cout << "Usage: " << argv[0] << " number" << std::endl; + return 1; + } + + double inputValue = std::stod(argv[1]); + +#ifdef USE_MYMATH + double outputValue = mysqrt(inputValue); +#else + double outputValue = sqrt(inputValue); +#endif + + std::cout << "The square root of " << inputValue << " is " << outputValue + << std::endl; + return 0; +} |