enhance(ci): Add ability to generate RPM package 31/331/7
authorE. Scott Daniels <daniels@research.att.com>
Wed, 12 Jun 2019 17:48:25 +0000 (13:48 -0400)
committerE. Scott Daniels <daniels@research.att.com>
Thu, 13 Jun 2019 18:35:54 +0000 (14:35 -0400)
The CMake configuration was enhanced to add the ability to
generate an RPM package in addition to a Debian package
provided the rpmbuild command is available in the current
environment.   The packages generated are now added to
the /tmp/build_output.yml file as fully qualified paths.

By default, the geneated package is a run-time package which
includes only the rmr libraries (no header files, and no
external libraries used to build RMr).  If the cmake
option -DDEV_PKG=1 is given at configure time, a dev package
will be generated which includes the header files, and
will have -dev added following the version info in the
package name (e.g. rmr-1.0.34.x86_64-dev.deb).

Signed-off-by: E. Scott Daniels <daniels@research.att.com>
Change-Id: Ifb606e1f8b1ad0f08b3c4bd8b4012c0382947e04
Signed-off-by: E. Scott Daniels <daniels@research.att.com>
BUILD
CMakeLists.txt
ci/Dockerfile
src/rmr/common/CMakeLists.txt

diff --git a/BUILD b/BUILD
index adae2f1..3bc677e 100644 (file)
--- a/BUILD
+++ b/BUILD
@@ -1,6 +1,6 @@
 #
 #==================================================================================
-#       Copyright (c) 2019 Nokia 
+#       Copyright (c) 2019 Nokia
 #       Copyright (c) 2018-2019 AT&T Intellectual Property.
 #
 #   Licensed under the Apache License, Version 2.0 (the "License");
@@ -43,10 +43,19 @@ To build RMr, the usual CMake steps are followed:
 This will create a .deb (provided the system supports this) in
 the build directory.  It's that simple.
 
-Continuous integration build 
+Continuous integration build
 Use the Dockerfile in the ci/ subdirectory. This installs all
 the required tools and creates an image in the local registry.
 
+To support the distribution of package(s) created during the
+build by the CI process, the fully qualified path of each generated
+package will be placed into a well known YAML file:
+/tmp/build_output.yml.   This file is created during CMake
+configuration and lists the package name(s) for packages which
+can be generated given the current environment. Currently
+Debian (.deb), and RPM packages are supported (the Ubuntu
+alien package must be installed in order to generate RPMs).
+
 
 Alternatives
 To build in a non-Linux environment, or to build with an
@@ -70,7 +79,7 @@ NOT built as the required tool has yet to be incorporated into
 the build process and generally is not available on most systems.
 
 
-Compiling and Linking
+Compiling and Linking User Applications
 Should the Rmr and NNG/Nano libraries be installed in a directory
 outside of the normal system spots (e.g. not in /usr/local)
 it might be necessary to define the specific directory for
@@ -118,3 +127,5 @@ and will trigger the generation of the man pages in both postscript
 and troff format.  The troff pages are placed into the deb and
 the postscript pages are left in the build directory for the
 developer to convert to PDF, or otherwise use.
+
+
index dff07ad..ff39103 100644 (file)
@@ -1,6 +1,6 @@
 #
 #==================================================================================
-#      Copyright (c) 2019 Nokia 
+#      Copyright (c) 2019 Nokia
 #      Copyright (c) 2018-2019 AT&T Intellectual Property.
 #
 #   Licensed under the Apache License, Version 2.0 (the "License");
@@ -22,7 +22,7 @@ cmake_minimum_required( VERSION 3.5 )
 
 set( major_version "1" )               # should be automatically populated from git tag later, but until CI process sets a tag we use this
 set( minor_version "0" )
-set( patch_level "33" )
+set( patch_level "34" )
 
 set( install_root "${CMAKE_INSTALL_PREFIX}" )
 set( install_lib "lib" )
@@ -47,23 +47,23 @@ endif()
 # ---------------- extract some things from git ------------------------------
 
 # commit id for the version string
-execute_process( 
-       COMMAND bash -c "git rev-parse --short HEAD|awk '{printf\"%s\", $0}'" 
+execute_process(
+       COMMAND bash -c "git rev-parse --short HEAD|awk '{printf\"%s\", $0}'"
        OUTPUT_VARIABLE git_id
 )
 
 # version information for library names and version string
-execute_process( 
+execute_process(
        COMMAND bash -c "git describe --tags --abbrev=0 HEAD 2>/dev/null | awk -v tag=0.0.4095 ' { tag=$1 } END{ print  tag suffix }'|sed 's/\\./;/g' "
        OUTPUT_VARIABLE mmp_version_str
        ERROR_QUIET OUTPUT_STRIP_TRAILING_WHITESPACE
 )
 
 # extra indicator to show that the build was based on modified file(s) and not the true commit
-# (no hope of reproducing the exact library for debugging). Used only for the internal version 
+# (no hope of reproducing the exact library for debugging). Used only for the internal version
 # string.
-execute_process( 
-       COMMAND bash -c "git diff --shortstat|awk -v fmt=%s -v r=-rotten '{ s=r } END { printf( fmt, s ) }'" 
+execute_process(
+       COMMAND bash -c "git diff --shortstat|awk -v fmt=%s -v r=-rotten '{ s=r } END { printf( fmt, s ) }'"
        OUTPUT_VARIABLE spoiled_str
 )
 
@@ -73,21 +73,53 @@ execute_process(
 #list( GET mmp_version 1 minor_version )
 #list( GET mmp_version 2 patch_level )
 
-message( "+++ building ${major_version}.${minor_version}.${patch_level}${spoiled_str}" )
 
 # define constants used in the version string
-add_definitions( 
-       -DGIT_ID=${git_id} 
+add_definitions(
+       -DGIT_ID=${git_id}
        -DMAJOR_VER=${major_version}
        -DMINOR_VER=${minor_version}
        -DPATCH_VER=${patch_level}${spoiled_str}
 )
 
-# create a file with the deb name so that jenkins can extract it
-execute_process( 
-       COMMAND bash -c "echo ${CMAKE_CURRENT_BINARY_DIR}/rmr_${major_version}.${minor_version}.${patch_level}.deb  >/tmp/rmr_deb_path"
+# ---------------- suss out pkg gen tools so we don't fail generating packages that the system cannot support --------------
+
+
+if( DEV_PKG )
+       set( dev_tag "-dev" )
+endif()
+set( pkg_label "${CMAKE_PROJECT_NAME}-${major_version}.${minor_version}.${patch_level}.${CMAKE_SYSTEM_PROCESSOR}${dev_tag}" )
+message( "+++ building ${pkg_label}${spoiled_str}" )
+set( out_yml /tmp/build_output.yml )                                   # we will record package names (we record only untainted names)
+find_program( rpm NAMES rpmbuild )                                             # rpm package gen requires this to be installed
+
+set( gen_rpm 0 )
+if( "${rpm}" MATCHES "rpm-NOTFOUND" )                         # cannot build rpm
+       set( pkg_list "DEB" )
+       message( "### make package will generate only deb package; cannot find support to generate rpm packages" )
+else()
+       set( pkg_list "DEB;RPM" )
+       set( gen_rpm 1 )
+       message( "+++ make package will generate both deb and rpm packages" )
+endif()
+
+execute_process(
+       COMMAND bash -c "printf '# RMr build generated list of package paths\n---\n' >${out_yml}"
 )
 
+execute_process(
+       COMMAND bash -c " echo deb: ${CMAKE_CURRENT_BINARY_DIR}/${pkg_label}.deb  >>${out_yml}"
+)
+
+if( gen_rpm )
+       execute_process(
+               COMMAND bash -c " echo rpm: ${CMAKE_CURRENT_BINARY_DIR}/${pkg_label}.rpm  >>${out_yml}"
+       )
+endif()
+
+execute_process(
+       COMMAND bash -c "printf '...\n' >>${out_yml}"
+)
 
 # ---------------- setup nano/nng things ---------------------------------------
 if( NOT SKIP_EXTERNALS )
@@ -153,9 +185,16 @@ if( NOT SKIP_EXTERNALS )
 
        message( "+++ installing nano/nng with: ${nano_major}.${nano_minor} | ${nng_major}.${nng_minor}" )
 else()
+       if( PACK_EXTERNALS )
+               unset( SKIP_EXTERNALS  CACHE )  # must remove so as not to trap user into a never ending failure
+               unset( PACK_EXTERNALS  CACHE )
+               message( FATAL_ERROR "ERROR: PACK_EXTERNALS can be set only if SKIP_EXTERNALS is unset (=0, or not supplied on command line)" )
+       endif()
        set( need_ext 0 )
 endif()
-unset( SKIP_EXTERNALS  CACHE ) # prevent it from being applied next build unless specifically set on comd line
+
+unset( SKIP_EXTERNALS  CACHE ) # prevent these from being applied next build unless specifically set on comd line
+unset( PACK_EXTERNALS  CACHE )
 
 
 # this gets us round a chicken/egg problem. include files don't exist until make is run
@@ -178,55 +217,54 @@ add_subdirectory( src/rmr/nng )
 add_subdirectory( doc )                                # this will auto skip if {X}fm is not available
 
 
-# shared and static libraries built from the same object files
-# Nanomsg based library (librmr )
-# library is built by pulling object files from nano and common subdirs
+# shared and static libraries are built from the same object files.
+# Nanomsg based library (librmr ) while nng based is librmr_nng.
+# library is built by pulling object files from either the nano or nng  and common subdirs
 #
 add_library( rmr_shared SHARED "$<TARGET_OBJECTS:nano_objects>;$<TARGET_OBJECTS:common_objects>" )
-add_library( rmr_static STATIC "$<TARGET_OBJECTS:nano_objects>;$<TARGET_OBJECTS:common_objects>" )
-
-# both libraries to be named with librmr prefix and given version numbers with sym links
-set_target_properties( rmr_shared 
-       PROPERTIES 
-               OUTPUT_NAME "rmr" 
-               SOVERSION ${major_version} 
-               VERSION ${major_version}.${minor_version}.${patch_level} )
 
-set_target_properties( rmr_static 
-       PROPERTIES 
-               OUTPUT_NAME "rmr" 
-               SOVERSION ${major_version} 
+set_target_properties( rmr_shared
+       PROPERTIES
+               OUTPUT_NAME "rmr"
+               SOVERSION ${major_version}
                VERSION ${major_version}.${minor_version}.${patch_level} )
 
-
-# NNG based library (librmr_nng )
-# library is built by pulling objects from nng and common subdirs.
-#
 add_library( rmr_nng_shared SHARED "$<TARGET_OBJECTS:nng_objects>;$<TARGET_OBJECTS:common_objects>" )
-add_library( rmr_nng_static STATIC "$<TARGET_OBJECTS:nng_objects>;$<TARGET_OBJECTS:common_objects>" )
+set_target_properties( rmr_nng_shared
+       PROPERTIES
+       OUTPUT_NAME "rmr_nng"
+       SOVERSION ${major_version}
+       VERSION ${major_version}.${minor_version}.${patch_level} )
+
+# we only build/export the static archive (.a) if generating a dev package
+if( DEV_PKG )
+       add_library( rmr_nng_static STATIC "$<TARGET_OBJECTS:nng_objects>;$<TARGET_OBJECTS:common_objects>" )
+       set_target_properties( rmr_nng_static
+               PROPERTIES
+               OUTPUT_NAME "rmr_nng"
+               SOVERSION ${major_version}
+               VERSION ${major_version}.${minor_version}.${patch_level} )
 
+       add_library( rmr_static STATIC "$<TARGET_OBJECTS:nano_objects>;$<TARGET_OBJECTS:common_objects>" )
 
+       set_target_properties( rmr_static
+               PROPERTIES
+               OUTPUT_NAME "rmr"
+               SOVERSION ${major_version}
+               VERSION ${major_version}.${minor_version}.${patch_level} )
+endif()
 
 # if externals need to be built, then we must force them to be built first by depending on them
 if( need_ext )
-       add_dependencies( rmr_static;rmr_shared nanomsg )
-       add_dependencies( rmr_nng_shared;rmr_nng_static ext_nng )
+       if( DEV_PKG )
+               add_dependencies( rmr_static;rmr_shared nanomsg )
+               add_dependencies( rmr_nng_shared;rmr_nng_static ext_nng )
+       else()
+               add_dependencies( rmr_shared nanomsg )
+               add_dependencies( rmr_nng_shared ext_nng )
+       endif()
 endif()
 
-
-# both libraries to be named with librmr_nng prefix and given version numbers with sym links
-set_target_properties( rmr_nng_shared 
-       PROPERTIES 
-               OUTPUT_NAME "rmr_nng" 
-               SOVERSION ${major_version} 
-               VERSION ${major_version}.${minor_version}.${patch_level} )
-
-set_target_properties( rmr_nng_static 
-       PROPERTIES 
-               OUTPUT_NAME "rmr_nng" 
-               SOVERSION ${major_version} 
-               VERSION ${major_version}.${minor_version}.${patch_level} )
-
 #
 if( APPLE  )
        message( "### apple hack: forcing hard coded library paths for nng/nano dynamic libraries" )
@@ -240,19 +278,25 @@ endif()
 # the moment, there are no header files specific to either nano or nng, so to the public
 # header directive is moot, but needed if some day there is one.
 #
-#install( TARGETS rmr_nng_shared;rmr_nng_static;rmr_shared;rmr_static;rmr_nng_shared_mm EXPORT LibraryConfig
-install( TARGETS rmr_nng_shared;rmr_nng_static;rmr_shared;rmr_static EXPORT LibraryConfig
-    ARCHIVE  DESTINATION ${install_lib}
-    LIBRARY  DESTINATION ${install_lib}
-    PUBLIC_HEADER DESTINATION ${install_inc}
+if( DEV_PKG )
+       set( target_list "rmr_nng_shared;rmr_nng_static;rmr_shared;rmr_static" )
+else()
+       set( target_list "rmr_nng_shared;rmr_shared" )
+endif()
+
+install( TARGETS ${target_list} EXPORT LibraryConfig
+       LIBRARY  DESTINATION ${install_lib}
+       ARCHIVE  DESTINATION ${install_lib}
+       PUBLIC_HEADER DESTINATION ${install_inc}
 )
 
 
+unset( DEV_PKG  CACHE )                        # prevent from being a hiddent setting if user redoes things
 
-# install any nano/nng libraries in to the deb as well, but ONLY if we created them.
-# (sure would be nice if FILEs allowed for globbing; sadlyy it does not.
+# install any nano/nng libraries in to the deb as well, but ONLY if asked for on the 'cmake ..' command
+# (sure would be nice if FILEs allowed for globbing; sadlyy it does not.)
 #
-if( need_ext )
+if( PACK_EXTERNALS )
        message( "including nano and nng libraries in the deb" )
        install( FILES
                ${CMAKE_CURRENT_BINARY_DIR}/${CMAKE_INSTALL_LIBDIR}/libnanomsg${nano_so_suffix}
@@ -266,13 +310,12 @@ if( need_ext )
        )
 endif()
 
-
 IF( EXISTS "${CMAKE_ROOT}/Modules/CPack.cmake" )
        include( InstallRequiredSystemLibraries )
 
        set( CPACK_set_DESTDIR "on" )
        set( CPACK_PACKAGING_INSTALL_PREFIX "${install_root}" )
-       set( CPACK_GENERATOR "DEB" )
+       set( CPACK_GENERATOR "${pkg_list}" )
 
        set( CPACK_PACKAGE_DESCRIPTION "Thin library for RIC xAPP messaging routed based on message type." )
        set( CPACK_PACKAGE_DESCRIPTION_SUMMARY "RIC message routing library" )
@@ -281,15 +324,14 @@ IF( EXISTS "${CMAKE_ROOT}/Modules/CPack.cmake" )
        set( CPACK_PACKAGE_VERSION_MAJOR "${major_version}" )
        set( CPACK_PACKAGE_VERSION_MINOR "${minor_version}" )
        set( CPACK_PACKAGE_VERSION_PATCH "${patch_level}" )
-       set( CPACK_PACKAGE_FILE_NAME "${CMAKE_PROJECT_NAME}_${major_version}.${minor_version}.${CPACK_PACKAGE_VERSION_PATCH}${spoiled_str}" )
-       set( CPACK_SOURCE_PACKAGE_FILE_NAME "vric${CMAKE_PROJECT_NAME}_${major_version}.${minor_version}.${CPACK_PACKAGE_VERSION_PATCH}" )
+       set( CPACK_PACKAGE_FILE_NAME "${pkg_label}${spoiled_str}" )
 
        # we build and ship the libraries, so there is NO dependency
-       #set( CPACK_DEBIAN_PACKAGE_DEPENDS "nanomsg ( >= 1.1.4 ), nng ( >= 1.1.1 )" )
 
        set( CPACK_DEBIAN_PACKAGE_PRIORITY "optional" )
        set( CPACK_DEBIAN_PACKAGE_SECTION "ric" )
        set( CPACK_DEBIAN_ARCHITECTURE ${CMAKE_SYSTEM_PROCESSOR} )
+       set( CPACK_RPM_ARCHITECTURE ${CMAKE_SYSTEM_PROCESSOR} )
 
        # this seems ingnored if included
        #set( CPACK_COMPONENTS_ALL Libraries ApplicationData )
index 9d4afc0..cd81fa3 100755 (executable)
 # Adds cmake for RMR
 
 FROM buildpack-deps:stretch
-RUN apt-get update && apt-get -q -y install cmake ksh
+RUN apt-get update && apt-get -q -y install cmake ksh alien
 ADD . /tmp
-# tests require directory named ".build"
-RUN cd /tmp && mkdir .build && cd .build && cmake .. && make install && make package
+# tests require directory named ".build" and dev_pkg to place header files in .build
+RUN cd /tmp && mkdir .build && cd .build && cmake .. -DDEV_PKG=1 && make install && make package
 # tests require a Linux host, fail in a Linux VM on mac/win
 RUN cd /tmp/test && ksh unit_test.ksh -v
 RUN cd /tmp/test/app_test && ksh run_all.ksh
index efd8480..b499a8f 100644 (file)
@@ -30,10 +30,12 @@ target_include_directories (common_objects PUBLIC
        $<INSTALL_INTERFACE:include>
        PRIVATE src)
 
-# we have to force headers to install
-install( FILES 
-       include/rmr.h
-       include/rmr_symtab.h
-       include/RIC_message_types.h
-       DESTINATION ${install_root}/${install_inc}
-)      
+# we have to force headers to install, and only if we are generating a development package
+if( DEV_PKG )
+       install( FILES 
+               include/rmr.h
+               include/rmr_symtab.h
+               include/RIC_message_types.h
+               DESTINATION ${install_root}/${install_inc}
+       )       
+endif()