package global name space

149 views
Skip to first unread message

Russ Cox

unread,
Jan 26, 2010, 7:32:18 PM1/26/10
to golang-nuts
It's come up a few times on the list that package names used by
standard packages could not be reused for new packages in different
locations. For example,
http://groups.google.com/group/golang-nuts/t/640942b76a3614df

The next Go release will eliminate this restriction in the gc
compilers (5g, 6g, 8g): you will be able to create your own package
math imported as "project/math" and it will not interfere with the
package of the same name imported as "math". (The changes are already
checked in at tip.)

The change that lifts the package name restrictions introduces a new
one: there must be a one-to-one correspondence between packages and
import paths. This means that if you do create your own math package
for project, you should import it as "project/math". You should not
use 6g -Iproject and import "math", because that will cause confusion
with the standard package.

Here at Google, we handle this case by installing all packages to the
standard Go package root, but our local packages have import paths
beginning with google/, like package codesearch imported as
"google/codesearch". We suggest using a similar convention for your
own projects: pick a unique top-level directory name for your project
and put all your packages under that directory, even if you choose to
use the -I flag to specify an alternate root. Note that if you use -I
to augment 5g/6g/8g's search path, you must also use -L to augment
5l/6l/8l's search path.

Eliminating the global name space assumption required a lot of changes
to the tool chain, most of which should be invisible. There is one
important visible change: if you write C or assembly functions and
compile them using 5c/6c/8c or 5a/6a/8a, you used to name a Go visible
symbol package·symbol. Now the package is implied and the name is
just ·symbol (note the leading ·). If you use cgo, this is all taken
care of for you.

If you run into problems, please file issues on the issue tracker.

As Ian mentioned earlier today, gccgo has not yet eliminated the
global name space assumption, but that work is in progress.

Thanks.
Russ

Kai Backman

unread,
Jan 27, 2010, 3:02:30 AM1/27/10
to r...@golang.org, golang-nuts
On Tue, Jan 26, 2010 at 4:32 PM, Russ Cox <r...@golang.org> wrote:
> Eliminating the global name space assumption required a lot of changes
> to the tool chain, most of which should be invisible.  There is one
> important visible change: if you write C or assembly functions and
> compile them using 5c/6c/8c or 5a/6a/8a, you used to name a Go visible
> symbol package·symbol.  Now the package is implied and the name is
> just ·symbol (note the leading ·).  If you use cgo, this is all taken
> care of for you.

We still have the exception that you can specify the full
package·symbol, right? This is mainly useful when you want to define a
function for another package than the one you place the code in. E.g.
defining a runtime·write outside runtime.

Given that it's no longer possible to pass in multiple files to
5l/6l/8l, can the single argument be a .a file instead of a .5/.6/.8?

Kai

Russ Cox

unread,
Jan 27, 2010, 4:25:29 AM1/27/10
to Kai Backman, golang-nuts
> We still have the exception that you can specify the full
> package·symbol, right? This is mainly useful when you want to define a
> function for another package than the one you place the code in. E.g.
> defining a runtime·write outside runtime.
>
> Given that it's no longer possible to pass in multiple files to
> 5l/6l/8l, can the single argument be a .a file instead of a .5/.6/.8?

Yes, and yes.

Russ

Charlie Dorian

unread,
Feb 2, 2010, 4:35:26 PM2/2/10
to golang-nuts
I'm having trouble understanding exactly what to do in my case.

I would create an assembly-language function (say, f.s) and run "8a
f.s" to create f.8. Then I would create f_test.go, in which I
declared f (just the line "func f(float64) float64" without curly
brackets). Then I would run "8g f_test.go"; followed by "8l f_test.8 f.
8" to create 8.out. Which, of course, now no longer works.

The FAQ says, "Put all the source files for the package in a directory
by themselves. Source files can refer to items from different files at
will; there is no header file or need for forward declarations." I
did that, and have a directory with f.8 and f_test.8. But now when I
run 8l f_test.8, I get the error message: "main.main: undefined:
main.f". (Even if I add a file f_decl.go, the error message is
"main.main: undefined: main.f".)

I've re-read Russ Cox's directions above, but I still don't get what
he's saying. I'd appreciate a more verbose explanation.

In short, what should I change about the way I do things? Thanks for
your help.

Russ Cox

unread,
Feb 2, 2010, 5:28:19 PM2/2/10
to Charlie Dorian, golang-nuts
If package main comprises multiple object files, 
you can combine them with gopack before passing it to 8l:

gopack grc f.a f.8 f_test.8
8l f.a

Russ

Charlie Dorian

unread,
Feb 2, 2010, 6:07:42 PM2/2/10
to golang-nuts
Thanks. When I combine them and try to load, the error message from
8l is:
mainstart: undefined: main.init
mainstart: undefined: main.main

Ian Lance Taylor

unread,
Feb 2, 2010, 7:59:33 PM2/2/10
to Charlie Dorian, golang-nuts
Charlie Dorian <cldo...@gmail.com> writes:

This means that you have no file in package main. You need to have
one in order to link. And it needs to define a function named main.

Ian

Charles Dorian

unread,
Feb 2, 2010, 8:20:23 PM2/2/10
to Ian Lance Taylor, golang-nuts
Except that I do have a function main() and a file in package main.  Any other suggestions?

Ian Lance Taylor

unread,
Feb 2, 2010, 8:29:52 PM2/2/10
to Charles Dorian, golang-nuts
Charles Dorian <cldo...@gmail.com> writes:

> Except that I *do* have a function main() and a file in package main. Any
> other suggestions?

Tell us exactly what you did.

Ian

Russ Cox

unread,
Feb 2, 2010, 8:53:52 PM2/2/10
to Charlie Dorian, golang-nuts
Assuming you ran

gopack grc f.a f.8 f_test.8
8l f.a

the only way to get this message should be if the
objects you rolled into f.a do not include the Go
program that defined the function main.

As Ian said, if you're still having trouble, please
post an exact example.

Russ

Charles Dorian

unread,
Feb 2, 2010, 8:56:16 PM2/2/10
to Ian Lance Taylor, golang-nuts
I've attached the actual two files I'm testing.  Here's my sequence of actions:

charles@ubuntu:~/proj/go/fmod$ 8g fmod_test.go
charles@ubuntu:~/proj/go/fmod$ 8a fmod_386.s
charles@ubuntu:~/proj/go/fmod$ gopack grc fmod.a fmod_test.8 fmod_386.8
charles@ubuntu:~/proj/go/fmod$ 8l fmod.a

mainstart: undefined: main.init
mainstart: undefined: main.main
charles@ubuntu:~/proj/go/fmod$

fmod_test.go
fmod_386.s

Ian Lance Taylor

unread,
Feb 2, 2010, 11:51:19 PM2/2/10
to Charles Dorian, golang-nuts
Charles Dorian <cldo...@gmail.com> writes:

Thanks for the test case. I think you've found a limitation in the
system. You have to use gopack to build a package containing an
assembler source, but you can't pass gopack output directly to 8l.

I was able to build your code by creating a new file

package p
func Fmod(x, y float64) float64

renaming fmod to Fmod in your assembler file, using gopack to build
that as a small package, adding an import statement to the main .go
file, and calling p.Fmod rather than fmod.

Ian

Charlie Dorian

unread,
Feb 3, 2010, 12:08:17 AM2/3/10
to golang-nuts
Wow! Thanks for figuring that out.

Russ Cox

unread,
Feb 3, 2010, 1:10:30 AM2/3/10
to Ian Lance Taylor, Charles Dorian, golang-nuts
Thanks for the test case.  I think you've found a limitation in the
system.  

Oops.  Kai and I were talking about this very case a few
days ago, and I completely forgot about it.  Sorry for the
runaround.  Added as issue #585.

Russ

Reply all
Reply to author
Forward
0 new messages