From: Luis Lavena Date: 2006-03-26T03:56:34+09:00 Subject: Re: Using Rake to compile FreeBASIC code Jim: After toyed with the rakefile with simple files, moved it to my project. my folder structure is something like this: my_project code/ shared/ test/ Rakefile Inside code is where my main code resides, and shared is a junction/symlink to where I store code for md5, blowfish, hash, list, etc. In test, I create a few test to "verify" each one of the units/modules of my project. Well, with the rakefile/rules you created in previous mail, making main a module located inside another folder fails, with this error: rake aborted! Don't know how to build task 'mains/test/test_bf.o' I have inside test a file named test_bf.bas The task is named test_blowfish, so don't "collide" between tasks The rule for '.o' => '.bas' worked fine, but the one that makes "mains" didn't. I tried to understand the regex rule, but fail to do so :-( Any hint or suggestion to what need to tweak? Regards and thank you for your time, Luis Jim Weirich wrote: > Luis Lavena wrote: >> Maybe the subject sound strange, but FreeBASIC >> (http://www.freebasic.net) offer us native assembly-linked code that we >> currently use to drive a few special purpose dlls on windows. >> >> Folling Rake Tutorial, we tried to recreate it for fb (instead of c). > > Cool! > >> The problem is related in the way FB set the main module on the compiled >> object (an special param must be passed to make the module as main). >> >> In the later link process, if no module is defined/marked as main, the >> link stop and raise a undefined main routine. > [...] >> The problem is that in our Rakefile we have several projects, and some >> of them use these modules but not as main, so it raises a problem of >> multiple definitions. > > Ok, the problem (as I understand it) is that a main module must be > specially compiled. Only one main module can be in a executable. And > modules that are main for one program need to be non-main for other > executables. > > Does that sound right? > > I approached with the thought that modules that could be main must be > compiled twice, once normally for use as a library, and once with the > main flag to be used as the main program. > > I setup two rules to handle that. The first rule is similar to the one > you gave in your Rakefile. It only compiles normal modules. > > The second rule is for generating objects in a special directory (e.g. > "mains"). All object modules in the "mains" directory have been > compiled for use as a main. > > Then all I had to do was have the project method excluded the normal .o > file that corresponds to the main module and include the specially > compiled version in the main directory. > > Just a couple notes. I don't have FreeBasic so I couldn't actually > compile anything. I just simulated the fbc program with a simple script > that just touched the output files. This means I may have gotten some > of the details wrong, especially the flags that are sent to the compile. > In particular, double check the -m flag. I assume that it wants the > name of the module without any directory name or file extension. > > Here's my version ... let me know of this works for you: > > -------------------------- > #!/usr/bin/env ruby > # -*- ruby -*- > > require 'rake/clean' > > CLEAN.include '**/*.o', 'mains' > CLOBBER.include '*.exe' > > LIBS = [] > > directory 'mains' > > # Rule to build normal objects from source. > rule '.o' => '.bas' do |t| > fbc_compile t.source, t.name > end > > # Rule to compile main objects from source. > rule %r{^mains/.*\.o$} => [ > proc { |fn| File.basename(fn).ext('bas') }, > proc { 'mains' } > ] do |t| > fbc_main_compile t, t.source > end > > def fb_project(executable, main, files, libs=[]) > bas_files = FileList[*files.grep(/\.bas$/)] > rc_files = FileList[*files.grep(/\.rc$/)] > objs = bas_files.ext("o") + rc_files > objs.exclude(main.ext("o")) > objs.include(File.join("mains", main.ext("o"))) > > task :compile => executable > task executable => executable.ext("exe") > file executable.ext("exe") => objs do |t| > fbc_link t.name, t.prerequisites, libs > end > end > > def fbc_compile(src, obj) > sh "fbc -c #{src} -o #{obj}" > end > > def fbc_main_compile(task, main_name) > sh "fbc -c #{task.source} -o #{task.name} -m #{main_name.ext}" > end > > def fbc_link(exec, deps, libs) > lb = libs.collect { |lib| "-l #{lib}" }.join(' ') > sh "fbc -x #{exec} #{deps.join(' ')} #{lb}" > end > > fb_project("test", "stub.bas", ["**/*.bas", '*.rc'], ["user32"]) > > fb_project("xx", "module1.bas", ["module2.bas"], ["user32"]) > > task :default => :compile > -------------------------- > > -- > -- Jim Weirich -- Posted via http://www.ruby-forum.com/.