MinGW gcc unrecognized command line option '-Wl'/'Wa'/'Wp' - gcc

In short, I have the most recent version of MinGW and I am attempting to pass options into the linker and the like.
For example, I wanted to change the stack size by:
gcc -Wl,--stack,[new size in bytes]
But it recognized neither -Wl nor --stack. And that applies for the other options too.
I'm able to compile my programs all well in good, it just seems as though I cannot use the various gcc options.
Is this an issue with MinGW, or am I overlooking something more?

I just confirmed in the documentation about passing arguments to linker, that you cannot have a space before the number, so it should be:
gcc -Wl,--stack,[new size in bytes]
Commas are changed into spaces, but a real space makes the next option gcc option, not linker option.

Related

Use --enable-stdcall-fixup to disable these warnings

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.

what do the symbols 'Wl,-R' and '-Wl,./lib' mean in makefile?

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'

Is there a method to make `gcc' dump/display all the flags in use while compiling code?

Do note this is different from
Get the compiler options from a compiled executable? which I did go through in detail.
Although -frecord-gcc-switches is great, it only captures the command line arguments.
For example, I am not interested in capturing -O2 which is usually passed in command line. I am more curious about recording all the flags like -fauto-inc-dec which are enabled by -O2.
(In contrast to the link above, do note that I have access to the source, the compiler and the build infrastructure. I just want to capture the flags during compilation. Not picky about any specific gcc version)
You can try -fverbose-asm. That dumps the optimisation options used in a comment at the top of the assembly file.

unrecognized -a option `ck_size'

I am using GCC ver-4.6.4 (both in Mac and Linux Mint 15) to compile a code I do for research.
The command I am using is :
gfortran -O2 -fopenmp -Wl,-stack_size,1000000 <...Lots of files...> -o a.out
, where I omit the actual file names.
This code compiles OK in Mac, however I get the following error in Mint:
/usr/bin/ld: unrecognized -a option `ck_size'
collect2: error: ld returned 1 exit status
make[1]: *** [a.out] Error 1
In Mint, this will compile if I do not use any flags at all, therefore this problem is related to OpenMP.
However, I do need OpenMP and do not understand what it says in the error, because I do not have 'ck_size'. BTW, deleting -O2 doesn't help.
The problem is not related to OpenMP, it is related to your different OS's.
-stack_size is specific to Macintosh and refers to the maximal size of arrays on the stack. Linux changes the stack size via the terminal command ulimit (to check your Mint settings type, ulimit -a to see everything, the stack size can be seen with ulimit -s, see the ulimit man page for more information).
Thus, you need to scrap that whole -stack_size,100000 portion from your compiler flag, it means nothing in Linux.
You passed -Wl,-stack_size,1000000 to gfortran, which is passing on the option "-stack_size 1000000" to the linker ld. It is interpreting "st" as single letter options "-s" and "-t", then reading the next letter as an option "-a", and the rest of the word ("ck_size") as its parameter.
I could find no reference to a -stack_size option for ld. It looks like the option is --stack, so you need to put something like -Wl,--stack,1000000 instead.

How to make gcc uses march=native as default?

Is there a way to change the specs file so that it will pass -march=native if nothing is specified in command line?
Related things in the default specs file is:
*cc1:
%(cc1_cpu)
*cc1_cpu:
%{march=native:%>march=native %:local_cpu_detect(arch) %{!mtune=*:%>mtune=native %:local_cpu_detect(tune)}} %{mtune=native:%>mtune=native %:local_cpu_detect(tune)}
I am not sure how specs works. Simply specifying -march=native before or after %(cc1_cpu) doesn't work. However, this line does take effect because GCC will report error if I put -something_wierd instead of -march=native.
Another thing I noticed is if I put %{march=i386:-something_wierd} before %(cc1_cpu), gcc reports error so looks like -march=i386 is always passed in if nothing is specified, so is there a way to distinguish between nothing specified and -march=i386 in specs file?
BTW, what does %> do? Seems like it is not specified in the documentation.
I am using MinGW's gcc-4.6.2.
Referring to your last question: The gcc 4.6.1 sources (gcc/gcc.c) contain the following comment on %>:
%>S Similar to "%<S", but keep it in the GCC command line.
For the sake of completeness following the comment for %< form the same file:
%<S remove all occurrences of -S from the command line.
Note - this command is position dependent. % commands in the
spec string before this one will see -S, % commands in the
spec string after this one will not.
To answer the first question in short: yes, but ....
... the only generic solution I found has the significant drawback that the -march option will be ignored, so every build is done as if -march=native had been specified. Anyhow there is a workaround to that.
1 The solution (without workaround)
Create a specs-file called let's say specs.nativealways containing:
*cc1_cpu:
%<march=* -march=native %>march=native %:local_cpu_detect(arch) %{!mtune=*:%>mtune=native %:local_cpu_detect(tune)} %{mtune=native:%>mtune=native %:local_cpu_detect(tune)}
When using the specs-file (for example by invoking gcc with the option -specs=specs.nativealways) the build will be done as if -march=native was specified (with the mentioned drawback that any occurrence of option -march=<arch> would have simply been ignored).
2 The workaround
To still by able to override the newly configured default behavior one can use a modified version of the specs-file described above, introducing a new option called -myarch using the same syntax as -march (except for -myarch=native, which won't work, which does not metter as native now is the default).
The modfied specs-file looks like this:
*cc1_cpu:
%<march=* %{myarch=*:%<myarch* -march=%* ; :-march=native %>march=native %:local_cpu_detect(arch) %{!mtune=*:%>mtune=native %:local_cpu_detect(tune)}} %{mtune=native:%>mtune=native %:local_cpu_detect(tune)}
PS: This has been tested with with gcc 4.6.2 on Linux, but should work on MinGW.
While not a direct answer to your question, you can reach a very similar effect by defining CFLAGS and CXXFLAGS in your shell's initialization file. 99% of the Makefiles are sufficiently standard to pick up the environment values and pass the flags to gcc.
*cc1_cpu:
+ %{!march*:-march=native}

Resources