linking clapack on linux - linux

I am moving a project which uses clapack from osx to linux and experiencing some problems with it. I use clapack by downloading the cmake project, compiling and moving the necessary .h and .a files to a relevant location within my project.
I have used the same steps in both scenarios (osx and linux) and have the same exact source code on both machines however I cannot get the everything to link properly on linux.
the lined of code in my cmake file look like this
#-----------------------------------------------------------------------------
# INCLUDE CLAPACK
#-----------------------------------------------------------------------------
INCLUDE_DIRECTORIES(${VMT_PRJ_SOURCE_DIR}/CLAPACK)
LINK_DIRECTORIES(${VMT_PRJ_SOURCE_DIR}/CLAPACK/lib)
LINK_LIBRARIES(blas f2c lapack tmglib)
and the error I am getting looks like this
/CLAPACK/lib/liblapack.a(sgesvd.c.o): In function `sgesvd_':
sgesvd.c:(.text+0x456): undefined reference to `s_cat'
sgesvd.c:(.text+0x1fa4): undefined reference to `s_cat'
This is the first time I have done a port from osx to linux and don't know if there are some different requirements I need to make in order to link or what the problem is
Any help would be much appreciated.
Scott

The order of linking matters. Since liblapack.a needs functions from libf2c.a, the latter needs to come after the former. So changing
LINK_LIBRARIES(blas f2c lapack tmglib)
to
LINK_LIBRARIES(blas lapack f2c tmglib)
should help.

Related

Bash command: export BLAS_LIBS="-L$LAPACKHOME/lib -lblas"

Can any body explain to me what does the whole sentence mean?
I know this is to set Macro BLAS_LIBS as another string.
But I'm not sure what's the "-lblas" mean and I don't know how to use it.
Similar as the following code. "-llapack"
export LAPACK_LIBS="-L$LAPACKHOME/lib -llapack"
How can the program find out the BLAS and LAPACK libraries just by "-lblas" and "-llapack" ?
Thanks for advance.
I'm not sure why you say "just by -llapack" because that's not what is happening here. Specifically, the -L option just before it specifies a directory path to add to the library resolution path. This works roughly like PATH in the shell.
For example, with the command line fragment gcc -Lfoodir -Lbardir -lfoo -lbar, you basically instruct the linker to search the directories foodir and bardir for the library files libfoo.a and libbar.a.
The -l option is described in GCC: Options for Linking and -L and friends in the following section GCC: Options for Directory Search.
This build arrangement -- configure the build to show where the required files are before compiling -- is common for libraries, where if a user has already downloaded and compiled a required library for some other project, they don't need to rebuild it; they can just point the compiler to wherever they already have the stuff needed for this project.
Building your own libraries is becoming increasingly unnecessary anyway, as prepackaged binaries of most common libraries are available for most systems these days. But of course, if you are on an unusual platform, or have specialized needs which dictate recompilation with different options than any available prebuilt binary, you will still need to understand how to do this.

Unable to make a portable Fortran executable in Cygwin

I'm attempting to compile a relatively simple Fortran executable so that it can be passed around to other Windows users that don't have Cygwin (or something of the sort) installed, however, I'm unable to get the executable to operate as a standalone. I've tried gfortran -static file.f and gfortran -static-libgfortran file.f, however other users always encounter this error:
The program can’t start because cygwin1.dll is missing from your computer. Try reinstalling the program to fix this problem.
From what I've read online (e.g. here), the -static option should be sufficient. I have verified that running the executable from my machine (DOS prompt) does work.
I have gcc (gfortran) version 4.7.3. I should also point out this is my first attempt at compiling portable Fortran.
Update
After realizing that this isn't a gfortran-specific issue (thanks to replies here), searches led me to related posts here and here
This is partially explained in the Cygwin FAQ. The solution is to install the mingw64-i686-gcc-fortran package with its dependencies, and cross-compile your code with i686-w64-mingw32-gfortran -static.
Just package the cygwin1.dll along with your binary file (both in the same folder) then it will run just fine.

How to set libs order in qmake?

We have a problem building out C++ software on Ubuntu Linux with qmake.
Problem is: we use some library, for example OpenCV, that can have different versions in one system.
qmake automatically add -L/usr/lib or -L/usr/lib/x86_64-linux-gnu to g++ arguments, and contents of LIBS variables after it.
So there conflicts with different versions of OpenCV, the system version is used, but we need custom one, located at our build tree.
Are there any methods to change libs order in -L or something else to solve this problem?
There are two components to doing this:
First, you need to make sure to include them in your .pro file correctly. Do this with something like (this is from my current project):
LIBS += L${OPENCV_HOME}/lib \
-lopencv_core \
-lopencv_highgui \
You can replace the environment variable with whatever your path is. I've found it convenient to use environment variables like this because you also need header includes:
INCLUDEPATH += $$(OPENCV_HOME)/include/opencv2 \
$$(OPENCV_HOME)/include/opencv \
$$(OPENCV_HOME)/include
This allows you to create projects and build them correctly.
When you attempt to run them, however, you will likely run into all sorts of issues due to your app finding the wrong libraries (from system libraries like you say) - you need to set your LD_LIBRARY_PATH variable correctly. In this case I have a launch script (you can do this in your user profile or elsewhere) which contains:
export LD_LIBRARY_PATH=${OPENCV_HOME}/lib
Which then looks to that (as well as other) locations on the LD_LIBRARY_PATH first, before system libraries.
Another hack is to exploit the LIBS = $(SUBLIBS) ... part of the Makefile qmake writes.
Namely, invoke the generated Makefile with
make SUBLIBS=-L/path/to/your/opencv
I had the same issue which I fixed by setting QMAKE_LIBDIR to the lib directory of the build tree. QMake automatically added the system library path after this value, thus allowing to correctly detect the desired libraries:
QMAKE_LIBDIR = /path/to/desired/opencvlib
I have two OpenCV versions on my PC, one installed by default in /usr and another installed by compiling the sources in a custom dir (not /usr).
The first worked just fine with Qt, the other didn't. I struggled a lot trying to make the Qt Creator work with my OpenCV compiled sources. So I added -L/opencv_lib_path but it always said 'undefined reference' for some OpenCV API I was using. It simply doesn't want to look there for the libs, it will look in LD_LIBRARY_PATH instead. I tried adding my opencv_lib_path to the LD_LIBRARY_PATH, no joy either.
The only thing that worked was Frodon's solution, just add this in your Qt .pro file and it will work.
QMAKE_LIBDIR = /path_to_installed_opencv/lib

Linker Issues with boost::thread under linux using Eclipse and CMake

I'm in the process of attempting to port some code across from PC to Ubuntu, and am having some issues due to limited experience developing under linux.
We use CMake to generate all our build stuff. Under windows I'm making VS2010 projects, and under Linux I'm making Eclipse projects. I've managed to get my OpenCV stuff ported across successfully, but am having major headaches trying to port my threaded boost apps.
Just so we're clear, the steps I have followed so-far on a clean Ubuntu 12 installation. (I've done 2 clean re-installs to try and fix potential library cock-ups, now I'm just giving up and asking):
Install Eclipse and Eclipse CDT using my package manager
Install CMake and CMake Gui using my package manager
Install libboost-all-dev using my package manager
So-far that's all I've done. I can create the eclipse project using CMake with no errors, so CMake is successfully finding my boost install. When I try and build through eclipse is when I get issues; The app I'm attempting to build uses boost::asio for some UDP I/O and boost::thread to create worker threads for the asio I/O services. I can successfully compile each module, but when I come to link I get spammed with errors such as:
/usr/bin/c++ CMakeFiles/RE05DevelopmentDemo.dir/main.cpp.o CMakeFiles/RE05DevelopmentDemo.dir/RE05FusionListener/RE05FusionListener.cpp.o CMakeFiles/RE05DevelopmentDemo.dir/NewEye/NewEye.cpp.o -o RE05DevelopmentDemo -rdynamic -Wl,-Bstatic -lboost_system-mt -lboost_date_time-mt -lboost_regex-mt -lboost_thread-mt -Wl,-Bdynamic
/usr/lib/gcc/x86_64-linux-gnu/4.6/../../../../lib/libboost_thread-mt.a(thread.o): In function `void boost::call_once<void (*)()>(boost::once_flag&, void (*)()) [clone .constprop.98]':
make[2]: Leaving directory `/home/david/Code/Build/Support/RE05DevDemo'
(.text+0xc8): undefined reference to `pthread_key_create'
/usr/lib/gcc/x86_64-linux-gnu/4.6/../../../../lib/libboost_thread-mt.a(thread.o): In function `boost::this_thread::interruption_enabled()':
(.text+0x540): undefined reference to `pthread_getspecific'
make[1]: Leaving directory `/home/david/Code/Build/Support/RE05DevDemo'
/usr/lib/gcc/x86_64-linux-gnu/4.6/../../../../lib/libboost_thread-mt.a(thread.o): In function `boost::this_thread::disable_interruption::disable_interruption()':
(.text+0x570): undefined reference to `pthread_getspecific'
/usr/lib/gcc/x86_64-linux-gnu/4.6/../../../../lib/libboost_thread-mt.a(thread.o): In function `boost::this_thread::disable_interruption::disable_interruption()':
(.text+0x59f): undefined reference to `pthread_getspecific'
Some Gotchas that I have collected from other StackOverflow posts and have already checked:
The boost libs are all present at /usr/lib
I am not getting any compile errors for inability to find the boost headers, so they must be getting found.
I am trying to link statically, but I believe eclipse should be passing the correct arguments to make that happen since my CMakeLists.txt includes SET(Boost_USE_STATIC_LIBS ON)
I'm officially out of ideas here, I have tried doing local builds of boost and a bunch of other stuff with no more success. I even re-installed Ubuntu to ensure I haven't completely fracked the libs directories and links with multiple weird versions or anything else. Any help would be muchly appreciated.
Correct mechanism is to use Threads package:
find_package(Threads)
#...
target_link_libraries(my_app ${CMAKE_THREAD_LIBS_INIT} ...)
See also cmake and libpthread
When you are building your targets, add -lpthread and it will compile.
See this other thread.
OK, so I found the solution.
It was to do with the absence of the -lpthread flag in the link command. In order to get CMake to link appropriately, then the TARGET_LINK_LIBRARIES line needs to be edited. My edit is:
Original:
TARGET_LINK_LIBRARIES( RE05DevelopmentDemo ${Boost_LIBRARIES} )
Modified and working:
IF(WIN32)
TARGET_LINK_LIBRARIES( RE05DevelopmentDemo ${Boost_LIBRARIES} )
ELSE(WIN32)
TARGET_LINK_LIBRARIES( RE05DevelopmentDemo ${Boost_LIBRARIES} pthread )
ENDIF(WIN32)
I'm guessing that I should probably change the ELSE(WIN32) to an elseif for or use the CMake command FindThreads to link in pthread if needed, but I'm not sure how to do that at the moment and have more imporatant things on my plate given the time I've lost. Interestingly enough, I noticed my link command now has two -lpthread flags appended at the end, one after another, but everything is still compiling quite happily.

Using GNU C++ built library in VS C++ project

I'm trying to implement an open source library that is built using the GNU compiler. (namely, this: https://github.com/mjwybrow/adaptagrams )
I've tried opening and building that source code using VSC++ 6, but it results in over a thousand errors due to the strict nature of the VS compiler I guess. And rather then go through every error and try fix it myself, I was wondering if it's possible to just include the .lib if it is built with the GNU compiler?
EDIT:
Included in the source code linked above is an autogen.sh file.
mkdir -p m4
autoreconf --install --verbose
automake -a --add-missing
./configure
make
Running that with Cygwin results in a few .a library files to be created, which are unusable in VS. Is it ok to just rename these to .lib files?
I've found some stuff online about how to use GCC and create a DLL, but my problem is that I don't know enough about the GNU compiler or makefiles, or the source code in general to be able to change it right now.
Does anybody have any clues on what exactly I'd need to change to get it right? Or even better, has anyone created a DLL using this source code already that would be able to pass it on to me, or let me know what I have to do?
Or could anyone point me towards a similar library that would be compatible with visual studio?
No; you can however build the .dll file with gcc and use the .dll from msvc (with either a hand-crafted include file or a properly formatted one from the beginning, with platform specific import/export macros on top).

Resources