Skip to content
Cecil Coupe edited this page Sep 25, 2018 · 7 revisions

While most open source projects use the autoconf system (./configure, ./make, ./make install), Shoes uses rake and it needs to be told some things (many things actually) because it doesn't explore your system looking for C compilers, libraries (dependencies) and which version of Ruby you want to use and where it is. We just can't do that for every platform for every situation.

Internals

We start everything with the Rakefile. It will load additional .rb files as needed. Those files are in a directory called 'make' and organized by {build_os}/{target}/{phase}.rb

So `make/linux/xrpi/setup.rb' is the setup phase of the xrpi target for the linux build host and 'make/darwin/yosemite/tasks.rb contains the needed things for building libshoes.dylib and shoes-bin from a OSX host for an OSX target.

env.rb

This reads the xxxx-custom-yaml and defines constants (see below). Mostly likely, it will call pkg-config 7 or 8 number of times to get all the compile and link info for major sub-systems like ruby, cairo and more. In order to use RbConfig:: values of the target ruby we'll need to load switch_ruby.

env.rb gets loaded for almost every rake task.

make/switch_ruby.rb

Some env.rb files will include this. The Ruby that is running Rake is not the Ruby we want to get information about. This deletes the current RbConfig and friends and replaces it with the target ruby Rbconfig. It also decouples ruby versions. That's a good thing and this is a hack.

tasks.rb

Primarily, the has three functions. new_so() - to build libshoes.so|dll|dylib and new_link() to build the executable. OSX is a bit confusing because it needs post_link processings. There is also a function to package up the build with an installer. Plus a few more functions we'll skip for tutorial purposes.

For better or for worse, these functions are actually methods of a 'Builder' class.

setup.rb

This is run once to create the zzsetup.done target. Typically it copies ruby and dependent libraries, includes files as well as the shoes statics and sample directories.

make/gems.rb

This copies the requested pre-built gems as part of the setup phase. There are other function that maybe used by older code or auxiliary programs.

stubs.rb

This is really only used for Windows targets and very rarely used. It's the build of 'stub.exe' used to create shoes.exe and cshoes.exe launchers. It's worth reading the code to understand how Shoes starts but you'd have to a have a really compelling reason to modify it and recompile. It is not part of the normal build cycle.

make/subsys.rb

This generates the dependency file tasks to compile all the .c and .m file and keep track of what needs building. The higher level dependencies are in the Rakefile file.

Constants

It wouldn't be Make-like without UPPERCASE. Sady, in rake - those are constants. These are the major ones

Constant	From	            Purpose
		
APP	        Rakefile	             General hash, used everywhere
NAME	        app.yaml	               'shoes'
APPNAME	        app.yaml	               'Shoes'
SONAME	        Rakefile	               'shoes’ in libshoes.so – make/build/target/tasks.rb
APPARGS	        Rakefile	                unused, hacketyhack?
RUBY_SO	        Rakefile	
RUBY_V	        Rakefile	                use APP[‘RUBY_V’]
SHOES_RUBY_ARCH	Rakefile	                use APP['SHOES_RUBY_ARCH']
CROSS	        Rakefile	                target selected when true
TOP_DIR	        Rakefile	                top of target – clobber this
TGT_DIR	        Rakefile	                top of target where libs live, build/clean this
APP['Bld_Tmp']	Rakefile	               'tmp’ where objects and status files live
APP['Bld_Pre']	[NFS_ALTP]	                env var. Abs path leading to TOP_DIR – optional build out of tree
TGT_ARCH	build_target file	        name of selected target, used often
builder	        Rakefile	                controls which general task.rb to call
NAMESPACE	Rakefile	                controls display options
SOLOCS	        make/<build>/<tarket>/env.rb	hash of libraries to copy (in make/build/target/setup.rb
DLEXT	        make/<build>/<tarket>/env.rb	.so, .dll, .dylib
LINUX_CFLAGS	make/<build>/<tarket>/env.rb	collection of -D and -I cflags
LIBUX_LIBS	make/<build>/<tarket>/env.rb	collection of -L <lib-path> -llib
LINUX_LDFLAG    make/<build>/<tarket>/env.rb	extra link info
CC              make/<build>/<tarket>/env.rb    'C' compiler - may not be a simple gcc or clang.
STRIP           make/<build>/<tarket>/env.rb    strip command to remove debug symbols 
RANLIB          make/<build>/<tarket>/env.rb    program to create simple libraries from objects.

Previous discussion. Mostly accurate.

You have to install the dependencies for your platform first but can should skim this first so you'll know what to do after those dependencies are setup.

Most people will need to setup a target to match their build system and what they want to build for. Do $ rake -T for all the possible options

In the autoconf paradigm you've partially done a './configure`. Now you need to do the rest by creating a custom.yaml file where you specify where Ruby is, where you put the dependent libs and which gems you want and where they are. Some people put them on the E: drive or the C:drive or drive:? with a name of their choice. Nearly Impossible learn that from a script. win7-custom.yaml allows yours to be different than mine. Also true of xmavericks-custom.yaml. Linux is a little easier but it needs a x86_64-linux.custom.yaml | i686-linux.yaml | pi2-custom.yaml. Copy one and modify to fit your situation.

With a proper custom.yaml and the correct rake setup command then you've done the equivalent of ./configure in the autoconf world. In that world there's usually a 'make distclean' or make 'realclean' that undoes the configure -- to start anew: I did something really wrong and want to start over. Shoes has rake clobber If you use that then you need to start again with the proper rake setup: command.

Now you can do rake and rake clean, just like make and make clean in a autoconf open source project.

On the first 'rake', our scripts will determine you haven't done what we call the 'setup' which copies a butt load of code and files to a semi-permanent directory in your shoes3 directory (win7, xmavericks, x86_64-linux....) it also copies the gems you asked for. This only happens once - unless you do rake clobber (to really start over). Inside the Rakefile(s) that location is known as TGT_DIR

The rake will proceed to compile C/Cocoa files that are newer than the object files in TGT_DIR/tmp which will be all of them on the first 'rake' If it ends w/o fatal error messages, you can run it win7\cshoes.exe or ./cshoes for osx or ./x86_64-linux/shoes for Linux (or ./pi2/shoes or ...)

Congratulations!

Where fun begins:

If you want fix a bug in Shoes or add some code then just edit the C file, rake will only compile that file and link a new shoes you can test. If you edit the static-manual-en.txt or one of .rb files in lib/ and rake, we still have to do a link but the manual change/ruby will be copied to the setup (aka TGT_DIR} without the multiple minutes of doing the setup copy and all the compiles of things that didn't change, 30 secs vs 2 minutes (or 20 minutes on a pi2)

You can do as many rake as you like as you update and test things and just like the autoconf make it only compiles/copies what is needed and nothing more. Note: like autoconf there maybe bugs in the scripts so be developer wise.

rake clean clears out the object files - so that will cause a recompile of everything (but the setup is still good) rake clobber removes the setup (e.g. ./configure)

Performance Issues.

I build Shoes from a network drive seen in Windows (samba/CFS mount) or NFS mount (pi, osx). Write speed is not an NFS feature and the pi network device is not a speed demon. R/W from a flash chip(pi) is very not speedy either and Shoes building does a lot of I/O. Samba is fast enough, for me because I only use it once a week. Anyway, that TGT_DIR which would normally be in your shoes3 source directory can be redirected. For example, I have an external USB drive on the pi3 as /mnt/backup which is many times faster than NFS and the pi2 flash chip. Still slow but not gawd awful slow. In the shell (.bashrc or .profile) I set export NFS_ALTP=/mnt/backup/build/ and most of the writes(setup, compile output, horsing around) go to there. That trailing '/' on the export is important if you're going to use this feature. I use this for OSX too. It should work for Windows and Linux in general if you have different drives with better write performance. Also, rake is not a speedy citizen and we're push 100's of files around, perhaps 1000's of files.

Clone this wiki locally