GHC error with System on OS X Lion - macos

I tried to compile and link simple program using ghc, but it failed during linking:
import System (getArgs)
main = do
args <- getArgs
print args
I tried to compile with
% ghc -c -O Main.hs
% ghc -o Main Main.o
ld: warning: could not create compact unwind for .LFB3: non-standard register 5 being saved in prolog
Undefined symbols for architecture i386:
"___stginit_haskell98zm1zi1zi0zi1_System_", referenced from:
___stginit_Main_ in Main.o
ld: symbol(s) not found for architecture i386
collect2: ld returned 1 exit status
zsh: exit 1 ghc -o Main Main.o
However, when compiling with --make:
% ghc --make Main.hs
everything works (besides tons of ld warnings)
Some more informations about environment:
% ghc --version
The Glorious Glasgow Haskell Compilation System, version 7.0.3
From Haskell Platform for Mac OS X 10.6 (Intel, 32 bit GHC)
System: Max OS X Lion 10.7.2
Any ideas what's wrong?
(Btw, I tried to install HP x64 but it failed during installation)

Michael is historically right. With --make, ghc figures out which packages it has to use and link in by itself (unless two installed packages expose the same module name, then it can't figure out which one to use), without --make, you have to tell it. However, as of 7.0, --make is the default mode of ghc, so plain ghc Main.hs is now the same as ghc --make Main.hs. The difference here is the two-step compilation. I don't know the precise details, but the cause is that the module System is in the haskell98 package (a propos, please use the hierarchical modules, getArgs should be imported via System.Environment, as of 7.2, haskell98 can't be used together with base), which by default is not linked in. So ghc -o Main Main.o doesn't find the symbol in the default packages. You'd have to tell it explicitly to look in the haskell98 package, ghc -c -O Main.hs; ghc -package haskell98 -o Main Main.o should work (and it works here, I've tested with 7.0.4 to make sure).

Perhaps it's because you're using something from System? ghc --make probably auto-detects which Haskell libraries it needs to link, and ghc by itself does not.

Related

Compiling GitHub project runs gcc with -static option on Mac and fails, how do I get around that?

I want to compile the following project that's hosted on GitHub. I'm on MacOs High Sierra 10.13.5.
When I run make on the solver directory, it gives the following error after running gcc with the -static option:
g++ -o dapcstp src/bbnode.o src/bbtree.o src/bounds.o src/cputime.o
src/heur.o src/inst.o src/main.o src/options.o src/prep.o
src/procstatus.o src/sol.o src/stats.o src/timer.o src/util.o -static -
lboost_timer -lboost_system -lboost_chrono -lboost_program_options -
lboost_filesystem
ld: library not found for -lcrt0.o
clang: error: linker command failed with exit code 1 (use -v to see
invocation)
make: *** [dapcstp] Error 1
In the answer to ld: library not found for -lcrt0.o on OSX 10.6 with gcc/clang -static flag it says the following:
This option will not work on Mac OS X unless all libraries (including libgcc.a) have also been compiled with -static. Since neither a static version of libSystem.dylib nor crt0.o are provided, this option is not useful to most people.
Is there a way I could circumvent this limitation and compile the project correctly on Mac ?
Looking at the project, the -static option is superfluous and counterproductive (even on system where static linking is supported). You can just remove it.

Issue when linking lapack and fftw3 libraries

I have a Fortran 90 program which uses lapack subroutines, and is successfully running on my Ubuntu system. Now I want to run it on Mac (OS X Version 10.11.4). I am using gfortran compiler as a part of gcc, installed from homebrew repositories, and lapack library, installed in /usr/local/lib/.
When I try to compile my code, I get the following error:
gfortran my_prog.f90 -L/usr/local/lib/ -llapack
Undefined symbols for architecture x86_64:
"_daxpy_", referenced from:
_zggbal_ in liblapack.a(zggbal.o)
...
"_ztrmv_", referenced from:
_zlarft_ in liblapack.a(zlarft.o)
ld: symbol(s) not found for architecture x86_64
collect2: error: ld returned 1 exit status
After some google search I understood that the problem is because the linking. When I compile it like this, everything works well:
gfortran my_prog.f90 -llapack
Also when llapack from framework accelerate is used, the compiler doesn't complain.
gfortran my_prog.f90 -framework accelerate
The libraries are of x86-64 architecture:
lipo -info *.a
input file libfftw3.a is not a fat file
input file liblapack.a is not a fat file
Non-fat file: libfftw3.a is architecture: x86_64
Non-fat file: liblapack.a is architecture: x86_64
LAPACK is not the only one which gives me an error, later the same problem appears with FFTW3. Could you please give me a hint to the solution to this problem?
FFTW is not part of the accelerate framework. If you want to use it, you need to add -lfftw3 to the compile options as well.
If the libraries are not in the default LIBRARY_PATH, you might need to specify -L/path/to/fftw/libs as well. The same holds for the include path if you are using its modules -I/path/to/fftw/includes.
Note that the vDSP part of the library also provides FFT implementations. You might not need FFTW at all.

Linking to libraries with $ld$hide$os10.X$ symbols in OSX

I'm trying to link against the BLAS implementation in OSX (/System/Library/Frameworks/Accelerate.framework/Versions/A/Frameworks/vecLib.framework/Versions/A/libBLAS.dylib, for the curious) but I don't want to link against the libLAPACK.dylib in that same directory, as I want to use my own build of LAPACK from netlib, as it is much more recent and up to date.
My problem is that there are symbols in the BLAS library that are typically stored in an LAPACK library, and as such are causing name clashes. As a concrete example, the spotrf function is defined in libBLAS.dylib:
$ nm /System/Library/Frameworks/Accelerate.framework/Versions/A/Frameworks/vecLib.framework/Versions/A/libBLAS.dylib | grep spotrf
0000000000010c05 T $ld$hide$os10.7$_spotrf
0000000000010c05 T $ld$hide$os10.8$_spotrf
000000000000746e T _spotrf
Those first two symbols made me a little suspicious, so to double-check, I check out libLAPACK.dylib as well:
$ nm /System/Library/Frameworks/Accelerate.framework/Versions/A/Frameworks/vecLib.framework/Versions/A/libLAPACK.dylib | grep spotrf
00000000000010c8 T $ld$hide$os10.4$_spotrf
00000000000010c8 T $ld$hide$os10.5$_spotrf
00000000000010c8 T $ld$hide$os10.6$_spotrf
000000000000765b T _spotrf
From what limited information I have been able to find, it seems that this prefix somehow instructs the dynamic linker to ignore these symbols if the users is compiling against a given OSX version. This makes sense if Apple moved symbols from libBLAS.dylib to libLAPACK.dylib between 10.6 and 10.7.
My question is, how can I inform the dynamic linker that it SHOULD hide spotrf etc... that are inside libBLAS.dylib?
First off, you don’t actually need to do anything special to get your desired behavior, as you’re linking dynamically. Ensure that your netlib-built LAPACK appears before -lblas in the link command, and all LAPACK interfaces will be picked up from the netlib LAPACK (ld matches all the undefined symbols it can against each of the libraries being linked against in order).
Alternatively, assuming that your netlib LAPACK is linked against the system BLAS, you should be able to configure the link of LAPACK so that it reexports all of the BLAS symbols. Then you can simply link against your LAPACK and leave -lblas out of your link command entirely.
The $show$ and $hide$ symbols come into play if and only if you are linking against both the system BLAS and the system LAPACK libs. A simple example will show how they work in that case:
Kronecker:~ scanon$ cat foo.c
void dgetrf_(void);
int main(void) { dgetrf_(); return 0; }
Building this on 10.9 and breaking on dgetrf_, we see that the symbol was picked up from libLAPACK.dylib, even though -lblas appears first in the build command. This is because the symbol is hidden in libBLAS.dylib when targeting 10.9:
Kronecker:~ scanon$ clang foo.c -lblas -llapack
Kronecker:~ scanon$ lldb a.out
Current executable set to 'a.out' (x86_64).
(lldb) b dgetrf_
Breakpoint 1: 2 locations.
(lldb) run
...
frame #0: 0x00007fff89237b70 libLAPACK.dylib`dgetrf
libLAPACK.dylib`dgetrf:
...
If we specify -mmacosx-version-min=10.6 (telling the compiler and linker that we want to produce an executable that can run on 10.6 Snow Leopard), we will see that the symbol is picked up from libBLAS.dylib instead. This is because the symbol doesn’t exist in libLAPACK.dylib on 10.6, so our executable wouldn’t be able to run on that platform if the symbol in libLAPACK.dylib were used:
Kronecker:~ scanon$ clang foo.c -lblas -llapack -mmacosx-version-min=10.6
Kronecker:~ scanon$ lldb a.out
Current executable set to 'a.out' (x86_64).
(lldb) b dgetrf_
Breakpoint 1: 2 locations.
(lldb) run
...
frame #0: 0x00007fff8c9d6841 libBLAS.dylib`DGETRF_
libBLAS.dylib`DGETRF_:
...

How can I compile and use Haskell as a C library using Xcode LLVM compiler?

I want to set up a project to take my .hs code, and my main .c program, and result in a statically linked executable through the use of LLVM compiler. I can get things working via ghc command line options to build a .hs, produce the stubs, and compile and link a driver application using ghc entirely. However, I get various issues within Xcode.
My first issue was that I of course need to use 32 bit compiling environment in Xcode. That solved, I had to fiddle with paths to explicitly include the HsFFI.h. That solved, I get a linker error:
Ld "build/Debug/FFI Test.app/Contents/MacOS/FFI Test" normal i386
cd "/Users/rcl/TestXCodeProjects/FFI Test"
setenv MACOSX_DEPLOYMENT_TARGET 10.6
/Developer/usr/bin/clang -arch i386
-isysroot /Developer/SDKs/MacOSX10.6.sdk
"-L/Users/rcl/TestXCodeProjects/FFI Test/build/Debug"
"-L/Users/rcl/TestXCodeProjects/FFI Test/FFI Test"
"-F/Users/rcl/TestXCodeProjects/FFI Test/build/Debug"
-filelist "/Users/rcl/TestXCodeProjects/FFI Test/build/FFI Test.build/
Debug/FFI Test.build/Objects-normal/i386/FFI Test.LinkFileList"
-mmacosx-version-min=10.6 -framework Cocoa
"/Users/rcl/TestXCodeProjects/FFI Test/FFI Test/ForeignExportCost.a"
-o "/Users/rcl/TestXCodeProjects/FFI Test/build/Debug/FFI Test.app/
Contents/MacOS/FFI Test"
Undefined symbols for architecture i386:
"_hs_init", referenced from:
-[FFI_TestAppDelegate applicationDidFinishLaunching:] in FFI_TestAppDelegate.o
"_simpleFunction", referenced from:
-[FFI_TestAppDelegate applicationDidFinishLaunching:] in FFI_TestAppDelegate.o
"_hs_exit", referenced from:
-[FFI_TestAppDelegate applicationDidFinishLaunching:] in FFI_TestAppDelegate.o
ld: symbol(s) not found for architecture i386
clang: error: linker command failed with exit code 1 (use -v to see invocation)
The "simpleFunction" is in "ForeignExportCost.a" library which I compile using ghc like this:
ghc -no-hs-main -fPIC -c ForeignExportCost.hs
ghc -no-hs-main -shared ForeignExportCost.o -o ForeignExportCost.a
What am I missing or doing wrong?
Ugh - it looks like the answer to my question is detailed here, telling me how to painfully add a ton of .a's to my project. And this blog post gave some helpful tips to getting on the way.
Although if someone tells me "hey wait, there's an easier way than iteratively figuring out failed deps" that would be awesome. Because I want to reuse this framework several times and this is a real pain of a way to get things up and going!

Haskell Parsec compile error

I've installed Haskell via the pre built installer v6.8.2.
When trying to compile this sample file with GHC
module Main where
import Text.ParserCombinators.Parsec
import System.Environment
main :: IO ()
main = do args <- getArgs
putStrLn ("Hello")
I get the following error:
D:\src\Haskell>ghc -o read read.hs
ghc -o read read.hs
read.o(.text+0x1b5):fake: undefined reference to `__stginit_parseczm2zi1zi0zi0_TextziParserCombinatorsziParsec_'
collect2: ld returned 1 exit status
I have installed Parsec via cabal.
Does anyone have any idea's as to what is wrong?
Try ghc --make -o read read.hs. GHC will take care of linker dependencies.
I'll put out one other way to make this work
ghc -package parsec -o read read.hs
From the ghc documentation
-package P
This option causes the installed package P to be exposed. The package P can be
specified in full with its version number (e.g. network-1.0) or the version number
can be omitted if there is only one version of the package installed. If there are
multiple versions of P installed, then all other versions will become hidden.
The -package P option also causes package P to be linked into the resulting
executable or shared object. Whether a packages' library is linked statically or
dynamically is controlled by the flag pair -static/-dynamic.
see http://www.haskell.org/ghc/docs/latest/html/users_guide/packages.html
According to the Parsec docs (section 1.2.1 Compiling with GHC), you should do this:
When your linking the files together,
you need to tell GHC where it can find
libraries (-L) and to link with the
Parsec library too (-l):
ghc -o myprogram myfile1.o myfile2.o -Lc:\parsec -lparsec
This documentation on the Haskell compiler may help.

Resources