I have created a simple library in C++ and have with pretty good discipline documented the API in Doxygen. There are a few example programs to use the library in the package. Is there a trick to documenting those (as command-line programs) in the same Doxygen process?
I've decided to add an answer to my comments with some more details.
As mentioned in my comments, I typically use the "MainPage" functionality of Doxygen.
For my public repositories, I use the README.md page and configure Doxygen as follows:
OUTPUT_DIRECTORY = docs/
EXTRACT_ALL = YES
EXTRACT_PRIVATE = YES
EXTRACT_PRIV_VIRTUAL = YES
EXTRACT_PACKAGE = YES
EXTRACT_STATIC = YES
EXTRACT_LOCAL_CLASSES = YES
INPUT = README.md <any other files or directories>
USE_MDFILE_AS_MAINPAGE = README.md
And then this generates the Doxygen HTML files and can be seen here, for example (excuse the shameless plug)
It's useful for providing a general overview of your library, use-cases and especially in your mentioned case, app arguments, switches, etc.
Edit 2023-01-10:
As mentioned in the comments under this answer, this is certainly not the only way of achieving OP's goal.
If separate files (i.e. the executables) are to be documented, they can easily be added to the Doxyfile as such:
# individual files
INPUT = lib/include/myheader.hpp lib/src/myimpl.cpp examples/dosomethingcool.cpp
# Directories
INPUT = lib/include/ lib/src/ examples/
FILE_PATTERNS = *.cpp *.hpp
In your example implementation, you can then add a simple JavaDoc-style header:
/**
* #file myimpl.cpp
* #author Your Name <you#you.net>
* #date 2023-01-01
*
* #brief Contains an example of implementing/using my awesome library.
*
* Enter a detailed description of your reference implementation here.
* You may also include Markdown, so you can create simple tables,
* or format your text in a way that you like.
*
* Alternatively, you could also add an example using code.
* #code{.sh}
* # call my implementation like this:
* ./myimpl -LgTz100
* #endcode
*
* # A complete list of arguments:
* | Long opt | short opt | Description |
* |----------|-----------|-----------------|
* | -foo | -f | Foos something |
* | -bar | -B | Bars the baz |
*/
#include <iostream>
/**
* #brief Program entry point.
* You can continue with normal documentation here.
*
* #param argc The total amount of args passed
* #param argv The string arguments passed to the application
*/
int main(int32_t argc, char** argv) {
// implement whatever here
}
Related
For our client we have defined a domain-specific (Auto)test (SCript)-language to simplify setting up testcases.
Each test in an ASC-file consists out of three parts:
test <name> - <options> # <-- defines the start of a test and some general options
<testheader> # <-- contains a number of header commands which need to be always filled in
<testbody> # <-- the real test-actions
Both in a <testheader> and <testbody> whitelines are allowed (to make the testcases better readable)
To check if the definitions in these ASC-files are correct we have made a validator-script which checks the tests in the following way:
# definitions of valid_header_command and valid_test_command not listed here since they themselves are not of importance for the question (just lists with definitions of keywords for those particular sections)
anyotherline = restOfLine - Optional(LineEnd())
test_command = NotAny(OneOfKeywords('if', 'elif', 'else', 'fi') | eot) - (valid_header_command | valid_test_command | anyotherline)
block = Forward()
pre_post_block = Forward()
if_statement = Keyword('if') - vp_expression - eol
then_block = ZeroOrMore(block)
elif_block = Keyword('elif') - vp_expression - eol - ZeroOrMore(block)
else_block = Keyword('else') - eol - ZeroOrMore(block)
fi_statement = Keyword('fi') - eol
conditional_block = if_statement - then_block - ZeroOrMore(elif_block) - Optional(else_block) - fi_statement
block << ( OneOrMore(test_command) | conditional_block ) # pylint: disable=expression-not-assigned
test_implementation = (OneOrMore(block) + eot).setParseAction(self._parseaction_validate_mandatory_header_commands)
test_name = CharsNotIn(' +:!,?;#=()\n\r')
test_options = ( #option-definitios
)
test_definition = Keyword('test') - White(' ') - test_name.addParseAction(self._parseaction_validate_unique_testcase).addParseAction(self._parseaction_reset_per_testcase_data) - test_options - eol
# if we can't find a test_definition, but we can find a line with something on it (so not the end of file), then report an error
testcase = (test_definition - test_implementation) | (restOfLine + ~StringEnd() + LineEnd()).setParseAction(self._parseaction_errorExpectingNextTest)
This works for the biggest part, but we saw that some strange behaviour was happening when somebody put an if around the <testheader> commands to prevent having to code 2 testcases which only differ in the header.
After long deliberation we decided that an if around the <testheader> commands is not allowed, since it is very rare that only the <testheader> differs.
So now we want to change the implementation in such a way that it does not allow if statements around a <testheader> anymore. To do this we wanted to try an approach like we did for testcase where a seperate check for test_definition (which defines the test keyword) is used before the rest of the <testheader> and <testbody> are checked.
(Note: we must stay backwards compatible, since the if around header-sections are almost never used).
What we tried was:
Split up the old test_command in a header_command section and a test_command section (only the changed code from the snippet above):
header_command = NotAny(OneOfKeywords('if', 'elif', 'else', 'fi') | eot) - (valid_header_command)
test_command = NotAny(OneOfKeywords('if', 'elif', 'else', 'fi') | eot) - (valid_test_command | anyotherline)
....
test_implementation = OneOrMore(header_command).setParseAction(self._parseaction_validate_mandatory_header_commands) + OneOrMore(block) + eot
For the <testheader> commands this solution is working. But now it fails on every <testbody> command since they do not match with the header_command section, where we would like that it continues with the test_command section if it fails in the header_command section.
Note again: whitespaces are allowed both in header- and body-sections, so we cannot use those as delimiters. And we must stay backwards compatible, so it is difficult/impossible to introduce any other delimiter.
We also tried keeping the original code but adding checks to the valid_header_command section, but that does not work since although the conditional_block definition is part of block it also contains block and thus only when the parts of if statements are already handled it will handle the remaining test_command part which contains the check in valid_header_command. So handling it there is Just Too Late.
And lastly: We considered changing the _parseaction_validate_mandatory_header_commands method, but how can we make sure that when that fails it goes first to the test_command before really raising an error?
Hence we did not follow that approach further at the moment.
We think that our original approach of splitting up the old testcommand into 2 sections is the correct one, but we are already breaking our heads for a number of days on this to get it to work. So we end up here asking for help.
--> Does anybody have an idea how we can make sure that after our validator sees that it is not a <testheader> command it continues to check against the <testbody> commands before raising an error?
Note: implementation is done in python 2.7 with pyparsing 2.3.0
A colleague of me found a working solution.
He also split up the block into a part that includes all and a test-command only part and replaced the block sections in the if-stements with the test-command only block.
He also added some extra parseactions:
test_command = NotAny(conditional_construct | eot) - (valid_header_command | valid_test_command | anyotherline)
no_header_command = NotAny(conditional_construct | eot) - (valid_test_command | anyotherline)
block = Forward()
no_header_block = Forward()
if_statement = (Keyword('if') - vp_expression - eol).addParseAction(self._parseaction_in_if_statement)
then_block = ZeroOrMore(no_header_block)
elif_block = Keyword('elif') - vp_expression - eol - ZeroOrMore(no_header_block)
else_block = Keyword('else') - eol - ZeroOrMore(no_header_block)
fi_statement = (Keyword('fi') - eol).addParseAction(self._parseaction_out_if_statement)
conditional_block = if_statement - then_block - ZeroOrMore(elif_block) - Optional(else_block) - fi_statement
block << ( OneOrMore(test_command) | conditional_block ) # pylint: disable=expression-not-assigned
no_header_block << ( OneOrMore(no_header_command) | conditional_block ) # pylint: disable=expression-not-assigned
I am trying to edit and run a snakemake pipeline. In a nutshell, the snakemake pipeline calls a default genome aligner (minimap) and produces output files with this name. I am trying to add a variable aligner to config.yaml to specify the aligner I want to call. Also (where I am actually stuck), the output files should have the name of the aligner specified in config.yaml.
My config.yaml looks like this:
# this config.yaml is passed to Snakefile in pipeline-structural-variation subfolder.
# Snakemake is run from this pipeline-structural-variation folder; it is necessary to
# pass an appropriate path to the input-files (the ../ prefix is sufficient for this demo)
aligner: "ngmlr" # THIS IS THE VARIABLE I AM ADDING TO THIS FILE. VALUES COULD BE minimap or ngmlr
# FASTQ file or folder containing FASTQ files
# check if this has to be gzipped
input_fastq: "/nexusb/Gridion/20190917PGD2staal2/PD170815/PD170815_cat_all.fastq.gz" # original is ../RawData/GM24385_nf7_chr20_af.fastq.gz
# FASTA file containing the reference genome
# note that the original reference sequence contains only the sequence of chr20
reference_fasta: "/nexus/bhinckel/19/ONT_projects/PGD_breakpoint/ref_hg19_local/hg19_chr1-y.fasta" # original is ../ReferenceData/human_g1k_v37_chr20_50M.fasta
# Minimum SV length
min_sv_length: 300000 # original value was 40
# Maximum SV length
max_sv_length: 1000000 # original value was 1000000. Note that the value I used to run the pipeline for the sample PD170677 was 100000000000, which will be coerced to NA in the R script (/home/bhinckel/ont_tutorial_sv/ont_tutorial_sv.R)
# Min read length. Shorter reads will be discarded
min_read_length: 1000
# Min mapping quality. Reads will lower mapping quality will be discarded
min_read_mapping_quality: 20
# Minimum read support required to call a SV (auto for auto-detect)
min_read_support: 'auto'
# Sample name
sample_name: "PD170815" # original value was GM24385.nf7.chr20_af. Note that this can be a list
I am posting below the sections of my snakefile which generate output files with the extension _minimap2.bam, which I would like to replace by either _minimap2.bam or _ngmlr.bam, depending on aligner on config.yaml
# INPUT BAM folder
bam = None
if "bam" in config:
bam = os.path.join(CONFDIR, config["bam"])
# INPUT FASTQ folder
FQ_INPUT_DIRECTORY = []
if not bam:
if not "input_fastq" in config:
print("\"input_fastq\" not specified in config file. Exiting...")
FQ_INPUT_DIRECTORY = os.path.join(CONFDIR, config["input_fastq"])
if not os.path.exists(FQ_INPUT_DIRECTORY):
print("Could not find {}".format(FQ_INPUT_DIRECTORY))
MAPPED_BAM = "{sample}/alignment/{sample}_minimap2.bam" # Original
#MAPPED_BAM = "{sample}/alignment/{sample}_{alignerName}.bam" # this did not work
#MAPPED_BAM = f"{sample}/alignment/{sample}_{config['aligner']}.bam" # this did nor work either
else:
MAPPED_BAM = find_file_in_folder(bam, "*.bam", single=True)
...
if config['aligner'] == 'minimap':
rule index_minimap2:
input:
REF = FA_REF
output:
"{sample}/index/minimap2.idx"
threads: config['threads']
conda: "env.yml"
shell:
"minimap2 -t {threads} -ax map-ont --MD -Y {input.REF} -d {output}"
rule map_minimap2:
input:
FQ = FQ_INPUT_DIRECTORY,
IDX = rules.index_minimap2.output,
SETUP = "init"
output:
BAM = "{sample}/alignment/{sample}_minimap2.bam",
BAI = "{sample}/alignment/{sample}_minimap2.bam.bai"
conda: "env.yml"
threads: config["threads"]
shell:
"cat_fastq {input.FQ} | minimap2 -t {threads} -K 500M -ax map-ont --MD -Y {input.IDX} - | samtools sort -# {threads} -O BAM -o {output.BAM} - && samtools index -# {threads} {output.BAM}"
else:
print(f"Aligner is {config['aligner']} - skipping indexing step for minimap2")
rule map_ngmlr:
input:
REF = FA_REF,
FQ = FQ_INPUT_DIRECTORY,
SETUP = "init"
output:
BAM = "{sample}/alignment/{sample}_minimap2.bam",
BAI = "{sample}/alignment/{sample}_minimap2.bam.bai"
conda: "env.yml"
threads: config["threads"]
shell:
"cat_fastq {input.FQ} | ngmlr -r {input.REF} -t {threads} -x ont - | samtools sort -# {threads} -O BAM -o {output.BAM} - && samtools index -# {threads} {output.BAM}"
I initially tried to create a alignerName parameter, similar to the sample parameter, as shown below:
# Parameter: sample_name
sample = "sv_sample01"
if "sample_name" in config:
sample = config['sample_name']
###############
#
# code below created by me
#
###############
# Parameter: aligner_name
alignerName = "defaultAligner"
if "aligner" in config:
alignerName = config['aligner']
Then I tried to input {alignerName} wherever I have minimap2 on my input/ output files (see commented MAPPED_BAM variable definition above), though this is throwing an error. I guess snakemake will interpret {alignerName} as a wildcard, though what I want is simply to pass the variable name defined in config['aligner'] to input/ output files. I also tried with f-string (MAPPED_BAM = f"{sample}/alignment/{sample}_{config['aligner']}.bam"), though I guess this it did not work either.
You are close!
The way wildcards work in snakemake is they get interpreted 'last', while f-strings get interpreted first. To not interpret a curly brace in an f-string you can escape it with another curly brace, like so:
print(f"{{keep curly}}")
>>> {keep curly}
So all we need to do is
MAPPED_BAM = f"{{sample}}/alignment/{{sample}}_{config['aligner']}.bam"
This question already has answers here:
Using different delimiters in sed commands and range addresses
(3 answers)
Closed 1 year ago.
When following their documentation and running ./build_packages --board=lakitu, I get the following error.
Using ubuntu 16.0.4. Looks like a sed syntax error? Am I missing a variable? Does sed work differently in different operating systems or is something wrong with their documentation/scripts? Followed their documentation to the t and didn't add or configure anything. Waiting for a successful run first.
Looking at similar questions, they all appear to be syntax errors...
* Package: sys-boot/shim-14.0.20180308-r4
* Repository: lakitu
* USE: abi_x86_64 amd64 elibc_glibc kernel_linux userland_GNU
* FEATURES: network-sandbox sandbox splitdebug userpriv usersandbox
* Running stacked hooks for pre_pkg_setup
* sysroot_build_bin_dir ... [ ok ]
* Running stacked hooks for post_pkg_setup
* python_eclass_hack ... [ ok ]
* Running stacked hooks for pre_src_unpack
* python_multilib_setup ... [ ok ]
>>> Unpacking source...
>>> Unpacking shim-14.0.20180308.tar.gz to /build/lakitu/tmp/portage/sys-boot/shim-14.0.20180308-r4/work
>>> Source unpacked in /build/lakitu/tmp/portage/sys-boot/shim-14.0.20180308-r4/work
* Running stacked hooks for post_src_unpack
* asan_init ... [ ok ]
>>> Preparing source in /build/lakitu/tmp/portage/sys-boot/shim-14.0.20180308-r4/work/shim-79cdb2a215de2ace7d1bf0a294165a04b726c70a ...
>>> Source prepared.
>>> Configuring source in /build/lakitu/tmp/portage/sys-boot/shim-14.0.20180308-r4/work/shim-79cdb2a215de2ace7d1bf0a294165a04b726c70a ...
>>> Source configured.
>>> Compiling source in /build/lakitu/tmp/portage/sys-boot/shim-14.0.20180308-r4/work/shim-79cdb2a215de2ace7d1bf0a294165a04b726c70a ...
make -j8 ARCH=x86_64 CROSS_COMPILE=x86_64-cros-linux-gnu- EFI_INCLUDE=/build/lakitu//usr/include/efi EFI_PATH=/build/lakitu//usr/lib64 ARCH_LDFLAGS=--no-experimental-use-relr COMMITID=79cdb2a215de2ace7d1bf0a294165a04b726c70a DEFAULT_LOADER=\\\\grub-lakitu.efi shimx64.efi
sed -e "s,##VERSION##,14," \
-e "s,##UNAME##,Linux x86_64 Intel Xeon E312xx (Sandy Bridge, IBRS update) GenuineIntel GNU/Linux," \
-e "s,##COMMIT##,79cdb2a215de2ace7d1bf0a294165a04b726c70a," \
< /build/lakitu/tmp/portage/sys-boot/shim-14.0.20180308-r4/work/shim-79cdb2a215de2ace7d1bf0a294165a04b726c70a/version.c.in > version.c
sed: -e expression #2, char 60: unknown option to `s'
make: *** [Makefile:183: version.c] Error 1
* ERROR: sys-boot/shim-14.0.20180308-r4::lakitu failed (compile phase):
* emake failed
*
* If you need support, post the output of `emerge --info '=sys-boot/shim-14.0.20180308-r4::lakitu'`,
* the complete build log and the output of `emerge -pqv '=sys-boot/shim-14.0.20180308-r4::lakitu'`.
* The complete build log is located at '/build/lakitu/tmp/portage/logs/sys-boot:shim-14.0.20180308-r4:20190531-002217.log'.
* For convenience, a symlink to the build log is located at '/build/lakitu/tmp/portage/sys-boot/shim-14.0.20180308-r4/temp/build.log'.
* The ebuild environment file is located at '/build/lakitu/tmp/portage/sys-boot/shim-14.0.20180308-r4/temp/environment'.
* Working directory: '/build/lakitu/tmp/portage/sys-boot/shim-14.0.20180308-r4/work/shim-79cdb2a215de2ace7d1bf0a294165a04b726c70a'
* S: '/build/lakitu/tmp/portage/sys-boot/shim-14.0.20180308-r4/work/shim-79cdb2a215de2ace7d1bf0a294165a04b726c70a'
There's a , after Bridge
-e "s,##UNAME##,Linux x86_64 Intel Xeon E312xx (Sandy Bridge, IBRS update) GenuineIntel GNU/Linux," \
Change to
-e "s###UNAME###Linux x86_64 Intel Xeon E312xx (Sandy Bridge, IBRS update) GenuineIntel GNU/Linux#" \
I want to generate MAC address and UUID in attribute and then pass the values to template.
something like this :
Attribute/default.rb:
default['libvirt']['xml_mac_Adrr'] = 'openssl rand -hex 6 | sed 's/\(..\)/\1:/g; s/:$//''
default['libvirt']['xml_uuid'] = 'uuidgen virbr0'
Template/network.erb:
<uuid><%= node['libvirt']['xml_uuid'] %></uuid>
<mac address='<%= node['libvirt']['xml_mac_Adrr']%>'/>
How can I do that?
UPDATE
I want to modify the default.xml network for the virtual network. Basically, we have to do it by virsh-net command
Now I want to use a template to pass UUID & MAC address values to XML file and modify it in guest machine.
this is my recipe:
template '/etc/libvirt/qemu/network/default.xml' do
source 'qemu-network.erb'
owner "root"
group "root"
mode "0644"
end
Yo can use backquotes to execute shell commands inside ruby and capture the response:
default['libvirt']['xml_mac_Adrr'] = `openssl rand -hex 6 | sed 's/\(..\)/\1:/g; s/:$//'`
default['libvirt']['xml_uuid'] = `uuidgen virbr0`
EDIT:
The second problem I see is that you have to use instance variables in the controller to share information with the view. So the best way would be:
#mac = `openssl rand -hex 6 | sed 's/\(..\)/\1:/g; s/:$//'`
#uuid = `uuidgen virbr0`
Then at view level you can use:
<uuid><%=#uuid %></uuid>
<mac address='<%=#mac %>'/>
Within chef relying on system commands should go through the shell_out method (which is included in the recipe dsl) to avoid some quirks when the DSL interpreter is run and getting methosd to clean up the ouput.
I'd go this way:
default['libvirt']['xml_mac_Adrr'] = Chef::ShellOut.new("openssl rand -hex 6 | sed 's/\(..\)/\1:/g; s/:$//'").stdout.chomp
default['libvirt']['xml_uuid'] = Chef::ShellOut.new('uuidgen virbr0').stdout.chomp
But this has a problem, at each run, a new mac address will be generated, so you should use normal and avoid redefining it, this is easiest moved into the recipe, following in recipe file before your template code should do:
node.normal['libvirt']['xml_mac_Adrr'] = shell_out("openssl rand -hex 6 | sed 's/\(..\)/\1:/g; s/:$//'").stdout.chomp unless node['libvirt'].includes?('xml_mac_Adrr')
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.