From 031d6d80e6365bb9a25bd6f951c3a338c5b15ed2 Mon Sep 17 00:00:00 2001 From: Teemu Murtola Date: Tue, 3 Sep 2013 07:11:38 +0300 Subject: [PATCH] Man page export from the wrapper binary. Implement nroff output format for 'gmx help -export'. Move the header/footer generation out of wman.cpp. The generation is now off by default. Can be reinstantiated if someone comes with a good approach for the case where the compiled binaries don't run on the build host (e.g., compiling AVX256 binaries on a SSE4.1 host). Related to #685 and #969. Change-Id: I17725e3a487470bea8f6db2a59da31139e70621e --- CMakeLists.txt | 21 +--- CPackInit.cmake | 10 +- cmake/BuildManPages.cmake | 65 ----------- cmake/CreateManPage.cmake | 7 -- share/CMakeLists.txt | 50 +++++++-- share/man/.gitignore | 2 + share/man/CMakeLists.txt | 102 ++++++++++++++++++ {man => share/man}/man7/gromacs.7.cmakein | 2 +- src/CMakeLists.txt | 3 - .../commandline/cmdlinemodulemanager.cpp | 54 ++++++++++ src/gromacs/onlinehelp/helpwritercontext.h | 1 + src/gromacs/onlinehelp/wman.cpp | 13 +-- 12 files changed, 214 insertions(+), 116 deletions(-) delete mode 100644 cmake/BuildManPages.cmake delete mode 100644 cmake/CreateManPage.cmake create mode 100644 share/man/.gitignore create mode 100644 share/man/CMakeLists.txt rename {man => share/man}/man7/gromacs.7.cmakein (98%) diff --git a/CMakeLists.txt b/CMakeLists.txt index 81b3f45d26..477c742764 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -81,16 +81,20 @@ set(CPACK_RESOURCE_FILE_LICENSE "${CMAKE_SOURCE_DIR}/COPYING") set(CPACK_RESOURCE_FILE_README "${CMAKE_SOURCE_DIR}/admin/InstallInfo.txt") set(CPACK_SOURCE_IGNORE_FILES "\\\\.isreposource$;\\\\.git/;\\\\.gitignore$") set(CPACK_PROJECT_CONFIG_FILE "${CMAKE_SOURCE_DIR}/CPackInit.cmake") -SET(CPACK_SOURCE_INSTALLED_DIRECTORIES "${CMAKE_SOURCE_DIR};/;${CMAKE_BINARY_DIR}/man;man") +set(CPACK_SOURCE_INSTALLED_DIRECTORIES "${CMAKE_SOURCE_DIR};/;${CMAKE_BINARY_DIR}/share/man;share/man") set(CPACK_PACKAGE_CONTACT "gmx-users@gromacs.org") #must come after all cpack settings! include(CPack) set(SOURCE_IS_GIT_REPOSITORY OFF) +set(SOURCE_IS_SOURCE_DISTRIBUTION OFF) if(EXISTS "${CMAKE_SOURCE_DIR}/.git") set(SOURCE_IS_GIT_REPOSITORY ON) endif() +if(NOT EXISTS "${CMAKE_SOURCE_DIR}/admin/.isreposource") + set(SOURCE_IS_SOURCE_DISTRIBUTION ON) +endif() ######################################################################## # Check and warn if cache generated on a different host is being reused @@ -1061,21 +1065,6 @@ if(GMX_LOAD_PLUGINS) endif(GMX_LOAD_PLUGINS) set(VMD_QUIETLY TRUE CACHE INTERNAL "") -if(EXISTS "${CMAKE_SOURCE_DIR}/admin/.isreposource") - if(NOT CMAKE_CROSSCOMPILING) - option(GMX_BUILD_MANPAGES "Build man pages" ON) - else() - message(STATUS "Building the man pages is not available when " - "cross-compiling the developer version from git") - endif() -else() - #make sure source package contains all man pages - if(NOT EXISTS "${CMAKE_SOURCE_DIR}/man/man1/ngmx.1") - message(FATAL_ERROR "Man pages are missing from source package.") - endif() -endif() -mark_as_advanced(GMX_BUILD_MANPAGES) - # Math and thread libraries must often come after all others when linking... if(HAVE_LIBM) list(APPEND GMX_EXTRA_LIBRARIES m) diff --git a/CPackInit.cmake b/CPackInit.cmake index eba4c45d7a..212f74947b 100644 --- a/CPackInit.cmake +++ b/CPackInit.cmake @@ -1,10 +1,10 @@ #TODO: add check that source doesn't contain any untracked files if(CPACK_SOURCE_PACKAGE_FILE_NAME) #building source package get_filename_component(CMAKE_BINARY_DIR ${CPACK_OUTPUT_CONFIG_FILE} PATH) - if(NOT EXISTS "${CMAKE_BINARY_DIR}/man/man1/ngmx.1") - message(FATAL_ERROR - "To create a complete source package all man pages need to be generated." - "The man pages are automatically built together with the binaries. " - "Make sure to build all binaries (e.g. GMX_X11=on).") + if(NOT EXISTS "${CMAKE_BINARY_DIR}/share/man/man1/gmx-view.1") + message(FATAL_ERROR + "To create a complete source package all man pages need to be generated. " + "You need to run 'make man' or set GMX_BUILD_MANPAGES=ON to get " + "them automatically built together with the binaries.") endif() endif() diff --git a/cmake/BuildManPages.cmake b/cmake/BuildManPages.cmake deleted file mode 100644 index 88fc9d62f7..0000000000 --- a/cmake/BuildManPages.cmake +++ /dev/null @@ -1,65 +0,0 @@ -MACRO(TODAY RESULT) - IF(UNIX) - EXECUTE_PROCESS(COMMAND "date" "+%F" OUTPUT_VARIABLE ${RESULT} OUTPUT_STRIP_TRAILING_WHITESPACE) - ELSE() - set(${RESULT} "????-??-??") - ENDIF() -ENDMACRO(TODAY) - -if(GMX_BUILD_MANPAGES) - set(MAN1_PATH ${CMAKE_BINARY_DIR}/man/man1) - file(MAKE_DIRECTORY ${MAN1_PATH}) - - #create gromacs.7 - FILE(READ "${CMAKE_SOURCE_DIR}/admin/programs.txt" contents) - - # Convert file contents into a CMake list. First escape ; - STRING(REGEX REPLACE ";" "\\\\;" contents "${contents}") - STRING(REGEX REPLACE "\n" ";" contents "${contents}") - - set(PROGMANPAGES "") - foreach(line ${contents}) - if (${line} MATCHES "^HEAD\\|") - string(REGEX REPLACE "^HEAD\\|" "" DESC ${line}) - set(PROGMANPAGES "${PROGMANPAGES}.Sh \"${DESC}\"\n.IX Subsection \"${DESC}\"\n.Vb\n.ta 16n\n") - elseif(${line} MATCHES "^END$") - set(PROGMANPAGES "${PROGMANPAGES}.Ve\n") - elseif(${line} MATCHES "\\|") - string(REGEX REPLACE "\\|" "\t" line ${line}) - set(PROGMANPAGES "${PROGMANPAGES}\\& ${line}\n") - else() - message(WARNING "Incorrectly formated line \"${line}\" in programs.txt") - endif() - endforeach() - TODAY(TODAYS_DATE) - configure_file(${CMAKE_SOURCE_DIR}/man/man7/gromacs.7.cmakein ${CMAKE_BINARY_DIR}/man/man7/gromacs.7) - install(FILES ${CMAKE_BINARY_DIR}/man/man7/gromacs.7 DESTINATION - ${MAN_INSTALL_DIR}/man7) -#man-pages are only avalaible if they are either build or this is a source archive -elseif(NOT EXISTS "${CMAKE_SOURCE_DIR}/admin/.isreposource") - install(FILES ${CMAKE_SOURCE_DIR}/man/man7/gromacs.7 DESTINATION - ${MAN_INSTALL_DIR}/man7) -endif() - -function (gmx_add_man_page EXENAME) - if(GMX_BUILD_MANPAGES) - file(STRINGS ${CMAKE_SOURCE_DIR}/admin/programs.txt DESC - REGEX "^${EXENAME}\\|" LIMIT_COUNT 1) - #Regex breaks with a "|" in description. Cmake doesn't support - #non-greedy regex. - string(REGEX REPLACE "^.*\\|" "" DESC "${DESC}") - if(DESC STREQUAL "") - message(WARNING "Missing description for ${EXENAME}") - endif() - add_custom_command(TARGET ${EXENAME} POST_BUILD - COMMAND ${CMAKE_COMMAND} -DINFILE=${EXENAME}${GMX_BINARY_SUFFIX}.nroff - -DOUTFILE=${MAN1_PATH}/${EXENAME}.1 -DDESC=" - ${DESC}" - -DEXENAME="${CMAKE_BINARY_DIR}/bin/${EXENAME}${GMX_BINARY_SUFFIX}" - -P ${CMAKE_SOURCE_DIR}/cmake/CreateManPage.cmake) - install(FILES ${MAN1_PATH}/${EXENAME}.1 DESTINATION - ${MAN_INSTALL_DIR}/man1 OPTIONAL) - elseif(NOT EXISTS "${CMAKE_SOURCE_DIR}/admin/.isreposource") - install(FILES ${CMAKE_SOURCE_DIR}/man/man1/${EXENAME}.1 DESTINATION - ${MAN_INSTALL_DIR}/man1) - endif() -endfunction () diff --git a/cmake/CreateManPage.cmake b/cmake/CreateManPage.cmake deleted file mode 100644 index f27b23ba36..0000000000 --- a/cmake/CreateManPage.cmake +++ /dev/null @@ -1,7 +0,0 @@ -#Create a single man page. Used by CreateManPage.cmake -execute_process(COMMAND ${EXENAME} -quiet -man nroff - RESULT_VARIABLE SUCCESS OUTPUT_QUIET ERROR_QUIET) -if(SUCCESS EQUAL 0) - configure_file(${INFILE} ${OUTFILE}) - file(REMOVE ${INFILE}) -endif() diff --git a/share/CMakeLists.txt b/share/CMakeLists.txt index 251744f74b..f4c7842c86 100644 --- a/share/CMakeLists.txt +++ b/share/CMakeLists.txt @@ -1,10 +1,44 @@ +# +# This file is part of the GROMACS molecular simulation package. +# +# Copyright (c) 2009,2010,2011,2012,2013, by the GROMACS development team, led by +# David van der Spoel, Berk Hess, Erik Lindahl, and including many +# others, as listed in the AUTHORS file in the top-level source +# directory and at http://www.gromacs.org. +# +# GROMACS is free software; you can redistribute it and/or +# modify it under the terms of the GNU Lesser General Public License +# as published by the Free Software Foundation; either version 2.1 +# of the License, or (at your option) any later version. +# +# GROMACS is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +# Lesser General Public License for more details. +# +# You should have received a copy of the GNU Lesser General Public +# License along with GROMACS; if not, see +# http://www.gnu.org/licenses, or write to the Free Software Foundation, +# Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. +# +# If you want to redistribute modifications to GROMACS, please +# consider that scientific software is very special. Version +# control is crucial - bugs must be traceable. We will be happy to +# consider code for inclusion in the official distribution, but +# derived work must not be called official GROMACS. Details are found +# in the README & COPYING files - if they are missing, get the +# official version at http://www.gromacs.org. +# +# To help us fund GROMACS development, we humbly ask that you cite +# the research papers on the package. Check out http://www.gromacs.org. + +add_subdirectory(man) add_subdirectory(template) -install(DIRECTORY . DESTINATION ${DATA_INSTALL_DIR} - COMPONENT data - PATTERN "Makefile*" EXCLUDE - PATTERN "CMake*" EXCLUDE - PATTERN "cmake*" EXCLUDE - PATTERN "*~" EXCLUDE - PATTERN "template" EXCLUDE -) +install(FILES README.tutor README_FreeEnergyModifications.txt + DESTINATION ${DATA_INSTALL_DIR} + COMPONENT data) +install(DIRECTORY top + DESTINATION ${DATA_INSTALL_DIR}/top + COMPONENT data + PATTERN "*~" EXCLUDE) diff --git a/share/man/.gitignore b/share/man/.gitignore new file mode 100644 index 0000000000..a0e7b5c1cb --- /dev/null +++ b/share/man/.gitignore @@ -0,0 +1,2 @@ +man1 +man7/gromacs.7 diff --git a/share/man/CMakeLists.txt b/share/man/CMakeLists.txt new file mode 100644 index 0000000000..d6c2f133eb --- /dev/null +++ b/share/man/CMakeLists.txt @@ -0,0 +1,102 @@ +# +# This file is part of the GROMACS molecular simulation package. +# +# Copyright (c) 2012,2013, by the GROMACS development team, led by +# David van der Spoel, Berk Hess, Erik Lindahl, and including many +# others, as listed in the AUTHORS file in the top-level source +# directory and at http://www.gromacs.org. +# +# GROMACS is free software; you can redistribute it and/or +# modify it under the terms of the GNU Lesser General Public License +# as published by the Free Software Foundation; either version 2.1 +# of the License, or (at your option) any later version. +# +# GROMACS is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +# Lesser General Public License for more details. +# +# You should have received a copy of the GNU Lesser General Public +# License along with GROMACS; if not, see +# http://www.gnu.org/licenses, or write to the Free Software Foundation, +# Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. +# +# If you want to redistribute modifications to GROMACS, please +# consider that scientific software is very special. Version +# control is crucial - bugs must be traceable. We will be happy to +# consider code for inclusion in the official distribution, but +# derived work must not be called official GROMACS. Details are found +# in the README & COPYING files - if they are missing, get the +# official version at http://www.gromacs.org. +# +# To help us fund GROMACS development, we humbly ask that you cite +# the research papers on the package. Check out http://www.gromacs.org. + +if(NOT SOURCE_IS_SOURCE_DISTRIBUTION) + if(NOT CMAKE_CROSSCOMPILING) + # Defaults to off to avoid breaking the build. + # Can be changed if someone finds a nice solution for cases where the + # binary does not execute on the compilation host. + option(GMX_BUILD_MANPAGES "Build man pages" OFF) + mark_as_advanced(GMX_BUILD_MANPAGES) + else() + message(STATUS "Building the man pages is not available when " + "cross-compiling the developer version from git") + endif() +else() + # Make sure source package contains all man pages. + if(NOT EXISTS "${CMAKE_CURRENT_SOURCE_DIR}/man1/gmx-view.1") + message(FATAL_ERROR "Man pages are missing from source package.") + endif() +endif() + +if(GMX_BUILD_MANPAGES) + # create gromacs.7 + FILE(READ "${CMAKE_SOURCE_DIR}/admin/programs.txt" contents) + + # Convert file contents into a CMake list. First escape ; + STRING(REGEX REPLACE ";" "\\\\;" contents "${contents}") + STRING(REGEX REPLACE "\n" ";" contents "${contents}") + + set(PROGMANPAGES "") + foreach(line ${contents}) + if (${line} MATCHES "^HEAD\\|") + string(REGEX REPLACE "^HEAD\\|" "" DESC ${line}) + set(PROGMANPAGES "${PROGMANPAGES}.Sh \"${DESC}\"\n.IX Subsection \"${DESC}\"\n.Vb\n.ta 16n\n") + elseif(${line} MATCHES "^END$") + set(PROGMANPAGES "${PROGMANPAGES}.Ve\n") + elseif(${line} MATCHES "\\|") + string(REGEX REPLACE "\\|" "\t" line ${line}) + set(PROGMANPAGES "${PROGMANPAGES}\\& ${line}\n") + else() + message(WARNING "Incorrectly formated line \"${line}\" in programs.txt") + endif() + endforeach() + configure_file(man7/gromacs.7.cmakein man7/gromacs.7) + install(FILES ${CMAKE_CURRENT_BINARY_DIR}/man7/gromacs.7 + DESTINATION ${MAN_INSTALL_DIR}/man7 + COMPONENT man) + + file(MAKE_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR}/man1) + # TODO: It could be nicer to not do this as part of the ALL target, + # but instead on demand as part of make install. + add_custom_target(man ALL + gmx -quiet help -export man + WORKING_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR} + COMMENT "Generating man pages for programs" + VERBATIM) + install(DIRECTORY ${CMAKE_CURRENT_BINARY_DIR}/man1 + DESTINATION ${MAN_INSTALL_DIR} + COMPONENT man) + set_directory_properties(PROPERTIES + ADDITIONAL_MAKE_CLEAN_FILES man1) + +# man pages are only available if they are either build or this is a source archive +elseif(SOURCE_IS_SOURCE_DISTRIBUTION) + install(FILES ${CMAKE_CURRENT_SOURCE_DIR}/man7/gromacs.7 + DESTINATION ${MAN_INSTALL_DIR}/man7 + COMPONENT man) + install(DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR}/man1 + DESTINATION ${MAN_INSTALL_DIR} + COMPONENT man) +endif() diff --git a/man/man7/gromacs.7.cmakein b/share/man/man7/gromacs.7.cmakein similarity index 98% rename from man/man7/gromacs.7.cmakein rename to share/man/man7/gromacs.7.cmakein index aa17f1f4f9..829867a4c6 100644 --- a/man/man7/gromacs.7.cmakein +++ b/share/man/man7/gromacs.7.cmakein @@ -130,7 +130,7 @@ .\" ======================================================================== .\" .IX Title "GROMACS 7" -.TH GROMACS 7 "${TODAYS_DATE}" "gromacs" "GROMACS suite, Version ${PROJECT_VERSION}" +.TH GROMACS 7 "" "${PROJECT_VERSION}" "GROMACS Manual" .SH "NAME" gromacs \- molecular dynamics simulation suite .SH "DESCRIPTION" diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index 6a551a16af..3a5f13644a 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -1,9 +1,6 @@ configure_file(config.h.cmakein config.h) configure_file(buildinfo.h.cmakein buildinfo.h) -if (NOT GMX_BUILD_MDRUN_ONLY) - include(../cmake/BuildManPages.cmake) -endif() if (BUILD_TESTING) add_custom_target(tests) if (GMX_BUILD_UNITTESTS) diff --git a/src/gromacs/commandline/cmdlinemodulemanager.cpp b/src/gromacs/commandline/cmdlinemodulemanager.cpp index dc3f8eb52b..2fbed0342e 100644 --- a/src/gromacs/commandline/cmdlinemodulemanager.cpp +++ b/src/gromacs/commandline/cmdlinemodulemanager.cpp @@ -43,6 +43,7 @@ #include +#include #include #include #include @@ -253,6 +254,51 @@ class HelpExportInterface const CommandLineModuleInterface &module) = 0; }; +/******************************************************************** + * HelpExportMan + */ + +/*! \internal \brief + * Implements export for man pages. + * + * \ingroup module_commandline + */ +class HelpExportMan : public HelpExportInterface +{ + public: + virtual void exportModuleHelp(const std::string &tag, + const CommandLineModuleInterface &module); +}; + +void HelpExportMan::exportModuleHelp(const std::string &tag, + const CommandLineModuleInterface &module) +{ + File file("man1/" + tag + ".1", "w"); + + // TODO: It would be nice to remove the VERSION prefix from the version + // string to make it shorter. + file.writeLine(formatString(".TH %s 1 \"\" \"%s\" \"GROMACS Manual\"\n", + tag.c_str(), + GromacsVersion())); + file.writeLine(".SH NAME"); + file.writeLine(formatString("%s - %s", tag.c_str(), + module.shortDescription())); + file.writeLine(); + + CommandLineHelpContext context(&file, eHelpOutputFormat_Man); + std::string displayName(tag); + std::replace(displayName.begin(), displayName.end(), '-', ' '); + context.setModuleDisplayName(displayName); + module.writeHelp(context); + + file.writeLine(".SH SEE ALSO"); + file.writeLine(".BR gromacs(7)"); + file.writeLine(); + file.writeLine("More information about \\fBGROMACS\\fR is available at <\\fIhttp://www.gromacs.org/\\fR>."); + + file.close(); +} + } // namespace /******************************************************************** @@ -349,6 +395,11 @@ int CommandLineHelpModule::run(int argc, char *argv[]) if (!exportFormat.empty()) { boost::scoped_ptr exporter; + if (exportFormat == "man") + { + exporter.reset(new HelpExportMan); + } + else { GMX_THROW(NotImplementedError("This help format is not implemented")); } @@ -483,6 +534,9 @@ class CMainCommandLineModule : public CommandLineModuleInterface case eHelpOutputFormat_Console: type = "help"; break; + case eHelpOutputFormat_Man: + type = "nroff"; + break; default: GMX_THROW(NotImplementedError( "Command-line help is not implemented for this output format")); diff --git a/src/gromacs/onlinehelp/helpwritercontext.h b/src/gromacs/onlinehelp/helpwritercontext.h index 6edae6658e..397e78f5ac 100644 --- a/src/gromacs/onlinehelp/helpwritercontext.h +++ b/src/gromacs/onlinehelp/helpwritercontext.h @@ -57,6 +57,7 @@ class File; enum HelpOutputFormat { eHelpOutputFormat_Console, //!< Plain text directly on the console. + eHelpOutputFormat_Man, //!< Man page. eHelpOutputFormat_NR //!< Used for the number of output formats. }; //! \endcond diff --git a/src/gromacs/onlinehelp/wman.cpp b/src/gromacs/onlinehelp/wman.cpp index 4e9e2e848d..af7ec6e08f 100644 --- a/src/gromacs/onlinehelp/wman.cpp +++ b/src/gromacs/onlinehelp/wman.cpp @@ -575,12 +575,6 @@ static void write_nroffman(FILE *out, int i; char tmp[256]; - - fprintf(out, ".TH %s 1 \"%s\" \"\" \"GROMACS suite, %s\"\n", program, mydate(tmp, 255), GromacsVersion()); - fprintf(out, ".SH NAME\n"); - fprintf(out, "%s@DESC@\n\n", program); - fprintf(out, ".B %s\n", GromacsVersion()); - fprintf(out, ".SH SYNOPSIS\n"); fprintf(out, "\\f3%s\\fP\n", program); @@ -665,10 +659,6 @@ static void write_nroffman(FILE *out, fprintf(out, "\\- %s\n\n", check_nroff(bugs[i])); } } - - fprintf(out, ".SH SEE ALSO\n.BR gromacs(7)\n\n"); - fprintf(out, "More information about \\fBGROMACS\\fR is available at <\\fIhttp://www.gromacs.org/\\fR>.\n"); - } char *check_tty(const char *s) @@ -1038,7 +1028,8 @@ void write_man(const char *mantp, } if (strcmp(mantp, "nroff") == 0) { - write_nroffman(out, program, nldesc, desc, nfile, fnm, npar, par, nbug, bugs, links); + write_nroffman(out, context->moduleDisplayName(), nldesc, desc, + nfile, fnm, npar, par, nbug, bugs, links); } if (strcmp(mantp, "help") == 0) { -- 2.22.0