パッケージの分割コンパイルとInit

Goでは1パッケージを分割コンパイル複数のファイルに分割することも可能で、単純に ${GC} に同じpackage宣言した複数の *.goを食わせてパッケージ名と同名のオブジェクトを作ればOK.
なのだけれど、、、、


maintest.go

package main
import "fmt"
import "sub"
func main ()
{
        var bb int64 = sub.Foo(100);
        cc := sub.Bar();
        fmt.Print("main :: subpackage's retval = ", bb, " and ", cc, "\n")
}


subfoo.go

package sub
import "fmt"
func Foo(x int) int64
{
        fmt.Print("sub.Foo :: I'm Foo in module 'sub'\n");
        return  (int64)(x)*4
}


subbar.go

package sub
import "fmt"
func Bar() int
{
        fmt.Print("sub.Bar :: I'm Bar in module 'sub'\n");
        return 10
}


include ${GOROOT}/src/Make.${GOARCH}

%.$O: %.go
        $(GC) $(GFLAGS) -o $@ $<
%: %.$O
        $(LD) -o $@ $^

GFLAGS = -I.

all: maintest
maintest: maintest.$O
maintest.$O: maintest.go sub.$O

sub.$O: subfoo.go subbar.go
        $(GC) -o $@ $^

include ${GOROOT}/src/Make.cmd

実行結果:

quartz% make
8g -o sub.8 subfoo.go subbar.go
8g -I. -o maintest.8 maintest.go
8l -o maintest maintest.8
quartz% ./maintest
init :: I'm called before main
main :: I'm main -- --
sub.Foo :: I'm Foo in module 'sub'
sub.Bar :: I'm Bar in module 'sub'
main :: subpackage's retval = 400 and 10

標準pkgのsrcを見てみると gopackなるプログラムでライブラリ化しているようなので、「おもしろそー」といじってみるんだけど、どうもやっていることが上記オブジェクトを包んでいるだけみたい。実際、別々の オブジェクトファイルをリンクしようとすると「二重定義ぢゃん」と怒られる。

quartz% gopack grc sub.a subfoo.8 subbar.8
duplicate text symbol: subbar.8 and subfoo.8: sub&#183;Init&#183;
sub.a not changed

func init定義しなくても自動的に出来てしまうのね Init。。。なんだか良くわからないのでちゃんと調べようとか思うのだけれども。中々時間が取れない(悲
うーん、もっかい大学生きたいよー

追記:分割「コンパイル」ではないか、、、ということに気がついたのだけれど、流石にタイトルは変えにくいのでこのまま行きます。