Skip to content

Commit

Permalink
build: Support rst as a man page option
Browse files Browse the repository at this point in the history
infiniband-diags uses rst as a man page preprocessor, so add it along side
pandoc in the build system.

Signed-off-by: Jason Gunthorpe <jgg@mellanox.com>
  • Loading branch information
jgunthorpe committed May 15, 2019
1 parent 87ec0dd commit 3f69f34
Show file tree
Hide file tree
Showing 9 changed files with 123 additions and 17 deletions.
1 change: 1 addition & 0 deletions .travis.yml
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@ addons:
- make
- ninja-build
- pandoc
- python-docutils
- pkg-config
- python
- valgrind
Expand Down
10 changes: 9 additions & 1 deletion CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -406,8 +406,9 @@ if (CYTHON_EXECUTABLE)
string(STRIP ${py_path} CMAKE_PYTHON_SO_SUFFIX)
endif()

# Look for pandoc
# Look for pandoc and rst2man for making manual pages
FIND_PACKAGE(pandoc)
FIND_PACKAGE(rst2man)

#-------------------------
# Find libraries
Expand Down Expand Up @@ -668,6 +669,13 @@ if (NOT PANDOC_FOUND)
message(STATUS " pandoc NOT found (using prebuilt man pages)")
endif()
endif()
if (NOT RST2MAN_FOUND)
if (NOT EXISTS "${CMAKE_SOURCE_DIR}/buildlib/pandoc-prebuilt")
message(STATUS " rst2man NOT found and NO prebuilt man pages. 'install' disabled")
else()
message(STATUS " rst2man NOT found (using prebuilt man pages)")
endif()
endif()
if (NOT CYTHON_EXECUTABLE)
message(STATUS " cython NOT found (disabling pyverbs)")
endif()
Expand Down
21 changes: 21 additions & 0 deletions buildlib/Findrst2man.cmake
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
# COPYRIGHT (c) 2019 Mellanox Technologies Ltd
# Licensed under BSD (MIT variant) or GPLv2. See COPYING.
find_program(RST2MAN_EXECUTABLE NAMES rst2man)

if(RST2MAN_EXECUTABLE)
execute_process(COMMAND "${RST2MAN_EXECUTABLE}" --version
OUTPUT_VARIABLE _VERSION
RESULT_VARIABLE _VERSION_RESULT
ERROR_QUIET)

if(NOT _VERSION_RESULT)
string(REGEX REPLACE "^rst2man \\(Docutils ([^,]+), .*" "\\1" RST2MAN_VERSION_STRING "${_VERSION}")
endif()
unset(_VERSION_RESULT)
unset(_VERSION)
endif()

include(FindPackageHandleStandardArgs)
find_package_handle_standard_args(rst2man REQUIRED_VARS RST2MAN_EXECUTABLE RST2MAN_VERSION_STRING VERSION_VAR RST2MAN_VERSION_STRING)

mark_as_advanced(RST2MAN_EXECUTABLE)
12 changes: 11 additions & 1 deletion buildlib/cbuild
Original file line number Diff line number Diff line change
Expand Up @@ -104,6 +104,7 @@ class centos6(YumEnvironment):
'pkgconfig',
'python',
'python-argparse',
'python-docutils',
'rpm-build',
'valgrind-devel',
};
Expand Down Expand Up @@ -149,7 +150,14 @@ class centos7_epel(centos7):

class fc30(Environment):
docker_parent = "fedora:30";
pkgs = (centos7.pkgs - {"make", "python-argparse" }) | {"ninja-build","pandoc","perl-generators","python3-Cython","python3-devel"};
pkgs = (centos7.pkgs - {"make", "python-argparse" }) | {
"ninja-build",
"pandoc",
"perl-generators",
"python3-docutils",
"python3-Cython",
"python3-devel",
};
name = "fc30";
specfile = "redhat/rdma-core.spec";
ninja_cmd = "ninja-build";
Expand Down Expand Up @@ -190,6 +198,7 @@ class xenial(APTEnvironment):
'pandoc',
'pkg-config',
'python3',
"python3-docutils",
'valgrind',
};
name = "ubuntu-16.04";
Expand Down Expand Up @@ -354,6 +363,7 @@ class leap(ZypperEnvironment):
'valgrind-devel',
'python3-Cython',
'python3-devel',
'python3-docutils',
};
rpmbuild_options = [ "--without=curlmini" ];
name = "opensuse-15.0";
Expand Down
33 changes: 29 additions & 4 deletions buildlib/pandoc-prebuilt.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,19 +4,31 @@
import subprocess
import sys
import hashlib
import re

def hash_rst_includes(incdir,txt):
h = ""
for fn in re.findall(br"^..\s+include::\s+(.*)$", txt, flags=re.MULTILINE):
with open(os.path.join(incdir,fn.decode()),"rb") as F:
h = h + hashlib.sha1(F.read()).hexdigest();
return h.encode();

def get_id(SRC):
"""Return a unique ID for the SRC file. For simplicity and robustness we just
content hash it"""
incdir = os.path.dirname(SRC)
with open(SRC,"rb") as F:
return hashlib.sha1(F.read()).hexdigest();
txt = F.read();
if SRC.endswith(".rst"):
txt = txt + hash_rst_includes(incdir,txt);
return hashlib.sha1(txt).hexdigest();

def do_retrieve(src_root,SRC):
"""Retrieve the file from the prebuild cache and write it to DEST"""
prebuilt = os.path.join(src_root,"buildlib","pandoc-prebuilt",get_id(SRC))
sys.stdout.write(prebuilt);

def do_build(build_root,pandoc,SRC,DEST):
def do_build_pandoc(build_root,pandoc,SRC,DEST):
"""Build the markdown into a man page with pandoc and then keep a copy of the
output under build/pandoc-prebuilt"""
try:
Expand All @@ -25,13 +37,26 @@ def do_build(build_root,pandoc,SRC,DEST):
sys.exit(100);
shutil.copy(DEST,os.path.join(build_root,"pandoc-prebuilt",get_id(SRC)));

def do_build_rst2man(build_root,rst2man,SRC,DEST):
"""Build the markdown into a man page with pandoc and then keep a copy of the
output under build/pandoc-prebuilt"""
try:
subprocess.check_call([rst2man,SRC,DEST]);
except subprocess.CalledProcessError:
sys.exit(100);
shutil.copy(DEST,os.path.join(build_root,"pandoc-prebuilt",get_id(SRC)));

# We support python 2.6 so argparse is not available.
if len(sys.argv) == 4:
assert(sys.argv[1] == "--retrieve");
do_retrieve(sys.argv[2],sys.argv[3]);
elif len(sys.argv) == 7:
assert(sys.argv[1] == "--build");
assert(sys.argv[3] == "--pandoc");
do_build(sys.argv[2],sys.argv[4],sys.argv[5],sys.argv[6]);
if sys.argv[3] == "--pandoc":
do_build_pandoc(sys.argv[2],sys.argv[4],sys.argv[5],sys.argv[6]);
elif sys.argv[3] == "--rst":
do_build_rst2man(sys.argv[2],sys.argv[4],sys.argv[5],sys.argv[6]);
else:
raise ValueError("Bad sys.argv[3]");
else:
raise ValueError("Must provide --build or --retrieve");
60 changes: 49 additions & 11 deletions buildlib/rdma_man.cmake
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,22 @@
rdma_make_dir("${CMAKE_BINARY_DIR}/pandoc-prebuilt")
add_custom_target("docs" ALL DEPENDS "${OBJ}")

function(rdma_man_get_prebuilt SRC OUT)
# If rst2man is not installed then we install the man page from the
# pre-built cache directory under buildlib. When the release tar file is
# made the man pages are pre-built and included. This is done via install
# so that ./build.sh never depends on pandoc, only 'ninja install'.
execute_process(
COMMAND "${PYTHON_EXECUTABLE}" "${CMAKE_SOURCE_DIR}/buildlib/pandoc-prebuilt.py" --retrieve "${CMAKE_SOURCE_DIR}" "${SRC}"
WORKING_DIRECTORY "${CMAKE_CURRENT_SOURCE_DIR}"
OUTPUT_VARIABLE OBJ
RESULT_VARIABLE retcode)
if(NOT "${retcode}" STREQUAL "0")
message(FATAL_ERROR "Failed to load prebuilt pandoc output")
endif()
set(${OUT} "${OBJ}" PARENT_SCOPE)
endfunction()

function(rdma_md_man_page SRC MAN_SECT MANFN)
set(OBJ "${CMAKE_CURRENT_BINARY_DIR}/${MANFN}")

Expand All @@ -18,18 +34,29 @@ function(rdma_md_man_page SRC MAN_SECT MANFN)
add_custom_target("man-${MANFN}" ALL DEPENDS "${OBJ}")
add_dependencies("docs" "man-${MANFN}")
else()
# If pandoc is not installed then we install the man page from the
# pre-built cache directory under buildlib. When the release tar file is
# made the man pages are pre-built and included. This is done via install
# so that ./build.sh never depends on pandoc, only 'ninja install'.
execute_process(
COMMAND "${PYTHON_EXECUTABLE}" "${CMAKE_SOURCE_DIR}/buildlib/pandoc-prebuilt.py" --retrieve "${CMAKE_SOURCE_DIR}" "${SRC}"
rdma_man_get_prebuilt(${SRC} OBJ)
endif()

install(FILES "${OBJ}"
RENAME "${MANFN}"
DESTINATION "${CMAKE_INSTALL_MANDIR}/man${MAN_SECT}/")
endfunction()

function(rdma_rst_man_page SRC MAN_SECT MANFN)
set(OBJ "${CMAKE_CURRENT_BINARY_DIR}/${MANFN}")

if (RST2MAN_EXECUTABLE)
add_custom_command(
OUTPUT "${OBJ}"
COMMAND "${PYTHON_EXECUTABLE}" "${CMAKE_SOURCE_DIR}/buildlib/pandoc-prebuilt.py" --build "${CMAKE_BINARY_DIR}" --rst "${RST2MAN_EXECUTABLE}" "${SRC}" "${OBJ}"
MAIN_DEPENDENCY "${SRC}"
WORKING_DIRECTORY "${CMAKE_CURRENT_SOURCE_DIR}"
OUTPUT_VARIABLE OBJ
RESULT_VARIABLE retcode)
if(NOT "${retcode}" STREQUAL "0")
message(FATAL_ERROR "Failed to load prebuilt pandoc output")
endif()
COMMENT "Creating man page ${MANFN}"
VERBATIM)
add_custom_target("man-${MANFN}" ALL DEPENDS "${OBJ}")
add_dependencies("docs" "man-${MANFN}")
else()
rdma_man_get_prebuilt(${SRC} OBJ)
endif()

install(FILES "${OBJ}"
Expand All @@ -50,6 +77,17 @@ function(rdma_man_pages)
"${I}"
"${MAN_SECT}"
"${BASE_NAME}")
elseif ("${I}" MATCHES "\\.in\\.rst$")
string(REGEX REPLACE "^.+[.](.+)\\.in\\.rst$" "\\1" MAN_SECT "${I}")
string(REGEX REPLACE "^(.+)\\.in\\.rst$" "\\1" BASE_NAME "${I}")
get_filename_component(BASE_NAME "${BASE_NAME}" NAME)

configure_file("${I}" "${CMAKE_CURRENT_BINARY_DIR}/${BASE_NAME}.rst" @ONLY)

rdma_rst_man_page(
"${CMAKE_CURRENT_BINARY_DIR}/${BASE_NAME}.rst"
"${MAN_SECT}"
"${BASE_NAME}")
elseif ("${I}" MATCHES "\\.in$")
string(REGEX REPLACE "^.+[.](.+)\\.in$" "\\1" MAN_SECT "${I}")
string(REGEX REPLACE "^(.+)\\.in$" "\\1" BASE_NAME "${I}")
Expand Down
1 change: 1 addition & 0 deletions debian/control
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@ Build-Depends: cmake (>= 2.8.11),
ninja-build,
pandoc,
pkg-config,
python-docutils,
python3-dev,
valgrind [amd64 arm64 armhf i386 mips mips64el mipsel powerpc ppc64 ppc64el s390x]
Standards-Version: 4.3.0
Expand Down
1 change: 1 addition & 0 deletions redhat/rdma-core.spec
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@ BuildRequires: libudev-devel
BuildRequires: pkgconfig
BuildRequires: pkgconfig(libnl-3.0)
BuildRequires: pkgconfig(libnl-route-3.0)
BuildRequires: python-docutils
BuildRequires: valgrind-devel
BuildRequires: systemd
BuildRequires: systemd-devel
Expand Down
1 change: 1 addition & 0 deletions suse/rdma-core.spec
Original file line number Diff line number Diff line change
Expand Up @@ -62,6 +62,7 @@ BuildRequires: pkgconfig(libsystemd)
BuildRequires: pkgconfig(libudev)
BuildRequires: pkgconfig(systemd)
BuildRequires: pkgconfig(udev)
BuildRequires: python-docutils
%if %{with_pyverbs}
BuildRequires: python3-Cython
BuildRequires: python3-devel
Expand Down

0 comments on commit 3f69f34

Please sign in to comment.