haskell makefile import library - haskell

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.

Related

How do I get the location of linkable libraries in GHC?

I'm working on a project that produces a shared object (.so) file. The source code is in both C and Haskell. It needs to be linked with libraries for the GHC Runtime System and for the Hint Haskell module.
Currently, the command to compile the file is:
ghc -Weverything -Werror -fforce-recomp $^ -o $# -dynamic -shared -lHSrts-ghc8.10.5 -lHShint-0.9.0.4-7GR8UnOuwIbHNCqCSHKCK0-ghc8.10.5
There must be a way to automate the finding of the libraries instead of hard-coding the names. I want the Makefile to continue to work with future releases of GHC and Hint. It seems to be that ghc-pkg
should be able to provide this, but I can't find how.

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.

Statically link a haskell program that uses C++ wrapper library

I am trying to make a program that, via some of the third party modules, is dependant upon icu library. I suspect that the dependency is via Network.HTTP.Conduit but maybe via something else. Dynamically linked binary is not portable even between adjacent versions of the same distribution because libicu* are of different versions that are not compatible.
So I am trying to build the program statically:
$ ghc --make -static -optc-static -optl-static my-prog.hs -optl-pthread
and I am getting a lot of errors of this kind:
/usr/lib/gcc/x86_64-linux-gnu/4.8/../../../x86_64-linux-gnu/libicuuc.a(dictionarydata.ao):(.data.rel.ro._ZTIN6icu_5222BytesDictionaryMatcherE[_ZTIN6icu_5222BytesDictionaryMatcherE]+0x0): undefined reference to `vtable for __cxxabiv1::__si_class_type_info'
/usr/lib/gcc/x86_64-linux-gnu/4.8/../../../x86_64-linux-gnu/libicuuc.a(dictionarydata.ao):(.data.rel.ro._ZTVN6icu_5217DictionaryMatcherE[_ZTVN6icu_5217DictionaryMatcherE]+0x28): undefined reference to `__cxa_pure_virtual'
collect2: error: ld returned 1 exit status
I believe that I have static versions of all involved libraries (libicu, libstdc++). It seems as if the linker has not been supplied with libstdc++ (or is it libitl? Apparently the offending functions are defined in the latter).
I tried adding the options -optl-static-libstdc++, -optl-lstdc++ and -optl-litm to the end of the command line to no avail.
What is the procedure to statically link a haskell program that is indirectly dependent on C++ support functions? I am running
The Glorious Glasgow Haskell Compilation System, version 7.6.3
gcc (Ubuntu/Linaro 4.8.1-10ubuntu9) 4.8.1
or
gcc (Ubuntu 4.8.2-19ubuntu1) 4.8.2
Edit:
I narrowed the problem to the package Data.Text.ICU, and here is a short program that cannot be built into a static executable:
{-# LANGUAGE OverloadedStrings #-}
module Main where
import Data.Text.ICU
main = print $ toUpper Current "Hello!"
The problem boils down to the fact that gcc doesn't actually have libstdc++, or the other core c++ libraries available to it, but g++ does.
Asking ghc to use g++ instead of gcc for linking should do the trick. Add the following to your cabal file as a parameter under ghc-options: -pgml g++. It sets the linking program to g++ which should allow the system linker to find the libraries it needs.

Haskell ghc compiling/linking error, not creating executable. (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...

Resources