Is there a way for Autotools to test a given function is deprecated in GNU libc?
I've been using AC_CHECK_FUNCS(readdir_r) to test whether a system has readdir_r() or not. But now, since GNU Libc 2.24, readdir_r() is deprecated, I'd like to use readdir() on those system.
Does autoconf have a macro to test a give function is deprecated or not? If not, what is the best way to handle this?
I know that newer GCC with -Wdeprecated-declarations prints a warning. But what I'm looking for is to find deprecated function at configure time so that I can use the recommended function instead.
Not easily, because AC_CHECK_FUNCS checks whether the function is available at link time. What you could do would be to use attribute.m4 (as shipped with, say, systemd), use CC_CHECK_WERROR, CC_CHECK_FLAGS_APPEND with -Wdeprecated-declarations and then use AC_COMPILE_IFELSE to figure out whether the whole thing compiles.
Related
Normally, I would compile a program that requires a specific library, e.g. math, by passing the linker flag after the sources that need it like so:
gcc foo.c -lm
However, it seems that older versions of gcc work equally well with the reverse order (let's call this BAD ORDER):
gcc -lm foo.c
I wouldn't worry about it if some popular open-source projects I'm trying to compile didn't use the latter while my version of gcc (or is it ld that's the problem?) work only in the former case (also, the correct one in my opinion).
My question is: when did the BAD ORDER stop working and why? It seems that not supporting it breaks legacy packages.
when did the BAD ORDER stop working and why? It seems that not supporting it breaks legacy packages.
When?
Not dead sure but I think pre-GCC 4.5. Long ago. Subsequently, the --as-needed option is operative for shared libraries by default,
so like static libraries, they must occur in the linkage sequence later than the objects for which they provide definitions.
This is a change in the default options that the gcc/g++/gfortran etc. tool-driver passes to ld.
Why?
It was considered confusing to inexpert users that static libraries by default has to appear
later that the objects to which they provided definitions while shared libraries by default did
not - the difference between the two typically being concealed by the -l<name> convention
for linking either libname.a or libname.so.
It was perhaps an unforeseen consequence that inexpert users who
had formerly had a lot of luck with the mistaken belief that a GCC
[compile and] link command conforms to the normal Unix pattern:
command [OPTION...] FILE [FILE...]
e.g.
gcc -lthis -lthat -o prog foo.o bar.o
now fare much worse with it.
For an embedded project (bare-metal) I need to use memc** functions.Though I haven't
disable the builtin functions I always get a linker error; e.g:
undefined reference to `memcmp'
no matter if I use: memcmp or __builtin_memcmp!
Is there anything I missed to enable the builtins?
My compile options are: -g -Wall -mcpu=cortex-a9
__builtin is a bit of a lie. It will optionally use a built-in implementation, if it exists. Otherwise it will call the library functions. You will need to provide implementations of these functions, either in your own code or in a C library. Note that "a C library" doesn't mean a full OS libc, there are plenty of bare metal C libraries that don't include OS-dependent functions.
The GCC docs at http://gcc.gnu.org/onlinedocs/gcc/C-Dialect-Options.html say (under -ffreestanding) that a freestanding environment implies -fno-builtin. I might be misunderstanding exactly what a freestanding environment is or how it works, but it seems to me that, since the builtins usually emit inline code instead of calling the library function, this is ideal for a freestanding environment where the standard library may be missing functionality or even missing entirely.
So why would we not want to use the biltins with a freestanding environment?
In freestanding mode the compiler can not rely on semantical considerations.
Most builtins in GCC work silently -- for instance the compiler sees that you are using strcpy() and in hosted mode it may guess that, when you are using strcpy(), you are intending exactly to copy a string. Then it may replace strcpy with an extensionally equivalent builtin, which is better for the given target to copy a string.
In freestanding mode, using strcpy() function means ANYTHING. The idea is just not the standard library absence in linkage. The idea of freestanding mode is that there is no standard library even on definition level, except float.h, iso646.h, limits.h, stdarg.h, stdbool.h, stddef.h, stdint.h (C99 standard 4.6). You may in freestanding mode decide to format your hard drive with strcpy, and this is perfectly legal for the C language. The compiler thus don't know how to use builtins, and it declines to use them at all.
Is there a site listing the various platforms and their support for GCC's atomic built-ins, for the various GCC versions?
EDIT:
To be more clear:
GCC adds _sync... as intrinsics on platforms it contains support for. On all other platforms it keeps those as normal functions declarations but does not supply an implementation. This must be done by some framework.
So the question is: For which platforms does GCC supply which intrinsics without need to add a function implementation?
I'm not aware if there's such a list, however http://gcc.gnu.org/projects/cxx0x.html says atomics are supported since GCC 4.4.
GCC libstdc++ implements <atomic> on top of the builtin functions `__sync_fetch_and_add' and friends ( http://gcc.gnu.org/onlinedocs/gcc-4.6.1/gcc/Atomic-Builtins.html ).
These functions are expanded either using machine specific expanders in the machine description of the target (usually in a file named `sync.md') or, lacking such expanders, using a CAS loop. If the presense of `sync.md' file is any indication for a proper atomics support, then you can count in MIPS, i386, ARM, BlackFin, Alpha, PowerPC, IA64 and Sparc.
[Though this is an old question, I thought I should update and complete the answer]
I am not aware of a per-architecture-version and per-gcc-version table, describing supported built-ins.
The __sync built-in functions of gcc exist since version 4.1 (see, e.g., gcc 4.1.2 manual. As stated there:
Not all operations are supported by all target processors. If a particular operation cannot be implemented on the target processor, a warning will be generated and a call an external function will be generated. The external function will carry the same name as the builtin, with an additional suffix `_n' where n is the size of the data type.
So, when there is not an implementation for a specific architecture, a compilation warning will appear and, I guess, a link-time error, unless you provide the required function with the appropriate name.
After gcc 4.7 there are also __atomic built-ins and __sync built-ins are deprecated.
For example, see how Fedora uses gcc __sync and __atomic here
I don't know how feasible it is and how sensible is this question here.
Is there any changes that we can make in makefile to recommend GCC inline all the function although the functions are not inlined during the declaration or nowhere in the source file.
There are a few ways you can make gcc inline functions. One of them is the option -finline-functions, which will make gcc inline "simple" functions. The compiler uses some heuristics to determine whether the function is small enough to be inlined. However, the user has some control over this algorithm through -finline-limit. Read the gcc manual to find the actual values you need.
When inlining functions you should remember that obviously not all functions can be inlined (the simplest example being recursive functions) and the compiler can inline only functions defined within the same translation unit. Also, it is worth mentioning that -finline-functions is on by default at -O3, so just -O3 may sometimes be your solution.
In the makefile you will have to add the right options to all calls to gcc. In a well written makefile you'll easily spot variables with other gcc options, where you can simply place your own.
The gcc -finline_functions option sounds like it might do what you want. Here is some documentation. If your makefile defines a CFLAGS variable, that would be the place to put it.