Haskell ghc compiling/linking error, not creating executable. (linux) - linux

I wrote a basic hello world program in haskel and tried to compile it with:
ghc filename.hs. It produces .hi and .o files but no executable and displays
this error in the linker:
marox#IT-marox:~/Marox$ ghc tupel.hs
Linking tupel ...
/usr/bin/ld: --hash-size=31: unknown option
/usr/bin/ld: use the --help option for usage information
collect2: ld returned 1 exit status
Googling didn't return any useful information.
I am on ubuntu 12.04.
How can I fix this?

Have you binutils-gold installed? If yes, this is the problem (since the gold linker does not support --hash-size AFAIK).
Possible solutions:
remove gold
your ld probably links to ld.gold, so change the symlink to ld.ld
tell the haskell compiler explicitly which linker to use with the -pgml option: ghc -pgml ld.ld tupel.hs
install ghc from source, since the configure script of ghc will then build ghc so that it won't use --hash-size
Depending on your version of ghc, you can adjust the linker settings in ghc's setting file /usr/lib/ghc-your.ghc.version/settings

Update - gold on Ubuntu 12.10 appears to move GNU ld to ld.bfd. To fix this problem I deleted the ld link as recommended and remade the link with
ln -s ld.bfd ld
ghc compilations are now going through.
(Couldn't see how to subvert the settings file in usr/lib/ghc, as the entry is for gcc which passes through its commandline to ld, although this would have been my preferred option, in case something else needs ld to be the way it was.)
Thanks to Dominic for the pointer of where to look! It was driving me crazy...

Related

haskell makefile import library

So I have the following makefile which I want to use to compile my haskell program. However, in my program.hs file I have imported a library that is not in the standard Haskell distribution (e.g. Data.List). As a result, when I try to compile I get the error below. How can I include the said library so that it compiles fine? P.S. I am NOT interested in other approaches which do not involve a makefile, thank you.
error:
Linking program...
ld: library not found for -lcrt0.o
clang: error: linker command failed with exit code 1 (use -v to see invocation)
makefile:
program: program.hs
ghc --make -static -optl-static program.hs
You went down the wrong path with static options. I assume you're on os-x. As explained at ld: library not found for -lcrt0.o on OSX 10.6 with gcc/clang -static flag that just makes things worse. In fact you got a different error, because you got an earlier error.
To write a good makefile, first ensure you can run ghc to compile the program without make, just by running the commands in the shell.
I.e. try to compile just ghc --make program.hs and see what happens. If you have the other libraries in your package environment already, it doesn't matter if they're in the standard distribution or not.

Is it possible to compile a standalone Fortran executable in Linux?

For example, consider that I wrote a Fortran program in one computer and want to run it on another computer which may not have required libraries and/or has a different compiler (or even better, no Fortran compiler at all). Is it possible to create an executable with all its dependencies?
I am using gfortran (7.2.1) in Fedora 26 and sometimes use LAPACK routines in my code.
Using -static option with the program
program main
write (*,*) 'Hello'
end
I get the output
gfortran -static a.f90
/usr/bin/ld: cannot find -lm
/usr/bin/ld: cannot find -lm
/usr/bin/ld: cannot find -lc
collect2: error: ld returned 1 exit status
There is no error with gfortran -static-libgfortran a.f90
In Fedora, gcc does not ship by default with static libraries.
You need to install the package glibc-static for the -static option to work, as hinted in this related question.
Note that -static-libgfortran will only do static linking of the libgfortran library and that you must have static versions of your dependencies as well.
The best option is to use Alpine Linux that uses musl libc. I highly recommend using the docker image (only 5 Mb).

Compile static library using g++

I have 3 classes - I denote those by firstClass,secondClass,thirdClass.
My headers - firstClass.h, secondClass.h, thirdClass.h and sources firstClass.cpp, secondClass.cpp, thirdClass.cpp.
In class thirdClass I create instance of firstClass and two instance of secondClass.
In main.cpp I deamonize and create instance thirdClass.
I want to create static library of thirdclass and linking to main.cpp.
firstClass and thirdClass used the same library libm.a
I created library step by step as following:
g++ -c -I-/usr/include/ -I-/usr/lib/ -I-/home/projects/Learninig firstClass.cpp -lstdc++ -lm-o WsChannel.o -w -m32
g++ -c -I-/usr/include/ -I-/usr/lib/ --I-/home/projects/Learninig secondClass -lstdc++ -o secondClass.o -w -m32
g++ -c -I-/usr/include/ -I-/usr/lib/ --I-/home/projects/Learninig thirdClass.cpp -lstdc++ -lm -o thirdClass.o -w -m32
ar rcs libLearning.a firstClass.o secondClass.o thirdClass.o
g++ main.cpp -L. -lLearning -lm -o MnLearning.o -m32
Compiling was maked correctly without any errors, but when I execute program I have same error. I spent some hours on checking code, but I don't find bugs. So then maybe compiling was incorrect. I did this using some tutorial in web.
If whatever was unclearly I am ready to more explain my question.
Edit: My error:
segfault at 557400000045 ip 00005574bd509dcd sp 00007ffd9e887900 error 4 in MnLearning[5574bd4f2000+26000]
The error is surely inside your own source code. Avoid undefined behavior in it, and be scared of UB.
Your use of -I- is strange, and probably wrong. I recommend removing it (and also, at first, remove the -m32 flag if your computer and distribution is 64 bits; work first to have your program run correctly on your laptop, then port it later to 32 bits Linux by adding the -m32 flag). You might use preprocessor options like -H to be shown what files are included.
I recommend building your library and your program with some build automation tool, such as GNU make or ninja.
Configure your build to compile with all warnings and debug info, i.e. using g++ -Wall -Wextra -g with GCC. Improve your source code to get no warnings. Then use the gdb debugger to understand the behavior of your program (and library).
So then maybe compiling was incorrect.
No, the compiler is probably good, and you should trust it.
The bug is very likely to be in your own code.
My error: segfault at 557400000045 ip 00005574bd509dcd sp 00007ffd9e887900 error 4 in MnLearning[5574bd4f2000+26000]
Segmentation fault is a symptom of some error in your own code (e.g. some buffer overflow, some bad pointer dereference, etc; or other kind of UB).
You might also use valgrind.
I spent some hours on checking code, but I don't find bugs.
You did not spend enough time (some bugs may take you weeks of work to be found), and you forgot to use the debugger, a very handy tool to help you understand the behavior of your program and find bugs in it. Be aware that programming is difficult, and don't be discouraged.

How to compile ld with custom linker scripts?

i am trying to build a custom version of the linux kernel 3.8 and i want my linker to behave a bit different so i changed its ldscripts.
Specifically I configure binutils -> make -> change ldscripts -> make install.
However when i try to compile libc using my linker the only thing i see is this :
GNU ld (GNU Binutils) 2.23
Supported emulations:
elf32_sparc
sparclinux
elf64_sparc
sun4
using internal linker script:
==================================================
/* Script for --shared -z combreloc: shared library, combine & sort relocs */
etc
The thing is that i have changed my ldscripts and prepended a tag at the beginning of each script in order to recognize them but my compiler does not seem to care.
However i don't have any other elf scripts in my system so the option of searching the wrong library path is not actually an option.
Is there something i am missing here?
Notice that i am cross compiling for sparc
You can pass a custom linker script to ld:
ld -T <path/to/file> ...
or to gcc:
gcc -Wl,-T,<path/tofile> ...
Default ld scripts get compiled into compiler driver (gcc) so you should at least rebuild the toolchain.
That's also probably the case that gcc will not look at any linker scripts other than built into it, so you'll have to modify them in toolchain (it's probably in spec files somewhere).

What's the different between -L/libpath and /etc/ld.so.conf configure the libpath that compiling in gcc/g++

I compiling my code, but failed.
# g++ -g test.cpp -o test -lboost_filesystem
/tmp/cc5yybJZ.o(.text+0xb0): In function `__static_initialization_and_destruction_0':
/usr/local/include/boost/system/error_code.hpp:214: undefined reference to `boost::system::generic_category()'
/tmp/cc5yybJZ.o(.text+0xbc):/usr/local/include/boost/system/error_code.hpp:215: undefined reference to `boost::system::generic_category()'
/tmp/cc5yybJZ.o(.text+0xc8):/usr/local/include/boost/system/error_code.hpp:216: undefined reference to `boost::system::system_category()'
/tmp/cc5yybJZ.o(.gnu.linkonce.t._ZN5boost10filesystem9file_sizeERKNS0_4pathE+0x19): In function `boost::filesystem::file_size(boost::filesystem::path const&)':
/usr/local/include/boost/filesystem/operations.hpp:447: undefined reference to `boost::filesystem::detail::file_size(boost::filesystem::path const&, boost::system::error_code*)'
collect2: error: ld returned 1 exit status
but it was success when I compile with -L/usr/local/lib
g++ -g test.cpp -o test -lboost_filesystem -L/usr/local/lib
and the /usr/local/lib has already configured in /etc/ld.so.conf
# cat /etc/ld.so.conf
include ld.so.conf.d/*.conf
/usr/lib64
/usr/local/lib
/usr/local/mpc/lib
/usr/local/mpfc/lib
What's the reason?
What's the different between -L/libpath and /etc/ld.so.conf configure the libpath?
/etc/ld.so.conf is used by the dynamic linker (see manpage ld.so(8)) to figure out which paths to search for your library file. This happens at runtime.
You still need to pass -L/usr/local/lib to gcc, which will pass it on to ld (see manpage ld(1)). This happens at compile time.
Why doesn't gcc or ld just look up the paths in /etc/ld.so.conf automatically? I'd guess a few possible reasons: (1) having more automatic behavior like this makes the system more complex and trickier to understand; (2) gcc runs on systems with different dynamic linkers (or none at all); (3) maybe that behavior is not what you wanted, and then you'd need some extra way to turn it off.
In any case, on most Linux systems, you would just have a package manager that puts the libraries in the right place (typically /usr/lib), so this is usually a non-issue. Otherwise, it's customary to just define your own CFLAGS variable to include the necessary -L... directives.
It's also possible to configure gcc to automatically pass various -L... directives (among other things) by modifying the spec file.
/etc/ld.so.conf is a runtime thing - it allows Linux to find the shared libraries your executables need to run.
You can augment /etc/ld.so.conf by defining $LD_LIBRARY_PATH in your environment.
"-L", on the other hand, is entirely for linking your program. It's an "ld" thing. Specifying "-L" in your g++ command should fix your link error.
You can use the "ldd" command to see what shared libraries a binary needs, and where in the environment it expects to find them.

Resources