How to undefine a macro in configure.ac - autoconf

I am writing my configure.ac script, and have a few custom enable arguments which define macros in my C code if enabled. An example:
AC_ARG_ENABLE([example],
AS_HELP_STRING([--enable-example], [This is an example]))
AS_IF([test "x$enable_example" = "xyes"], [
AC_DEFINE(EXAMPLE_MACRO, 1, [This is a definition example])
])
Now say I have an enable option which, if enabled, must disable the effects of --enable-example option. I have the normal setup:
AC_ARG_ENABLE([another-feature],
AS_HELP_STRING([--another-feature], [This is a feature which enables something, but disables --enable-example]))
AS_IF([test "x$enable_another_feature" = "xyes"], [
AC_DEFINE(ANOTHER_FEATURE_MACRO, 1, [This is another feature definition])
])
Now I need to be able to undefine the EXAMPLE_MACRO macro, but I can't find anything to undo the AC_DEFINE. Am I missing something?

Why not simply delay the AC_DEFINE function calls? Note, I'm not a big fan of the AS_IF macro...
if test "x$enable_another_feature" = xyes ; then
# enable_example="no" # (optional)
AC_DEFINE([ANOTHER_FEATURE_MACRO], [1])
elif test "x$enable_example" = xyes ; then
AC_DEFINE([EXAMPLE_MACRO], [1])
fi
If the AC_DEFINE is not executed, the corresponding #define ... is not instantiated in the config header. Discussed here.

In case of boolean type symbols like in your example, where you simply enable flag or disable, all you need is another call to AC_DEFINE to disable the symbol:
AC_DEFINE(EXAMPLE_MACRO, 0)
The symbol will still exist, but with the new value of 0 (boolean false).
Update:
To complete the answer, the usual way you do it if there are conflicting options specified is termination with error during compilation. When you define a symbol, and config.h.in contains the #undef EXAMPLE_MACRO, the AC_DEFINE will turn it around into #define EXAMPLE_MACRO. So you have two options to work with such a macro, check if its value is set to 1/0 or do a check for both macros set and assert if they are.

Related

How to suppress warnings messages in Rcpp/RcppArmadillo functions

I am using RcppArmadillo within an R package. I want to suppress a warning message that occurs in a C++ function due to numerical precision when a symmetric matrix fails a test of symmetry within eig_sym(). I am confident this is a precision issue as I have saved some of the matrices hitting this warning and tested them in R using isSymmetric() and they pass this.
I have tried including #define ARMA_WARN_LEVEL 0 at the top of the header file where the function with this issue is defined, but this does not solve my issue and I am told 'ARMA_WARN_LEVEL' macro redefined (presumably it is defined in the config file of RcppArmadillo).
Ideally I would suppress only errors associated with this call of eig_sym, but failing this I am content to suppress all warnings. If anyone can advise on how to effect this I would be very grateful.
Thank you.
Looking at Armadillo's config.hpp -- the first header file included by Armadillo -- we see that it starts with
#if !defined(ARMA_WARN_LEVEL)
#define ARMA_WARN_LEVEL 2
#endif
//// The level of warning messages printed to ARMA_CERR_STREAM.
//// Must be an integer >= 0. The default value is 2.
//// 0 = no warnings
//// 1 = only critical warnings about arguments and/or data which are likely to lead to incorrect results
//// 2 = as per level 1, and warnings about poorly conditioned systems (low rcond) detected by solve(), spsolve(), etc
//// 3 = as per level 2, and warnings about failed decompositions, failed saving/loading, etc
so a simple
#define ARMA_WARN_LEVEL 0
#include <RcppArmadillo.h>
should take care of things. We cannot "show" this as we have no reproducible example to work with.
Also note that there is a good reason why warnings are usually on. They signal something you as author should be aware of.

JCL : IF Statement with SET Statement

I have set FLAG as 1 and I am execpting ARG value should be DEV only. But am getting as ARG= DEV + CLIENTID
000023 // FLAG=1
000026 // IF (&FLAG=1) THEN
000027 //SET1 SET ARG=DEV
000028 // ELSE
000029 //SET2 SET ARG=DEV+&CLIENT
000030 // ENDIF
It mean JCL assign the value in RUNTIME (before checking the IF Condition).
Please help me to understand.
Thanks!
Bharathi
What #hogstrom said is correct. The JCL IF statement tests Step Return codes and not Variable values:
//IFBAD IF (ABEND | STEP1.RC > 8) THEN
Following on from what he said you can use a variable in an include statement
Include With variable
// INCLUDE MEMBER=OPT&FLAG
and setup members in the proclib
MEMBER=OPT1
// SET ARG=DEV
MEMBER=OPT2
// SET ARG=DEV+&CLIENT
You have to setup an include for every possible value of &FLAG and it is very long winded for one SET. It is more commonly used when you can set lots of variables like:
// INCLUDE MEMBER=ENV&ENV
where &ENV=PROD \ TEST etc
Your case
Do not use flag, just set the variable:
// SET ARG=DEV
or
// SET ARG=DEV+&CLIENT
There is some good information in the JCL Manual to understand the purpose of the IF/THEN/ELSE purpose.
Here are a few bullets from the manual:
The IF/THEN/ELSE/ENDIF statement construct does not conditionally control the processing of JCL; rather, it conditionally controls the
execution of job steps.
The result of processing an IF/THEN/ELSE/ENDIF statement construct, once determined, remains unchanged regardless of the outcome from
running any remaining steps in a job. The system does not reexamine
the original condition at any later job step termination, either
normal or abnormal. See Example 9.
The system allocates all DD statements defined to a step if the execution time evaluation of the relational-expression determines
that a step is to be executed. All data sets defined on DD statements
in the job must be available at the time the job is selected for
execution.
You can nest IF/THEN/ELSE/ENDIF statement constructs up to a maximum of 15 levels. You can specify symbolic parameters on
IF/THEN/ELSE/ENDIF statements provided that they resolve to one of the
supported relational-expression keywords. Any other symbolic
parameters, even if accepted by the system, are not intended or
supported.
What your doing seems logical, but, its not the intended purpose of JCL SET and conditional logic.
In your case, the last SET executed is what is used and why your seeing the DEV + CLIENTID

How to understand AS_IF in autoconf?

The document says
Macro: AS_IF (test1, [run-if-true1], ..., [run-if-false])
Run shell code test1. If test1 exits with a zero status then run shell code run-if-true1, else examine further tests. If no test exits with a zero status, run shell code run-if-false, with simplifications if either run-if-true1 or run-if-false is empty.
The configure.ac file contains
AS_IF([test "$have_hdf5" != "no"], [AC_DEFINE([HAVE_HDF5], [], [we have HDF5 library + headers])])
But when I type in the run shell code test1, i.e. test "$have_hdf5" != "no", nothing appeared. No matter what I entered (such as test $have_hdf5), I got nothing. But it actually works when I ./configure. So how does the AS_IF and the test1 shell code work? Is it testing some environment variables?
The test utility doesn't have visible output unless you supply an erroneous expression.
test will exit with a 0 status if the expression was true and a nonzero exit status indicates the expression was false (or invalid).
AS_IF tests the exit status of the expression you supply as its first parameter.
If it was 0 (true), the associated block of code is executed. If not, it moves on to the next test expression and performs with the same behavior.
This happens until the macro runs out of tests. Once all tests are found false, it executes the last parameter's contents if the last parameter was supplied.
Edit
Naturally if you don't have "have_hdf5" defined in your current shell, it won't be true when you execute your test expression alone, but if it is true in the configure script, it will do what it is meant to. In any case, output will not happen unless you use an output statement.
The AS_IF M4sh macro will expand out to a portable Bourne shell if statement (when processed by autoconf in the process of writing configure), something like:
if test1 ; then run-if-true1 ... else run-if-false fi
where the interior tests and actions are wrapped in an elif ... ; then ....
Every other parameter starting from the 0th is tested. Usually these are some kind of variable test (e.g. test "$have_hdf5" != "no"), but don't necessarily need to be.

How do I apply command line overrides to SystemVerilog ovm_sequence objects?

I'd like to apply a command line override to an ovm_sequence object like this:
+ovm_set_config_int=*,max_timeout,100000
The max_timeout field is declared inside ovm_sequence_utils macro.
Is there any way to do it? My understanding is that ovm sequences are not part of the ovm hierarchy, so perhaps they can't be modified from the command line.
I'm not aware of a mechanism that lets you set-up config space like that from the command line. A quick grep of the OVM source doesn't show anything either.
A quick comment on
ovm sequences are not part of the ovm hierarchy
They're not constructed at build time, that's correct. They are created just before they start running on a sequencer, but any ovm_object based class can interrogate a config integer via get_config_int()
Normally I'd use a plus-arg for things like this, and the set the config int in my base test class based on that plus-arg. For example, the command line would have:
+max_timeout=100000
...and then, in my base test class, which all my tests inherit from:
function void build();
int timeout;
[....]
if ($value$plusargs("max_timeout=%d", timeout)) begin
`ovm_info(get_type_name(), "Setting timeout", OVM_MEDIUM);
set_config_int("*", "max_timeout", timeout");
end
[....]
endfunction
Normally my uses are not quite so literal as that, having flags that set multiple values up, but that's the basics of it.
I got it working (following instructions from http://www.testbench.in/OT_10_OVM_SEQUENCE_5.html) by adding the following to my ovm_sequence in task body():
if(!(p_sequencer.get_config_int("max_timeout",max_timeout)))
max_timeout = ... // some default value
The key here is that the command line config needs to be set for the sequencer, and the sequence can pick up that config using the above-mentioned code.

How do I combine AC_SUBST and AC_DEFINE?

I've a configure.ac file containing lines like:
AC_DEFINE(CONF_XDISP, ":8", "X screen number")
These constants are used in the C source for setting compile defaults. I also have a configuration file conf/bumblebee.conf in which these defaults need to be set. I'm told that AC_SUBST can be used to get #CONF_XDISP# substituted for ":8" such that the below line:
VGL_DISPLAY=#CONF_XDISP#
becomes:
VGL_DISPLAY=":8"
Making an AC_SUBST line for each AC_DEFINE does not look the best way to me as it includes a lot duplication of lines. How can I combine these options, such that I can use something like AC_DEFINE_SUBST? Other ideas and suggestions to improve this are welcome too.
Thanks to thinton, I could cook up the below code:
# AC_DEFINE_SUBST(NAME, VALUE, DESCRIPTION)
# -----------------------------------------
AC_DEFUN([AC_DEFINE_SUBST], [
AC_DEFINE([$1], [$2], [$3])
AC_SUBST([$1], ['$2'])
])
For AC_DEFINE_SUBST(CONF_XDISP, ":8", "X screen number"), this generates a configure file containing:
$as_echo "#define CONF_XDISP \":8 \$PWD\"" >>confdefs.h
CONF_XDISP='":8"'
Related docs:
http://www.gnu.org/savannah-checkouts/gnu/autoconf/manual/autoconf-2.68/html_node/Setting-Output-Variables.html
http://www.gnu.org/savannah-checkouts/gnu/autoconf/manual/autoconf-2.68/html_node/Macro-Definitions.html
m4 is a macro language, after all, so something like
AC_DEFUN([AC_DEFINE_SUBST],
[AC_DEFINE($1,$2,$3)
AC_SUBST($1)])
should do the trick. You might have to fiddle with [ a little to get escaping right.

Resources