@@ -32,6 +32,7 @@ addons:
- libudev-dev
- make
- ninja-build
+ - pandoc
- pkg-config
- python
- valgrind
@@ -135,6 +135,7 @@ include(RDMA_BuildType)
include(RDMA_DoFixup)
include(publish_headers)
include(rdma_functions)
+include(rdma_man)
if (NOT DEFINED ENABLE_STATIC)
set(ENABLE_STATIC "OFF" CACHE BOOL "Produce static linking libraries as well as shared libraries.")
@@ -280,7 +281,10 @@ else()
endif()
# Look for Python
-FIND_PACKAGE (PythonInterp)
+FIND_PACKAGE(PythonInterp REQUIRED)
+
+# Look for pandoc
+FIND_PACKAGE(pandoc)
#-------------------------
# Find libraries
@@ -500,6 +504,13 @@ else()
message(STATUS " netlink/route/link.h and net/if.h NOT co-includable (old headers)")
endif()
endif()
+if (NOT PANDOC_FOUND)
+ if (NOT EXISTS "${CMAKE_SOURCE_DIR}/buildlib/pandoc-prebuilt")
+ message(STATUS " pandoc NOT found and NO prebuilt man pages. 'install' disabled")
+ else()
+ message(STATUS " pandoc NOT found (using prebuilt man pages)")
+ endif()
+endif()
if (NOT SYSTEMD_FOUND)
message(STATUS " libsystemd NOT found (disabling features)")
endif()
@@ -82,7 +82,7 @@ best experience.
```sh
$ yum install epel-release
-$ yum install cmake3 unzip ninja-build
+$ yum install cmake3 ninja-build pandoc
```
NOTE: EPEL uses the name 'ninja-build' for the 'ninja' command, and 'cmake3'
new file mode 100644
@@ -0,0 +1,21 @@
+# COPYRIGHT (c) 2017 Mellanox Technologies Ltd
+# Licensed under BSD (MIT variant) or GPLv2. See COPYING.
+find_program(PANDOC_EXECUTABLE NAMES pandoc)
+
+if(PANDOC_EXECUTABLE)
+ execute_process(COMMAND "${PANDOC_EXECUTABLE}" -v
+ OUTPUT_VARIABLE _VERSION
+ RESULT_VARIABLE _VERSION_RESULT
+ ERROR_QUIET)
+
+ if(NOT _VERSION_RESULT)
+ string(REGEX REPLACE "^pandoc ([^\n]+)\n.*" "\\1" PANDOC_VERSION_STRING "${_VERSION}")
+ endif()
+ unset(_VERSION_RESULT)
+ unset(_VERSION)
+endif()
+
+include(FindPackageHandleStandardArgs)
+find_package_handle_standard_args(pandoc REQUIRED_VARS PANDOC_EXECUTABLE PANDOC_VERSION_STRING VERSION_VAR PANDOC_VERSION_STRING)
+
+mark_as_advanced(PANDOC_EXECUTABLE)
@@ -73,6 +73,7 @@ class DockerFile(object):
self.lines = ["FROM %s"%(src)];
class Environment(object):
+ pandoc = True;
python_cmd = "python";
aliases = set();
use_make = False;
@@ -106,18 +107,21 @@ class centos6(YumEnvironment):
};
name = "centos6";
use_make = True;
+ pandoc = False;
class centos7(YumEnvironment):
docker_parent = "centos:7";
pkgs = centos6.pkgs | {'systemd-devel'};
name = "centos7";
use_make = True;
+ pandoc = False;
specfile = "redhat/rdma-core.spec";
class centos7_epel(centos7):
- pkgs = (centos7.pkgs - {"cmake","make"}) | {"ninja-build","cmake3"};
+ pkgs = (centos7.pkgs - {"cmake","make"}) | {"ninja-build","cmake3","pandoc"};
name = "centos7_epel";
use_make = False;
+ pandoc = True;
ninja_cmd = "ninja-build";
# Our spec file does not know how to cope with cmake3
is_rpm = False;
@@ -130,7 +134,7 @@ class centos7_epel(centos7):
class fc27(Environment):
docker_parent = "fedora:27";
- pkgs = (centos7.pkgs - {"make"}) | {"ninja-build"};
+ pkgs = (centos7.pkgs - {"make"}) | {"ninja-build","pandoc"};
name = "fc27";
specfile = "redhat/rdma-core.spec";
ninja_cmd = "ninja-build";
@@ -165,6 +169,7 @@ class trusty(APTEnvironment):
'libudev-dev',
'make',
'ninja-build',
+ 'pandoc',
'pkg-config',
'python',
'valgrind',
@@ -300,6 +305,7 @@ class ZypperEnvironment(Environment):
return res;
class leap(ZypperEnvironment):
+ proxy = False;
docker_parent = "opensuse:42.3";
specfile = "suse/rdma-core.spec";
pkgs = {
@@ -310,6 +316,7 @@ class leap(ZypperEnvironment):
'udev',
'make',
'ninja',
+ 'pandoc',
'pkg-config',
'python3',
'rpm-build',
@@ -432,6 +439,35 @@ def get_image_id(args,image_name):
# -------------------------------------------------------------------------
+def get_tar_file(tarfn,pandoc_prebuilt=False):
+ """Create a tar file that matches what buildlib/github-release would do if it
+ was a tagged release"""
+ prefix = "%s-%s/"%(project,get_version());
+ if not pandoc_prebuilt:
+ subprocess.check_call(["git","archive",
+ # This must match the prefix generated buildlib/github-release
+ "--prefix",prefix,
+ "--output",tarfn,
+ "HEAD"]);
+ return;
+
+ # When the OS does not support pandoc we got through the extra step to
+ # build pandoc output in the travis container and include it in the
+ # tar. This is similar to what buildlib/github-release does.
+ subprocess.check_call(["buildlib/cbuild","make","travis","docs"]);
+
+ tmp_tarfn = os.path.join(os.path.dirname(tarfn),"tmp.tar");
+ get_tar_file(tmp_tarfn,False);
+
+ subprocess.check_call([
+ "tar",
+ "-rf",tmp_tarfn,
+ "build-travis/pandoc-prebuilt/",
+ "--xform","s|build-travis/pandoc-prebuilt|%sbuildlib/pandoc-prebuilt|g"%(prefix)]);
+ with open(tarfn,"w") as F:
+ subprocess.check_call(["gzip","-9c",tmp_tarfn],stdout=F);
+ os.unlink(tmp_tarfn);
+
def run_rpm_build(args,spec_file,env):
with open(spec_file,"r") as F:
for ln in F:
@@ -447,11 +483,7 @@ def run_rpm_build(args,spec_file,env):
os.mkdir(os.path.join(tmpdir,"SOURCES"));
os.mkdir(os.path.join(tmpdir,"tmp"));
- subprocess.check_call(["git","archive",
- # This must match the prefix generated buildlib/github-release
- "--prefix","%s-%s/"%(project,get_version()),
- "--output",os.path.join(tmpdir,"SOURCES",tarfn),
- "HEAD"]);
+ get_tar_file(os.path.join(tmpdir,"SOURCES",tarfn),pandoc_prebuilt=not env.pandoc);
with open(spec_file,"r") as inF:
spec = list(inF);
@@ -6,5 +6,7 @@ if [[ $TRAVIS_TAG == v* ]] && [ "$TRAVIS_OS_NAME" = "linux" ]; then
# Let's create release for vX tags only.
# Strip the v from the TRAVIS_TAG for our prefix and output items
REL_TAG=`echo $TRAVIS_TAG | sed -e 's/^v//'`
- git archive --prefix rdma-core-$REL_TAG/ --output rdma-core-$REL_TAG.tar.gz $TRAVIS_TAG
+ git archive --prefix rdma-core-$REL_TAG/ --output rdma-core-$REL_TAG.tar $TRAVIS_TAG
+ tar -rf rdma-core-$REL_TAG.tar build-clang/pandoc-prebuilt/ --xform "s|build-clang/pandoc-prebuilt|rdma-core-$REL_TAG/buildlib/pandoc-prebuilt|g"
+ gzip -9 rdma-core-$REL_TAG.tar
fi
new file mode 100644
@@ -0,0 +1,37 @@
+#!/usr/bin/env python
+import os
+import shutil
+import subprocess
+import sys
+import hashlib
+
+def get_id(SRC):
+ """Return a unique ID for the SRC file. For simplicity and robustness we just
+ content hash it"""
+ with open(SRC,"rb") as F:
+ return hashlib.sha1(F.read()).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):
+ """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([pandoc,"-s","-t","man",SRC,"-o",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]);
+else:
+ raise ValueError("Must provide --build or --retrieve");
@@ -10,6 +10,16 @@ set(RDMA_STATIC_LIBS "" CACHE INTERNAL "Doc" FORCE)
set(COMMON_LIBS_PIC ccan_pic rdma_util_pic)
set(COMMON_LIBS ccan rdma_util)
+function(rdma_make_dir DDIR)
+ if(NOT EXISTS "${DDIR}/")
+ execute_process(COMMAND "${CMAKE_COMMAND}" "-E" "make_directory"
+ "${DDIR}" RESULT_VARIABLE retcode)
+ if(NOT "${retcode}" STREQUAL "0")
+ message(FATAL_ERROR "Failed to create directory ${DDIR}")
+ endif()
+ endif()
+endfunction()
+
# Create a symlink at filename DEST
# If the directory containing DEST does not exist then it is created
# automatically.
@@ -26,13 +36,7 @@ function(rdma_create_symlink LINK_CONTENT DEST)
get_filename_component(DDIR "${DEST}" DIRECTORY)
endif()
- IF(NOT EXISTS "${DDIR}/")
- execute_process(COMMAND "${CMAKE_COMMAND}" "-E" "make_directory"
- "${BUILD_LIB}" RESULT_VARIABLE retcode)
- if(NOT "${retcode}" STREQUAL "0")
- message(FATAL_ERROR "Failed to create directory ${DDIR}")
- endif()
- endif()
+ rdma_make_dir("${DDIR}")
# Newer versions of cmake can use "${CMAKE_COMMAND}" "-E" "create_symlink"
# however it is broken weirdly on older versions.
@@ -229,39 +233,6 @@ function(rdma_test_executable EXEC)
set_target_properties(${EXEC} PROPERTIES RUNTIME_OUTPUT_DIRECTORY "${BUILD_BIN}")
endfunction()
-# Install man pages. This deduces the section from the trailing integer in the
-# filename
-function(rdma_man_pages)
- foreach(I ${ARGN})
- if ("${I}" MATCHES "\\.in$")
- string(REGEX REPLACE "^.+[.](.+)\\.in$" "\\1" MAN_SECT "${I}")
- string(REGEX REPLACE "^(.+)\\.in$" "\\1" BASE_NAME "${I}")
- get_filename_component(BASE_NAME "${BASE_NAME}" NAME)
- rdma_subst_install(FILES "${I}"
- DESTINATION "${CMAKE_INSTALL_MANDIR}/man${MAN_SECT}/"
- RENAME "${BASE_NAME}")
- else()
- string(REGEX REPLACE "^.+[.](.+)$" "\\1" MAN_SECT "${I}")
- install(FILES "${I}" DESTINATION "${CMAKE_INSTALL_MANDIR}/man${MAN_SECT}/")
- endif()
- endforeach()
-endfunction()
-
-# Create an alias for a man page, using a symlink.
-# Input is a list of pairs of names (MAN_PAGE ALIAS)
-# NOTE: The section must currently be the same for both.
-function(rdma_alias_man_pages)
- list(LENGTH ARGN LEN)
- math(EXPR LEN ${LEN}-1)
- foreach(I RANGE 0 ${LEN} 2)
- list(GET ARGN ${I} FROM)
- math(EXPR I ${I}+1)
- list(GET ARGN ${I} TO)
- string(REGEX REPLACE "^.+[.](.+)$" "\\1" MAN_SECT ${FROM})
- rdma_install_symlink("${FROM}" "${CMAKE_INSTALL_MANDIR}/man${MAN_SECT}/${TO}")
- endforeach()
-endfunction()
-
# Finalize the setup of the static libraries by copying the meta information
# from the shared and setting up the libtool .la files.
function(rdma_finalize_libs)
new file mode 100644
@@ -0,0 +1,80 @@
+# COPYRIGHT (c) 2017-2018 Mellanox Technologies Ltd
+# Licensed under BSD (MIT variant) or GPLv2. See COPYING.
+
+rdma_make_dir("${CMAKE_BINARY_DIR}/pandoc-prebuilt")
+add_custom_target("docs" ALL DEPENDS "${OBJ}")
+
+function(rdma_md_man_page SRC MAN_SECT MANFN)
+ set(OBJ "${CMAKE_CURRENT_BINARY_DIR}/${MANFN}")
+
+ if (PANDOC_EXECUTABLE)
+ add_custom_command(
+ OUTPUT "${OBJ}"
+ COMMAND "${PYTHON_EXECUTABLE}" "${CMAKE_SOURCE_DIR}/buildlib/pandoc-prebuilt.py" --build "${CMAKE_BINARY_DIR}" --pandoc "${PANDOC_EXECUTABLE}" "${SRC}" "${OBJ}"
+ MAIN_DEPENDENCY "${SRC}"
+ WORKING_DIRECTORY "${CMAKE_CURRENT_SOURCE_DIR}"
+ COMMENT "Creating man page ${MANFN}"
+ VERBATIM)
+ 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}"
+ 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()
+ endif()
+
+ install(FILES "${OBJ}"
+ RENAME "${MANFN}"
+ DESTINATION "${CMAKE_INSTALL_MANDIR}/man${MAN_SECT}/")
+endfunction()
+
+# Install man pages. This deduces the section from the trailing integer in the
+# filename
+function(rdma_man_pages)
+ foreach(I ${ARGN})
+ if ("${I}" MATCHES "\\.md$")
+ string(REGEX REPLACE "^.+[.](.+)\\.md$" "\\1" MAN_SECT "${I}")
+ string(REGEX REPLACE "^(.+)\\.md$" "\\1" BASE_NAME "${I}")
+ get_filename_component(BASE_NAME "${BASE_NAME}" NAME)
+
+ rdma_md_man_page(
+ "${I}"
+ "${MAN_SECT}"
+ "${BASE_NAME}")
+ elseif ("${I}" MATCHES "\\.in$")
+ string(REGEX REPLACE "^.+[.](.+)\\.in$" "\\1" MAN_SECT "${I}")
+ string(REGEX REPLACE "^(.+)\\.in$" "\\1" BASE_NAME "${I}")
+ get_filename_component(BASE_NAME "${BASE_NAME}" NAME)
+ rdma_subst_install(FILES "${I}"
+ DESTINATION "${CMAKE_INSTALL_MANDIR}/man${MAN_SECT}/"
+ RENAME "${BASE_NAME}")
+ else()
+ string(REGEX REPLACE "^.+[.](.+)$" "\\1" MAN_SECT "${I}")
+ install(FILES "${I}" DESTINATION "${CMAKE_INSTALL_MANDIR}/man${MAN_SECT}/")
+ endif()
+ endforeach()
+endfunction()
+
+# Create an alias for a man page, using a symlink.
+# Input is a list of pairs of names (MAN_PAGE ALIAS)
+# NOTE: The section must currently be the same for both.
+function(rdma_alias_man_pages)
+ list(LENGTH ARGN LEN)
+ math(EXPR LEN ${LEN}-1)
+ foreach(I RANGE 0 ${LEN} 2)
+ list(GET ARGN ${I} FROM)
+ math(EXPR I ${I}+1)
+ list(GET ARGN ${I} TO)
+ string(REGEX REPLACE "^.+[.](.+)$" "\\1" MAN_SECT ${FROM})
+ rdma_install_symlink("${FROM}" "${CMAKE_INSTALL_MANDIR}/man${MAN_SECT}/${TO}")
+ endforeach()
+endfunction()
@@ -13,6 +13,7 @@ Build-Depends: cmake (>= 2.8.11),
libsystemd-dev,
libudev-dev,
ninja-build,
+ pandoc,
pkg-config,
python,
valgrind [!alpha !armel !hppa !ia64 !m68k !powerpcspe !sh4 !sparc64 !x32]
@@ -45,6 +45,11 @@ BuildRequires: make
%define cmake_install DESTDIR=%{buildroot} make install
%endif
+%if 0%{?fedora} >= 25
+# pandoc was introduced in FC25
+BuildRequires: pandoc
+%endif
+
%description
RDMA core userspace infrastructure and documentation, including initialization
scripts, kernel driver-specific modprobe override configs, IPoIB network
@@ -51,6 +51,7 @@ Source1: baselibs.conf
BuildRequires: binutils
BuildRequires: cmake >= 2.8.11
BuildRequires: gcc
+BuildRequires: pandoc
BuildRequires: pkgconfig
BuildRequires: pkgconfig(libsystemd)
BuildRequires: pkgconfig(libudev)