I am trying to build a dll in C++ in which I use a C dll with prototypes like :
int __stdcall foo();.
When linking, the compiler outputs:
Warning: resolving _foo#0 by linking to _foo
Use --enable-stdcall-fixup to disable these warnings
so I added the option when linking, the command looks like:
g++ -std=c++0x -o fooLib.dll fooObj.o -lfooClib --enable-stdcall-fixup -shared
but seems like the g++ doesn't know this option:
g++.exe: error: unrecognized option '--enable-stdcall-fixup'
when I am adding only -enable-stdcall-fixup (one hyphen), it still shows the warnings (looks like has the option has no effect), and the ouput is kind weird:
g++ -std=c++0x -o fooLib.dll fooObj.o -lfooClib -enable-stdcall-fixup -shared
Warning: resolving _foo#0 by linking to _foo
Use --enable-stdcall-fixup to disable these warnings
Use --disable-stdcall-fixup to disable these fixups
ld.exe: warning: cannot find entry symbol nable-stdcall-fixup; defaulting to 679c1000
so does any body know what I am doing wrong ?
g++ --version
g++ (GCC) 4.6.1
Indeed, --enable-stdcall-fixup is not a g++ option. It's a linker option, and you can find it in the ld(1) manpage:
--enable-stdcall-fixup
--disable-stdcall-fixup
If the link finds a symbol that it cannot resolve, it will attempt
to do "fuzzy linking" by looking for another defined symbol that
differs only in the format of the symbol name (cdecl vs stdcall)
and will resolve that symbol by linking to the match. For example,
the undefined symbol "_foo" might be linked to the function
"_foo#12", or the undefined symbol "_bar#16" might be linked to the
function "_bar". When the linker does this, it prints a warning,
since it normally should have failed to link, but sometimes import
libraries generated from third-party dlls may need this feature to
be usable. If you specify --enable-stdcall-fixup, this feature is
fully enabled and warnings are not printed. If you specify
--disable-stdcall-fixup, this feature is disabled and such
mismatches are considered to be errors. [This option is specific
to the i386 PE targeted port of the linker]
gcc is able to recognize some common linker options and pass them on to ld. For example, gcc passes the -llibrary options used to link in library code directly to the linker, as well as an option -e which will be relevant below. Whenever this is the case, it's documented in the gcc(1) manpage.
As you've discovered, this is not the case with --enable-stdcall-fixup, so you'll need to explicitly pass it. In order to pass arbitrary options to the linker, gcc has -Wl. From gcc(1):
-Wl,option
Pass option as an option to the linker. [...]
So in your case, you would call
g++ -Wl,--enable-stdcall-fixup [...]
I don't have the version of the linker mentioned in the manpage, so it still comes up as an unrecognized option for me. But on your system, given that the linker is telling you to use the option, I can only assume it is the version that recognizes it.
As an aside, when you tried calling the option with only one dash, you ran into a red herring. You were actually invoking the -e gcc option that I mentioned above, with the option argument nable-stdcall-fixup. From gcc(1):
-e entry
--entry=entry
Specify that the program entry point is entry. The argument is
interpreted by the linker; the GNU linker accepts either a symbol
name or an address.
So you actually ended up passing an option to the linker saying that, when you execute your program, you want it to begin execution from a function named nable-stdcall-fixup instead of the usual main.
Related
I am using arm-none-eabi-gcc for STM32
I am trying to generate cross-reference table by passing option '--cref' to the linker, but I get this error
arm-none-eabi-gcc: error: unrecognized command line option '--cref'; did you mean '--xref'?
is '--xref' a replacement for '--cref' ?
--cref is an option for the GNU binutils linker, ld, but it is not an option of gcc
You can direct gcc to pass such options through to ld when it invokes the linker by using the the
gcc option -Wl, which has the usage:
-Wl,<ld-option>[,<ld-option>...]
So, instead of --cref, pass -Wl,--cref in your gcc commandline.
By itself, this will make the linker print the cross-reference table on the standard output. If you
would prefer to have it in a mapfile, then request a mapfile from the linker as well and the cross-reference
table will be appended to it: -Wl,--cref,-Map=mapfile
(--xref was an option for gcc long ago. It is not longer one, but the commandline
parser will still suggest it as one that you might have meant when it parses an unknown
option.)
Here is an example of makefile:
LINKFLAGS += -L./lib -lqn -Wl,-R -Wl,./lib
What exactly are the symbols '-Wl,-R' and '-Wl,./lib'?
The symbols in question have no particular meaning to make. They are just text as far as it is concerned, so their meaning depends on how they are used.
If the name "LINKFLAGS" is to be taken as indicative, however, then these will be included among the command-line arguments to link commands make runs (but this is still a question of parts of the makefile that are not in evidence). Such flags are not standardized, so the meaning is still somewhat in question.
If you happen to be using the GNU toolchain then the -Wl option to gcc and g++ assists in passing arguments through to the underlying linker, which would be consistent with the apparent intention. Appearing together as you show them, and supposing that ./lib is a directory, the effect on the GNU linker is equivalent to using its -rpath option and specifying ./lib. That would be a somewhat odd thing to do, but not altogether senseless.
Those are options for the linker (or the link step done by the compiler). You can find in the man page of gcc.
-Wl,option
Pass option as an option to the linker. If option contains commas, it is
split into multiple options at the commas. You can use this syntax to pass
an argument to the option. For example, -Wl,-Map,output.map passes
-Map output.map to the linker. When using the GNU linker, you can also get
the same effect with -Wl,-Map=output.map.
So, it is equivalent to pass the options -Rand .lib to the linker. The man page of ld stats than -R .lib is equivalent to -rpath=.lib
-rpath=dir
Add a directory to the runtime library search path. This is used when linking
an ELF executable with shared objects. All -rpath arguments are concatenated
and passed to the runtime linker, which uses them to locate shared objects at
runtime. The -rpath option is also used when locating shared objects which are
needed by shared objects explicitly included in the link; see the description
of the -rpath-link option. If -rpath is not used when linking an ELF executable,
the contents of the environment variable "LD_RUN_PATH" will be used if it is
defined.
gcc documentation indicates that -Wl is used to pass options to the linker.
gnu ld documentation and ld.so man page indicate that -R does. In summary, registering in the executable a path where shared libraries are searched when the executable is launched. The information about --enable-new-dtags and --disable-new-dtags may be also useful in understanding what happens.
The use of ./lib as argument of -R is odd, $ORIGIN is probably what is desired. Thus, with the various escape mechanisms needed,
LINKFLAGS += -L./lib -lqn -Wl,-R '-Wl,$$ORIGIN/lib'
Sorry for noobie question but I could not understand this .. what does gcc -lnsl flag do .
I tried searching over internet also read about rpc.
This flag tells gcc to link the binary with nsl library. To be more clear, the line gcc -lnsl could be rewritten to more verbose equivalent gcc -l nsl. See man gcc:
-llibrary
-l library
Search the library named library when linking. (The second
alternative with the library as a separate argument is only for
POSIX compliance and is not recommended.)
The -l option is passed directly to the linker by GCC. Refer to
your linker documentation for exact details. The general
description below applies to the GNU linker.
The linker searches a standard list of directories for the
library. The directories searched include several standard
system directories plus any that you specify with -L.
What is the right flag or order of flags to disable treating particular warning as error in GCC? I want to do that for -Wimplicit-interface.
>cat test.f90
call s
end
> gfortran -c -Werror -Wimplicit-interface -Wno-error=implicit-interface test.f90 -o test.o
test.f90:1.7:
call s
1
Warning: Procedure 's' called with an implicit interface at (1)
>ls test*
test.f90
No test.o was generated.
Without -Werror it works
> gfortran -c -Wimplicit-interface -Wno-error=implicit-interface test.f90 -o test.o
test.f90:1.7:
call s
1
Warning: Procedure 's' called with an implicit interface at (1)
> ls test*
test.f90 test.o
GCC version is gcc version 4.9.2 20141030 (Cray Inc.) (GCC).
This is not an explicit answer to the question. I found it educative enough and too long to be put as comment.
As you just found, you might not be able to achieve what you want if you combine -Werror and -Wno-error=implicit-interface. Let me explain: as opposed to what we have in the doc, especially the following sentence,
The combined effect of positive and negative forms is that more specific options have priority over less specific ones, independently of their position in the command-line.
It seems that it is not the case in the actual implementation. I had a similar problem recently, and by googling, I found this which contains this sentence:
'-w' permanently sets all warnings off no matter what specific warning is set on
It actually suggests that by using some non specific options, the actual implementation does not allow you to change specific option included in the non specific one.
As #innoSPG points out, the actual behaviour does not conform to what is claimed in the manual.
The comment by #MarkGlisse revealed that this have changed with GCC 5. Therefore it was probably a bug.
The solution is therefore to use the recent version, or to not use one of the -Werror and -Wimplicit-interface.
Or to really provide explicit interfaces everywhere, but that can be problematic, as MPI libraries differ in the amount of explicit interfaces provided in the mpi modules.
GCC can get pretty picky about the order in which it accepts its arguments:
# Works.
g++ Foo.cpp -L. -I. -lBar -o Foo
# Linker errors.
g++ -o Foo -I. -L. -lBar Foo.cpp
What, specifically, are the ordering requirements for command-line options?
Libraries are loaded on demand based on the symbols required from them, so the library which provides a symbol needed by something else must follow that something else. This is historical; arguably a modern system should resolve symbols automatically, handling loops sensibly (that being the reason for the rule; you broke dependency cycles manually by specifying libraries in order and as many times as needed), but g++ follows the traditional rule so it will work with vendor lds. (GNU ld doesn't work everywhere, so it wouldn't be possible to rely on it to resolve symbol dependency loops. There are also bootstrapping concerns even on platforms where GNU ld does work.) Similarly, other linker-oriented options must be specified in the correct order relative to the things they affect (for example, a -L option must precede a library which lives in the specified directory; this can be important if a library in one directory shadows a library of the same name in a standard directory).