gcc testsuite - howto adjust spec file

Robert Connolly robert at linuxfromscratch.org
Mon Jun 15 19:36:07 PDT 2009

On Monday June 15 2009 04:18:06 pm robert baker wrote:
> I have never built a uclibc based HLFS, but this is what I came up
> with to get through the test suites without any unexpected failures on
> my glibc build.
> *cc1:
> %(cc1_cpu) %{profile:-p} %{!-fPIE:-fno-PIE}
> %{!-stack-protector:-fno-stack-protector}
> *cc1plus:
> %{!-fPIE:-fno-PIE} %{!-stack-protector:-fno-stack-protector}

Use this:
%(cc1_cpu) %{profile:-p} -fno-stack-protector -fno-PIE

-fno-stack-protector -fno-PIE

Command line options will supersede these options, so if a test uses -fPIE cc1 
will get "-fno-PIE -fPIE", and everything will be okay. There's no need for 
gcc spec rules for this application (toolchain test suites). This does make a 
mess of "gcc -v", so it's not healthy to do this without rules with the 
installed compiler.

Here's a run down of the spec language:

A % is an if statement, which is wrapped in {}'s. If it is wrapped in ()'s 
then the statement has an alias, like %(cc1_cpu). Aliases are usefull if you 
use the same statement more than once. I could use them for cc1 and cc1plus 
specs, but I don't because it makes the patch more complicated and there's no 
serious benefit.

An alias is defined like any spec:

%{something:} means "if something is true", and %{!something:} means "if 
something is not true".

The : means "then". %{something:-someoption} means "if something is true then 
pass -someoption to gcc".

A ; is an "else" statement.

A | is an "or" statement.

The leading - for the "if" options is not needed, but is needed for the "then" 

There are a few ways to handle multiple conditions. The following three rules 
all do the same thing:

%{!O: %{!O1: %{!O2: %{!O3: -O}}}}
This does "if -O is not true, then if -O1 is not true, then if -O2 is not 
true, then if -O3 is not true, then pass -O". I consider this "long hand" if 
it's used with multiple if statements, but with the simple rules it's 

%{!O*: -O}
Here the * is a wildcard.

%{O|O1|O2|O3: ; :-O}
This rule does "if -O, -O1, -O2, or -O3, then do nothing, else 
(unconditionally), pass -O". Having spaces between the :;: is not needed. I 
consider this "short hand".

I prefer the shortest rule, whatever it may be. I'm pretty sure the 
performance is the same with either style.

Here's another example of multiple conditions:
%{O3:-msse -msse2 -msse3;O2:-finline-functions}
Here we have "if -O3, then pass -msse -msse2 -msse3, else if -O2, then 
pass -finline-functions".

This gets more complicated... The above msse example is unsafe. If you 
pass "-O3 -O2", the O3 rule will match while -O2 is what finally ends up 
going to gcc, and "-O2 -msse -msse2 -msse3" is what would be used. A safer 
rule would be:
%{O2:;O3: -msse -msse2 -msse3} %{O3:;O2: -finline-functions}
Long hand this would be:
%{!O2: %{O3: -msse -msse2 -msse3}} %{!O3: %{O2: -finline-functions}}
However, if you passed "-O3 -O2" on the command line, both of these rules will 
match and fail to pass the extra options.

The gcc spec file rules search all options on the command line for matches to 
if statements, not the last option given. Something to keep in mind if you 
write complicated rules and use screwed up command line options.

The %e macro causes an error, like:
%{march=i386:%e don't use -march=i386}

%n is a notice or warning:
%{mcpu=*:-mtune=%* %n`-mcpu=' is deprecated. Use `-mtune=' or '-march=' 

%* is a macro for whatever the * wildcard turned out to be.

There are more macro's but I don't know them all. It's documented somewhere. 
Aside from that I think that covers everything you need to know about gcc 

Any questions?

-------------- next part --------------
A non-text attachment was scrubbed...
Name: not available
Type: application/pgp-signature
Size: 197 bytes
Desc: not available
URL: <http://lists.linuxfromscratch.org/pipermail/hlfs-dev/attachments/20090615/33113b41/attachment.sig>

More information about the hlfs-dev mailing list