What is ladir in noinst_libfoo_ladir? - c++

I created an example project called foo, its configure.ac is:
AC_PREREQ([2.69])
AC_INIT([foo], [1.0.0], [a#a.a])
AC_CONFIG_SRCDIR([foo.cpp])
AC_CONFIG_HEADERS([config.h])
AM_INIT_AUTOMAKE([foreign])
LT_INIT
AC_PROG_CXX
AC_CONFIG_FILES([Makefile])
AC_OUTPUT
and its Makefile.am is:
lib_LTLIBRARIES = libfoo.la
libfoo_la_SOURCES = foo.cpp
noinst_libfoo_la_DATA = test
When I run autoreconf -i, I get:
Makefile.am:3: error: 'noinst_libfoo_la_DATA' is used but
'noinst_libfoo_ladir' is undefined.
What is noinst_libfoo_ladir? I can’t seem to find documentation on this.

Your problem is this line, as indicated in the error:
noinst_libfoo_la_DATA = test
automake deals with these variable suffixes when deciding how to build. Note that suffixes ending in _DATA is not one of them. However, it does recognize _DATA as being installed in a location (e.g. data_DATA is installed in datadir). The location that noinst_libfoo_la_DATA would be installed to would therefore be in the variable noinst_libfoo_ladir, the definition of which does not exist in Makefile.am, hence the error.
So ladir is nothing. It's just suffixing noinst_libfoo_la with dir, trying to find an undefined variable. The same process applied to data_DATA would be data (strip off _DATA suffix) + dir = datadir. In order to not get an error, you would need to define something like:
noinst_libfoo_ladir = $(datadir)/libfoo
in Makefile.am. I'd call it something else since a noinst_ prefix has a special meaning for other things in autotools (don't install).

Related

How can I make a C++ program to read predefined files after installation on linux

My project folder has the following structure
-Project/
/src
-Main.cpp
-MyReader.cpp
/headers
-MyReader.h
/DataFiles
-File.dat
-File1.dat
My class Object.cpp has a couple of methods which reads from File.dat and File1.dat and parse the information to Map objects. My problem is that I am using Autotools (in which I'm very very newbie) for generating config and installer files and I don't know how to make all the DataFiles files accessible for the program after installation. The program doesn't work properly because of the code fails when trying to read those files through relative paths. Locally, the program runs perfectly after executing in terminal make && ./program.
How can I solve this issue? Thanks in advance for your help!
A platform independent way to do this with Autotools is using the $(datadir) variable to locate the system data directory and work relative to that.
So in your Makefile.am file you can create a name like this:
myprog_infodir = $(datadir)/myprog
# Set a macro for your code to use
myprog_CXXFLAGS = -DDATA_LOCATION=\"$(datadir)/myprog\"
# This will install it from the development directories
myprog_info_DATA = $(top_srcdir)/DataFiles/File.dat $(top_srcdir)/DataFiles/File1.dat
# make sure it gets in the installation package
extra_DIST = $(top_srcdir)/DataFiles/File.dat $(top_srcdir)/DataFiles/File1.dat
Then in your program you should be able to refer to the data like this:
std::ifstream ifs(DATA_LOCATION "/File.dat");
Disclaimer: Untested code
I figured out one method and will give my example here:
In my Makefile.am
AM_CPPFLAGS = -D MATRIXDIR="\"$(pkgdatadir)/matrix\""
nobase_dist_pkgdata_DATA = matrix/AAcode.txt \
matrix/BLOSUM50 matrix/BLOSUM70.50 matrix/BLOSUM100 matrix/BLOSUM50.50 \
matrix/BLOSUM75 matrix/BLOSUM100.50 matrix/BLOSUM55 matrix/BLOSUM75.50 \
... more not shown
I put quite some number of datafiles in the matrix directory, just show a few of them. In my source file, I simply use the macro MATRIXDIR:
scorematrix.cpp:string MatrixScoreMethod::default_path=MATRIXDIR;
This seems to work well for me. You can use other versions of the data automake variable, such as dist_data_DATA instead of pkgdata. It is a good idea to use pkgdata this way your data will not be mixed with other packages. The nobase_ is to tell automake not to strip the matrix directory during install. Those escaped double quotes seems to be needed for string type so that you don't get compiler errors.

Missing '/' path while compiling using scons in CPPPATH expansion

Fatal error[Pe1696]: cannot open source file "Someheaderfile.hpp"
Although the path for Someheaderfile.hpp is included with
COMMON_INCLUDES = ['#Source/Interfaces/Common']
env.Append(CPPPATH = COMMON_INCLUDES)
The compiler while searching for the mentioned header prints the path as follows
searched: "SourceInterfacesCommon"
which is basically all the '/' removed.
The call made was
myEnv.Library(target, src_files)
and this boils down to
iccarm --silent -o Prod\somepath_obj\Somefile.o -otherflags
-ISource\Interfaces\Common Prod\somepath\Somefile.cpp
So although from the CPPPATH the file was included on the command line when carrying compilation it is not able to locate.
Is there anything which i miss that resulted in
Source/Interfaces/Common being changed to SourceInterfacesCommon
i have sorted out the issue ... seems to be because of the way i was creating the environment variable. On changing env = Environment(platform = ['cygwin'], ENV = os.environ) to env = Environment(ENV = os.environ) along with few other changes, everything works fine.
Also i am not explicitly mentioning what should be the path seperator between folders to be, rather using os.join.path('X','Y','Z').

Automake AM_LDADD workaround

I want to set the same LDADD attribute (Unit test library) to a large number of targets (unit test C++ files). I first though that maybe automake has AM_LDADD variable to add that library to all the targets within the file but is not the case.
In some mail list I found some short discussion asking to add it:
http://gnu-automake.7480.n7.nabble.com/AM-LIBS-AM-LDADD-td3698.html
My question is, how do you deal with that? is it there any way to avoid manually adding LDADD attribute to each target?
So far my Makefile.am looks like:
test1_SOURCES = ...
test1_LDADD = -llibrary
...
...
test20_SOURCES = ...
test20_LDADD = -llibrary
The equivalent of an AM_LDADD variable is simply LDADD. e.g.,
LDADD = -llibrary
test1_SOURCES = ...
...
test20_SOURCES = ...
If you need to override LDADD for a particular program: prog, then prog_LDADD will always take precedence.
I always assumed that since there was no LDADD standard environment variable passed to configure - as you can see with configure --help - there is no real reason for an AM_LDADD. This kind of makes sense, as the configure script, and any options, e.g., --with-foo=<path> should (ideally) work out the library dependencies.
On the other hand, passing CFLAGS via configure might still need an AM_CFLAGS that combines CFLAGS and with other compiler flags determined by the configure script; or even a foo_CFLAGS override. Since configure must be informed of your custom CFLAGS.
Also, I don't know if the test<n> programs only take a single C++ source file, but if so, you can simplify the Makefile.am with:
LDADD = -llibrary
check_PROGRAMS = test1 test2 ... test20
AM_DEFAULT_SOURCE_EXT = .cc # or .cpp
as described here.
In regards to your comment, your can use a convenience library for that purpose - which is particularly useful for common code used by test programs:
noinst_LIBRARIES = libfoo.a # or noinst_LTLIBRARIES = libfoo.la
libfoo_a_SOURCES = MyClass.hh MyClass.cc # or libfoo_la_SOURCES
LDADD = ./libfoo.a -llibrary # or libfoo.la if using libtool.
... etc ...
It's a bad idea to modify LDADD in your Makefile.am, even if it seems convenient. It will make your build system very fragile.
In particular, if the user attempts to override LDADD from the make command line, then your definition of LDADD in Makefile.am will disappear. It's not unreasonable to expect that a user might override LDADD, so you should definitely protect yourself against this situation.
Your original definitions of test1_LDADD, ...,test20_LDADD are much more robust and, as far as I understand the automake manual, the recommended use.
See the remarks here for more info:
https://www.gnu.org/software/automake/manual/html_node/User-Variables.html
https://www.gnu.org/software/automake/manual/html_node/Flag-Variables-Ordering.html

How to set a define through "./configure" with Autoconf

I have one project that can generate two diferent applications based on one define.
libfoo_la_CXXFLAGS = -DMYDEFINE
I have to modify the Makefile.am to set this define, so it is not automatic.
Can I set this define somehow through the configure command?
Is there any other way to set one define using autotools?
You have to edit the file configure.ac, and before AC_OUTPUT (which is the last thing in the file) add a call to AC_DEFINE.
In a simple case like yours, it should be enough with:
AC_DEFINE(MYDEFINE)
If you want to set a value, you use:
AC_DEFINE(MYDEFINE, 123)
This last will add -DMYDEFINE=123 to the flags (DEFS = in Makefile), and #define MYDEFINE 123 in the generated autoconf header if you use that.
I recommend you read the documentation from the beginning, and work through their examples and tutorials. Also check other projects' configure files to see how they use different features.
Edit: If you want to pass flags on the command line to the make command, then you do something like this:
libfoo_la_CXXFLAGS = $(MYFLAGS)
Then you call make like this:
$ make MYFLAGS="-DMYDEFINE"
If you don't set MYFLAGS on the command line, it will be undefined and empty in the makefile.
You can also set target-specific CPPFLAGS in Makefile.am, in which case the source files will be recompiled, once for each set of flags:
lib_LTLIBRARIES = libfoo.la libbar.la
libfoo_la_SOURCES = foo.c
libfoo_la_CPPFLAGS = -DFOO
libbar_la_SOURCES = foo.c
libbar_la_CPPFLAGS = -DBAR
These days autoheader demands
AC_DEFINE([MYDEFINE], [1], [Description here])

Setting and using path to data directory with GNU AutoTools

I am trying to use GNU AutoTools for my C++ project. I have written configure.ac, makefile.am etc. I have some files that are used by the program during execution e.g. template files, XML schema etc. So, I install/copy these files along the executable, for which I use something like:
abcdir = $(bindir)/../data/abc/
abc_DATA = ../data/knowledge/abc.cc
Now it copies the file correctly and My program installation structure looks somethings as follows:
<installation_dir>/bin/<executableFile>
<installation_dir>/data/abc/abc.cc
Now the problem is that in the source code I actually use these files (abc.cc etc.) and for that I need path of where these files resides to open them. One solution is to define (using AC_DEFINE) some variable e.g. _ABC_PATH_ that points to the path of installation but how to do that exactly?. OR is there any better way to do that. For example, in source code, I do something like:
...
ifstream input(<path-to-abc-folder> + "abc.cc"); // how to find <path-to-abc-folder>?
..
The AC_DEFINE solution is fine in principle, but requires shell-like variable expansion to take place. That is, _ABC_PATH_ would expand to "${bindir}/../data/abs", not /data/abc.
One way is to define the path via a -D flag, which is expanded by make:
myprogram_CPPFLAGS += -D_ABC_PATH='\"${abcdir}\"'
which works fine in principle, but you have to make include config.status in the dependencies of myprogram.
If you have a number of such substitution variables, you should roll out a paths.h file that is
generated by automake with a rule like:
paths.h : $(srcdir)/paths.h.in config.status
sed -e 's:#ABC_PATH#:${abcdir}:' $< > $#
As a side-note, you do know about ${prefix} and ${datarootdir} and friends, don't you? If not, better read them up; ${bindir}/.. is not necessarily equal to ${prefix} if the user did set ${exec_prefix}.