How to set package name in .ned file? - omnet++

I'm new to omnet++. How to set the correct package name?
I created a new .ned file in omnet++5.4.1, but there was not a package name.And I type a name,the omnetide show me that declared package "org.car2x.veins.base.modules" does not match expected package "".
How to know which is the correct package name?
Thank you.
I use omnet++5.4.1 and veins 5a1.

The OMNeT++ manual has an explanation for the definition of a package.
Directories in a NED source tree correspond to packages. If NED files are in the /a/b/c directory (where is listed in NED path), then the package name is a.b.c. The package name has to be explicitly declared at the top of the NED files as well, like this:
package a.b.c;

Related

Declared package does not match expected package in OMNET++

I am trying to simualte M\M\1 Queuing Model using OMNET++ on my Mac M1.
The name of the project is "MM1QueueModel" while the same for .ned and .cc are "MM1Queue.ned" and "MM1Queue.cc" respectively.
In the "MM1Queue.ned" file, I am using the package as:
package MM1QueueModel;
but this is giving an error "Declared package does not match expected package in OMNET++"
The solution described in Solution is not working for me. Please help
Take a look at Packages Overview and check whether your directories meet that requirement:
The package name that follows from the directory name and the declared package must match; it is an error if they don't.

Importing Protofile from a different path

I am trying to import a Proto file into another one from a different folder and haven't been successful in doing so. Here's the scenario:
I have a .Proto in folder ....\abc\protos\ProtoA.proto and another one in folder ....\def\protos\ProtoB.proto.
I need ProtoA to import ProtoB but it's in a different folder and using Import "....\def\protos\ProtoB.proto" doesn't work because it doesn't like "...." in the path.
What are the steps i need to follow to import the file in correctly from a different path?
It's confusing and I'm unsure whether it's effectively explained in the docs.
Proto file imports are absolute to the proto package and the package structure must be preserved in the filing system structure.
However, the absolute disk location is only important when using protoc per #Brits comment so that the compiler can find the protos.
So.... Your import for ....\def\protos\ProtoB.proto should reflect the specific package and service or method or message name that you're importing not its disk location (which is what you're using).
Then, when you protoc, you should --proto_path and give (I think absolute not relative) paths to the filing system locations that contain the protos needed to be imported.
Have a look at Any by way of example.
In a proto, you import "google.protobuf.Any", it's package plus the message name.
When you protoc it, Any is often already in the include path but, if it weren't, you'd need to --proto_path=/path/to/foo if foo is the root directory containing google/protobuf/any.proto; the proto file must be in a directory called protobuf in a directory called google for the import to work.
If you're familiar with Golang and GOPATH, this mirrors how Go packages are named by their directory (not file) name and referenced locally by their location being in the GOPATH; it's now different with Go Modules.

Relationship between a package statement and the directory of a .go file

See this experiment.
~/go/src$ tree -F
.
├── 1-foodir/
│   └── 2-foofile.go
└── demo.go
1 directory, 2 files
~/go/src$ cat demo.go
package main
import (
"fmt"
"1-foodir"
)
func main() {
fmt.Println(foopkg.FooFunc())
}
~/go/src$ cat 1-foodir/2-foofile.go
package foopkg
func FooFunc() string {
return "FooFunc"
}
~/go/src$ GOPATH=~/go go run demo.go
FooFunc
I thought that we always import a package name. But the above example
shows that we actually import a package directory name ("1-foodir")
but while invoking exported names within that package, we use the
package name declared in the Go files (foopkg.FooFunc).
This is confusing for a beginner like me who comes from Java and Python world,
where the directory name itself is the package name used to qualify
modules/classes defined in the package.
Why is there a difference in the way we use import statement and
refer to names defined in the package in Go? Can you explain the rules
behind these things about Go?
If what you said was true, then your function call would actually be 1-foodir.FooFunc() instead of foopkg.FooFunc(). Instead, go sees the package name in 2-foofile.go and imports it as foopkg because in go the name of the package is exactly what comes after the words package at the top of .go files, provided it is a valid identifier.
The only use of the directory is for collecting a set of files that share the same package name. This is reiterated in the spec
A set of files sharing the same PackageName form the implementation of a package. An implementation may require that all source files for a package inhabit the same directory.
In go, it is convention that the directory match the package name but this doesn't have to be the case, and often it is not with 3rd party packages. The stdlib does do a good job of sticking to this convention.
Now where directories do come into play is the import path. You could have 2 packages named 'foo' in your single binary as long as they had different import paths, i.e.
/some/path/1/foo and /some/path/2/foo
And we can get really swanky and alias the imports to whatever we wanted, for example I could do
import (
bar "/some/path/1/foo"
baz "/some/path/2/foo"
)
Again the reason this works is not because the package name has to be unique, but the package import path must be unique.
Another bit of insight to glean from this statement is -- within a directory, you cannot have two package names. The go compiler will throw an error stating it cannot load package and that it found packages foo (foo.go) and bar (bar.go).
See https://golang.org/doc/code.html#PackageNames for more information.
Roughly for the why:
Packages have a "name" which is set by the package clause, the package thepackagename at the start of your source code.
Importing packages happens by pretty much opaque strings: the import path in the import declarations.
The first is the name and the second how to find that name. The first is for the programmer, the second for the compiler / the toolchain.
It is very convenient (for compilers and programmers) to state
Please import the package found in "/some/hierarchical/location"
and then refer to that package by it's simple name like robot in statements like
robot.MoveTo(3,7)
Note that using this package like
/some/hierarchical/location.MoveTo(3.7)
would not be legal code and neither readable nor clear nor convenient.
But to for the compiler / the toolchain it is nice if the import path has structure and allows to express arbitrary package locations, i.e. not only locations in a filesystem, but e.g. inside an archive or on remote machines, or or or.
Also important to note in all this: There is the Go compiler and the go tool. The Go compiler and the go tool are different things and the go tool imposes more restrictions on how you lay out your code, your workspace and your packages than what the Go compiler and the language spec would require. (E.g. the Go compiler allows to compile files from different directories into one package without any problems.)
The go tool mandates that all (there are special cases, I know) your source files of a package reside in one file system directory and common sense mandates that this directory should be "named like the package".
First thing first, the package clause and import path are different things.
package clause declares PackageName:
PackageClause = "package" PackageName .
PackageName = identifier .
The purpose of a package clause is to group files:
A set of files sharing the same PackageName form the implementation of a package.
By convention, the path basename (directory name) of ImportPath (see below) is the same as PackageName. It's recommended for convenient purposes that you don't need to ponder what's the PackageName to be used.
However, they can be different.
The basename only affects the ImportPath, check spec for import declartions:
ImportDecl = "import" ( ImportSpec | "(" { ImportSpec ";" } ")" ) .
ImportSpec = [ "." | PackageName ] ImportPath .
ImportPath = string_lit .
If the PackageName is omitted, it defaults to the identifier specified in the package clause of the imported package.
For example, if you have a dir foo but you declare package bar in a source file resides in it, when you import <prefix>/foo, you will use bar as a prefix to reference any exported symbols from that package.
darehas' answer raises a good point: you can't declare multiple packages under the same basename. However, according to package clause, you can spread the same package over different basenames:
An implementation may require that all source files for a package inhabit the same directory.

What is the purpose of the package declaration?

Every Go file starts with package <something>.
As far as I understand - and this is probably where I am missing some information - there are only two possible values for <something>: The name of the directory it is in*, or main. If it is main, all other files in that directory can only have main, too. If it is something else, the project is inconsistent/violating convention.
Now if it is the name of the directory, it's redundant, because the same information is, well, in the name of the directory.
If it is main, it's kind of useless, because as far as I can see there is no way to tell go build to "please build all main packages".
* Because, in other words, one directory is one package.
The name of the package does not have to coincide with the directory name. It is possible to have package foobar in the directory xyz/go-foobar. In this case, xyz/go-foobar becomes an import path, but the package name that you use to quality the identifiers (functions, types etc.) would be foobar.
Here's an example to make it more concrete: I created a test package http://godoc.org/github.com/dmitris/go-foobar (source in https://github.com/dmitris/go-foobar) - you can see from the documentation page, that the import path is "github.com/dmitris/go-foobar" but the package name is foobar, so you would call the function it provides as foobar.Demo() (not go-foobar.Demo()).
A similar real-life example - the import path for the NSQ Messaging platform is "github.com/nsqio/go-nsq" while the package name is "nsq": http://godoc.org/github.com/nsqio/go-nsq. However, for the sake of user-friendliness and simplicity, the standard and recommended practice is to keep the last portions of the import path and the package name being the same whenever possible.
package main is not useless - it tells the Go compiler to create an executable as opposed to a .a library file (with go install or go get; go build discards the compilation result). The executable is named after the directory name in which the package main file or files are placed. Again a concrete example - I made a test program https://github.com/dmitris/go-foobar-client, you install it with go get github.com/dmitris/go-foobar-client and you should get a go-foobar-client executable placed in your $GOPATH/bin directory. It is from the the directory name where the package main file is placed that the Go compiler takes the name of the executable from. The filename of the .go file that contains the main() function is not important - in the example above, we can rename main.go to client.go or something else, but as long as the enclosing directory is called go-foobar-client, that's how the resulting executable will be named.
For an additional accessible and practically oriented reading about Go packages, I recommend Dave Cheney's article "Five suggestions for setting up a Go project" http://dave.cheney.net/2014/12/01/five-suggestions-for-setting-up-a-go-project.
The missing information you "have" is that the package name does not need to be the same as the directory name.
It is perfectly fine to use a package name other than the folder name. If you do so, you still have to import the package based on the directory structure, but after the import you have to refer to it by the name you used in the package clause.
For example, if you have a folder $GOPATH/src/mypck, and in it you have a file a.go:
package apple
const Pi = 3.14
Using this package:
package main
import (
"mypck"
"fmt"
)
func main() {
fmt.Println(apple.Pi)
}
Just like you are allowed to use relative imports but is not advisable, you may use package names other that their containing folder, but this is not advisable also to avoid further misunderstanding.
Note that the specification doesn't even require all files belonging to the same package to be in the same folder (but it may be an implementation requirement). Spec: Package clause:
A set of files sharing the same PackageName form the implementation of a package. An implementation may require that all source files for a package inhabit the same directory.
What's the use of this?
Simple. A package name is a Go identifier:
identifier = letter { letter | unicode_digit } .
Which allows unicode letters to be used in identifiers, e.g. αβ is a valid identifier in Go. Folder and file names are not handled by Go but by the Operating System, and different file systems have different restrictions. There are actually many file systems which would not allow all valid Go identifiers as folder names, so you would not be able to name your packages what otherwise the language spec would allow.
So in one hand not all valid Go identifiers may be valid folder names. And on the other hand, not all valid folder names are valid Go identifiers, for example go-math is a valid folder name in most (all?) file systems, but it's not a valid Go identifier (as identifiers cannot contain the dash - character).
Having the option to use package names different than their containing folders, you have the option to really name your packages what the language spec allows, regardless of the underlying operating and file system, and put it in a folder named anything that the underlying OS and file system allows - regardless of the package name.

Getting access to functions from subdirectories

I'm writing small app following http://golang.org/doc/code.html
My directory tree looks like
-blog
-bin
-pkg
-src
-github.com
-packages_that_i_imported
-myblog
-config
routes.go
server.go
my server.go file contains following code
package main
import "..." //ommited imports
func main(){
r:= mux.InitRoutes() //function from imported package
Register_routes(r) //function from routes.go
}
And my routes.go
package main
func Register_routes(r *Router){
r.addRoute("test", "test", "test)
}
But after I do go run server.go
I'm getting following error
$ go run server.go
# command-line-arguments
./server.go:10: undefined: Register_routes
GOPATH variable points to my /blog folder
What am I missing? Why go doesn't it see files in subdirectories?
P.S. config/routes.go is part of server.go package
P.P.S I have moved routes.go to the same folder as server.go, but the error is still present
In order to use a function defined in another package, first you have to import it:
import "myblog/config"
And after that you have to refer to it by the package name:
config.Register_routes(r)
Also the package name should reflect the folder name in which it is defined. In your routes.go the package should be config. Package main is special, the main package will be compiled into an executable binary (it is the entry point of the program). See Program Execution in the language specification.
From the page you linked: Package names:
Go's convention is that the package name is the last element of the import path: the package imported as "crypto/rot13" should be named rot13.
Executable commands must always use package main.
There is no requirement that package names be unique across all packages linked into a single binary, only that the import paths (their full file names) be unique.
Check out the blog post Package names for a detailed guideline.
Note that different files of the same package have to be put into the same folder. And different files of the same package can use everything from the package without importing it and without using the package name (doesn't matter in which file it is defined). This is also true for unexported identifiers. From another package you can only access exported identifiers (their name must start with a capital letter).
Also the go naming convention is to used mixed caps rather than underscores to write multiword names, see Effective Go / MixedCaps. So the function should be named RegisterRoutes but this is not a requirement.

Resources