From: Jim Weirich Date: 2006-03-21T14:32:50+09:00 Subject: Re: Using Rake to compile FreeBASIC code 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/.