Creating shared object file in Go for an entire module - go

I am trying to create a .so file for entire Go module, my module directory looks something like this:
goAgent/
-- cavagent.go file
-- modules/
-- sample/
-- differentsample/
When I make a .so of the goAgent/ , all I'm getting are the functions of the .go file and not those that present inside the other Go modules. Is there any known way where we can found the functions that are present inside the several Go modules?
What I want is that the functions that are present inside the Go files of modules i.e sample/ and differentsample/ should be available inside my .so.
If you can see below the names of the directory is goAgent/ and it contains a modules folder, which in turn contains different modules. I want the functions that are present inside the files of these sub modules to be present in my .so , a sort of common .so for the entire goAgent/ and sub-folders.
Currently my .so contains only the functions of cavagent.go file only.
I made my .so using the -buildmode=shared -linkshared command.

[Can I create a] shared object file in Go for an entire module [?]
No.

Related

VSCode look for Go packages in different directory

I successfully used rules_go to build a gRPC service:
go_proto_library(
name = "processor_go_proto",
compilers = ["#io_bazel_rules_go//proto:go_grpc"],
importpath = "/path/to/proto/package",
proto = ":processor_proto",
deps = ["//services/shared/proto/common:common_go_proto"],
)
However, I'm not sure how to import the resulting file in VSCode. The generated file is nested under bazel_bin and under the original proto file path; so to import this, it seems like I would need to write out the entire path (including the bazel_bin part) to the generated Go file. To my understanding, there doesn't seem to be a way to instruct VSCode to look under certain folders that only contain Go packages/files; everything seems to need a go.mod file. This makes it quite difficult to develop in.
For clarity, my directory structure looks something like this:
WORKSPACE
bazel-bin
- path
- to
- generated_Go_file.go
go.mod
go.sum
proto
- path
- to
- gRPC_proto.proto
main.go
main.go should use the generated_Go_file.go.
Is there a way around this?
I don't use Bazel and so cannot help with the Bazel configuration. It's likely there is a way to specify the generated code location so that you can revise this to reflect you preference.
The outline you provide of the generated code, is workable though and a common pattern. Often the generated proto|gRPC code is placed in a module's gen subdirectory.
This is somewhat similar to vendoring where your code incorporates what may often be a 3rd-party's stubs (client|server) into your code. The stubs must reflect the proto(s) package(s) and, when these are 3rd-party, using gen or bazel-bin provide a way to keep potentially multiple namespaces discrete.
You're correct that the import for main.go, could (!) be prefixed with the module name from go.mod (first line) followed by the folder path to the generated code. This is standard go packaging and treats the generated code in a similar way to vendored modules.
Another approach is to use|place the generated code in a different module.
For code generated from 3rd-party protos, this may be preferable and the generated code may be provided by the 3rd-party in a module that you can go get or add to your go.mod.
An example of this approach is Google Well-Known Types. The proto (sources) are bundled with protoc (lib directory) and, when protoc compiles sources that references any of these, the Go code that is generated includes imports that reference a Google-hosted location of the generated code (!) for these types (google.golang.org/protobuf/types/known).
Alternatively, you can replicate this behavior without having to use an external repo. The bazel-bin folder must be outside of the current module. Each distinct module in bazel-bin, would need its own go.mod file. You would include in a require block in your code's go.mod file references to the modules' (one or more) locations. You don't need to publish the module to a external repo but can simply require ( name => path/to/module ) to provide a local reference.

Can I specify a replace directive elsewhere other than go.mod for sharing with other developers?

go.mod's replace directive is a local configuration option, different developers could have the local module source in different locations.
It just feels wrong including this option in a file that has to be committed to a repo from which others can use the module (be it private or public).
Is there a way to specify this somewhere else than in go.mod?
Example:
https://github.com/Drean64/c64/blob/master/src/go.mod#L5
module github.com/Drean64/c64
go 1.18
replace github.com/Drean64/cpu6502 => ../../cpu6502/src
replace directive temporary solution when you want to use local modules but I prefer to use build flags, below -modfile is good and you can use it while building or running the program.
example : go run -modfile=local.mod main.go
-modfile file
in module aware mode, read (and possibly write) an alternate go.mod
file instead of the one in the module root directory. A file named
"go.mod" must still be present in order to determine the module root
directory, but it is not accessed. When -modfile is specified, an
alternate go.sum file is also used: its path is derived from the
-modfile flag by trimming the ".mod" extension and appending ".sum".
I do use replace directive only when needs a temporary solution.
different developers could have the local module source in different locations.
By using a relative path, you could reference a folder which is a submodule of your main repository project, which means all developer would benefit from the same local replace directive.
Is there a way to specify this somewhere else than in go.mod?
It does not seem to be, the replace directive is linked to go.mod, and:
replace directives only apply in the main module’s go.mod file and are ignored in other modules.

Build a go project with a different go.mod file [duplicate]

This question already has an answer here:
How to use an alternate go.mod file for local development?
(1 answer)
Closed 10 months ago.
I would like to know how can I build a go project using a different go.mod file. Suppose I want to build project A inside project B module using project B go.mod file without copying the files around. That means I want to use dependencies in Project B to build Project A.
Manual option
"Module files" refers to both go.mod and go.sum
Rename or move project A's module files to some temporary names / location
Copy project B's module files into project A
Edit the newly copied go.mod file in project A, and change the module name:
module github.com/x/b changes to module github.com/x/a
Build whatever you need to build in project A
Delete the active module files in project A
Restore the proper module files for project A that you renamed or moved in step 1
These steps could be automated with a shell script or batch file if you need to do it often.
With build command
Using the go help build command, we can see the build flag -modfile
-modfile file
in module aware mode, read (and possibly write) an alternate go.mod
file instead of the one in the module root directory. A file named
"go.mod" must still be present in order to determine the module root
directory, but it is not accessed. When -modfile is specified, an
alternate go.sum file is also used: its path is derived from the
-modfile flag by trimming the ".mod" extension and appending ".sum".
Using this, we can directly use an alternative set of module files to build things in project A.
First, the flag description indicates that it may write to the go.mod file, so it's probably still a good idea to create a copy of project B's module files to do this.
Second, using project B's module file is going to be a problem if: 1. project A and project B have a different module name declared in their module file, and 2. packages in project A import other packages in project A. The module name determines what the import path of packages in the module will be, so changing it could break imports.
So the best practice should still be to:
Make a copy of project B's module files
Change the module name in the copy
Then you can run the build command like this to build in project A:
go build -modfile path/to/projectb/go.mod
First, make a folder b somewhere. Then make a folder a inside b. Then make
b/b.go:
package b
const Something = 1
Then make b/a/a.go:
package a
import "b"
func something() int {
return b.Something
}
Then go back to b folder, and do go mod init b. Done.

Golang: "package ast_test" underscore test

Source file from Golang's stdlib
File's base directory: ast
Package specified in the file: ast_test ???
Package specified in all other files inside the same directory: ast
From golang.org:
src contains Go source files organized into packages (one package per directory) ...
By convention, packages are given lower case, single-word names; there should be no need for underscores or mixedCaps
... Another convention is that the package name is the base name of its source directory
How is it possible to have multiple packages (here 2) in one folder?
You find another example in src/pkg/go/ast/commentmap_test.go, with the comment:
// To avoid a cyclic dependency with go/parser, this file is in a separate package.
I suppose it allows for an othogonal command like:
go test
That will test parser features while avoiding for that test to be part of the same parser features (since it has been put in a separate package)
From go command man page:
Test files that declare a package with the suffix "_test" will be compiled as a separate package, and then linked and run with the main test binary.
This thread asked the question:
Now that the go tool requires each directory to be one package and doesn't allow to have files with different package names inside the same folder, how is the package keyword useful? It seems like a unnecessary repetition.
Is it required by the compiler or is there any plan to remove it?
The answers hinted at the fact that you can have more than one package in a folder:
The package declaration declares the name of the package.
The language Go doesn't know what a file or a directory is and the import path itself doesn't effect the actual name of the package that is being imported. So the only way the compiler knows what to call the package is the package declaration.
The language doesn't require separate packages to be in separate directories; it is a requirement of the go tool.
Another hypothetical implementation may not have this requirement.
Even this go tool requirement can be bypassed thanks to the "// +build" build tags.
For example, read misc/cgo/gmp or misc/cgo/stdio (some files include // +build ignore)

Windows Compact Embedded - Include external native files

I have created a Sub project which just prints "Hello World". My goal is to create a C file inside the same subproject but within a folder named "src", also I want to create a H file within a folder named "include".
The H file contains only one function declaration "void printContent();" and the C file contains its definition which prints "Hello Buddy".
I added the C file inside the Source Files section of Sub project and added the H file inside the Header File Section, but when I compile the subproject and try to deploy it on to an emulator, I got an error.
BUILD: [01:0000000047:ERRORE] NMAKE : U1073: don't know how to make 'obj\ARMV4I\debug\content.obj'
I tried to configure the subproject by providing the below lines in the sources file of every Sub project.
INCLUDES= include/
But nothing changed and the problem still persists.
In wince subproject, sub folders are treated differently in the source file layout.
Rule No.1 You can't have both source and dirs files in the same folder.
So you either use one folder, or use several sub folders, then the root folder is clean and have one dirs file and several folders, no source file.
Rule No. 2 Each sub folder should have both source and makefile
You can copy and then edit the source file, the makefile will always be the same.
Ok, if you are going to use subfolder just to make the folder structure cleaner, my suggestion is that you create 2 subprojects, one is the main subproject; the other includes all your src files and its type is set to be static library. Then you can link to the static .lib file just as you are including them as in a subfolder. Of cource you need to set the additional include folder and input library.

Resources