V: A solution to the ~/code problem. What do you think?

Created on 23 Jun 2019  ยท  26Comments  ยท  Source: vlang/v

Hey,

Right now V must be installed in ~/code/v, because it needs to know the location of the vlib modules.

One way to fix this is introduce an environment variable, like Go's GOROOT. But I really don't like this.

I came up with the following idea. You git clone v.git in any directory, cd compiler/, build V. When building for the first time, V will look for the modules in the parent directory, and write down that directory in ~/.config/v.

Now it can be used anywhere, and the V installation can also be anywhere.

What do you think?

Announcement

Most helpful comment

@aguspiza should be $XDG_CONFIG_HOME/(v|vlang)

All 26 comments

I wouldn't really regard keeping track of the modules a configuration, more so metadata than anything. Personally I think ~/.v would be a viable decision, and any subsequent child directories such as modules, build data, output, etc, would get placed within there. Having a defuncto place where everything is located keeps things much simpler, having explicit control via environmental variables seems more hassle than it's worth - but still maybe a consideration.

How about instead installing libraries in /usr/lib?

How about instead installing libraries in /usr/lib?

As much as it sounds nice, libraries shouldn't be system wide imo. But confined within the users home directory which also helps with versioning and libs potentially conflicting. Seems to be a much more simplistic route than placing libs globally.

I remember most time we don't need explicit set GOROOT var, but go depend on it's install directory structure. So once you know go's path, it can automatically populate lib path.

Another, not think save a config file is good. just dynamically calculate.

I would like to have ~/.vlang as V config directory.

I suggest using /usr/share/vlang/ for compiler source files and vlib; compiled modules should be stored and automatically looked for in project directories, e.g. ./modules, ./.modules, etc.

A GOPATH or PYTHONPATH like solution is the cleanest in my opinion. It doesn't clutter the system path with libraries of different versions.

We should consider multi-versions of vlang coexists on a system.

I like the GOPATH way better.
If a config file is used,

  • how do you use different v versions? with an environment variable for the configuration path?
  • how do you use a version you haven't built yourself (e.g. a packaged binary)?

The default path could also be specified at build time and embedded in the binary, which would help for distributions and local development builds.

We should consider multi-versions of vlang coexists on a system.

A great approach could be involving a solution like rustup/nvm, by using it we can updating/choosing the compiler version (for example: "v use v0.0.*, v use stable or v use devel).

And what should Linux package maintainers do?
In Linux, the right place where vlib should be is /usr/lib/(v|vlang)/(lib|vlib)

For example in ArchLinux
For Rust /usr/lib/rustlib/

For Go:

$ echo $GOPATH
/home/user/.go
$ \ls -1 ~/.go/
bin
pkg
src



md5-b79b441eba996a3dfdcb5c913da0e4b2



$ readlink -f /usr/bin/go
/usr/lib/go/bin/go



md5-b79b441eba996a3dfdcb5c913da0e4b2



$ \ls -1 /usr/lib/go/
api
bin
doc
lib
misc
pkg
src
test
VERSION

Please do not clutter home with hidden folders, use ~/.config/.v or ~/.config/v
Thank you for you awesome work.

A great approach could be involving a solution like rustup/nvm, by using it we can updating/choosing the compiler version (for example v0.0.*, stable and devel).

I like rustup too. but:

  • rustup is a outband tool. It is not in the rustc.
  • it is difficult to make this approach work well. rustup have 23k loc (even more than the whole vlang project). using GOPATH way just keep it simple.

@aguspiza should be $XDG_CONFIG_HOME/(v|vlang)

I used to be less than fond of the GOPATH way myself.
Once you get used to it, you really don't want to miss it though.

It's really not that bad. I think you should consider it.

Personally I would also put my voice behind following the freedesktop specification.
Using $XDG_DATA_HOME for libraries / compilers and maybe even global modules (if that would be added) and $XDG_CONFIG_HOME for a config file managing the information about versions/libraries. Sure that would be more effort to implement, but it would be a clean solution.

A temprorary work around is something like this:

cd v

wget https://vlang.io/v.c

curren_lib="$(pwd)"

sed \
    "s|os__home_dir(), tos2(\"/code/v/\")|tos2(\"${curren_lib}\"), tos2(\"/\")|g" \
    v.c \
    > compiler/v.c

cd compiler
clang -w -o vc v.c

sed -i \
    "s|mut lang_dir = os.home_dir() + '/code/v/'|mut lang_dir = '/usr/lib/v/'|g" \
    main.v

./vc -o v .

Maybe the makefile can be modified to make those changes on the fly and compile and even support a PREFIX flag to be able to change the /usr/lib value...

I implemented it experimentally.
Screenshot from 2019-06-24 22-25-22

It uses V_PATH env-var and use ~/code/v/ if not defined.
I think a great point of this way is

  • we can even introduce config file later
  • developer can choose the path according to preference

+1 for considering Linux package managers.
/usr/lib, or /usr/share should be fine.

A bit off, but I made a asdf version manager plugin for V, and I seemed to achieve multiple v installs by recreating symlinks.

$ asdf plugin-add v https://github.com/ndac-todoroki/asdf-v.git
$ asdf install v master
$ asdf install v ref:c32c02b
$ asdf global v master

$ v
V 0.1.0

$ asdf global v ref:c32c02b

$ v
V 0.0.12

This still requires ~/code/v to be untouched by the user. (The plugin simply does rm ~/code/v and ln -s ~/.asdf/installs/v/{version}/v ~/code/v everytime v is called)
If the installation directory could be given as a argument as compile options, I think these kind of things could be implemented more cleaner.

Taking this opportunity I want to insert a pretty penny. Personally, I like how it (subject) is organized in Go. I would not mind if it will be done like in rvm/nodejs (e,g, ~/.v), it is OK too. Options with installation into /usr/share/usr/src and similar are OK too. But option with ~/.config/v causes rejection. This is because the directory contains the source code, not the configuration.

IIRC clang has a similar issue with its so called "ressources" directory. As far as I remeber, one solution is to look for this ressources directory relatively to the clang binary path itself, with different checks (to support a build tree and a final installation tree).

In the end, my recommandation is: check how clang is doing.it :)

We talked to the author about it and it seems the preliminary decision on this issue will be as follows:

  • $VROOT, ~/.vlang will be removed.
  • Third-party modules will be stored in ~/.local/lib/vmodules
  • During the compilation, you will be able to specify the path in which the vlib will stored. This path will be hardcoded (eg. /usr/lib/vlib). This is linux friendly.

    • Without this option (or if this path will be invalid) V will try to search for vlib in ./vlib/ or ../vlib/ (for github repo builds)

  • Different versions of V can be changed by simply changing the symbolic link for /usr/bin/v or ~/bin/v

We should use a $VROOT environment variable.
It's better in many points:

  • If we want to use another version of V to test a file it's only one line:
    VROOT=/another/version v run test.v
  • If we want to change the V version for a project, we just change the environment variable and it doesn't affect the whole system version of V. Meaning if we have another terminal or SSH session opened, they are not affected by the version change of V and they will still use the default V version.
  • If there are multiple versions of V installed in a docker image (why not) it's easier to switch to another version:
    docker run -e VROOT=/another/version -it vlang v
    Good luck with a symlink.
  • It allows more flexibility for the user. If he doesn't want to store V in the default folder, he can simply change the directory of V and set the environment variable to the new path.

We should also determine how we can separate a project into multiple modules and find them at the project level. We can get inspiration from Go:

// project/api/main.v 

module api
....
// project/config/main.v 

module config
....
// project/cmd/test/main.v

module main

import github.com/someone/project/api
import github.com/someone/project/config
....

I like the idea of having the test file next to the module it tests (unit test), while having a tests folder for other integration or functional tests

โ””โ”€ myproject
   โ”œโ”€โ”€ src
   โ”‚   โ”œโ”€โ”€ main.v
   โ”‚   โ””โ”€โ”€ vmodules
   โ”‚   โ””โ”€โ”€ mymodule.v
   โ”‚   โ””โ”€โ”€ mymodule_test.v
   โ””โ”€โ”€ tests
       โ””โ”€โ”€ helloworld.v

Now, when you compile v - it does not use external directory ~/.vlang/
Third-party modules will be stored in ~/.vmodules in future
We will not add -vlib or -vlib-dir

For Linux packages, you should copy v, vlib, thirdparty to /usr/lib/vlang and create a symbolic link /usr/bin/v -> /usr/lib/vlang/v

This is the same as in Go https://git.archlinux.org/svntogit/community.git/tree/trunk/PKGBUILD?h=packages/go

Look in Archlinux PKGBUILD for example https://aur.archlinux.org/cgit/aur.git/tree/PKGBUILD?h=vlang-git

Please create a new issue if you have any other suggestions.

Was this page helpful?
0 / 5 - 0 ratings

Related issues

medvednikov picture medvednikov  ยท  3Comments

aurora picture aurora  ยท  3Comments

elimisteve picture elimisteve  ยท  3Comments

ArcDrake picture ArcDrake  ยท  3Comments

markgraydev picture markgraydev  ยท  3Comments