Golang: Can't use syscall.EpollCreate - go

I am trying to port a program from C to Go, so using a lot of stuff from the syscall package is required.
I am trying to use https://pkg.go.dev/syscall#EpollCreate, but VSCode refuses to autocomplete it for me or recognize that it is a defined function. FWIW, I get autocomplete for many other things in the syscall package.
My project is using Go 1.14. I am unsure how to tell what version of Go things were introduced in, so I am wondering if that is my problem.
I tried creating a dummy project that uses Go 1.17 and still no luck.
I am writing the code on a Mac, but it will eventually be compiled for ARM Linux, if that matters.
So is this a Go problem or a VSCode problem? Both? Neither?
Sample dummy project:
go.mod:
module epoll-noodle
go 1.14
main.go:
package main
import (
"syscall"
)
func main() {
syscall.EpollCreate(4)
}

It turns out that if you are developing for a platform that differs from your own, some things may be unsupported (like EpollCreate in this case, as #JimB said). The Go extension does let you change your env vars though, so you can work around this in VSCode. In your extensions settings, put something like:
{
"go.toolsEnvVars": {"GOOS" : "linux"}
}
and your project will be built for that OS.
The settings file can be found in the .vscode folder in the root of your project. If there isn't one, you can go to the Go extension in VSCode and fiddle with some settings (for the workspace, not the user) and it will create one for you. Then edit as necessary.
See also: https://github.com/microsoft/vscode-go/issues/632

Related

go modules import for sub folder and general imports concepts understanding issues

I want to use a function from a parent module for this project https://github.com/eregnier/beuss
however (and for the repository in the current state), all my tries fails.
in my root folder I have the following go.mod file
module github.com/eregnier/beuss
go 1.17
in the ./cmd folder I have the following go.mod file
module beuss/cmd
go 1.17
I tried various combination of go.mod file for the cmd folder like
module github.com/eregnier/beuss/cmd
go 1.17
I also tried some imports from the https://github.com/eregnier/beuss/blob/main/cmd/cmd.go file looking like
import (
"fmt"
"io/ioutil"
"log"
"os"
"github.com/eregnier/beuss"
// The following line does not work either
// "github.com/eregnier/beuss" beuss
)
//try to use parent module functions
func main () {
connPUT, err := beuss.newClient(beuss.MESSAGE_PUT)
}
nothing work.
I tried the following commands desperately
go mod init
go mod tidy
go get github.com/eregnier/beuss
go install github.com/eregnier/beuss
I got the follwing errors :
go get: github.com/eregnier/beuss#v0.0.0-20220101172233-d7ecaadb1d81: parsing go.mod:
module declares its path as: beuss
but was required as: github.com/eregnier/beuss
with not understanding the real issue. I googled errors, I had a look at this which looks intersting https://go.dev/doc/code#Workspaces
In the end, I am just loosing patience for this issue where I already spend lot of time without really understanding the real good practice / why it should be done like this or that.
I am sorry if this is a redundant question. but this topic looks nebulous to me where I just want to resolve a dependency. I guess I am lost between local imports / remote imports / modules and pacakges concepts. I guess I just want an entry point to understand all of this where in javascript a simple require('../code.js') does the trick.
What I would like in the end is to be able to better understand go imports system, and pragmatically, how to solve my linked project dependency so I can use functions from parent "folder" (ideally without namespacing)
As the question was unclear because I did not understand what was wrong, I'll try here to synthetise what worked for me.
I followed andrey dyatlov advice by simply removing the go.mod from my cmd folder and It is possible to make this folder a standalone program without module management. So I can go run / build the command file.
Also I slightly changed imports system and reorganized my code folders by understanding how imports works a bit better (I did not practised go since a while and I am a relatively new commer to go world)
So for this last point, doing imports with github.com/eregnier/beuss does the trick, but I missed to export my "lib" functions by just capitalizing their name. Doing so let me import and use them elsewhere in the code.
For the next person that this question might help, it should be possible to see the state of the project (wip) from the link in the question to see how it works now.

What are the differences between CGO invocations in the main package vs a module?

I have written a BPF program that I can install using gobpf, i.e. using their bcc tooling. While this works alright from a main package, this breaks as soon as I move it into a package for importing it as a module.
To clarify: It works with all code in package main, but as soon as I rename the package and move the main() to cmd/command.go it stops working with go run complaining that it can't find an included lib (bcc/proto.h). Incidentally, this is the same error as I always got when running gcc on my .c file without any indication I want to use BPF (the part that gobpf did for me, until I moved its invocation to a module...).
I realize this is question very specific and sits in a weird place between Go, CGo, the way C and C++ handle includes, BPF, and bcc, but I am at a loss here.
You can check out my code here https://github.com/bwNetFlow/bpfdump if that helps. It needs bcc installed in addition to go run doing its thing. Basically:
HEAD is the modularized version that does not work (go run cmd/dump.go)
HEAD~ is my initial experiment that does work (go run bpfdump.go) (you'll get an permission error as user, which is fine as it has compiled anyways).
PS: I think it might have to do with this (rather creative?) construction of bcc/proto.h: https://github.com/iovisor/bcc/blob/master/src/cc/exported_files.cc

GoLand (JetBrains) shows error message "Unresolved Reference". But Code compiles and runs

I am writing a project using the Go language with GoLand IDE by Jetbrains.
While writing the code, GoLand shows me an error message such as "unresolved reference" when the reference do exist and that the program compiles and runs correctly.
Here is a similar (but simpler) example of some code that I have found here on stackoverflow (Go - append to slice in struct) to reproduce this issue.
The same error message appears even though I have implemented the methods just a few lines above.
package main
import (
"fmt"
)
type MyBoxItem struct {
Name string
}
type MyBox struct {
Items []MyBoxItem
}
func (box *MyBox) AddItem(item MyBoxItem) {
box.Items = append(box.Items, item)
}
func main() {
item1 := MyBoxItem{Name: "Test Item 1"}
item2 := MyBoxItem{Name: "Test Item 2"}
box := MyBox{}
box.AddItem(item1)
box.AddItem(item2)
// checking the output
fmt.Println(len(box.Items))
fmt.Println(box.Items)
}
box.AddItem(item1) and box.AddItem(item2) are marked red as an error. If I move my cursor above it, it says unresolved reference "AddItem". Yet the code compiles and runs. And as this was the solution to an other stackoverflow question, I do not think that the code is wrong. Furthermore I cannot find any mistakes in it.
[EDIT: I load the code from a remote server and edit it locally on my private pc. After finishing my changes, I upload it to the remote server (using GoLands tools like "Browse remote host") and build and compile it there. After trying it out locally with the very same code, the error message sometimes is there and sometimes not. I am totally confused]
I experienced a similar issue, but it was a lot more prevalent. Even things like fmt.Printf() were showing as unresolved. Was able to resolve the issue by going to File -> Invalidate Caches / Restart.
I found best way to fix this issue.
close your project and IDE
go to your project directory
remove ./.idea
try to open it again
woops woops, fixed
Edit : better way try to use this one in Goland Menu
file -> repair IDE
it will be refresh index module
Today I faced that problem and I fixed it by enabling go module integration. For that
Settings -> Other Settings -> Go Modules then enable go modules integration.
This will work if you using go modules in your project.
I'm using go module and it's solved by:
Deselect Preferences->Go->GOPATH->Use GOPATH that's defined in system environment
File->Invalidate caches / Restart
I'm a bit late to the answer lol but incase anyone is still running into this, all I did was delete the .idea file and reloaded the project on GoLand (by clicking File -> Open -> file location). Did the trick for me.
I just removed the project from Goland and re-create it from existing files. It was weird but it worked.
I cannot reproduce the issue in GoLand 2020.2. I suggest upgrading to it.
If that doesn't fix the issue then you can take the following steps to investigate the issue:
Is your project using Go modules or the traditional GOPATH?
If it's using GOPATH, have you enabled indexing of GOPATH under Settings/Preferences | Go | GOPATH?
If it's using Go modules, check to see that the support is enabled under Settings/Preferences | Go | Go Modules and then use Alt+Enter | Sync packages of‍‍ <project>
For me the issue was the version of Golang, I had been using go1.19 which threw unreferenced errors with .Close methods, switching back to an older version go16.15 helped me resolve this issue.
I had a similar issue for gin.WrapH function utils.go. Tried the Override File Type option for utils.go in local module path which changed the file as a Go file but had a little cross sign where a tooltip marked that the file is excluded from compilation. The error Unresolved reference only went away when I selected the file, navigated to File -> File Properties -> Associate with File Type -> Register new file type association, and chose Go files
No option from other comments helped me. I had to switch GO SDK version in Setting -> Go -> GOROOT. Goland automatically downloaded 1.16 beta 1 version and it worked.
In Goland preferences, if you're using the Global GOPATH, check the option "Index entire GOPATH" and hit apply.
I had the same issue, I did try invalidates cache, but that did not work.
But the thing worked is just add a below line in your idea.properties file. And then restart IDE.
# custom GoLand properties (expand/override 'bin/idea.properties')
idea.max.intellisense.filesize=100000
This is because, Goland does not index huge packages. But you can force it to do that.
For Mac users, i solved this by setting Custom Tags to 'unix'.
In Preferences > Go > Build Tags & Vendoring. In the Custom Tags, input unix.
I'm using GoLand 2022.1.2
I had the same problem and it got fix weirdly.So I installed and opened project in vscode in order to continue coding.It started installing a extension called gopls. After installation completed I returned to GoLand to close project, but I waited for indexing to complete.Suddenly references were green !
Goland version 2020.1: I opened a folder with subfolders of golang projects and goland didn't recognize dependencies. I solved this problem setting Project GOPATH
ctrl + alt + s
Go > GOPATH
Click on plus button + In Project GOPATH
Add your golang's project folder, example: ~/projects/my-golang-projects
I faced the same issue when I do bazel run //:gazelle, I fixed this issue by doing bazel sync (Bazel -> Sync -> Sync Project with BUILD Files). But you should have the below settings.
(This fix is for Goland IDE, Mac. Of course we should add GOPATH in .bash_profile or .zshrc)
I had the same issue with aws go sdk, changing the Custom Properties (Help -> Edit Custom Properties) helped me.
here is the reference to the JetBrains thread https://youtrack.jetbrains.com/issue/GO-5029
idea.max.intellisense.filesize=10000
idea.max.content.load.filesize=20000
Restart the IDE to let the changes take effect.
I had been using go1.19 which threw unreferenced errors with .Close methods. I download the GoLand 2022.2.4 package and install, issue has been solved.
In my case, I fixed it by running go mod tidy in the console.
In my case go mod was 1.18 and IDE indexed my project with 1.19.
At Preferences -> GOROOT I selected Go 1.18 and problem solved.
Today face the same problem using GoLand 2021.3 MacOS.
Fixed it with go to File Menu -> Repaire IDE...
Then it will automatic fixing issues
I solved it by reinstall Go to D:\go, then reset Go sdk.

Using binary packages directly

I'm writing a library in Go. I'm planning to distribute it, and with a main requirement of 'without source codes'.
For testing, I have created two workspaces like following,
WS1
bin/
pkg/linux_amd64/lib.a
src/lib/src.go
WS2
bin/
pkg/
src/main/main.go
My first workspace (WS1) is the actual dummy library, which has some utility functions. Second workspace (WS2) has main function which uses the package (lib.a) from WS1.
Everything was working good until I remove the sources from WS1. If I remove the directory /lib/src.go in WS1, I'm getting the following error during go build,
main.go:5:2: cannot find package "lib" in any of:
/usr/local/go/src/pkg/lib (from $GOROOT) ../Testing/ws1/src/lib
(from $GOPATH)
The above message indicates us that we should keep the source files as well. Precompiled binary packages alone cannot be used directly.
Based on few suggestions online, we may keep some dummy sources with timestamp value lesser than binary packages' timestamp. But, this doesn't seems to be a feasible solution for us. What happens if timestamp of the dummy sources got updated unfortunately?
I have seen similar issue discussed here,
https://github.com/golang/go/issues/2775
My Questions:
Distributing the sources is the only possibility in Golang?
Why Go is not providing a provision for using '.a' files directly?
If keeping the source is mandatory for Go, why this small thing is
not mentioned anywhere in Go? (or) Am I missing something here?
Thanks in advance for your help guys!
The Go compiler just needs the .a files. If you ship them anybody will be able to use your package without the source code.
BUT your users will have to invoke the compiler (e.g. 6g, not the go tool) manually. If you ship a myfoo.a file and a dummy source myfoo.go containing just package myfoo and the timestamp of myfoo.a is newer than that of myfoo.go (and you put everything in place) you may use the go tool.
Update: Newer version of the go tool detect deleted files and require all files (possibly empty) with the proper filenames and older timestamps in the src folder.
Managing a timestamp should not be a dealbreaker.
Don't get fooled that the go tool is Go: It is a dead convenient tool to build, test, get, whatever your Go code, but it is neither the language nor the compiler nor the linker.
BTW: There is really no point in not distributing the sources.
The binary-only packages will be available in go1.7 (August 2016) - https://tip.golang.org/doc/go1.7
This release adds experimental, minimal support for building programs using binary-only packages, packages distributed in binary form without the corresponding source code. This feature is needed in some commercial settings but is not intended to be fully integrated into the rest of the toolchain. For example, tools that assume access to complete source code will not work with such packages, and there are no plans to support such packages in the “go get” command.
The proposal is at https://github.com/golang/proposal/blob/master/design/2775-binary-only-packages.md , https://tip.golang.org/pkg/go/build/#hdr-Binary_Only_Packages has more information about the new feature.
The binary-only packages is supported in go 1.7 now.
You can only provide .a files and fake go files without source code to distribute it now.
Here is a detailed example and a script of Go1.7 binary package generator.
myframework/frameImplement.go
package myframework
import "fmt"
func Hello(name string) string {
return fmt.Sprintf("Hello, %s!", name)
}
main/main.go
package main
import (
"fmt"
"golang-binary-package-generator/myframework"
)
func main() {
fmt.Println(" start program ")
fmt.Println(" print program :", myframework.Hello("print something now"))
}
If I want to hide my framework's source code, just build it with go build -i -o $GOPATH/pkg/framework.a, then modify your source code to
//go:binary-only-package
package framework
//you can add function prototype here for go doc etc, but no necessary.
, which you can use my binary package generator(script) to help you.
The decision to drop the feature:
cmd/go: drop support for binary-only packages

Why can't I add a main to my library in golang?

I'm having trouble achieving what should be an easy task. I understand the GitHub model for code organization (ie a library repo and an app repo that consumes the library). I think it's fantastic. But I find often that I want mylib to come bundled with a simple executable in a single main.go file. The main.go should be package main and should import mylib. In other words, it should be an exact documentation of how to build an app that consumes this library.
My point is, since it is often enough convenient to provide a simple command line interface that wraps your library, there should be an easy way to do this without having to make another repo, and golang should help.
I'd like something like the following:
$GOPATH/src/github.com/me/mylib
mylib.go
mylib_also.go
main.go
where mylib is the library (package mylib) and main.go is package main and on running go install it generates bin/mylib and pkg/mylib.a.
Either main.go should import "github.com/me/mylib" (if I do that now, I get cyclical import error) or go would understand what's happening since this feature should be built in and the one main.go in the repo generates the exec. Probably requiring the import (and dropping the cyclical error) is the better way.
Right now, I have to do
$GOPATH/src/github.com/me/mylib
mylib/
mylib.go
main.go
So I have to import github.com/me/mylib/mylib which is ridiculous.
In sum, go install should allow the special case of a package and a main which imports the package and provides a simple cli that demonstrates the packages API. The GitHub model promotes two repos, but it should be easy to do simple clis in one!
You can't have multiple packages per folder. Go operates on a package-level, not a file level.
Convention in this case—a binary that consumes your library—is to create a cmd folder with your package main - i.e. as per https://github.com/bradfitz/camlistore/tree/master/cmd or https://github.com/boltdb/bolt
In your case this would be:
$GOPATH/src/github.com/me/mylib
mylib/
mylib.go
README.md
cmd/
your-lib-tool/
main.go
If you just want a convenient, little wrapper, just some command line interface to your lib for demonstration purpose and it is okay if the main program is not built on go get (and not during simple go build and go install) but you are okay by running it via go run main.go or building it manually e.g. with 6g: Just use a build tag (see http://golang.org/pkg/go/build/#hdr-Build_Constraints) in main.go:
// +build ignore
and you won't need a different folder or repo.

Resources