Automake pattern expansion - filenames

I'd like to include many files in one Makefile.am file in the xxx_SOURCES = ... part. Is there any way to use a typical shell expansions there? What I'm looking for is a working equivalent for:
xxx_SOURCES = xxx.c $(top_builddir)/src/{aaa,bbb,ccc}.c

1) There is no way to do that in portable Make syntax (ephemient's answer will work only with GNU Make)
2) There is no way to do that using Automake either. (Although the feature should not be too hard to implement by someone who need it...)
Personally I don't really see the advantage to using
foo_SOURCES = subdir/{foo,bar,baz}.c
over
foo_SOURCES = \
subdir/foo.c \
subdir/bar.c \
subdir/baz.c
I find the former is more cryptic, and it is not grepable (e.g. to answer the question "which Makefile mentions foo.c?").

I don't know if it's the best way, but this is what I've always done:
xxx_SOURCES = xxx.c $(shell echo $(top_builddir)/src/{aaa,bbb,ccc}.c)

Related

Makefile and variable target from command line

Newbie question for Makefiles... why doesn't this work?
TARGET=$#
$(TARGET): * **/*
#echo "TARGET=$(TARGET)"
Where this does?
TARGET=my_target
$(TARGET): * **/*
#echo "TARGET=$(TARGET)"
When started with make my_target?
Result of the former is, "no rule to make target `my_target'."
In addition to the question "why this doesn't work," is there a workaround? I'd like to be able to specify an arbitrary target from the command line. I suppose I could react to an env var, but that makes the CLI clunky, e.g., make target=my_target build or similar.
I've searched, but I'm not getting the right hits to solve this. GNU make 3.81. Thanks!
The automatic variable $# is defined in the context of a pattern rule; outside of any rule it has no value.
If you want Make to do the same thing to whatever target you name, you can use a match-anything rule:
%:
#echo TARGET=$#

How to check if a full path executable is correct in autoconf

I am writing a macro to check for cython on the system my program is about to be compiled.
i can use AC_PATH_PROG all right to find cython when it is in the path, but if the user want to specifiy it in the configure line like this:
./configure CYTHON=/home/user/cythonFoo
I just can't find the right way to check for it.
This is not working, it always pass the test whatever the value of CYTHON is:
AC_PATH_PROG( CYTHON, $CYTHON,"" )
This is kinda working, but not really usable, because it would require me to extract filename and filepath beforehand:
AC_PATH_PROG( CYTHON, cythonFoo,"", /home/user/ )
So i've wrote my own test, but i think there may be a standard way to do it
AC_MSG_CHECKING([Checking Cython path $CYTHON is correct])
AS_IF($CYTHON -V > /dev/null 2>&1, , CYTHON="")
if test -z $CYTHON; then
AC_MSG_RESULT([ no ])
else
AC_MSG_RESULT([ yes ])
fi
You're observing the expected behavior of AC_PATH_PROG. If the user sets CYTHON, AC_PATH_PROG is going to treat it as the cython to use, even if it's bogus. As the first line of the linked page states
If you need to check the behavior of a program as well as find out whether it is present, you have to write your own test for it
So what you've done is the "standard way".

conditional making depending on support of SSE instructions

I want to make certain programs only if the SSE instruction set is supported on the machine where make is run (native target). Assuming it runs linux,
grep sse /proc/cpu_info | wc -l
returns 0 if SSE instructions are not supported and >0 otherwise. But how can I use that in my makefile to facilitate conditional makes?
I currently use GNU Make 3.81, running on linux.
In traditional GNU usage, you wouldn't let make do this job, but rather configure, which writes its output into a Makefile. After all, you don't want to re-check your environment every time you run make - in the best case, you waste time rechecking an unchanged environment, and in the worst, your build gets inconsistent.
That said, a make-only solution would look like:
HAVE_SSE=$(filter-out 0,$(shell grep sse /proc/cpu_info | wc -l))
CFLAGS+=$(if $(HAVE_SSE),-msse)
ifneq ($(HAVE_SSE),)
sse-target
endif
The shell function expands to the shell command's output. The filter-out makes the non-SSE output an empty string instead of 0 because that's easier to conditionalize. Then, you can use the if function as indicated to have conditionals on the value.
So I figured out a (working!) solution by myself, similar to the suggestion by thiton:
SSE := $(shell grep sse /proc/cpuinfo)
INVALID := $(shell grep non-sense /proc/cpuinfo)
ifneq ($(INVALID),$(SSE))
sse_target
endif

Gnu Makefile, compile should fail

I have a collection of examples that I want to make sure they fail to compile. What is the best way to to that with a *GNU Makefile?
test_nocompile: $(NOCOMPILE_CPP)
for cpp in $(NOCOMPILE_CPP) ; do \
echo === $$cpp === ; \
if $(CXX) $(CXXFLAGS) -c -o fail.o $$cpp ; then echo ok ; else exit 1; fi ; \
done
As you can see, I have several difficulties here:
Accessing the shell-for variable cpp: $cpp, \$cpp and $$cpp both do not work.
Even with my if the make stops after the first g++-compile fails. But thats exactly what I want. I want failing to g++-compile to be considered the correct behaviour.
Shell-for-loops in Makefiles are not the best idea. Is there a better way? I can not think of one, because since I expect the compiles to fail, I do not have a correct target, right?
Advanced and optional:
If I could manage to have the fail-check above working, I could try a second pass of compilation, this time with an additional -DEXCLUDE_FAIL, which takes out the offending line from my examples, and then the code should compile. Any idea?
or should write a Python script for that...? ;-)
Edit:
I think my "advanced and optional" gave me a very good idea right now. I could use makes dependency checking again. Just a rough sketch here:
NOCOMPILE_CPP := $(wildcard nocompile/ *.cpp)
NOCOMPILE_XFAILS := $(addsuffix .xfail,$(basename $(NOCOMPILE_CPP)))
%.xfail: %.cpp
if $(CXX) $(CXXFLAGS) -o $# $< ; then exit 1 ; else echo OK ; fi
$(CXX) $(CXXFLAGS) -DEXCLUDE_FAILCODE -o $# $<
test_nocompile: $(NOCOMPILE_XFAILS)
Is this elegant? Then I only have to work out how -DEXCLUDE_FAILCODE can make the failing tests work.... Non-trivial, but doable. I think that could do it, right?
Works for me. What do you get in echo?
You need to negate the condition in if then. Right now it quits when the file doesn't compile and AFAIU you need the opposite.
Why it's not a good idea? But you can write a script that will call $(CXX) and return a proper error code (0 if it doesn't compile). Then you may have normal targets with this script. I'm not very good with specifics of GNU make, probably it's possible with the builtin stuff.
Advanced & optional:
1. Let's first make the thing work:)
2. Personally i don't use python, therefore don't see a need here =:P

Is there a cmake function to update .pot files?

I am migrating a project from autotools to cmake. I have a question about gettext support.
There is an existing FindGettext.cmake modules that provides a nice function :
GETTEXT_CREATE_TRANSLATIONS(foo.pot ALL fr.po de.po)
where you provide a pot file and translated po fil ; the function takes care of turning the po files into gmo files, and add the proper installation targets to make sure the files can be found at runtime. All good and well.
Now comes the question : how do you update your pot files and you po files when you add new messages ?
For this, autotools would generate a "update-po" target, that (from what I understand), reads a POTFILES.in with the lists of all files containing translated strings, mixes it with other info, and ends up calling xgetext to generate the po. I think the coresponding Makefile task is the one that contains something like :
case `$(XGETTEXT) --version | sed 1q | sed -e 's,^[^0-9]*,,'` in \
'' | 0.[0-9] | 0.[0-9].* | 0.1[0-5] | 0.1[0-5].* | 0.16 | 0.16.[0-1]*) \
$(XGETTEXT) --default-domain=$(DOMAIN) --directory=$(top_srcdir) \
--add-comments=TRANSLATORS: $(XGETTEXT_OPTIONS) \
--files-from=$(srcdir)/POTFILES.in \
--copyright-holder='$(COPYRIGHT_HOLDER)' \
--msgid-bugs-address="$$msgid_bugs_address" \
;; \
*) \
$(XGETTEXT) --default-domain=$(DOMAIN) --directory=$(top_srcdir) \
--add-comments=TRANSLATORS: $(XGETTEXT_OPTIONS) \
--files-from=$(srcdir)/POTFILES.in \
--copyright-holder='$(COPYRIGHT_HOLDER)' \
--package-name="$${package_gnu}ube" \
--package-version='0.4.0-dev' \
--msgid-bugs-address="$$msgid_bugs_address" \
;; \
esac
So, before I reinvent the wheel, is there an existing cmake function to do the same thing ?
Or do I have to find the xgettext executable, lists the files, and do this by hand ? THe makefile version seems quite complicated (although it seems to handle lots of cases) ; I would not mind not having to write the cmake equivalent ;)
Thanks
PH
Don't let the autotool bloat scare you. :-)
You can use the following code:
SET(_potFile ${PROJECT_NAME}.pot)
ADD_CUSTOM_COMMAND(OUTPUT ${_potFile}
COMMAND ${XGETTEXT_CMD} ${_xgettext_option_list} -o ${_potFile} ${_src_list}
DEPENDS ${_src_list}
WORKING_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR}
COMMENT "Extract translatable messages to ${_potFile}"
)
ADD_CUSTOM_TARGET(pot_file ${_all}
DEPENDS ${_potFile}
)
For C programs, I am using following as _xgettext_option_list
--language=C --keyword=_ --keyword=N_ --keyword=C_:1c,2 --keyword=NC_:1c,2 -s
--package-name=${PROJECT_NAME} --package-version=${PRJ_VER}
I did reinvented the wheel when the FindGettext did not have the option ALL (when it was cmake-2.4) :-)
According to this kde wiki page, using cmake for editing sources is not a good idea. Better use standalone script for updating translations.
In fact, the extraction and merging of messages does not map well onto the CMake concept of out-of-source builds, and CMake can't
provide too much help for this step, either.
Hence, in this tutorial, we will handle the first step with a
standalone shell script, and only the second step will be handled by
CMake.