How do I install GHC 7.8.1 and assign it a different command? - unix

I would like to install GHC 7.8.1, but would like to assign it different commands, so as not to clash with 7.6.3. For example:
runghc with runghc7.8.1
ghci with ghci7.8.1
etc...
Or similar. (ghci would be most important, for typed holes.)
Basically, I want to be able to use GHC 7.8 and 7.6, so if there is a more direct way to do this tell me (A-B problem.)
Note: Ubuntu 13.10

Because you are on a unix-like system (Ubuntu) you can do the following:
Choose a folder you like for installing ghc (e.g. in a subfolder of your home directory like $HOME/ghc7.8.1 or in a subfolder of /opt like /opt/ghc7.8.1 – I would prefer the later one if you are the only user of your computer and the first one if this isn't the case). See this wikipedia article for explanations about the unix directory structure.
Download the source code into that folder and follow the installation instructions:
See also https://ghc.haskell.org/trac/ghc/wiki/Building/Using#Runtheconfigurescript
In configure setp its important, that you set the --prefix to the folder you have chosen above (if you don't do this, ghc will be installed in /usr/local/ which you do not want)! For example:
./configure --prefix=/opt/ghc7.8.1
After the installations look for the folder with the created binaries (it will be called bin if you did not use another name for bindir). Lets imagine this folder is /opt/ghc7.8.1/bin.
Now you have two possibilities:
Solution with creating symlinks: Create symlinks in a folder which is in your $PATH pointing to the created binaries (for example /usr/local/bin or $HOME/bin – I would use the first one, if you are the only user on your computer and the second if, if you are not). Therefore you have to use the command line tool ln. For example:
sudo ln -s -T /opt/ghc7.8.1/bin/runghc /usr/local/bin/runghc7.8.1
After this command there is a file /usr/local/bin/runghc7.8.1 pointing to the binary /opt/ghc7.8.1/bin/runghc. Executing /usr/local/bin/runghc7.8.1 via typing runghc7.8.1 will now execute the runghc binary created in /opt (Note: sudo is not necessary if you create your symlink in $HOME/bin – it is just needed because root can create files under /usr)
Solution with bash aliases: Write in your $HOME/.bash_aliases (#Others: you can alternatively choose $HOME/.bashrc or $HOME/.profile depending of your system/preference) the following line:
alias runghc7.8.1='/opt/ghc7.8.1/bin/runghc'
Now typing runghc7.8.1 in your terminal is an shortcut (alias) for typing /opt/ghc7.8.1/bin/runghc and will execute this binary.
Note, that with this solution typing runghc7.8.1 will just work, when you typed it into your terminal. There are cases, when it does not work (for example calling runghc7.8.1 in a script).

Related

Different local and remote organisation R Project and GitHub

I want to version control my R scripts so I've created an R project and a GitHub repo. My scripts are scattered through several directories within the same directory where the R project is.
I would like that my GitHub repository harbors only the scripts, independently of the folders they are locally stored in. However when I run the below command:
git add folder/file.R
git commit -m "my_message"
git push -u origin master
A directory named folder is created containing file.R but I'd like to just see file.R without the folder. Do you know how can I do this? Also, would it be good practice? My local folders are organized so each directory contains its own scripts and results, that's the reason the scripts are separated.
Thank you very much
is there a way to add the file.R without specifying the path?
Not using git add, no. The design constraint for git add is that it should store the file's name exactly as it appears, including the forward slashes, so if the file's name is folder/file.R, that's the file's name.
You have some options here though:
You can make a parallel directory where you put the files with the names you want them to have. Run git init in that directory, copy the folder/file.R file to file.R in that directory. Then cd ../gitdir or whatever is appropriate to get there, and git add file.R.
This method is probably the best because it's the simplest.
You can write your own programs using git hash-file -w and git update-index, which are two of Git's plumbing commands. A plumbing command, in Git, is basically a command that exists so that you can build user-facing commands: they're not meant to be run by humans but rather by other programs. So you write a program (in whatever language you like) that uses these plumbing programs to achieve whatever you want.
In particular, you can create or find a Git blob object holding the contents of file.R as read from anywhere you like, then use git update-index to create an index entry holding whatever path you like and referring to the blob object you created (or found) with git hash-object with the -w flag.
Since Git is a suite of tools, not a solution, you can come up with your own method. The tools in Git are made with particular approaches in mind, but they are flexible enough to be repurposed.

Why changing LD_LIBRARY_PATH has no effect in Ubuntu?

I was trying to deploy my application on Ubuntu 16.04. So i made a package with the following hierarchy -
Package
|
----bin
|
-----application
-----application.sh
-----Qt
|
-----necessary qt libraries
-----platforms
Here is the application.sh file -
#!/bin/sh
export LD_LIBRARY_PATH=`pwd`/Qt
./application
When i execute the application.sh file, it shows me that it cant find the libQt5MultimediaWidgets.so.5 file. But its in the Qt folder. Also when i print the ldd application from the application.sh file after exporting LD_LIBRARY_PATH it gives me following output -
Please check the marked parts. Can anyone please explain why the libraries from the Qt folder are not found even after exporting the LD_LIBARRY_PATH?
Edit:
So as suggested by #Zang, i have checked the debug log and here it is -
Please check the marked parts.
It seems like its actually trying the actual libQt5MultimediaWidgets.so and then report that its unable to find it. Can anyone please help me understand whats happening here?
Edit-2: As per suggestion from #Tarun, i have ran ls -al on my Qt folder. Here is the output -
All files in Your Qt directory are actually simlinks to non-existing files in the same directory, therefore they cannot be found.
If you look at the output of your ls -al
These are soft links that you have. Your softlink libQt5MultimediaWidgets.so.5 points to libQt5MultimediaWidgets.so.5.9.2 in the same directory and the file is not there at all. So you need to either set the correct softlink path or have the file in same directory
First
Could it be that the pwd is not where you assume it is?
You could try adding
# Figure out where the application.sh script is located
scriptpath="$( cd "$(dirname "$0")" ; pwd -P )"
# Make sure our pwd is that location
cd "$scriptpath"
in the top of your script (assumes bash shell, from here)
By doing this all relative paths to Qt folder will be valid.
Second
Maybe you should considder exporting your new LD_LIBRARY_PATH, like so (from here):
LD_LIBRARY_PATH=whatever
export LD_LIBRARY_PATH
Third
It may be useful to run ldconfig command for ld to update after changing the variable (from here):
sudo ldconfig
The file libQt5MultimediaWidgets.so is not present in /Desktop/package/bin/Qt according to the screenshots shown.

Symlink dotfiles

I am having trouble symlinking dotfiles. I have a folder in my home directory ~/dotfiles which I have synced to a github repo. I am trying to take my .vimrc file in ~/dotfiles/.vimrc and create a symbolic link to put it at ~/.vimrc. To do this I type in
ln -s ~/dotfiles/.vimrc ~/.vimrc
But when I run that it says
ln: /Users/me/.vimrc: File exists
What am I doing wrong?
That error message means that you already have a file at ~/.vimrc, which ln is refusing to overwrite. Either delete the ~/.vimrc and run ln again or let ln delete it for you by passing the -f option:
ln -s -f ~/dotfiles/.vimrc ~/.vimrc
There is a better solution for managing dotfiles without using symlinks or any other tool, just a git repo initialized with --bare.
A bare repository is special in a way that they omit working directory, so you can create your repo anywhere and set the --work-tree=$HOME then you don't need to do any work to maintain it.
Approach
first thing to do is, create a bare repo
git init --bare $HOME/.dotfiles
To use this bare repo, you need to specify --git-dir=$HOME/.dotfiles/ and --work-tree=$HOME, better is to create an alias
alias dotfiles='/usr/bin/git --git-dir=$HOME/.dotfiles/ --work-tree=$HOME
At this point, all your configuration files are being tracked, and you can easily use the newly registered dotfiles command to manage the repository, ex :-
# to check the status of the tracked and untracked files
dotfiles status
# to add a file
dotfiles commit .tmux.conf -m ".tmux.conf added"
# push new files or changes to the github
dotfiles push origin main
I also use this way to sync and store my dotfiles, see my dotfiles repository and can read at Storing dotfiles with Git where I wrote about managing for multiple devices.
How to symlink all dotfiles in a directory recursively
Have a dotfiles directory that is structured as to how they should be structured at $HOME
dotfiles_home=~/dotfiles/home # for example
cp -rsf "$dotfiles_home"/. ~
-r: Recursive, create the necessary directory for each file
-s: Create symlinks instead of copying
-f: Overwrite existing files (previously created symlinks, default .bashrc, etc)
/.: Make sure cp "copy" the contents of home instead of the home directory itself.
Tips
Just like ln, if you want no headache or drama, use an absolute path for the first argument like the example above.
Note
This only works with GNU cp (preinstalled in Ubuntu), not POSIX cp. Check your man cp, you can install GNU coreutils if needed.
Thanks
To this and this.

How to share/transfer an Atom installation (packages and settings) from one Mac to another?

Is it possible to copy Atom from one Mac to another, including all installed packages, settings etc?
There are several ways to synchronize your settings and packages between Atom installations:
Git: Create a public or private Git repo and store the contents of your local ~/.atom folder in there. Ignore the following files/directories in a .gitignore file:
storage
compile-cache
dev
.npm
.node-gyp
Use a package like sync-settings. This will store your configuration in a GitHub Gist.
Dropbox (or similar): Move your ~/.atom folder to your Dropbox folder and then symlink it from there to its original location. This has the downside of syncing everything in ~/.atom, even the things you could ignore.
Use stars to select your favorite packages. On the Atom web site, create an account and mark your favorite packages with stars. Then use apm stars --install to install all starred packages on any machine. Downside: This only works for packages, not for settings.
More details:
https://discuss.atom.io/t/syncing-settings-packages-between-machines/1385
As a user who uses a dotfile management system such as RCM, I prefer independent config files.
For now, Atom doesn't officially provide a packages.cson file to manage plugins, but as the post Syncing settings & packages between machines mentioned, there is a plugin called package-sync that will generate a packages.cson file for us.
So with the help of package-sync, now I can just sync those mininal config files to have my Atom settings and packages consistent across multiple machines.
This is how to do it (Use ubuntu as an example):
Install Atom, and install package-sync through Edit-->Preferences-->Install as the screen shot shows:
Open your command pallete and type: Create Package List and there will be a packages.cson file under your ~/.atom folder.
Edit the gitignore file:
$ gedit ~/.atom/.gitignore
Make sure the content is:
blob-store
compile-cache
dev
storage
.node-gyp
.npm
.apm
packages/
atom-shell/
This is a screenshot of the .gitignore file:
This makes sure the content downloaded by Atom from the Internet will not get synced to your dotfiles repo.
Move the .atom folder to the dotfile repo:
$ mv ~/.atom ~/dotfiles/tag-atom/atom
Relink the folder:
$ ln -s ~/dotfiles/tag-atom/atom ~/.atom
Or if you have rcm installed:
$ rcup
Now go to another machine, and install Atom and package sync. Update your dotfiles repo, and then Open your Atom command pallete and type: sync
Now your Atom settings will get synced and integrated with the RCM dotilfe management system.
This is the files in my ~/.atom folder that get synced:
I recently built a package that syncs automatically your Atom settings and packages across multiple computers. A little bit like the bookmark synchronization mechanism in Google Chrome. It's called atom-package-sync. Maybe it could fit your needs.
You can sync your packages via package-list.txt file and a simple shell script.
Create the package-list.txt file
apm list --installed --bare > package-list.txt
Install missing packages on another host
BASEDIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
INSTALLEd_PKGS=$(apm list --installed --bare)
for PKG in $(cut -f1 -d# $BASEDIR/package-list.txt); do
grep -q $PKG <<< $INSTALLEd_PKGS || apm install $PKG
done
The .atom folder contains the packages folder, which can be rather huge. Unfortunately OneDrive doesn't allow you to exclude folders, so I went with a git option.
I excluded the packages from git and instead I committed a text file containing my packages (my-packages.txt).
To re-install packages I need to run: apm install --packages-file my-packages.txt.
To generate the my-packages.txt, I need something like this on a Bash shell: ls packages | xargs -n 1 echo | cut -d/ -f1 > my-packages.txt
I sync my Atom settings between Windows, macOS, and Linux machines using Resilio Sync Home. It is free and the files are not saved on the "cloud" (like Dropbox or Gists), but it requires that, at least, two machines are online in order to sync the current settings.
I do not want to sync caches, installation specific settings, et al., I update the .sync/IgnoreList file that is created in the synced directory (i.e., the ~/.atom directory). Unfortunately, you will have to update this on each machine that you sync (ironically, the IgnoreList file is not synced). By default, the file specifies various temporary files to be omitted from syncing, so you'll need to add the following:
## Atom-specific
/packages/node-debugger/debugger.log
\packages\node-debugger\debugger.log
/.apm
\.apm
/.node-gyp
\.node-gyp
/.npm
\.npm
/blob-store
\blob-store
/compile-cache
\compile-cache
/dev
\dev
/recovery
\recovery
/split-diff
\split-diff
/storage
\storage
Some of the omitted directories are package-specific (e.g., split-diff). Because Windows has different path delimiters than other platforms, I need to specify both(!!)
Install Resilio Sync Home on your first machine
Add the .atom directory to Resilio to be synced.
Update its IgnoreList file, as shown above. Save this file for the other machines you want to sync with.
Send a Resilio "Read & Write" link of that folder to the other machines you want to sync with or copy the "Read & Write" key to be used on the other machines. To do this, in Resilio's folder view, click on the .atom folder's menu (vertical dots on the right edge) and select "Copy Read & Write key". Save it for later.
Then on your other machines,
Install Resilio Sync Home
Create .atom/.sync
Copy the IgnoreList from your first machine to that directory
Add the .atom directory to be synced with the other machine. You should add the folder using "Enter key or link," then enter the key you copyed, above.
Wait until syncing is done before opening Atom. The first time will may take a few minutes.
Now I don't need to go around installing/removing packages on every machine, separately!
FYI: Changes to files and directories are saved in .sync/Archive, for some period of time, if you should need to recover them.

How do I create a directory with a file in it, in one step?

In the terminal, is there a way to create a directory with a file in it in one step?
Currently I do this in 2 steps:
1. mkdir foo
2. touch foo/bar.txt
Apparently, touch foo/bar.txt doesn't work.
With only standard unix tools, the most direct way to create a directory and a file in this directory is
mkdir foo && touch foo/bar.txt
Unix is built around the philosophy of simple, single-purpose tools with the shell as a glue to combine them. So to create a directory and a file, you instruct a shell to run the directory creation utility then the file creation utility.
I won't swear that there isn't some bizarre way of using a standard tool that lets you do it with a single command. (In fact, there is: unpack an archive — except that you'll need to provide that archive as a file, with predefined owner, date and other metadata, or else use another command to build an archive.) But whatever it is would be convoluted.

Resources