LFS: GCC links wrong - linux-from-scratch

I'm stuck on chapter 6.20 of the current LFS book. I get:
$ readelf -l a.out | grep Requesting
[Requesting program interpreter: /tools/lib64/ld-linux-x86-64.so.2]
instead of the desired:
[Requesting program interpreter: /lib64/ld-linux-x86-64.so.2]
The other tests lower down in the chapter all succeed.
This is my second time through the whole book being extremely careful and I got the same result last time around. Could there be some mistake?
For guidance it just said "The most likely reason is that something went wrong with the specs file adjustment.". That's a reference to 6.10 where it says "It is a good idea to visually inspect the specs file to verify the intended change was actually made" but there's no guidance as to what these intended changes are. But on this second go round I did check in /tools/lib/gcc/x86_64-pc-linux-gnu/7.2.0/specs that there was no mention of "tools" and the /usr paths were mentioned.

I seem to have solved it by making another specs file for the new compiler:
gcc -dumpspecs | sed -e 's#/tools##g' > `dirname $(gcc --print-libgcc-file-name)`/specs
After that, I redo the test:
echo 'int main(){}' > dummy.c
cc dummy.c -v -Wl,--verbose &> dummy.log
readelf -l a.out | grep ': /lib'
And all is well.

Related

gcc command line structure arguments

I try to compile a c file with gcc version 6.3.0 20170516 (Raspbian 6.3.0-18+rpi1+deb9u1).
I run the compiler in the source file's folder, but I keep getting the 'file not found' error message for the last argument ('bcm2835').
gcc -o gpio -l rt /home/pi/bcm2835-1.15/src/bcm2835.c -l bcm2835
/usr/bin/ld: cannot find -lbcm2835
collect2: error: ld returned 1 exit status
AFAIK, The gcc does not specify the third argument, I have no idea what this 3rd argument is used for and where to find it.
If I omit that argument, I get several error lines, each for one of the internal commands, like:
undefined reference to bcm2835_init
I also wish to know what the rt stands for. I could not find it in the official gcc docs.
Thanks
After -l, there should be no space. So it should be -lrt (not -l rt) and it should be -lbcm2835 (not -l bcm2835).
You need to add a linker search path with -L (uppercase L) right before calling -lbcm2835.
The input file should usually be last (that's the argument ending with main.c). That would be
gcc -o main -lrt -lbcm2835 /home/pi/bcm2835-1.15/main.c
-l links a library to the program. -L sets the library search path such that -l will find the libraries specified.
See this page for details on -l and -L.

Determine if app is Wayland or X client

Is there a way to determine if an arbitrary app is an X client or a Wayland client (or neither) from the command line without fully launching it?
You can run ldd on the binary to check which libraries it links against. If it has "libwayland-client" you're probably looking at a Wayland client. For X you need to look for "libX11" or "libxcb".
To expand on the excellent answer given by #Alexander Sukhoverkhov what needs to be done is:
cd /usr/bin
ldd $application_name | grep wayland
Furthermore, to check which binaries have wayland support you could try:
cd /usr/bin
find . | xargs ldd | grep wayland -B 55
The above is not really very clean but it works. You can further pipe it to a file and then use vim to navigate.
cd /usr/bin
find . | xargs ldd | grep wayland -B 55 >> candidates
vim candidates
# Use vi movement
The -B flag stands for before and helps to print the binary name.

Batch rename with command line

I have some files: file1.txt, file2.txt and I would like to rename them like this: file1.something.txt and file2.something.txt
I looked for some similar questions and I come up with this:
for i in file*.txt; do echo mv $i file*.something.txt; done
but unfortunately the output is:
mv file1.txt file*.something.txt
mv file2.txt file*.something.txt
and therefore only 1 file is created.
Could please somebody help?
(I am using a macbook air, I am not sure if this is relevant)
Thank you very much
Try this :
rename -n 's/\.txt/something.txt' *
(remove -n switch when your tests are OK)
There are other tools with the same name which may or may not be able to do this, so be careful.
If you run the following command (GNU)
$ file "$(readlink -f "$(type -p rename)")"
and you have a result like
.../rename: Perl script, ASCII text executable
and not containing:
ELF
then this seems to be the right tool =)
If not, to make it the default (usually already the case) on Debian and derivative like Ubuntu :
$ sudo update-alternatives --set rename /path/to/rename
(replace /path/to/rename to the path of your perl's rename command.
If you don't have this command, search your package manager to install it or do it manually
Last but not least, this tool was originally written by Larry Wall, the Perl's dad.

run a prolog code with swipl in a command line

I am searching for swipl the similar feature as perl -e
In particular, I want to run prolog code in this fashion:
swipl --wanted-flag "fact(a). message:-writeln('hello')." -g "message" -t halt
This is possible to do with
swipl -f file -g "message" -t halt
where the prolog clauses are written in file
I am running swipl on the server side that takes user input as prolog clauses, therefore writing a file on the server is not a good idea.
One thing you can do is to use load_files/2 with the option stream, and load from standard input, not from an argument (you can still pass the entry point as an argument, I guess):
Say in a file fromstdin.pl you have:
main :-
load_files(stdin, [stream(user_input)]),
current_prolog_flag(argv, [Goal|_]),
call(Goal),
halt.
main :- halt(1).
and with this you can do:
$ echo 'message :- format("hello~n").' | swipl -q -t main fromstdin.pl -- message
|: hello
The comments by #false to this answer and the question will tell you what this |: is, if you are wondering, but if it annoys you, just do:
$ echo 'message :- format("hello~n").' \
| swipl -q -t main fromstdin.pl -- message \
| cat
hello
instead.
This will let you read any Prolog from standard input and call an arbitrary predicate from it. Whether this is a clever thing to do, I don't know. I would also not be surprised if there is a much easier way to achieve the same.

Is there something wrong with sed for the mac terminal?

I am having trouble making sed work on my mac terminal. The original version I have is /usr/bin/sed
I want to see what version it is so I type:
sed --version
I get the following output:
/usr/bin/sed: illegal option -- - usage: sed script [-Ealn] [-i
extension] [file ...]
sed [-Ealn] [-i extension] [-e script] ... [-f script_file] ... [file ...]
My man page is for sed 4.2 and that should have a --version option
I then installed to /usr/local/bin by downloading from gnu ftp http://ftp.gnu.org/gnu/sed/
I then run /usr/local/bin/sed --version and still get same output as with original version. I am completely confused, can anyone figure out what I am doing wrong?
EDIT: It seems like even though which sed gives me /usr/local/bin/sed the command sed is still running /usr/bin/sed, consequently /usr/local/bin/sed is not being invoked. If I invoke with full path it works as expected.
I guess question is now why which sed is giving me /usr/local/bin/sed yet the command run when I type sed is /usr/bin/sed
Your /usr/bin/sed is the BSD sed which does not support --version as your error statement shows. The man page for it is /usr/share/man/man1/sed.1.gz, when I read that there is no mention of a version at all, however the date on the man page is May 10, 2005.
I am thinking you have an incorrect man page. Most probably a MANPATH that is looking somewhere else first.
As for why /usr/local/bin/sed which you are saying is GNU sed does not honor the --version I am not sure about. Can you give more detail about this?