go build output depending on project structure

176 views
Skip to first unread message

Nitish Saboo

unread,
Mar 18, 2020, 9:18:27 AM3/18/20
to golang-nuts
Hi,

Case 1
----------

I have a project called 'nitish' where the folder structure looks like the following:

nitish
       main.go
       util
            util.go
       lib
            node.c
            node.h
            a.go

When I try compiling this project in the following ways:

1) go build -v - x

>> This creates a binary called 'nitish'

2)  go build -v - x main.go

>>  This creates a binary called 'main'

ldd output of both the binaries is the same.


Case 2
----------


Now, when I restructure the project 'nitish' in the following manner:

nitish
       main.go
       util.go
       node.c
       node.h
       a.go

When I try compiling this project in the following ways:

1) go build -v - x

>> This creates a binary called 'nitish'

2) go build -v - x main.go

>> This error out with the following:

/tmp/go-build074530518/b001/_x002.o: In function `_cgo_8eab385aa676_Cfunc_load_pattern_db':
/tmp/go-build/cgo-gcc-prolog:86: undefined reference to `load_pattern_db'
collect2: error: ld returned 1 exit status


1) In Case 1, why the binaries are created with different names though both the binaries have the same 'ldd output' and work the same manner?

2) Why we see an error with the command 'go build -v - x main.go' in Case 2 but not in Case 1?

Thanks,
Nitish

Gregor Best

unread,
Mar 18, 2020, 9:36:30 AM3/18/20
to golan...@googlegroups.com

Hi,

In both `go build main.go`-examples, you tell the compiler to _only_ build `main.go`.

In your first example, `main.go` probably imports both `util` and `lib` (you might want to give them less generic names by the way). The go compiler thus knows "to build `main.go`, I need to build both `util` and `lib` and link them in".

In the second example, it has no way of knowing where `load_pattern_db` comes from, since you didn't tell it to compile a file that defines that function.

The examples where you omit the `main.go` tell the compiler "build the package in this directory", which includes all `.go`-files in the directory. `node.c` and `node.h` are likely built because of `cgo` directives in `a.go`.

The compiler and linker did exactly as you told them to.

--
You received this message because you are subscribed to the Google Groups "golang-nuts" group.
To unsubscribe from this group and stop receiving emails from it, send an email to golang-nuts...@googlegroups.com.
To view this discussion on the web visit https://groups.google.com/d/msgid/golang-nuts/CALjMrq6gpXPbED%2BK2xiOKYvRg08FZwkjoPSUaGg%3DFu5hKP-%2BKQ%40mail.gmail.com.
-- 
--
  Gregor Best
  be...@pferdewetten.de

Nitish Saboo

unread,
Mar 18, 2020, 9:51:12 AM3/18/20
to Gregor Best, golang-nuts
Hi Gregor,

Got your point.Thank you for your response.
That explains why the binaries have different names post compilation.

Thanks,
Nitish


Nitish Saboo

unread,
Mar 18, 2020, 10:03:39 AM3/18/20
to Gregor Best, golang-nuts
Hi Gregor,

nitish
       main.go
       node.c
       node.h

I compiled using 'go build -v -x main.go'
But if my cgo directive is defined in main.go, this should have compiled successfully..right? But it fails with the following whereas 'go build -v -x' works fine.

/tmp/go-build439591561/b001/_x002.o: In function `_cgo_5637ad3d75e4_Cfunc_load_pattern_db':

/tmp/go-build/cgo-gcc-prolog:86: undefined reference to `load_pattern_db'
collect2: error: ld returned 1 exit status

package main

//#include <stdlib.h>
//#include "node.h"
import "C"
import (
"fmt"
_ "fmt"
"os"
"path"
"unsafe"
)

Please let me know what am I missing here?

Thanks,
Nitish

Gregor Best

unread,
Mar 18, 2020, 10:15:31 AM3/18/20
to Nitish Saboo, golang-nuts

Hi,

it looks like my initial reply wasn't entirely correct. It should build if you pass in both the `.go` file and the `.c` file.

Nitish Saboo

unread,
Mar 18, 2020, 10:27:19 AM3/18/20
to Gregor Best, golang-nuts
Hi Gregor,

Do you mean like this 'go build -v -x main.go node.c' ? But it does not compile and gives the following output:

WORK=/tmp/go-build714119815
named files must be .go files

Thanks,
Nitish

Jake Montgomery

unread,
Mar 19, 2020, 9:48:18 AM3/19/20
to golang-nuts
Nitish,

Is there some reason that you want, or need, to be using go build this way, by specifying files? Or is it just curiosity about how the tools work?
The typical way to use go build is to build without specifying individual files. If you are using CGO, I would certainly recommend that you do it by building as a  package, just to keep things simple. Not that CGO is ever simple.
To unsubscribe from this group and stop receiving emails from it, send an email to golan...@googlegroups.com.
-- 
--
  Gregor Best
  be...@pferdewetten.de
--
You received this message because you are subscribed to the Google Groups "golang-nuts" group.
To unsubscribe from this group and stop receiving emails from it, send an email to golan...@googlegroups.com.

Nitish Saboo

unread,
Mar 19, 2020, 10:21:31 AM3/19/20
to Jake Montgomery, golang-nuts
Hi Jake,

Is there some reason that you want, or need, to be using go build this way, by specifying files? Or is it just curiosity about how the tools work?
>>There is no particular reason to use go build by specifying the files. I was trying different ways to compile the project and ended up with this scenario.
I am curious to know the reason for this.

The typical way to use go build is to build without specifying individual files. If you are using CGO, I would certainly recommend that you do it by building as a  package, just to keep things simple. Not that CGO is ever simple.
>> I will try compiling the package without specifying the individual files. But the following case works all fine whether we pass the individual file or not.:

Case 1
----------

I have a project called 'nitish' where the folder structure looks like the following:

nitish
       main.go
       util
            util.go
       lib
            node.c
            node.h
            a.go

When I try compiling this project in the following ways:

1) go build -v - x

>> This creates a binary called 'nitish'

2)  go build -v - x main.go

>>  This creates a binary called 'main'

ldd output of both the binaries is the same.

Thanks,
Nitish


To unsubscribe from this group and stop receiving emails from it, send an email to golang-nuts...@googlegroups.com.
To view this discussion on the web visit https://groups.google.com/d/msgid/golang-nuts/cfddeb60-03af-4f87-a6a8-74f76fb069a5%40googlegroups.com.

Jake Montgomery

unread,
Mar 19, 2020, 11:58:59 AM3/19/20
to golang-nuts


On Thursday, March 19, 2020 at 10:21:31 AM UTC-4, Nitish Saboo wrote:
Hi Jake,

Is there some reason that you want, or need, to be using go build this way, by specifying files? Or is it just curiosity about how the tools work?
>>There is no particular reason to use go build by specifying the files. I was trying different ways to compile the project and ended up with this scenario.
I am curious to know the reason for this.

The typical way to use go build is to build without specifying individual files. If you are using CGO, I would certainly recommend that you do it by building as a  package, just to keep things simple. Not that CGO is ever simple.
>> I will try compiling the package without specifying the individual files.
 
Right, as I said, this is the standard way. You should always build the package this way, unless you have a specific use case that requires compiling a single file.

But the following case works all fine whether we pass the individual file or not.:
 
The reason that works is because the package you are building only contains one file, 'main.go'. The other files are actually in different packages, so they are pulled in by import. So `go build -v - x` builds the package `nitish`, which only contains one file, `main.go`. Since the package name is `nitish` you get an executable named `nitish`. `go build -v - x main.go` is a special use of the tool. I mostly use it for quick code tests, when the playground will not suffice, or for using go to write quick scripts. It will not build the package `nitish`, instead it will build only the single file, and produce an executable named after the file, in this case `main.exe`. Since the `nitish` package only contains one file, the result is otherwise the same (AFAIK).

Hope this has some useful information.

Ian Lance Taylor

unread,
Mar 19, 2020, 1:41:27 PM3/19/20
to Jake Montgomery, golang-nuts
It might help to read
https://golang.org/cmd/go/#hdr-Package_lists_and_patterns, including
the paragraph starting "As a special case, if the package list is a
list of .go files from a single directory,...."

Ian
> To unsubscribe from this group and stop receiving emails from it, send an email to golang-nuts...@googlegroups.com.
> To view this discussion on the web visit https://groups.google.com/d/msgid/golang-nuts/a0d2fca4-951d-4661-bf08-8010d13bd48b%40googlegroups.com.

Nitish Saboo

unread,
Mar 20, 2020, 8:32:31 AM3/20/20
to Ian Lance Taylor, Jake Montgomery, golang-nuts
Thank you Ian and Jake for the response.
Sure Ian, will go through it.

Thanks,
Nitish


Reply all
Reply to author
Forward
0 new messages