UTS_RELEASE defines the kernel version in Linux. It's defined in generated/utsrelease.h, which is created by the main Makefile like so:
# KERNELRELEASE can change from a few different places, meaning version.h
# needs to be updated, so this check is forced on all builds
uts_len := 64
define filechk_utsrelease.h
if [ `echo -n "$(KERNELRELEASE)" | wc -c ` -gt $(uts_len) ]; then \
echo '"$(KERNELRELEASE)" exceeds $(uts_len) characters' >&2; \
exit 1; \
fi; \
(echo \#define UTS_RELEASE \"$(KERNELRELEASE)\";)
endef
I was wondering what UTS stands for, here?
I will do a bet : it comes from unix history age.
Unix Time Sharing
http://en.wikipedia.org/wiki/Time-sharing
( with another link to give more weight to my guess : http://www.linuxmisc.com/9-unix-programmer/515225795f89ebf5.htm )
Additionally if you search for UTS on Wikipedia you'll find this as evidence too:
UTS is a three-letter abbreviation which may describe:
Time-sharing, known as Unix Time-sharing System (UTS) when abbreviated in the source code of many Unix-like operating systems
Maybe https://lwn.net/Articles/531114/ and https://lwn.net/Articles/179345/ are the right(tm) answer :-)
For example, if KERNELRELEASE value is:
3.18.31-g18e453b
Also in the file
*utsrelease.h
Will be:
#define UTS_RELEASE "3.18.31-g18e453b"
In Android, it goes here:
Settings > About Phone > Kernel Version
Related
I can multi-thread a make with make -jN
Can I dictate multi-threading within the Makefile so that just make from the command-line runs multiple threads. Here's my makefile:
BIN_OBJS = $(wildcard *.bin)
HEX_OBJS = $(subst .bin,.hex,$(BIN_OBJS))
all: $(HEX_OBJS)
$(HEX_OBJS): %.hex: %.bin
python ../../tools/bin2h.py $< > $#
First, to be clear, make is not multi-threaded. Using -j just tells make to run multiple commands at the same time (in the background, basically).
Second, no, it's not possible to enable multiple jobs from within the makefile. You don't want to do that, in general, anyway because other systems will have different numbers of cores and whatever value you choose won't work well on those systems.
You don't have to write multiple makefiles, though, you can just use:
BIN_OBJS = $(wildcard *.bin)
HEX_OBJS = $(subst .bin,.hex,$(BIN_OBJS))
.PHONY: all multi
multi:
$(MAKE) -j8 all
all: $(HEX_OBJS)
$(HEX_OBJS): %.hex: %.bin
python ../../tools/bin2h.py $< > $#
Be careful using -j if the filesystem where the make is occurring is an nfs share. I have seen odd results and had it mentioned to me that nfs mounted directories operate differently (some sort of file lock issue?)
I ran my multi makes from a script and checked cpuinfo to find out how many processors the build box had (was running same script against multiple architectures/build machines)
CPUCOUNT=$(grep -c "^processor" /proc/cpuinfo)
if [ ${CPUCOUNT} -lt 1 -o ${CPUCOUNT} -gt 4 ]
then
echo "Unexpected value for number of cpus, ${CPUCOUNT}, exiting ..."
exit 16
fi
echo "This machine has ${CPUCOUNT} cpus, will use make -j${CPUCOUNT} where possible"
I have a linux makefile that needs to compile on 2 different kernel versions. The makefile is not generated from automake/autoconf.
The C code are already conditioned using macros to generate different code for different kernel version, but certain features in the makefile needs to be also conditioned.
Is there a way in a makefile to do:
if (kernel_version > 2.6.30)
newer_kernel = 1
else
newer_kernel = 0
endif
Well, I can think of one quick way to do it with bash:
KERNEL_VERSION=`uname -r`
HIGHER_VERSION=`echo -e "$KERNEL_VERSION\n2.6.30" | sort -g -t '.' | tail --lines=1`
if [ "$HIGHER_VERSION" == "2.6.30" ]
# its an older kernel
else
# its a newer kernel
fi
Basically, you use uname to obtain the version of the current kernel, then compare it to 2.6.30 using sort (the -g flag enables numeric sorting, -t '.' means use dot as a field separator), then use tail to determine which of the two version was higher in the list. Not exactly a beautiful solution, but it will work.
You can put it into a separate script or directly into the makefile recipe
My program requires at least Linux 2.6.26 (I use timerfd and some other Linux-specific features).
I have an general idea how to write this macro but I don't have enough knowledge about writing test macros for Autoconf. Algorithm:
Run "uname --release" and store output
Parse output and subtract Linux version number (MAJOR.MINOR.MICRO)
Compare version
I don't know how to run command, store output and parse it.
Maybe such macro already exists and it's available (I haven't found any)?
I think you'd be better off detecting the specific functions you need using AC_CHECK_FUNC, rather than a specific kernel version.
This will also prevent breakage if you find yourself cross-compiling at some point in the future
There is a macro for steps 2 (parse) and 3 (compare) version, ax_compare_version. For example:
linux_version=$(uname --release)
AX_COMPARE_VERSION($linux_version, [eq3], [2.6.26],
[AC_MSG_NOTICE([Ok])],
[AC_MSG_ERROR([Bad Linux version])])
Here I used eq3 so that if $linux_version contained additional strings, such as -amd64, the comparison still succeeds. There is a plethora of comparison operators available.
I would suggest you not to check the Linux version number, but for the specific type you need or function. Who knows, maybe someone decides to backport timerfd_settime() to 2.4.x? So I think AC_CANONICAL_TARGET and AC_CHECK_LIB or similar are your friends. If you need to check the function arguments or test behaviour, you'd better write a simple program and use AC_LANG_CONFTEST([AC_LANG_PROGRAM(...)])/AC_TRY_RUN to do the job.
Without going too deep and write autoconf macros properly (which would be preferable anyway) don't forget that configure.ac is basically a shell script preprocessed by m4. So you can write shell commands directly.
# prev. part of configure.ac
if test `uname -r |cut -d. -f1` -lt 2 then; echo "major v. error"; exit 1; fi
if test `uname -r |cut -d. -f2` -lt 6 then; echo "minor v. error"; exit 1; fi
if test `uname -r |cut -d. -f3` -lt 26 then; echo "micro error"; exit 1; fi
# ...
This is just an idea if you want to do it avoiding writing macros for autoconf. This choice is not good, but should work...
The best way is the already suggested one: you should check for features; so, say in a future kernel timerfd is no more available... or changed someway your code is broken... you won't catch it since you test for version.
edit
As user foof says in comments (with other words), it is a naive way to check for major.minor.micro. E.g. 3.5.1 will fail because of 5 being lt 6, but 3.5.1 comes after 2.6.26 so (likely) it should be accepted. There are many tricks that can be used in order to transform x.y.z into a representation that puts each version in its "natural" order. E.g. if we expect x, y, or z won't be greather than 999, we can do something like multiplying by 1000000 major, 1000 minor and 1 micro: thus, you can compare the result with 2006026 as Foof suggested in comment(s).
I need to find out which library will be loaded given in the information returned from /sbin/ldconfig. I came up with the following:
#!/bin/bash
echo $(dirname $(/sbin/ldconfig -p | awk "/$1/ {print \$4}" | head -n 1))
Running this results with:
$ whichlib libGL.so
/usr/X11R6/lib
This a two part question:
Will this produce a reliable result across platform?
Is there a slicker way to parse the output of ldconfig?
Thanks,
Paul
There're several ways the library is loaded by executeable:
1.
Using $LD_LIBRARY_PATH
Using ld cache
Libary with full path compiled into binary (-rpath gcc flag)
You're using option 2, while option 1 and 3 are not considered.
Depending on what exactly you're doing you may want to run ldd directly on the executable you're planning to run rather than the general case ldconfig.
Since you asked, you could write your script like this:
dirname "$(/sbin/ldconfig -p | awk "\$1 == "$1" {print \$4; exit}")"
It's a little more precise and has one less pipe. Also echo $(cmd) is redundant; you can just write cmd.
I'm building my first autoconf managed package.
However I can't find any simple examples anywhere of how to specify a required library, and find that library where it might be in various different places.
I've currently got:
AC_CHECK_LIB(['event'], ['event_init'])
but:
It doesn't find the version installed in /opt/local/lib
It doesn't complain if the library isn't actually found
I need to set the include path to /opt/local/include too
any help, or links to decent tutorials much appreciated...
autoconf script cannot guess the "optional" library locations, which may vary from one platform to another. So you can say
CPPFLAGS="-I/opt/local/include" LDFLAGS="-L/opt/local/lib" ./configure
For AC_CHECK_LIB() you need to specify the fail condition explicitly in "action-if-false" argument:
dnl This is simply print "no" and continue:
AC_CHECK_LIB([m], [sqrt123])
dnl This will stop:
AC_CHECK_LIB([m], [sqrt123], [], [AC_MSG_ERROR([sqrt123 was not found in libm])])
Output:
checking for sqrt123 in -lm... no
checking for sqrt123 in -lm... no
configure: error: sqrt123 was not found in libm
AC_CHECK_LIB() does not fail by default on obvious reasons: one may check for several different libraries that provide similar functionality and choose one of them :)
Also have a look at this post for similar topic.
You need to manually set CFLAGS, CXXFLAGS and LDFLAGS if you want gcc/g++ to look in non-standard locations.
So, before calling AC_CHECK_LIB(), do something like
CFLAGS="$CFLAGS -I/opt/local/include"
CXXFLAGS="$CXXFLAGS -I/opt/local/include"
LDFLAGS="$LDFLAGS -L/opt/local/lib"
You don't need CXXFLAGS if you're only using gcc throughout your configure script.
If the library ships a .pc file, consider using the PKG_CHECK_MODULES() macro which does the things you want. If it's your own library, just ship a .pc file into /usr/lib/pkgconfig, it'll make it much easier for other developers to depend/use it.
I know this is an old thread now, but I guess this may help some people out. This is how I find some stuff.
hdff="no"
hdffprefix="ERROR"
AC_ARG_WITH(hdf,[ --with-hdf Compile with hdf library, for output.],[hdffprefix=$withval hdff="yes"],[])
# if there is no value given, it appears tha hdffprefix is set to "yes"
if test $hdffprefix = "yes" -a $hdff = "yes"
then
echo "HDF: Attempting to find HDF"
hdffprefix="ERROR"
# check if hdffprefix is set, if it is not, it sets it to "ERROR" and the
# 'if' comparison evaluates to true
if [[ "$hdffprefix" == "ERROR" ]]
then
echo "HDF: hdffprefix not set, searching PATH"
for i in `echo $PATH | tr ':' '\n'`
do
if [[ $i == *hdf* ]]
then
if [[ $i == *bin/* ]]
then
hdffprefix=${i%bin/}
# if it doesn't exist, re-set to ERROR
if [[ ! -f ${hdffprefix}include/hdf.h ]]
then
hdffprefix="ERROR"
fi
elif [[ $i == *bin* ]]
then
hdffprefix=${i%bin}
# if it doesn't exist, re-set to ERROR
if [[ ! -f ${hdffprefix}include/hdf.h ]]
then
hdffprefix="ERROR"
fi
fi
fi
done
if [[ "$hdffprefix" == "ERROR" ]]
then
echo "HDF: hdffprefix not found in PATH, trying 'which'"
WHICH_TEST_HDF=`which hdf2gif`
if [[ WHICH_TEST_HDF != "" ]]
then
hdffprefix=${WHICH_TEST_HDF%bin/hdf2gif}
else
echo "HDF: Warning - hdf not found"
fi
fi
fi
if [[ "$hdffprefix" != "ERROR" ]]
then
hdff="yes"
echo "HDF found: $hdffprefix"
fi
fi
if test $hdff = 'yes'; then
hdfincs=" -DUSE_HDF -I"${hdffprefix}"include"
scriptotherlibsinc=${scriptotherlibsinc}" -L"${hdffprefix}"/lib"
scriptotherlibs=${scriptotherlibs}" -lmfhdf -ldf -ljpeg -lz"
AC_CHECK_HEADERS([${hdffprefix}/include/hdf.h],,[AC_MSG_ERROR([Cannot find hdf.h])])
AC_CHECK_HEADERS([${hdffprefix}/include/mfhdf.h],,[AC_MSG_ERROR([Cannot find mfhdf.h])])
fi
Here's how to do it:
# We need the math library for some tests.
AC_CHECK_LIB([m], [floor], [],
[AC_MSG_ERROR([Can't find or link to the math library.])])
Note that it does not automatically error out when the library is not found, you must called AC_MSG_ERROR() as in the code above.
So you want to setup autoconf to find these directories automatically and codelogic gives the answer; but suppose you don't want to search there on all system, only on a mac. You can add the following
AC_CANONICAL_HOST
case $host_os in
darwin* )
CFLAGS="$CFLAGS -I/opt/local/include"
CXXFLAGS="$CXXFLAGS -I/opt/local/include"
LDFLAGS="$LDFLAGS -L/opt/local/lib"
;;
esac
Note that I added it as a case tree so that you can add things for a variety of operating systems later (such as linux* and BSD).
If you are happen to be using GCC or CLANG, the standard way is having the environment variable CPLUS_INCLUDE_PATH with the path of the non-official includes files and LIBRARY_PATH for the libraries. Remind that you do not have to change anything in the configure.ac. So you can just call the configure in this way:
$ export CPLUS_INCLUDE_PATH=/opt/local/include
$ export LIBRARY_PATH=/opt/local/lib
$ ./configure
The facto standard variables
Variable | lang | Usage
-------------------|------|---------
C_INCLUDE_PATH | C | colon separated list of include directory paths
CPLUS_INCLUDE_PATH | C++ | colon separated list of include directory paths
LIBRARY_PATH | C/C++| colon separated compiling time static linking dirs
LD_RUN_PATH | C/C++| colon separated compiling time dynamic linking dirs
LD_LIBRARY_PATH | C/C++| colon separated run-time dynamic linking dirs
CPPFLAGS | C/C++| prepocessor flags
CFLAGS | C | Compiling flags
CXXFLAGS | C++ | Compiling flags
LDFLAGS | C++ | Linking flags
NOTE You can use CPPFLAGS or LDFLAGS, however, CPLUS_INCLUDE_PATH /LIBRARY_PATH exactly fits your requirement. CPPFLAGS/LDFLAGS are for flags which can be many things but *_PATH are for PATHs
Portability Note: While this will work on many modern compilers, not all compilers will respect these variables. Some cross-compilers will outright ignore or overwrite them, which forces one to resort to CFLAGS and LDFLAGS modifications as mentioned in other answers.
SOURCE Might the downvotes here be because of the lack of sources in my answer. Here is for CPLUS_INCLUDE_PATH in GCC: https://gcc.gnu.org/onlinedocs/cpp/Environment-Variables.html