ps3 spu/ppu toolchain.

Added by Kevin Thacker about 5 years ago

We have a spu job which compiles down to a spu elf executable.
(A C.Application using spu toolchain)

We then convert this to a ppu obj (as a postbuild step).

We then need to link against this obj with our main app.
Our main app is a ppu application.

In each jamfile we choose the toolchain with:

C.ToolChain $(PLATFORM) $(CONFIG) $(TOOLCHAIN) ;

at the top of the file.
We need to re-define some include dirs and defines because they seem to get lost in the switch. (Previously defined with C.IncludeDirectories * and C.Defines * ).

We then do the appropiate adding of files and setting up libraries. In the case of spu it does a c.application to make the output.

These jam files are included from others.

So our jam files are a mix of spu and ppu, all driven from a main jam file.

The basic problem is:
1. how do I define that an output from the spu toolchain is a dependency of the ppu toolchain?
2. how do I get the ppu toolchain to see our spu toolchain file?

What hints and tips are there for mixing of toolchains like this?


Replies (9)

RE: ps3 spu/ppu toolchain. - Added by Joshua Jensen about 5 years ago

Does the samples/fakeps3 code show you what you need, or do you need additional details?

Each toolchain has its own set of include directories and defines and other settings. I can go into detail about the reasons why, if you'd like, until I can get it properly documented.

-Josh

RE: ps3 spu/ppu toolchain. - Added by Kevin Thacker about 5 years ago

Joshua Jensen wrote:

Does the samples/fakeps3 code show you what you need, or do you need additional details?

Each toolchain has its own set of include directories and defines and other settings. I can go into detail about the reasons why, if you'd like, until I can get it properly documented.

-Josh

Looking at it, yes it does. The C.Library or C.Application (can't remember which it is, and I don't have the code with me) returns a variable which I can use in C.LinkLibraries.

Is there another rule I can use to get the same value that the variable returns so I can access it from another jam script.

e.g.

mainjam.jam:

SubIncludeRelative spuLib ;

C.Toolchain $(MY_APP) : ppu ;

C.LinkLibraries $(MY_APP) : [ OtherToolChain spuLib ] ;

spuLib.jam:

C.Toolchain $(MY_APP) : spu ;

C.Library spuLib : .... ;

Here i don't remember the return value of C.Library. I use the "OtherToolChain" rule to fetch the same value, but from another jam file.

This would help me to keep the jam files more generic and maintainable.

I couldn't work out the necessary jam instructions to make this rule.

RE: ps3 spu/ppu toolchain. - Added by Joshua Jensen about 5 years ago

With the latest pushed Git code, you can do:

C.LinkLibraries $(MY_APP) : [ C.GetLinkTargets spuLib : spu ] ;

Documentation was updated to reflect this new rule.

RE: ps3 spu/ppu toolchain. - Added by Kevin Thacker about 5 years ago

Ok I think I've found another problem.

I have setup a ps3-spu toolchain and a ps3-ppu toolchain.

Each has their own C++, Archive, CC, Link, FDefines, FIncludes, FLibraryPaths rules. Each has their own library include paths etc.

When I build a spu exe on it's own, everything is fine. exe is generated and then an obj is generated from the exe. All is good.
When I build a ppu exe on it's own, everything is fine too.

So seperately the toolchains work good.

But when I build a ppu exe which links to an obj generated as the result of a spu exe, it doesn't work correctly.

The spu version of the C++ is called correctly for each cpp file. e.g. C.ps3-spu.C++ is seen when building ps3 cpp files.
I see the correct ppu rule for c++ being called for the ppu files.

But when it goes to do a link for the spu app, it chooses the c.ps3-ppu.Link rule instead. The result is that the ppu obj from the spu exe is never generated and the link fails.

I think the fakeps3 example doesn't highlight this because both fake ppu and fake spu use the vc compiler internally, and uses the same rules.

Another problem I've seen is that if I specify:

Includes and defines for * target.

C.Defines * : MY_GLOBAL_DEFINE ;

which is meant to be common to both ppu/spu, it gets "cleared" when I switch tool chains. This may be the correct operation here, but it suprised me.

RE: ps3 spu/ppu toolchain. - Added by Kevin Thacker about 5 years ago

Switching back and forth between toolchains seems to be a problem and this is exactly what I do.

RE: ps3 spu/ppu toolchain. - Added by Kevin Thacker about 5 years ago

Kevin Thacker wrote:

Switching back and forth between toolchains seems to be a problem and this is exactly what I do.

And here is the fix:

in rule C.Toolchain TOOLCHAIN_SPEC {

which is in c-autodetect.jam

add this line:
C.COMPILER_SUITE on $(gristedConfigSpec) = $(C.COMPILER_SUITE) ;
before/after:
C.COMPILER_SUITE_SYMBOL on $(gristedConfigSpec) = $(C.COMPILER_SUITE_SYMBOL) ;

then at the end of the function add this:
C.COMPILER_SUITE = $(C.COMPILER_SUITE:Z=$(gristedConfigSpec)) ;
before/after:
C.COMPILER_SUITE_SYMBOL = $(C.COMPILER_SUITE_SYMBOL:Z=$(gristedConfigSpec)) ;

you can now switch back and forth between toolchains and the c.application link now works correctly.

RE: ps3 spu/ppu toolchain. - Added by Joshua Jensen about 5 years ago

Your fix was half of the problem. I incorporated it and solved the other half in the same commit: 55d4cab7df055af7f8105729d3a4ad30db42ff9d

I have updated the fakeps3 sample to account for this behavior. One day, I'll get it into the test suite.

Thank you!

RE: ps3 spu/ppu toolchain. - Added by Joshua Jensen about 5 years ago

Kevin Thacker wrote:

Another problem I've seen is that if I specify:

Includes and defines for * target.

C.Defines * : MY_GLOBAL_DEFINE ;

which is meant to be common to both ppu/spu, it gets "cleared" when I switch tool chains. This may be the correct operation here, but it suprised me.

This is expected behavior. Each toolchain has its own settings. It wouldn't do well to have this:

C.Toolchain ps3 debug ppu ;
C.Defines * : MY_PPU_DEFINE ;
C.Toolchain ps3 debug spu ;
  1. MY_PPU_DEFINE applied here because of the *.

-Josh

RE: ps3 spu/ppu toolchain. - Added by Kevin Thacker about 5 years ago

I got your latest changes. All is working good for us now.

I setup a special rule so that I can specify the spu library from the ppu toolchain.

Internally it does similar to this:

C.Toolchain $(PLATFORM) $(CONFIG) spu ;

C.ActiveTarget $(SPU_LIB) ;

it then retrieves a value that I store on the SPU_LIB (it's the ppu obj generated from the elf by the spu toolchain).

then:

switch back to ppu

C.Toolchain $(PLATFORM) $(CONFIG) ppu ;

C.ActiveTarget $(PPU_APP) ;

and then

NEEDLIBS on $(C.ACTIVE_TOOLCHAIN_TARGET) += $(PPU_OBJS) ;

This works great, and we have all we need to link against.

I don't know if there is much in the way of overhead of doing the c.toolchain switch, but it works for us.

Thanks.

I don't have a problem with the C.Defines behaviour. I implemented a way that works for us when switching using C.Toolchain.

So all is good for us now with this.

Thanks again.

(1-9/9)