how to find an executable on NixOS? - haskell-stack

On NixOS if I invoke stack exec which it isn't able to find the which binary.
stack exec which -- which
Executable named which not found on path: [... huge list of PATHs omitted ...]
what is the idiomatic way to find where an executable is located? (which is made available by a build-tool-depends)
Note that which which works, I have no idea why stack exec which breaks down.

Related

How can I invoke my code in bash like most compilers/interpreters are invoked? i.e. when someone types "python <file>", "java <file>" or "g++ <file>"

I am on Mac, but it would be best if there was a way to do this on any platform.
I want my program to behave as if it is an "HTML Compiler" - namely, to behave like the compilers/interpreters for Python, Java, C, C++, Node, etc. I don't understand how to install the program in bash so that I can invoke it like those other ones are invoked.
Namely, I want to run my program with
a global command (meaning accessible from any directory),
an optional specified argument for the HTML file, and also
context of which directory the command came from (so that the program can make later changes to that directory).
This is what it should look like:
parchment index.html or parchment .
I know how to make aliases and custom scripts in bash, but there is some piece missing where I can't figure out how to get all of these functionalities.
If it matters, the program itself is written in Java, and currently not an executable. I run it in the directory it is in by typing "java Parchment".
Thanks!
Create parchment like this
#! /usr/bin/env python3
import os
import sys
print('arg:', sys.argv)
print('cwd:', os.getcwd())
then
chmod +x parchment
You can run it from anywhere on your filesystem, like
/path/to/your/parchment
If you don't want to specify the absolute (or relative) path, parchment should be in a directory in your PATH. Check
echo $PATH
and move it to a directory in there
mv parchment /Users/myuser/bin/
edit
One more clarification. Once you have done all of these steps do:
parchment myfile.html
and see the output.

Linker fails in sandbox when running through Bazel but works when sandboxed command is executed from the command line

I'm trying to get our cross-toolchain (standard Yocto toolchain) working with Bazel. I followed the instructions on https://github.com/bazelbuild/bazel/wiki/Building-with-a-custom-toolchain but the linker fails every time I try to build a simple test program. It says
external/toolchain_e6500/sysroots/x86_64-fslsdk-linux/usr/bin/powerpc64-fsl-linux/../../libexec/powerpc64-fsl-linux/gcc/powerpc64-fsl-linux/4.9.2/real-ld: cannot find /lib64/libc.so.6
external/toolchain_e6500/sysroots/x86_64-fslsdk-linux/usr/bin/powerpc64-fsl-linux/../../libexec/powerpc64-fsl-linux/gcc/powerpc64-fsl-linux/4.9.2/real-ld: cannot find /usr/lib64/libc_nonshared.a
external/toolchain_e6500/sysroots/x86_64-fslsdk-linux/usr/bin/powerpc64-fsl-linux/../../libexec/powerpc64-fsl-linux/gcc/powerpc64-fsl-linux/4.9.2/real-ld: cannot find /lib64/ld64.so.1
The sysroot is set properly. When running the linker command outside of the sandbox (e.g. with --spawn_strategy=standalone or just manually) it works always. The strange thing is that when I use --debug_sandbox and run the emitted command from the command line, it works, too.
I've been debugging this issue for two days now, including straceing the Bazel daemon and comparing the real-ld input but I didn't find anything suspicious.
There must be a difference between the execution environments but I'm out of ideas now. Here is the failing command as printed by --debug_sandbox:
(cd /home/sick/.cache/bazel/_bazel_sick/2a7ae5e27644389520091aa03d045c73/execroot/__main__ && \
exec env - \
PATH=/home/sick/bin:/home/sick/.local/bin:/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin:/usr/games:/usr/local/games:/snap/bin:/home/sick/bin \
PWD=/proc/self/cwd \
TMPDIR=/tmp \
/home/sick/.cache/bazel/_bazel_sick/2a7ae5e27644389520091aa03d045c73/execroot/__main__/_bin/linux-sandbox -t 15 -w /home/sick/.cache/bazel/_bazel_sick/2a7ae5e27644389520091aa03d045c73/sandbox/linux-sandbox/2/execroot/__main__ -w /tmp -w /dev/shm -D -- tools/compiler_e6500/e6500_gcc/powerpc64-fsl-linux-gcc -o bazel-out/e6500-fastbuild/bin/test '--sysroot=external/toolchain_e6500/sysroots/ppc64e6500-fsl-linux' -no-canonical-prefixes -pie -Wl,-z,relro,-z,now -Wl,-S -Wl,#bazel-out/e6500-fastbuild/bin/test-2.params)
You can take a look at the workspace here https://github.com/jasal82/bazel-cross-eval
I can provide the toolchain if needed.
UPDATE 2018-09-25
I did some more investigation after reading the answer regarding the linker script below. Section 4.4.2 in this manual says that
In case a sysroot prefix is configured, and the filename starts with
the / character, and the script being processed was located inside the
sysroot prefix, the filename will be looked for in the sysroot prefix.
Otherwise, the linker will try to open the file in the current
directory.
Obviously the script is not being considered to be located inside the sysroot prefix by ld and thus used literally (i.e. resolved relative to the current dir, probably the sandbox root). That would explain the observed behavior. However, I still don't understand why it does not happen when I run the command manually, i.e. not through the Bazel daemon.
Could this be related to the relative sysroot path used in the CROSSTOOL file? As far as I understood you cannot specify an absolute path to the sysroot due to the sandboxing. What is the recommended way to handle this in Bazel? I would like to avoid having to patch the toolchain.
Have a look at lib.so in your sysroot. It probably looks something like this:
/* GNU ld script
Use the shared library, but some functions are only in
the static library, so try that secondarily. */
OUTPUT_FORMAT(elf64-x86-64)
GROUP ( /lib/x86_64-linux-gnu/libc.so.6 /usr/lib/x86_64-linux-gnu/libc_nonshared.a AS_NEEDED ( /lib/x86_64-linux-gnu/ld-linux-x86-64.so.2 )
Change the paths in it to be relative to the directory that libc.so is in. You'll have to perform a similar operation on libm.so and libpthread.so.
The GNU linkers resolve symlinks before evaluating whether a script is within the sysroot. The current Bazel Linux sandbox implementation makes a symlink farm of all an action's inputs. Thus, the libc.so.6 linker script is detected as being in the sysroot outside the sandbox but not within the sandbox.

Why might "--enable-load-relative" not work for a ruby install?

I need to install ruby at several sites, but the exact location of the install may be slightly different between the various sites.
I configured and compiled using the -enable-load-relative. This seems to work for my linux install but not for aix. When I configured for linux I used
--enable-load-relative --prefix=blah --exec-prefix=blah/linux_code_rel
I was able to test the relative loading by doing the following:
first with the install dir named linux_code_rel
blah/linux_code_rel/bin/ruby -e " puts 'hello' "
then after renaming the directory to linux_code, ran
blah/linux_code/bin/ruby -e " puts 'hello' "
both times I got back hello
When I did the same thing for aix, it does not seem to work.
I configured and installed using
--enable-load-relative --prefix=blah --exec-prefix=blah/aix_code_rel
after installing if I run
blah/aix_code_rel/bin/ruby -e "puts 'hello' "
I get back
hello
if i rename aix_code_rel to aix_code and run
blah/aix_code/bin/ruby -e "puts 'hello' "
I get
<internal:gem_prelude>:1:in `require': cannot load such file -- rubygems.rb (LoadError)
from <internal:gem_prelude>:1:in `<compiled>'
creating a symbolic link using ln -s aix_code aix_code_rel, seems to fix this, which indicates that the install is always looking for the code to be found using the path blah/aix_code_rel , despite the fact that i configured with --enable-load-relative
I seem to be able to get past this by setting the RUBYLIB env variable, but this seems messy, especially given that the linux install seems to work with the relative loading.
Anyone have an idea what I might be doing wrong? Is there any other why I can set the default LOAD_PATH? Maybe some post install configuration file?
I've not tried that option but on AIX that will be some trick to get it to work.
If you find an executable or a shared library (like miniruby or libruby.so.xxxxx) and do:
dump -H miniruby
you will see output that shows what it depends upon. Below the "Import File Strings" you will see a list. The 0th entry is what that particular executable or shared library uses for its "libpath". You could make those relative paths. It does work. But that introduces a security risk (which I just recently was told of) that the Ruby build process tries to avoid.
This is if LIBPATH is not set in the environment. If LIBPATH is set in the environment, then it will use that path in all cases.
Oh... there is actually an exception to this. (I'm editing as I'm typing) The 1st through nth entries in the import file strings list can be absolute paths in which case not even LIBPATH will alter the search since there is no search done.
What might work is to wrapper "ruby" in a script that sets LIBPATH and then exec's ruby using the same arguments. Something like:
#!/bin/sh
export LIBPATH=/blah:/ble/blah:/usr/lib:/lib
exec real-ruby "$#"
The small dance that you have to do or worry about is if ruby looks at argv[0] and does different things based upon its name. I don't think it does. And the other part is that you might need to set GEM_HOME and some of the other ruby environment variables.
The other real world suggesting is to create a symlink from where it is suppose to be installed to the place that it is installed. Do this for the bin and lib directory and that might work as well.

-bash: otool: command not found, Can you teach bash a default location to look for a command?

I can find the tool command in my filesystem under:
/Applications/Xcode.app/Contents/Developer/usr/bin/otool
If I specify that entire path, otool will work.
/Applications/Xcode.app/Contents/Developer/usr/bin/otool -tV hello -p _main
However, since I have to be inside the folder of the hello.c file I'm referencing, bash won't find otool automatically if I just type
otool -tV hello -p _main
I've had this same problem with a number of commands. Is there any way to set up bash so it automatically finds otool (and similar commands), without me having to writing out the entire path name each time? Thanks!
Note: If it matters, I'm using a Mac.
Note 2: I've read through a ton of the "Command not found" threads but none seem to answer the question of teaching bash where to look for a command by default. I feel like this question should have been answered somewhere, but haven't come across it yet. Since the only programs I'll be working with any time soon will be iOS/Xcode related, this is worthwhile shortcut.
PATH=$PATH:/Applications/Xcode.app/Contents/Developer/usr/bin
Put this in your ~/.bashrc to have it persist.
You can also Try using alias to do this. e.g.
$ alias otool='/Applications/Xcode.app/Contents/Developer/usr/bin/otool'
You can also add this in your bashrc/profile file.

OCaml Installation, not finding binaries

I am attempting to install and run objective-caml on a remote unix server.
I have successfully built and installed all files included in the ocaml package. However, when attempting to use it, eg:
[~]# ocamllex
gives:
-bash: /home1/PATHTOMYHOME/local/bin/ocamllex: /usr/local/bin/ocamlrun: bad interpreter: No such file or directory
Is there any way to tell it to look somewhere else for ocamlrun? The correct directory is in the $PATH variable (ocamlrun works).
You can pass the name of the bytecode file to ocamlrun:
/correct/path/to/ocamlrun /home1/PATHTOMYHOME/local/bin/ocamllex
Alternately, it may just work to edit the first line of the bytecode file: there is a #! and a hardcoded path there. The rest of the file is bytecode though, but if your editor does not mess with it, there is a chance...
As a third solution, use the native-compiled version ocamllex.opt: it does not rely on ocamlrun.
On unix systems, Ocaml bytecode executables begin with a shebang line that gives the path to the bytecode interpreter (ocamlrun). It seems that your executables start with #!/usr/local/bin/ocamlrun. Change this to /home1/PATHTOMYHOME/local/bin/ocamlrun.
If you want ocamlrun to be looked up in the $PATH, change the shebang line to #!/usr/bin/env ocamlrun.
Here's a way to change the path to the bytecode executables in the current directories, leaving other files intact. Remove the *.orig files once you've checked the replacement works.
perl -i.orig -pe 's~^#!.*/ocamlrun.*~#!/usr/bin/env ocamlrun~ if $.==1; close ARGV if eof' *
I suggest that you compile OCaml with ./configure -prefix /home1/PATHTOMYHOME/local. That way all programs will look in the right directories automatically.

Resources