Related
There is a macro to add a new symbol into the resulting config.h file from a configuration file. This allows you to check the system and enable options in C/C++ applications. There are two types of macros: adding a dynamic symbol and a fixed symbol. By using AC_DEFINE_UNQUOTED, which is a macro to add a dynamic symbol, it is possible to set a symbol where the name or value is from a variable.
Here is my simple configure.ac file
name="test"
AC_DEFINE_UNQUOTED([USE_${name}], [1], [Enable test usage])
I expecte that USE_test be added into config.h as C/C++ definistion. However, the difinistion does not exist in the result config.h file.
By running Autotools there is the following line in configure.status:
D["USE_test"]=" 1"
This means Autotools will search the config.h.in to replace the USE_test with the new value.
But the generated config.h.in file does not contain the following definition:
#define Use_test 1
So Autoheader does not run correctly?! And it is not possible to add a variable text as a symbol to config.h?!
Where is the problem or is it possible to add a symbol with a variable name by configure.ac?
But the final config.h file does not contain the following definition
[...] config.h.in is generated dynamically and it does not contain the
definition too.
The latter is actually the key issue. When you use AC_CONFIG_HEADERS to request that definitions be recorded in a header file instead of being expressed via compiler command-line options, Autoconf handles it by processing one or more header templates, such as config.h.in, to produce the resulting header(s). The autoconf command does not produce these templates itself, however. You can write them by hand if you wish, but a separate program, autoheader, is available to perform this job, and autoreconf (not autoconf) automatically runs autoheader to generate a template for the first header named in the first AC_CONFIG_HEADERS call.
The behavior you describe is a longtime known issue (not accounted a bug, per se), which you can find discussed in the archives of the bug-autoconf mailing list. The resolution was a documentation change, whose result you can still see in the section of the Autoconf manual that discusses Autoheader:
In order to do its job, autoheader needs you to document all of the
symbols that you might use. Typically this is done via an AC_DEFINE
or AC_DEFINE_UNQUOTED call whose first argument is a literal
symbol and whose third argument describes the symbol (see Defining
Symbols).
(Emphasis added.)
This indeed seems to be the technically appropriate place for those details. That is, AC_DEFINE_UNQUOTED does behave as advertised, as can be seen by disabling AC_CONFIG_HEADERS (a viable workaround under many circumstances), or by employing one of the alternatives the docs go on to suggest:
you can use AH_TEMPLATE (see Autoheader
Macros), or you can supply a suitable input file for a subsequent
configuration header file. Symbols defined by Autoconf's builtin tests
are already documented properly; you need to document only those that
you define yourself.
If you were to argue that it would have been nice for that issue to be mentioned in the AC_DEFINE_UNQUOTED docs, too, then I would fully agree with you. But I do also think that the situation is considerably different now than when the doc change was first put in, on account of the introduction and rise to prevalence of autoreconf, which hides the involvement of autoheader from most users.
In any case, I'll ignore the "supply your own template" option, which is a bit fraught, and focus on AH_TEMPLATE. To use it to support the particular case presented in the question, one would add something along these lines to configure.ac:
AH_TEMPLATE([USE_test], [Define to 1 to use test])
Perhaps you ask "What's the point then? I might as well use a regular AC_DEFINE." That's a good question, to which you should indeed give careful consideration. Note well that there is no point to defining arbitrary preprocessor macros, as only those corresponding to symbols appearing in one or more of your sources will ever be expanded. That does not necessarily make configure-time macro name generation useless, but it does mean that when maintaining configure.ac, you can and should have a complete list of all the generated macro names that need to be supported. In that case, it is indeed plausible that you might write appropriate AH_TEMPLATE invocations for all the needed cases. Under most circumstances, however, going straight to (conditional) AC_DEFINEs for each symbol is probably a better choice.
I am using ARM-GCC v4.9 (released 2015-06-23) for a STM32F105RC processor.
I've searched stackoverflow.com and I've found this in order to try to convince gcc not to optimize out a global variable, as you may see below:
static const char AppVersion[] __attribute__((used)) = "v3.05/10.oct.2015";
Yet, to my real surprise, the compiler optimized away the AppVersion variable!
BTW: I am using the optimize level -O0 (default).
I also tried using volatile keyword (as suggested on other thread), but it didn't work either :(
I already tried (void)AppVersion; but it doesn't work...
Smart compiler!? Too smart I suppose...
In the meantime, I use a printf(AppVersion); some place in my code, just to be able to keep the version... But this is a boorish solution :(
So, the question is: Is there any other trick that does the job, i.e. keep the version from being optimized away by GCC?
[EDIT]:
I also tried like this (i.e. without static):
const char AppVersion[] __attribute__((used)) = "v3.05/10.oct.2015";
... and it didn't work either :(
Unfortunately I am not aware of a pragma to do this.
There is however another solution. Change AppVersion to:
static char * AppVersion = "v3.05/10.oct.2015";
and add:
__asm__ ("" : : "" (AppVersion));
to your main function.
You see I dropped the 'used' attribute, according to the documentation this is a function attribute.
Other solutions: Does gcc have any options to add version info in ELF binary file?
Though I found this one to be the easiest. This basically won't let the compiler and linker remove AppVersion since we told it that this piece of inline assembly uses it, even though we don't actually insert any inline assembly.
Hopefully that will be satisfactory to you.
Author: Andre Simoes Dias Vieira
Original link: https://answers.launchpad.net/gcc-arm-embedded/+question/280104
Given the presence of "static", all your declaration does is ask the compiler to include the bytes representing characters of the string "v3.05/10.oct.2015" in
some order at some arbitrary location within the file, but not bother to tell
anyone where it put them. Given that the compiler could legitimately write
that sequence of bytes somewhere in the code image file whether or not it
appeared anywhere in the code such a declaration really isn't very useful. To
be sure, it would be unlikely that such a sequence would appear in the code
entirely by chance, and so scanning the binary image for it might be a somewhat
reliable way to determine that it appeared in the code, but in general it's
much better to have some means of affirmatively determining where the string
may be found.
If the string isn't declared static, then the compiler is required to tell the
linker where it is. Since the linker generally outputs the names and
addresses of all symbols in a variety of places including symbol tables,
debug-information files, etc. which may be used in a variety of ways that the
linker knows nothing about, it may be able to tell that a symbol isn't used
within the code, but can generally have no clue about whether some other
utility may be expecting to find it in the symbol table and make use of it. A directive saying the symbol is "used" will tell the linker that even though it doesn't know of anything that's interested in that symbol, something out in the larger universe the linker knows nothing about is interested in it.
It's typical for each compilation unit to give a blob of information to the
linker and say "Here's some stuff; I need a symbol for the start of it, but
I can compute all the addresses of all the internals from that". The linker
has no way of knowing which parts of such a blob are actually used, so it
has no choice but to accept the whole thing verbatim. If the compiler were
to include unused static declarations in its blob, they'd make it through
to the output file. On the other hand, the compiler knows that if it doesn't
export a symbol for something within that blob, nobody else downstream would
be able to find it whether or not the object was included; thus, there would
typically be little benefit to being able to include such a blob and compiler writers generally have to reason to provide a feature to force such inclusion.
It seems that using a custom section also works.
Instead of
__attribute__((used))
try with
__attribute__((section(".your.section.name.here")))
The linker won't touch it, nor will the strip command.
i've been working for some time with an opensource library ("fast artificial neural network"). I'm using it's source in my static library. When i compile it however, i get hundreds of linker warnings which are probably caused by the fact that the library includes it's *.c files in other *.c files (as i'm only including some headers i need and i did not touch the code of the lib itself).
My question: Is there a good reason why the developers of the library used this approach, which is strongly discouraged? (Or at least i've been told all my life that this is bad and from my own experience i believe it IS bad). Or is it just bad design and there is no gain in this approach?
I'm aware of this related question but it does not answer my question. I'm looking for reasons that might justify this.
A bonus question: Is there a way how to fix this without touching the library code too much? I have a lot of work of my own and don't want to create more ;)
As far as I see (grep '#include .*\.c'), they only do this in doublefann.c, fixedfann.c, and floatfann.c, and each time include the reason:
/* Easy way to allow for build of multiple binaries */
This exact use of the preprocessor for simple copy-pasting is indeed the only valid use of including implementation (*.c) files, and relatively rare. (If you want to include some code for another reason, just give it a different name, like *.h or *.inc.) An alternative is to specify configuration in macros given to the compiler (e.g. -DFANN_DOUBLE, -DFANN_FIXED, or -DFANN_FLOAT), but they didn't use this method. (Each approach has drawbacks, so I'm not saying they're necessarily wrong, I'd have to look at that project in depth to determine that.)
They provide makefiles and MSVS projects which should already not link doublefann.o (from doublefann.c) with either fann.o (from fann.c) or fixedfann.o (from fixedfann.c) and so on, and either their files are screwed up or something similar has gone wrong.
Did you try to create a project from scratch (or use your existing project) and add all the files to it? If you did, what is happening is each implementation file is being compiled independently and the resulting object files contain conflicting definitions. This is the standard way to deal with implementation files and many tools assume it. The only possible solution is to fix the project settings to not link these together. (Okay, you could drastically change their source too, but that's not really a solution.)
While you're at it, if you continue without using their project settings, you can likely skip compiling fann.c, et. al. and possibly just removing those from the project is enough – then they won't be compiled and linked. You'll want to choose exactly one of double-/fixed-/floatfann to use, otherwise you'll get the same link errors. (I haven't looked at their instructions, but would not be surprised to see this summary explained a bit more in-depth there.)
Including C/C++ code leads to all the code being stuck together in one translation unit. With a good compiler, this can lead to a massive speed boost (as stuff can be inlined and function calls optimized away).
If actual code is going to be included like this, though, it should have static in most of its declarations, or it will cause the warnings you're seeing.
If you ever declare a single global variable or function in that .c file, it cannot be included in two places which both compile to the same binary, or the two definitions will collide. If it is included in even one place, it cannot also be compiled on its own while still being linked into the same binary as its user.
If the file is only included in one place, why not just make it a discrete compilation unit (and use its globals via extern declarations)? Why bother having it included at all?
If your C files declare no global variables or functions, they are header files and should be named as such.
Therefore, by exhaustive search, I can say that the only time you would ever potentially want to include C files is if the same C code is used in building multiple different binaries. And even there, you're increasing your compile time for no real gain.
This is assuming that functions which should be inlined are marked inline and that you have a decent compiler and linker.
I don't know of a quick way to fix this.
I don't know that library, but as you describe it, it is either bad practice or your understanding of how to use it is not good enough.
A C project that wants to be included by others should always provide well structured .h files for others and then the compiled library for linking. If it wants to include function definitions in header files it should either mark them as static (old fashioned) or as inline (possible since C99).
I haven't looked at the code, but it's possible that the .c or .cpp files being included actually contain code that works in a header. For example, a template or an inline function. If that is the case, then the warnings would be spurious.
I'm doing this at the moment at home because I'm a relative newcomer to C++ on Linux and don't want to get bogged down in difficulties with the linker. But I wouldn't recommend it for proper work.
(I also once had to include a header.dat into a C++ program, because Rational Rose didn't allow headers to be part of the issued software and we needed that particular source file on the running system (for arcane reasons).)
Any idea about this error?
gcc -oxtmpmain.exe xtmpmain.o fiber_driver.o xtmp_options.o getopt.o D:\usr\xtensa\XtDevToolsDE\in
stall\tools\RB-2008.4-win32\XtensaTools\lib\iss\xtmp.lib
xtmpmain.o(.text+0x213):xtmpmain.c: undefined reference to `_uart_setup'
xtmpmain.o(.text+0x2da):xtmpmain.c: undefined reference to `_uart_cleanup'
collect2: ld returned 1 exit status
make: *** [xtmpmain.exe] Error 1
This is a plain linking error. You're calling two functions, uart_setup() and uart_cleanup(), that the linker is not finding.
There might be several causes, including (but certainly not limited to):
They really are missing, perhaps you forgot to link against one object file
Namespacing preventing the existing function from being found
Library paths
Marshalling or problems with external names and underscores
Without more detail, it's hard to tell for sure.
It means that xtmpmain.c called functions named uart_setup() and uart_cleanup(), but they weren't found by the linker. You probably need to include a library, or to implement those functions for Windows in terms of the Win32 API.
Some "is it plugged in questions" are:
Are the functions declared?
Are the functions defined (i.e. implemented)?
With exactly those names?
Were those definitions excluded by the preprocessor?
There is a gcc option that controls the presence or absence of a leading underscore. You didn't accidentally use that for one file and not others, right?
Verify the declared calling convention. __cdecl and __stdcall are very different animals. They usually produce mismatched exported symbol names for safety, and this error can be a symptom of that.
If this is a porting project, then it is likely that the original implementation of a UART-related function is written in a platform-dependent way. In that case, they often would be guarded by a #ifdef of some form that depends on the compile-time platform.
To resolve that, you would need to implement them for this platform, in a style consistent with their usage in the rest of the application, and similarly guarded.
Shouldn't be hard, right? Right?
I am currently trawling the OpenAFS codebase to find the header definition of pioctl. I've thrown everything I've got at it: checked ctags, grepped the source code for pioctl, etc. The closest I've got to a lead is the fact that there's a file pioctl_nt.h that contains the definition, except it's not actually what I want because none of the userspace code directly includes it, and it's Windows specific.
Now, I'm not expecting you to go and download the OpenAFS codebase and find the header file for me. I am curious, though: what are your techniques for finding the header file you need when everything else fails? What are the worst case scenarios that could cause a grep for pioctl in the codebase to not actually come up with anything that looks like a function definition?
I should also note that I have access to two independent userspace programs that have done it properly, so in theory I could do an O(n) search for the function. But none of the header files pop out to me, and n is large...
Edit: The immediate issue has been resolved: pioctl() is defined implicitly, as shown by this:
AFS.xs:2796: error: implicit declaration of function ‘pioctl’
If grep -r and ctags are failing, then it's probably being defined as the result of some nasty macro(s). You can try making the simplest possible file that calls pioctl() and compiles successfully, and then preprocessing it to see what happens:
gcc -E test.c -o test.i
grep pioctl -C10 test.i
There are compiler options to show the preprocessor output. Try those? In a horrible pinch where my head was completely empty of any possible definition the -E option (in most c compilers) does nothing but spew out the the preprocessed code.
Per requested information: Normally I just capture a compile of the file in question as it is output on the screen do a quick copy and paste and put the -E right after the compiler invocation. The result will spew preprocessor output to the screen so redirect it to a file. Look through that file as all of the macros and silly things are already taken care of.
Worst case scenarios:
K&R style prototypes
Macros are hiding the definition
Implicit Declaration (per your answer)
Have you considered using cscope (available from SourceForge)?
I use it on some fairly significant code sets (25,000+ files, ranging up to about 20,000 lines in a file) with good success. It takes a while to derive the file list (5-10 minutes) and longer (20-30 minutes) to build the cross-reference on an ancient Sun E450, but I find the results useful.
On an almost equally ancient Mac (dual 1GHz PPC 32-bit processors), cscope run on the OpenAFS (1.5.59) source code comes up with quite a lot of places where the function is declared, sometimes inline in code, sometimes in headers. It took a few minutes to scan the 4949 files, generating a 58 MB cscope.out file.
openafs-1.5.59/src/sys/sys_prototypes.h
openafs-1.5.59/src/aklog/aklog_main.c (along with comment "Why doesn't AFS provide these prototypes?")
openafs-1.5.59/src/sys/pioctl_nt.h
openafs-1.5.59/src/auth/ktc.c includes a define for PIOCTL
openafs-1.5.59/src/sys/pioctl_nt.c provides an implementation of it
openafs-1.5.59/src/sys/rmtsysc.c provides an implementation of it (and sometimes afs_pioctl() instead)
The rest of the 184 instances found seem to be uses of the function, or documentation references, or release notes, change logs, and the like.
The current working theory that we've decided on, after poking at the preprocessor and not finding anything either, is that OpenAFS is letting the compiler infer the prototype of the function, since it returns an integer and takes pointer, integer, pointer, integer as its parameters. I'll be dealing with this by merely defining it myself.
Edit: Excellent! I've found the smoking gun:
AFS.xs:2796: error: implicit declaration of function ‘pioctl’
While the original general question has been answered, if anyone arrives at this page wondering where to find a header file that defines pioctl:
In current releases of OpenAFS (1.6.7), a protoype for pioctl is defined in sys_prototypes.h. But that the time that this question was originally asked, that file did not exist, and there was no prototype for pioctl visible from outside the OpenAFS code tree.
However, most users of pioctl probably want, or are at least okay with using, lpioctl ("local" pioctl), which always issues a syscall on the local machine. There is a prototype for this in afssyscalls.h (and these days, also sys_prototypes.h).
The easiest option these days, though, is just to use libkopenafs. For that, include kopenafs.h, use the function k_pioctl, and link against -lkopenafs. That tends to be a much more convenient interface than trying to link with OpenAFS libsys and other stuff.
Doesn't it usually say in the man page synopsis?