Autoconf macro for Boost MPI? - c++

I'm searching an autoconf macro to use in my configure.ac that checks for Boost MPI.
It's not hard to find a couple of them on the Internet but none of the one I tried worked as expected.
What ax_boost_mpi.m4 do you use?
EDIT: I'll explain my requirement better. I need the macro to tell me if Boost MPI is available or not (defining HAVE_BOOST_MPI) to store the compiler and linker flags somewhere and to switch the compiler from the nornal c++ compiler to an available mpiCC or mpic++.
If the Boost MPI is not found I'd like to be able to choose if I want to stop the configuration process with an error or continue using g++ without HAVE_BOOST_MPI defined.
As a plus it should define an MPIRUN variable to allow running some checks.

I'm unaware of a turnkey solution here, but that doesn't mean one's unavailable.
With some work, you could probably adapt http://www.gnu.org/software/autoconf-archive/ax_mpi.html#ax_mpi and http://github.com/tsuna/boost.m4 to do what you want. The former digging up the MPI compiler and the latter checking for Boost MPI. You'd have to add a Boost MPI check to boost.m4 as it doesn't have one. You'd have to add your own MPIRUN-searching mechanism.
If you find a solution and/or roll your own, please do share.

# ===========================================================================
#
# SYNOPSIS
#
# AX_BOOST_MPI
#
# DESCRIPTION
#
# Test for MPI library from the Boost C++ libraries. The macro
# requires a preceding call to AX_BOOST_BASE, AX_BOOST_SERIALIZATION
# and AX_MPI. You also need to set CXX="$MPICXX" before calling the
# macro.
#
# This macro calls:
#
# AC_SUBST(BOOST_MPI_LIB)
#
# And sets:
#
# HAVE_BOOST_MPI
#
# LICENSE
#
# Based on Boost Serialize by:
# Copyright (c) 2008 Thomas Porschberg <thomas#randspringer.de>
#
# Copyright (c) 2010 Mirko Maischberger <mirko.maischberger#gmail.com>
#
# Copying and distribution of this file, with or without modification, are
# permitted in any medium without royalty provided the copyright notice
# and this notice are preserved. This file is offered as-is, without any
# warranty.
#serial 1
AC_DEFUN([AX_BOOST_MPI],
[
AC_ARG_WITH([boost-mpi],
AS_HELP_STRING([--with-boost-mpi#<:#=special-lib#:>#],
[use the MPI library from boost - it is possible to
specify a certain library for the linker
e.g. --with-boost-mpi=boost_mpi-gcc-mt-d-1_33_1 ]),
[
if test "$withval" = "no"; then
want_boost="no"
elif test "$withval" = "yes"; then
want_boost="yes"
ax_boost_user_mpi_lib=""
else
want_boost="yes"
ax_boost_user_mpi_lib="$withval"
fi
],
[want_boost="yes"]
)
if test "x$want_boost" = "xyes"; then
AC_REQUIRE([AC_PROG_CC])
CPPFLAGS_SAVED="$CPPFLAGS"
CPPFLAGS="$CPPFLAGS $BOOST_CPPFLAGS"
AC_MSG_WARN(BOOST_CPPFLAGS $BOOST_CPPFLAGS)
export CPPFLAGS
LDFLAGS_SAVED="$LDFLAGS"
LDFLAGS="$LDFLAGS $BOOST_LDFLAGS"
export LDFLAGS
LIBS_SAVED="$LIBS"
LIBS="$LIBS $BOOST_SERIALIZATION_LIB"
export LIBS
AC_CACHE_CHECK(whether the Boost::MPI library is available,
ax_cv_boost_mpi,
[AC_LANG_PUSH([C++])
AC_COMPILE_IFELSE(AC_LANG_PROGRAM([[#%:#include <boost/mpi.hpp>
]],
[[int argc = 0;
char **argv = 0;
boost::mpi::environment env(argc,argv);
return 0;
]]),
ax_cv_boost_mpi=yes, ax_cv_boost_mpi=no)
AC_LANG_POP([C++])
])
if test "x$ax_cv_boost_mpi" = "xyes"; then
AC_DEFINE(HAVE_BOOST_MPI,,[define if the Boost::MPI library is available])
BOOSTLIBDIR=`echo $BOOST_LDFLAGS | sed -e 's/#<:#^\/#:>#*//'`
if test "x$ax_boost_user_mpi_lib" = "x"; then
for libextension in `ls $BOOSTLIBDIR/libboost_mpi*.{so,a}* 2>/dev/null | grep -v python | sed 's,.*/,,' | sed -e 's;^lib\(boost_mpi.*\)\.so.*$;\1;' -e 's;^lib\(boost_mpi.*\)\.a*$;\1;'` ; do
ax_lib=${libextension}
AC_CHECK_LIB($ax_lib, exit,
[BOOST_MPI_LIB="-l$ax_lib"; AC_SUBST(BOOST_MPI_LIB) link_mpi="yes"; break],
[link_mpi="no"])
done
if test "x$link_mpi" != "xyes"; then
for libextension in `ls $BOOSTLIBDIR/boost_mpi*.{dll,a}* 2>/dev/null | grep -v python | sed 's,.*/,,' | sed -e 's;^\(boost_mpi.*\)\.dll.*$;\1;' -e 's;^\(boost_mpi.*\)\.a*$;\1;'` ; do
ax_lib=${libextension}
AC_CHECK_LIB($ax_lib, exit,
[BOOST_MPI_LIB="-l$ax_lib"; AC_SUBST(BOOST_MPI_LIB) link_mpi="yes"; break],
[link_mpi="no"])
done
fi
else
for ax_lib in $ax_boost_user_mpi_lib boost_mpi-$ax_boost_user_mpi_lib; do
AC_CHECK_LIB($ax_lib, exit,
[BOOST_MPI_LIB="-l$ax_lib"; AC_SUBST(BOOST_MPI_LIB) link_mpi="yes"; break],
[link_mpi="no"])
done
fi
if test "x$link_mpi" != "xyes"; then
AC_MSG_ERROR(Could not link against $ax_lib !)
fi
fi
LIBS="$LIBS_SAVED"
CPPFLAGS="$CPPFLAGS_SAVED"
LDFLAGS="$LDFLAGS_SAVED"
fi
])

This comment is a bit late, but I will add it here so that others searching for the same topic can find it. I had personally been looking for a function integrated into boost.m4 that defined similar variables as the other boost libraries (BOOST_MPI_LDFLAGS, BOOST_MPI_LIBS). I finally just added one and submitted a pull request here:
https://github.com/tsuna/boost.m4/pull/50
This uses the MPICXX variable for CXX/CXXCPP if it is already defined (by ax_mpi.m4, acx_mpi.m4, etc), otherwise it uses the existing CXX/CXXCPP.

Related

if condition to folder branch in Jenkinsfile

I have branch folder "feature-set" under this folder there's multibranch
I need to run the below script in my Jenkinsfile with a condition if this build runs from any branches under the "feature-set" folder like "feature-set/" then run the script
the script is:
sh """
if [ ${env.BRANCH_NAME} = "feature-set*" ]
then
echo ${env.BRANCH_NAME}
branchName='${env.BRANCH_NAME}' | cut -d'\\/' -f 2
echo \$branchName
npm install
ng build --aot --output-hashing none --sourcemap=false
fi
"""
the current output doesn't get the condition:
[ feature-set/swat5 = feature-set* ]
any help?
I would re-write this to be primarily Jenkins/Groovy syntax and only go to shell when required.
Based on the info you provided I assume your env.BRANCH_NAME always looks like `feature-set/
// Echo first so we can see value if condition fails
echo(env.BRANCH_NAME)
// startsWith better than contains() based on current usecase
if ( (env.BRANCH_NAME).startsWith('feature-set') ) {
// Split branch string into list based on delimiter
List<String> parts = (env.BRANCH_NAME).tokenize('/')
/**
* Grab everything minus the first part
* This handles branches that include additional '/' characters
* e.g. 'feature-set/feat/my-feat'
*/
branchName = parts[1..-1].join('/')
echo(branchName)
sh('npm install && ng build --aot --output-hashing none --sourcemap=false')
}
This seems to be more on shell side. Since you are planning to use shell if condition the below worked for me.
Administrator1#XXXXXXXX:
$ if [[ ${BRANCH_NAME} = feature-set* ]]; then echo "Success"; fi
Success
Remove the quotes and add an additional "[]" at the start and end respectively.
The additional "[]" works as regex

Running only changed or failed tests with CMake/CTest?

I work on a large code base that has close to 400 test executables, with run times varying between 0.001 second and 1800 seconds. When some bit of code changes CMake will rebuild intelligently only the targets that have changed, many times taking shorter than the actual test run will take.
The only way I know around this is to manually filter on tests you know you want to run. My intuition says that I would want to re-run any test suite that does not have a successful run stored - either because it failed, or because it was recompiled.
Is this possible? If so, how?
ctest command accepts several parameters, which affects on set of tests to run. E.g. ,"-R" - filter tests by name, "-L" - filter tests by label. Probably, using dashboard-related options, you may also choose tests to run.
As for generating values for these options according to changed executables, you may write program or script, which checks modification time of executables and/or parses last log file for find failed tests.
Another way for run only changed executables is to wrap tests into additional script. This script will run executable only if some condition is saticfied.
For Linux wrapper script could be implemented as follows:
test_wrapper.sh:
# test_wrapper.sh <test_name> <executable> <params..>
# Run executable, given as second argument, with parameters, given as futher arguments.
#
# If environment variable `LAST_LOG_FILE` is set,
# checks that this file is older than the executable.
#
# If environment variable LAST_LOG_FAILED_FILE is set,
# check that testname is listed in this file.
#
# Test executable is run only if one of these checks succeed, or if none of checks is performed.
check_succeed=
check_performed=
if [ -n $LAST_LOG_FILE ]; then
check_performed=1
executable=$2
if [ ! ( -e "$LAST_LOG_FILE" ) ]; then
check_succeed=1 # Log file is absent
elif [ "$LAST_LOG_FILE" -ot "$executable" ]; then
check_succeed=1 # Log file is older than executable
fi
fi
if [ -n "$LAST_LOG_FAILED_FILE" ]; then
check_performed=1
testname=$1
if [ ! ( -e "$LAST_LOG_FAILED_FILE" ) ]; then
# No failed tests at all
elif grep ":${testname}\$" "$LAST_LOG_FAILED_FILE" > /dev/null; then
check_succeed=1 # Test has been failed previously
fi
fi
if [ -n "$check_performed" -a -z "$check_succeed" ]; then
echo "Needn't to run test."
exit 0
fi
shift 1 # remove `testname` argument
eval "$*"
CMake macro for add wrapped test:
CMakeLists.txt:
# Similar to add_test(), but test is executed with our wrapper.
function(add_wrapped_test name command)
if(name STREQUAL "NAME")
# Complex add_test() command flow: NAME <name> COMMAND <command> ...
set(other_params ${ARGN})
list(REMOVE_AT other_params 0) # COMMAND keyword
# Actual `command` argument
list(GET other_params 0 real_command)
list(REMOVE_AT other_params 0)
# If `real_command` is a target, need to translate it to path to executable.
if(TARGET real_command)
# Generator expression is perfectly OK here.
set(real_command "$<TARGET_FILE:${real_command}")
endif()
# `command` is actually value of 'NAME' parameter
add_test("NAME" ${command} "COMMAND" /bin/sh <...>/test_wrapper.sh
${command} ${real_command} ${other_params}
)
else() # Simple add_test() command flow
add_test(${name} /bin/sh <...>/test_wrapper.sh
${name} ${command} ${ARGN}
)
endif()
endfunction(add_wrapped_test)
When you want to run only those tests, which executables have been changed since last run or which has been failed last time, use
LAST_LOG_FILE=<build-dir>/Testing/Temporary/LastTest.log \
LAST_FAILED_LOG_FILE=<build-dir>/Testing/Temporary/LastTestsFailed.log \
ctest
All other tests will be automatically passed.

How to move fossil repository subdirectory tree (to elsewhere within same repository, retaining tree levels)

I have a directory with multiple levels of subdirectories inside a fossil checkout, that I want to move to another location in a different subdirectory and retain the multiple-level directory structure.
For instance, to move a1 into a2 below, to go from having (handwritten like an abbreviated find command output):
a1/
a1/b/
a1/b/files
a1/c/
a1/c/d/
a1/c/d/more-files
a2/
I want fossil mv --hard a1 a2 to result in:
a2/a1/
a2/a1/b/
a2/a1/b/files
a2/a1/c/
a2/a1/c/d/
a2/a1/c/d/more-files
Just like the normal unix mv command would result in. Ideally with the history of the mv kept so it can be merged into another branch with any changes to files and more-files intact; as I could just fossil remove the files then re-add them as fresh files, but this is an uglier solution than I'd like.
fossil mv command (in v1.33 on Linux) loses the multiple levels and I end up with all files from lower level subdirectories moved into the top level directory of the new location.
One solution was to write a script to move each directoy individually, a level at a time, so it retained the structure. I would like to suggest this functionality to the fossil developer(s). I may post the script (below, with another dependency script included below that) to my github (user jgbreezer) sometime, but for now, this script (which I called fossilmvtree). It ignores files in the checkout not in fossil and will leave the old files/dirs where there are any (I don't believe it deletes them):
#!/bin/bash
# $1=source tree
# $2=dest. dir
# supports fossil mv options
# moves single source tree as-is to under/new dest.dir (not reducing dir levels to flat structure under dest dir)
exclude=''
usage () {
cat >&2 <<EOF
Usage: fossilmvtree [-x|--exclude= exclude_dirname] source dest"
-x option may be specified multiple times; do not specify full paths, just last
(filename/aka basename) of a directory to exclude from the move.
Command-line arguments are always included.
EOF
}
while [ -z "${1##-*}" ]
do
case "$1" in
-x|--exclude|--exclude=*)
if [[ "${1#--exclude=}" == "$1" ]]
then
# separate arg, '--exclude=' not used
shift
arg="$1"
else
arg="${1#--exclude=}"
fi
excinfo="$excinfo $arg"
# pruning is efficient
exclude="$exclude -type d -name '${arg//\'/\\\'}' -prune -o"
;;
--case-sensitive)
fossilopts="$fossilopts $1 $2"; shift;;
-*)
fossilopts="$fossilopts $1";;
esac
shift
done
echo "excluding paths: $excinfo"
echo "fossil mv options: $fossilopts"
[ $# -eq 2 ] || { usage; exit 1; }
mv="$(which fossilmvrev 2>/dev/null)" || { usage; echo "error:Missing fossilmvrev" >&2; exit 1; }
src="$1"
srcdir="$(basename "$src")"
dst="$2"
if [ -f "$dst" ]
then
# move src to new subdir of dst; otherwise we're renaming and moving
[ -d "$dst" ] || { echo "error:Destination '$dst' exists but is not a directory" >&2; exit 1; }
dst="$dst/$srcdir"
fi
#could set safe PATH (-execdir is cautious of relative/empty paths in $PATH but fossil binary might not be in std.location): PATH=/bin:/usr/bin:/usr/local/bin
eval find "$src" $exclude -type d -printf '%P\\n' | {
while read -r dir
do
[ -z "$dir" ] || [[ "$src/$dir" == "$dst/$dir" ]] && continue
echo
echo "fossil mv $src/$dir/* $dst/$dir/"
mkdir -p "$dst/$dir" || exit 1
find "$src/$dir" -maxdepth 1 \! -type d -exec "$mv" $fossilopts "$dst/$dir" '{}' +
rmdir "$src/$dir" # tidy up, as we only moved the files above (fossil doesn't really manage dirs)
# if rmdir fails due to remaining files, let user manage that (rmdir will complain to stderr if so) -
# likely to be unversioned files they might have forgotten about, shouldn't delete without user's knowledge.
done
}
It was only really tested once or twice on my specific fossil checkout, though written ready to be a re-usable script; please check the diffs (suggest do a clean checkout somewhere else and run it on that, then diff against your regular one using "diff -qr" or something before committing to check it behaved itself).
Careful if using the -x/exclude option, I wasn't sure that worked properly.
It depends on fossilmvrev script:
#!/bin/sh
# switch order of move arguments around to work with find -exec ... +
opts=''
while [ -z "${1##-*}" ]
do
case "$1" in
--case-sensitive) opts="$opts $1 $2"; shift 2;;
*) opts="$opts $1"; shift;;
esac
done
destdir="$1"
shift
fossil mv $opts "$#" $destdir
I think there is a much simpler solution
(this is under Windows but similarly for Linux)
md a2\a1
fossil mv a1 a2/a1 --hard

C++ Name Mangler [duplicate]

Is there any way to get back the mangled name from demangled name in g++.
For example , I have the demangled name func(char*, int), what should I do to get the mangled name i.e _Z4funcPci back?
My question is g++ specific.
You can simply use g++ to compile an empty function with the signature you require and extract the name from that. For example:
echo "int f1(char *, int) {} " | g++ -x c++ -S - -o- | grep "^_.*:$" | sed -e 's/:$//'
gives output
_Z2f1Pci
which is I think what you require. Make sure that you include any relevant header files as they will affect the way the symbols are mangled.
Based on the Bojan Nikolic's approach, here's a better script:
mangle.bash:
IFS='::' read -a array <<< "$1"
indexes=("${!array[#]}")
prefix=""
middle=""
suffix=""
rettype=""
if [ -z "$2" ]; then
rettype="void"
fi
for index in "${indexes[#]}"
do
#echo "$index ${array[index]}"
if [ $index == ${indexes[-1]} ]; then
#echo "last"
middle="$rettype ${array[index]};"
elif [ -n "${array[index]}" ]; then
#echo "not empty"
prefix="${prefix}struct ${array[index]}{"
suffix="${suffix}};"
fi
done
#echo "$prefix$middle$suffix $rettype $1{}"
echo "$prefix$middle$suffix $rettype $1{}" | g++ -x c++ -S - -o- | grep "^_.*:$" | sed -e 's/:$//'
Use:
$ ./mangle.bash "abc::def::ghi()"
_ZN3abc3def3ghiEv
$ ./mangle.bash "abc::def::ghi(int i, char c)"
_ZN3abc3def3ghiEic
$ ./mangle.bash "abc::def::def(int i, char c)" constr
_ZN3abc3defC2Eic
$ ./mangle.bash "abc::def::~def()" destr
_ZN3abc3defD2Ev
But as to constructors and destructors, remember that there are C0 C1 C2 and D0 D1 D2 ones.
What's worst, sometimes you cannot mangle a name because you must get more than one result.
See https://reverseengineering.stackexchange.com/q/4323/4398 (there are multiple destructors in VFT, and all of them are demangled as ClassName::~ClassName()). (The same applies to constructors, I have seen C0 and C2 constructors.)
On the other hand, that answer references the Itanium ABI: https://refspecs.linuxbase.org/cxxabi-1.75.html#mangling-type where mangling is specified.
The itanium-abi Haskell package: it did not work for me (May 2014)
There is a Haskell package
http://hackage.haskell.org/package/itanium-abi
that promises both demangling and mangling, but I could run only the demangling:
Installation on Ubuntu Precise:
sudo aptitude install ghc
sudo aptitude install cabal-install
cabal update
cabal install itanium-abi
Then you run ghci and after import ABI.Itanium and import Data.Either you get:
Prelude ABI.Itanium Data.Either> cxxNameToText $ head (rights [ demangleName "_ZTI13QSystemLocale" ])
"typeinfo for QSystemLocale"
There is mangleName, but it takes a DecodedName which is a data structure rather than a string, and that data structure is produced only by demangleName (unless I overlooked something). Hopefully, this will get better in some future release.
The clang code
I did not try the clang code.

Getting mangled name from demangled name

Is there any way to get back the mangled name from demangled name in g++.
For example , I have the demangled name func(char*, int), what should I do to get the mangled name i.e _Z4funcPci back?
My question is g++ specific.
You can simply use g++ to compile an empty function with the signature you require and extract the name from that. For example:
echo "int f1(char *, int) {} " | g++ -x c++ -S - -o- | grep "^_.*:$" | sed -e 's/:$//'
gives output
_Z2f1Pci
which is I think what you require. Make sure that you include any relevant header files as they will affect the way the symbols are mangled.
Based on the Bojan Nikolic's approach, here's a better script:
mangle.bash:
IFS='::' read -a array <<< "$1"
indexes=("${!array[#]}")
prefix=""
middle=""
suffix=""
rettype=""
if [ -z "$2" ]; then
rettype="void"
fi
for index in "${indexes[#]}"
do
#echo "$index ${array[index]}"
if [ $index == ${indexes[-1]} ]; then
#echo "last"
middle="$rettype ${array[index]};"
elif [ -n "${array[index]}" ]; then
#echo "not empty"
prefix="${prefix}struct ${array[index]}{"
suffix="${suffix}};"
fi
done
#echo "$prefix$middle$suffix $rettype $1{}"
echo "$prefix$middle$suffix $rettype $1{}" | g++ -x c++ -S - -o- | grep "^_.*:$" | sed -e 's/:$//'
Use:
$ ./mangle.bash "abc::def::ghi()"
_ZN3abc3def3ghiEv
$ ./mangle.bash "abc::def::ghi(int i, char c)"
_ZN3abc3def3ghiEic
$ ./mangle.bash "abc::def::def(int i, char c)" constr
_ZN3abc3defC2Eic
$ ./mangle.bash "abc::def::~def()" destr
_ZN3abc3defD2Ev
But as to constructors and destructors, remember that there are C0 C1 C2 and D0 D1 D2 ones.
What's worst, sometimes you cannot mangle a name because you must get more than one result.
See https://reverseengineering.stackexchange.com/q/4323/4398 (there are multiple destructors in VFT, and all of them are demangled as ClassName::~ClassName()). (The same applies to constructors, I have seen C0 and C2 constructors.)
On the other hand, that answer references the Itanium ABI: https://refspecs.linuxbase.org/cxxabi-1.75.html#mangling-type where mangling is specified.
The itanium-abi Haskell package: it did not work for me (May 2014)
There is a Haskell package
http://hackage.haskell.org/package/itanium-abi
that promises both demangling and mangling, but I could run only the demangling:
Installation on Ubuntu Precise:
sudo aptitude install ghc
sudo aptitude install cabal-install
cabal update
cabal install itanium-abi
Then you run ghci and after import ABI.Itanium and import Data.Either you get:
Prelude ABI.Itanium Data.Either> cxxNameToText $ head (rights [ demangleName "_ZTI13QSystemLocale" ])
"typeinfo for QSystemLocale"
There is mangleName, but it takes a DecodedName which is a data structure rather than a string, and that data structure is produced only by demangleName (unless I overlooked something). Hopefully, this will get better in some future release.
The clang code
I did not try the clang code.