Linking to ".O" Files

BlitzMax Forums/BlitzMax Programming/Linking to ".O" Files

Kalakian(Posted 2005) [#1]
I don't know if anyone will find this useful, but I sure will so I thought I'd post it :D

When you compile your blitz program, some temporary files are created, the .i, .o and .s for each of the code files. I thought it'd be good to be able to use these files, and not knowing anything about how compilers work, I decided to play around with a few things.

Firstly, I created two source files:
'*** test.bmx ***
Strict

Function ThisIsATest()
	Print("This is a test!!")
EndFunction


'*** main.bmx ***
Strict

Import "test.bmx"

ThisIsATest()

End



Compile main.bmx, and your executable will be created, as well as the temporary files. Let's grab the "test.bmx.o" and rename as "test.o" and put it in the directory where "main.bmx" is.

Now, change main.bmx to:
'*** main.bmx ***
Strict

Import "test.o"
Extern
	Function ThisIsATest()="bb_ThisIsATest"
EndExtern

ThisIsATest()

End



Again, compile main.bmx again, and your executable will be created as usual, but using the .o file instead of the source file. This method could be useful for writing code libraries without giving your source code away, if you don't want to create your own module.

I haven't had time to test this with types etc, but will post here when I've done that.

Also, this may be a windows only thing, so if anyone could test this on a mac or linux, that would be very helpful.


BlitzSupport(Posted 2005) [#2]
It's better to do this using modules, as you won't have to define each function as in your example. Here's a brief guide to creating a module; I'm assuming BlitzMax is installed in "C:\BlitzMax" here -- simply adjust as necessary.

· Create a folder within "C:\BlitzMax\mod\pub.mod" called yourmodulename.mod -- I'll call mine "rocket.mod"...

C:\BlitzMax\mod\pub.mod\rocket.mod\


· Inside that folder, create a .bmx file with the same name, but without .mod -- in my case, "rocket.bmx". You could do this by running the BlitzMax IDE, creating a new file, and saving it into your "pub.mod\rocket.mod" folder as "rocket.bmx"...

C:\BlitzMax\mod\pub.mod\rocket.mod\rocket.bmx


· With "rocket.bmx" opened in the BlitzMax IDE, add some module information, starting with the module declaration, which should be Module pub.mymodule -- in this case, "Pub.Rocket". This tells BlitzMax we're creating a module called Pub.Rocket...

Module Pub.Rocket


Add some module information of your own, something like this...

ModuleInfo "Module: Rocket Module"
ModuleInfo "Version: 1.00"
ModuleInfo "Author: Werner Von Boyd"
ModuleInfo "License: Public Domain"

' What goes in the quotes is really up to you...


Now add the module's code:

Import BRL.GLMax2D

Type Rocket

     Field x
     Field y

     Function Create:Rocket (x, y)
              r:Rocket = New Rocket
              r.x = x
              r.y = y
              Return r
     End Function

 	 Method Draw ()
 	 	 Plot x, y
 	 End Method
	
End Type


In this case, it's just a type definition, plus an import (because the type's Draw method uses a GLMax2D call, Plot, which Blitz won't otherwise find when compiling the module).

The pub.mod\rocket.mod\rocket.bmx file should now contain something like this:

Module Pub.Rocket

ModuleInfo "Module: Rocket Module"
ModuleInfo "Version: 1.00"
ModuleInfo "Author: Werner Von Boyd"
ModuleInfo "License: Public Domain"

Import BRL.GLMax2D

Type Rocket

     Field x
     Field y

     Function Create:Rocket (x, y)
              r:Rocket = New Rocket
              r.x = x
              r.y = y
              Return r
     End Function

 	 Method Draw ()
 	 	 Plot x, y
 	 End Method
	
End Type


IMPORTANT: Don't try to run it from the IDE, but instead choose "Build Modules" from the IDE's Program menu.

If you're in debug mode, this will build a debug module (as well as building any other modules that haven't been compiled since their last change). If you're not in debug mode, it creates a release version of the module.

This part can alternatively be done via the command line (useful for other IDEs) like so:

bmk makemods
bmk makemods -r


This creates the debug module and the release module.

· To use the module, simply import Pub.Rocket in your main program:

Import Pub.Rocket

Graphics 640, 480, 0

r:Rocket = Rocket.Create (320, 240)

Cls

r.Draw

Flip

WaitMouse
End


You can distribute the rocket.mod folder to other programmers, who simply have to drag it into their own mod\pub.mod folder. If you want to, you can simply remove the rocket.bmx source file and the .bmx folder from the rocket.mod folder before distributing it, leaving only these files:

rocket.a
rocket.i

rocket.debug.a
rocket.debug.i


The .a files are the debug and release modules (you called "Build Modules" with debug on and debug off, right?), and the .i files are the automatically generated interface files that take the place of your function declaration above.

Corrections welcome if I've made any mistakes here!


Robert(Posted 2005) [#3]
If you remove the source code would the original module programmer have to recompile for each platform?


BlitzSupport(Posted 2005) [#4]
Good point -- yes. They'd have to distribute 3 versions (not a problem if the source is supplied, of course).


Kalakian(Posted 2005) [#5]
Thanks for the thorough explanation for making mods, I was a bit confused about this before as it seemed like a lot of hassle. I was just trying to get a quick alternative to making your own mods, but now that you've explained it, I think I can make a Textpad tool to do this automatically.

Cheers


Kalakian(Posted 2005) [#6]
Another point is that to make the mod you have to have MingW installed (on Windows), but the method I described is good for a quick fix.

I got it all working, and now I can make mods :D


Chris C(Posted 2005) [#7]
the ar command can be used to produce .a files

from memory....

ar -r blobby.a blobby.o

i think its -r, if not ar --help for loadsa spew!