makefile: how to call macros in macros - linux

I have the following macros in my make file:
pdf:
// do something
clean:
// just another fancy thing
No I want to declare a macro all: which include (or call) the macros above. The following thing doesn't work:
all:
pdf:
clean:
I don't want to repeat the code from pdf: and clean: in order not to rebel against DRY principle.
Thanks for your help.

Those are not macros, they are targets.
Makefiles take the syntax of [target]: [dependent target 1] [dependent target 2]
Try:
all: pdf clean

executing make without argument is
same as calling make all.
That's not correct. The first normal target in the file is the default target. There's nothing magical about all, though it is conventional to use that as the first target.

You also can run:
make clean pdf
Any way, all is commonly used as a default make target - in other words executing make without argument is same as calling make all. This maybe very confusing for expirienced users, therefore if you want "such a shortcut", call it deferently (e.g. cpdf)

Related

How to add "-lsqlite3" option into makefile of an open source programe

I want to test a function into an open source program, such as LLDPD, it will get input data from SQLite3 database, then output it. But there is always a problem that "undefined function sqlite3_open" when using "make" after "./configure".
I think this problem happens because I can't using "-lsqlite3" option when using "make" to compile lldp.c file - the file I modified.
I want to add "-lsqlite3" into the makefile to solve my problem, but I don't know it's legal or not?
If it's legal, could you give me some advice to do that? I really appreciate that.
Thank you so much for your time.
You can add link flags by setting LDFLAGS:
LDFLAGS="-lsqlite3" ./configure

Turning off unittest execution of third-party code

I'm trying to understand how the '-unittest' dmd switch can be used to select which files have their unittests executed.
I have a file, "a.d", containing a unittest block. File "a.d" imports from a third-party module (requiring the file "b1.d" and in turn "b2.d") which contain their own unittest blocks.
I don't want to run the tests in the third-party code: I just want to run the tests in a.d.
If I compile the third-party code first
dmd -c b1.d b2.d
then try to link it with my code with the unittests copied in
dmd -unittest a.d b1.o b2.o
then I get an error saying that the module in b1.d which a.d is trying to import is in a file that cannot be read.
Can anyone show me how to accomplish this?
Thanks!
What you want to do is not possible because a.d has imported b1.d and b2.d. It means that those modules must be passed to the compiler.
If you want to link some *.o files it's more complex: you have to write an interface (*.di file for them just like for a *.so) thus it's not a good idea to use this mechanism to bypass the unittests. (although this could work it's a bit heavy).
A more straightforward way to arbitrary select some unittests is to use the trait getUnitTests. It's really more the way to go.
You are almost there. Just use separate compilation and linking steps, i.e.
dmd -c -unittest a.d
and then:
dmd a.o b1.o b2.o
That's it.

AC_CHECK_LIB does not find library but compilation runs anyway

I am adding autotool support to a library project. It relies on another self-written library which is not necessarily in a default library path. So I will set LDFLAGS when configuring.
Nevertheless, I want to check for the library in order to warn the user to set LDFLAGS correctly. Therefore I put in this line:
AC_CHECK_LIB([foo], [foo_func],
[AC_DEFINE([HAVE_FOO, [1],
[Define if you have libfoo])],
[AC_MSG_WARN([libfoo not found.])])
Now, if I do not set LDFLAGS, the check fails as expected and the warning is printed. BUT: When I run make, the code compiles nevertheless, because I have the library path set in the environment variable LD_LIBRARY_PATH. I find this confusing... I would want either the check to fail and the code not to compile or the check does not fail and the code compiles.
Am I misunderstanding what AC_CHECK_LIB means or what am I doing wrong?
AC_CHECK_LIB does not care what conclusions you attach to the presence or absence of the library. It just determines whether the library is there and executes its third argument if so, and its fourth argument if not.
So getting the logic you want is up to you. If you replace AC_MSG_WARN by AC_MSG_ERROR in the fourth argument, as ldav1s suggests in the comment, then the configure script will abort if the check fails, and the code will not compile.

in a makefile, declaring a phony target as a wildcard

I want to declare my wildcard target as phony, but phony doesn't support wildcards:
My makefile:
%.config:
gcc <<compile>>
I want the user to be able to use my makefile to compile the project, using a specific configuration file:
make something.config
make something_else.config
obviously, I need my target to be phony, becuase the target files exist, but simply writing:
.PHONY: %.config
doesn't work.
I've seen here that makeapp supports another syntax, that would help:
$(phony %.config): ...
but I can only use make, and not makeapp.
Is there any way to do it with make?
These are conflicting aims. A phony target is one that doesn't correspond to a real file. In your case, the file exists, but it's not really a target.
I would suggest not using the name of the config file as the target. Instead, construct a system based on one of the following:
make something_else
make CONFIG=something_else.config

autoconf/automake: conditional compilation based on presence of library?

I need to conditionally compile some code based on the presence of a library. Seems like this should be easy with autoconf/automake but I can't figure it out.
For example, if there is a PNG library present, I want to include code to use it. My configure.ac has:
AC_CHECK_LIB([png], [png_create_write_struct_2])
and my Makefile.am has:
if USE_LIBPNG
libdev_la_SOURCES += png.c
endif
(which adds png.c to the list of sources for libdev so it gets compiled).
An automake conditional like USE_LIBPNG requires the conditional be defined in configure.ac, so i need:
AM_CONDITIONAL([USE_LIBPNG], [test SOMETHINGOROTHER])
The question is, what can test SOMETHINGOROTHER be? What does AC_CHECK_LIB define that I can test for?
AC_CHECK_LIB's default behavior is to define a symbol (in config.h) which can be used in source code, but that doesn't help the Makefile since the AM_CONDITIONAL needs a shell test
I tried overriding the default AC_CHECK_LIB behavior like so:
AC_CHECK_LIB([png], [png_create_write_struct_2], [HAS_LIBPNG=1])
after which I could test for it:
AM_CONDITIONAL([USE_LIBPNG], [test "x$HAS_LIBPNG" = "x1"])
This is ugly, but works for the Makefile... but creates a new problem: since it discards the original AC_CHECK_LIB behavior, and I no longer get a symbol added to config.h, which I need.
I must be missing something basic, or possible Doing It Wrong. Have been digging around for hours and found no answer.
Anyone?
If the library you're checking for supplies a .pc file for use with pkg-config, then you're much better off using PKG_CHECK_MODULES to get the correct flags. libpng does:
(in configure.ac)
PKG_CHECK_MODULES([libpng], [libpng12])
This gives you access to the variables $(libpng_CFLAGS) and $(libpng_LIBS) which you will want to add to Makefile.am (probably in AM_CFLAGS/AM_CXXFLAGS and LDADD, or target-specific versions thereof).
It will also cause configure to fail with an error if libpng12.pc isn't found. If you want configure to continue, you'll need to supply the third and fourth arguments to PKG_CHECK_MODULES, which are ACTION-IF-FOUND and ACTION-IF-NOT-FOUND:
(in configure.ac)
PKG_CHECK_MODULES([libpng], [libpng12], [HAVE_LIBPNG=1], [HAVE_LIBPNG=0])
Now, if you need an automake conditional, you can do something like:
(in configure.ac)
AM_CONDITIONAL([USE_LIBPNG], [test "$HAVE_LIBPNG" -eq 1])
If you also need the preprocessor definition, you could use AC_DEFINE like so:
(in configure.ac)
AS_IF([test "$USE_LIBPNG" -eq 1], [AC_DEFINE([USE_LIBPNG], [1], [Define if using libpng.])])
Possibly nicer is to set the definition in Makefile.am:
(in Makefile.am)
AM_CPPFLAGS =
if USE_LIBPNG
AM_CPPFLAGS += -DUSE_LIBPNG
endif
This will clutter your command line, though, whereas AC_DEFINE can put the definition in a header if you use AC_CONFIG_HEADERS. I guess this doesn't really matter if you use AM_SILENT_RULES([yes]) or don't care about your command line being neat (and let's be honest, automake generates some pretty gnarly command lines anyway).
A note on good autoconf style
It is considered poor form to build optional support based on whether or not a check succeeded (see this gentoo doc for details). Here's how I'd code optional support for libpng:
(in configure.ac)
# This is because the first PKG_CHECK_MODULES call is inside a conditional.
PKG_PROG_PKG_CONFIG
AC_ARG_WITH([libpng],
[AS_HELP_STRING([--with-libpng],
[support handling png files #<:#default=check#:>#])],
[],
[with_libpng=check])
AS_CASE(["$with_libpng"],
[yes], [PKG_CHECK_MODULES([libpng], [libpng12], [HAVE_LIBPNG=1])],
[no], [],
[PKG_CHECK_MODULES([libpng], [libpng12], [HAVE_LIBPNG=1], [HAVE_LIBPNG=0])])
AM_CONDITIONAL([USE_LIBPNG], [test "$with_libpng" != no -a "$HAVE_LIBPNG" -eq 1])
(in Makefile.am)
if USE_LIBPNG
AM_CPPFLAGS += -DUSE_LIBPNG
AM_CFLAGS += $(libpng_CFLAGS)
LDADD += $(libpng_LIBS)
libdev_la_SOURCES += png.c
endif
If your library doesn't have a .pc file
For completeness, here's how I'd check for a library that didn't have a .pc file. I'll skip over the details of following good autoconf style. AC_CHECK_LIB sets a cache variable, so you can test that instead of replacing the ACTION-IF-FOUND of AC_CHECK_LIB:
(in configure.ac)
AC_CHECK_LIB([png], [png_create_write_struct_2])
# Then test:
AS_IF([test "$ac_cv_lib_png_png_create_write_struct_2" = yes], [HAVE_LIBPNG=1], [HAVE_LIBPNG=0])
# Or set conditional:
AM_CONDITIONAL([USE_LIBPNG], [test "$ac_cv_lib_png_png_create_write_struct_2" = yes])
IMHO, you should only do it this way if you have no other option.
I will disagree mildly with Jack on his recommendation to use PKG_CHECK_MODULES. It is probably best to avoid using that. But I will agree with Jack on avoiding assigning to LIBS in the 3rd argument to AC_CHECK_LIB. Life is easier if you let AC_CHECK_LIB use the default settings.
Although AC_CHECK_LIB does not define a shell variable indicating whether or not the library was found, you can do this in configure.ac:
AM_CONDITIONAL([USE_LIBPNG],[grep HAVE_LIBPNG confdefs.h > /dev/null])
Arguably, this is relying on internal autoconf details, but in practice will work reliably.
Thanks for the replies.
Jack: I'm trying for maximum portability, so can't assume the libraries were installed as part of a package (they're not on my own box!), which means the no-other-option solution you suggested is what I already tried-- setting a shell variable manually-- but also manually performs the extra steps that would have been done by AC_CHECK_LIB: prepending the library to LIBS and defining HAVE_LIBxxx.
There was a catch though: autoheader complains about the bare AC_DEFINE:
autoheader: warning: missing template: HAVE_LIBPNG
autoheader: Use AC_DEFINE([HAVE_LIBPNG], [], [Description])
I'd be nice if autoheader worked in the future, so I had to change AC_DEFINE to the full monty:
AC_CHECK_LIB([png], [png_create_write_struct_2],
[HAS_LIBPNG=1
LIBS="-lpng $LIBS"
AC_DEFINE([HAVE_LIBPNG], 1, [Define to 1 if you have the `png' library (-lpng)])])
This works, but I don't much like having to duplicate the default behavior of AC_CHECK_LIB.
William: Yes I could grep for the symbol definition in confdefs.h, that also works.
Both solutions have their pros and cons (what doesn't?). Not sure which way I'll go, but it's nice to have options.
Thanks again.

Resources