BMK NG - extreme experimentation

BlitzMax Forums/BlitzMax NG/BMK NG - extreme experimentation

Brucey(Posted 2008) [#1]
The following is presumed *very early beta* and is subject to change at any time!

*ADVANCED USE ONLY* :-p

Imagine, if you will, a BMK that allowed you to add extra functionality to it without having to modify BMK itself. Perhaps you'd like to post-process some files after your build.
How about the ability to add build-changing commands into the source itself?

Well, that's what's been going on over here at Brucey Central recently, mostly because I've got two modules on hold as BMK as it currently stands needs work to support them properly.

Up to the plate steps, BMK NG. The same backwards compatible BMK, with a dash of Lua integration.

* What does it need to run.

Everything is included in the Zip.

- Some new modules : Pub.Lua and BRL.MaxLua
(Before you get too excited, the names and locations are only proposals, but who knows.... maybe one day.)

- And of course, the bmk files.

* What are those core.bmk and make.bmk files?

These need to be dropped (along with your bmk exe) into the bin dir. They are script files that BMK uses to define certain functionality.
If you were to look into these file you would see something like :
@define echo
	print(arg0)
@end

This defines the name of a function/command, along with some Lua code to execute. In this case we've defined a function called "echo" which will print the contents of the rest of the line passed to it.

To execute the command, we could simply, in the *same* file, add the line :
echo Hey, is this cool or what?

which, when processed by BMK would output to the console that text.

Okay, not a very exciting example? Now, what if we wanted to include another .bmk script file as part of our build? Well, we have a command for that :
@define include
	bmk.LoadBMK(arg1)
@end

You could use it like so:
include "resources/create_stuff.bmk"

This would cause the file to be loaded, parsed, and if inline commands exist, executed, before moving on to the next line in the current file. We call this, extensibility ;-)

* What's that bmk.LoadBMK() thing all about?
In this case, "bmk" is an object, and LoadBMK is a method of that object. In fact, this is calling *into* BMK itself. Currently there are a few different objects exposed :
* bmk - some internal methods.
* sys - provides access to BRL.FileSystem and BRL.System functionality.
* utils - access to BRL.MaxUtil functionality.
* globals - a global variable resource/stack. Used extensively for tracking build options and other useful things.

Other than what's in the code, there's no specific documentation yet, as things change often.

* How do we use variables?
You can define a variable on-the-fly...
myname=Brucey
echo %myname%

You can use variables within function definitions
@define test
  if %myname% == "Brucey" then
    print("Hi there!")
  end
@end

Yes, that's Lua. What actually happens during script loading is that the script is processed and any variables are transformed into Lua-friendly code.
You can also use global environment variables with the same syntax. For example %path% would equate to the current system PATH environment variable. (you can use upper or lower case).

* You mentioned adding commands to the source?
That's right!
In your BlitzMax source, you can include @bmk pragmas, which can call any of the previously defined functions. These act just like a line in a script file, except you precede it with @bmk.
A little example : (edited to fix typo)
SuperStrict

' @bmk echo *** Building my cool app ***
' @bmk include "my_own_scripts.bmk"
'
' @bmk push cc_opts
' @bmk addccopt -DSPECIAL_OPTION
'
' @bmk make "src/someglue.cpp"
'
' @bmk pop cc_opts
' @bmk make "src/other.cpp"
'

The "push" command saves the current state of a variable, allowing you to make modification to it, after which time you can "pop" it back to its old state. Handy for on-the-fly tweaks :-)

Again, the push and pop commands are defined like the others - in the script files.

* Can we do post build stuff?
Sure, just add a "post.bmk" file into the same dir as your app, and it will be loaded after completion of the compilation stage, but before execution (if you chose to Run it). This can be useful if you want to copy files into an App Bundle, or run the exe through some compression utility, for example.


Anyhoo, that's all for now.
Remember, this is just for fun at the moment, and things are likely to change as time goes on, but it's working rather well at the moment.

Please remember to *back up* your current bmk before you get started!!

You can download the early beta version from here (209k).
Copy the modules into their respective locations - into BRL and Pub folders.
Once built, copy the bmk exe and the two (core and make) .bmk files into the bin folder.

Please remember to *back up* your current bmk before you get started!!


And most of all, have fun ;-)


Retimer(Posted 2008) [#2]
This could be interesting. Looking forward to giving this a go when I get back home this afternoon.


Space_guy(Posted 2008) [#3]
Sounds scary. But probbably quite usefull :)


DavidDC(Posted 2008) [#4]
This has amazing potential. Looking forward to seeing what people come up with!


Retimer(Posted 2008) [#5]
BMK compiled fine, example worked fine.

I think you meant SuperStrict , not SuperScript in the example though, although it really is a super script =P

I'll post back when I get something going with it.


Brucey(Posted 2008) [#6]
Aye, I probably did mean that :-)


Retimer(Posted 2008) [#7]
I added a custom command for myself, for adding includes depending whether a variable is equal to 1 or not.

I threw into core.bmk:
@define ifinclude
	if arg1 == "1" then
		print("Executing "..arg2)
	else
		print(arg2.." was not executed")
	end
	bmk.LoadBMK(arg2)
@end


and some really simple code:
' @bmk publish = 1

' @bmk ifinclude %publish% publish/PackageData.bmx
' @bmk ifinclude %publish% publish/ftp_update.bmx


So it's basically a flexible include function.

I think this pre/post-processing can come in very handy for publishing. Nice work brucey.

Is there any other plans you have for this aside from its current use?


Brucey(Posted 2008) [#8]
Is there any other plans you have for this aside from its current use?

Not off the top of my head, but it's so configurable that I imagine that there could be all kinds of uses it could be put to.

For now, I just need to be able to control much more of the build process than is currently possible with BMK.


DavidDC(Posted 2008) [#9]
Putting aside for a moment whether they are actually good ideas, you could also use this to initiate a pre-compile parser for case checking, and expanding enumerated types and macros?
[edit] Logging the build number?


plash(Posted 2009) [#10]
Just out of curiosity.. this doesn't break anything, right? It would be nice to have pre-processing in the next Max release.

EDIT: For example, I could have a module that could use one of Brucey's modules, but the user might not have or want that module, so the import could be turned off and the user wouldn't have to go around removing all dependent modules after every svn checkout.

Obviously that would only work if the user had this modified bmk aswell..


Azathoth(Posted 2009) [#11]
Can this be used to act in with the bmx code? Like a C preprocessor?


Brucey(Posted 2009) [#12]
Just out of curiosity.. this doesn't break anything, right?

It is completely backwards compatible. (of course ;-)
By that, I mean, you can use this bmk with any modules/apps.

However, if you build a module to use specific functionality with this bmk, it's not going to do much if you try to build it elsewhere.

Can this be used to act in with the bmx code? Like a C preprocessor?

Not specifically, It's more of a build tool than something which "modifies" code.

Since bcc actually compiles the .bmx files, you'd have to generate intermediate .bmx files for bcc to compile instead. Which is a bit messy - although I think someone has done something along those lines.


This system is essentially a custom build environment. You get some basic functionality which you can expand upon. You may want to use it to automate your build process - build/copy/compress/package - or whatever.
I'm sure there are lots of other uses for it. I'm mostly interested in giving *me* more options at compile time - since I need to compile filetypes that bcc doesn't like.