I previously had some troubles updating old code that still needed a not supported compiler and expensive libraries to a version with gfortran in Eclipse on Windows. I let it rest for a while and recently I took a whole other approach, rebuilding the program from scratch, developping on a ubuntu machine, but now I want to bring it back to a windows machine so that my co-workers can contribute on it.
The status:
Program compiles, runs and gives good results on an ubuntu machine with the GCC GNU compiler
Windows 7 machine, 64bit
Cygwin installation (for gnu fortran) with lapack and liblapack-devel (however, I don't use these, because I compile blas and lapack manually)
(C:/cygwin/lib added to windows Path)
Original Issue:
The program compiles in cygwin (by calling the make-command, calling the make command with the makefile situated here: http://thijsvandenbrande.be/phd/hamfemInstall/makefile
This returns the file hamfem.exe which returns the following error when runned by double-clicking on it in windows: The program can't start because cyglapack-0.dll is missing from your computer. Try reinstalling the program to fix this problem.
When running the executable from cygwin, by calling the ./hamfem.exe command the executable starts to run. However, I want a solution so that I can give this executable to my co-workers so that they can change the input files (located in a folder in that has a relative path to the executable).
Going further on the comments below, I tried the next things:
Adding the exact path to the C:\cygwin\lib\lapack\cyglapack-0.dll file in windows path and even rebooting afterwards doesn't help.
adding a -static to the makefile before calling the library, resulting in dependency errors because I use two commands of the lapack library that depend on quite a lot of other commands (DPBTRF and DPBTRS). These commands are used in the mainprog.f90 module. The error: /usr/lib/gcc/i686-pc-cygwin/4.7.3/../../../liblapack.a(dpbtrf.f.o): In function 'dpbtrf':
/usr/src/debug/lapack-3.4.2-1/SRC/dpbtrf.f:277: undefined reference to 'dtrsm_'
and a couple of more lines stating the dependencies.
add the liblapack.a file to the src folder, but compiler always goes back to the lapack in cygwin
On the website of lapack you can normally download the functions with their dependencies (example DPBTRF), but these are not available anymore. Does anyone have another idea how to include these two functions and their dependencies in a static library-file that I can compile beforehand and add to the src-folder?
Current (semi-)Fix
The next thing worked (a bit) for me: following the instructions on http://gcc.gnu.org/wiki/GfortranBuild to manually build libblas.a and liblapack.a in the /usr/src folder of Cygwin and refering to this folder in the makefile. The updated makefile can be found here: http://thijsvandenbrande.be/phd/hamfemInstall/makefileNew
The code compiles nicely on Windows by running the make command from cygwin (next step in the process, running it out of Eclipse) and i get a .exe file that can be run by double clicking it and that keeps running if I move it with its folder to another location. Because this process is quite labour intensive, figuring it all out, I added the answer here below, stating the commands you have to parse to cygwin in order to make it work.
For your information: my file structure looks like this (after the build, I move the .exe file one folder up, both in the linux version as the windows version):
hamfem.exe
in
input.txt
NGCR_building01.txt
out
(empty folder for output files of the routine)
src
hamfem.f90 (main file)
mainprog.f90 (file that contains the commands from lapack)
...(a bunch of other modules)
makefile
I figured things out myself, with some pointers from all over stackoverflow. In order for others to help them resolve similar issues, I would like my work method here so that the question is fully documented.
The issue can be resolved by clean building the Lapack library !and the Blas library on your local machine in cygwin and pasting the liblapack.a and libblas.a file to the library folder that you refer to in the makefile. The errors that were casted by calling Lapack staticly where a result of some routines of Blas used in the two commands.
These are the steps I followed:
download the lapack.tgz and blas.tgz files from the website and past them in the C:\Cygwin\usr\src folder
Extract these files with the following commands in cygwin:
cd /usr/src
tar -xvzf lapack.tgz
tar -xvzf blas.tgz
Build the two library files with the commands shown below in Cygwin. Compiling Lapack can take a while and will result in some errors in the end because of some missing links in the test files. These tests are run for accuracy tools. A more detailed look into the make.inc file is needed to resolve these issues.
cd $HOME
cd /usr/src/BLAS
make
mv blas_LINUX.a ../libblas.a
cd ../lapack-3.4.2
mv make.inc.example make.inc
make
mv liblapack.a ../liblapack.a
check the makefile included in this repository for the correct linking to the libraries. These should say /usr/src and -static -llapack -lblas, the other options are for the linux compiler.
Related
The link on this page (https://www.ghostscript.com/download.html) for Linux x64, gets you a .tgz with an executable binary.
However, while trying to use this binary as an .so, (after renaming it into libgs.so and putting into appropriate place) via Ghost4J, I invariably get errors as follows:
java.lang.UnsatisfiedLinkError: /tmp/jna-100923095/jna3513656669313044092.tmp: cannot dynamically load executable
Once I install the Ghostscript via apt-get install ghostscript, the same code runs fine (as it now loads an .so from /usr/lib/x86_64-linux-gnu/libgs.so.9.22)
Question: which minimal set of files should I put to some folder, so that I could link to Ghostscript dynamic library (.so) successfully, without Ghostscript being installed on the machine/container?
UPD: under Windows, this seems to be possible, the /bin folder of the installation contains both DLL and EXE files; if I put that .dll file into a win32-x86-64 folder under resources, it is being picked up by JNA (via Ghost4j) and Ghostscript instance works fine, even once I remove the "official" installation). I would like to have same behaviour (i.e. self-sufficient, self-containing JAR file) for Linux as well.
Well, I ended up building the shared object myself, using Ubuntu 18.04 installed as WSL 1 distribution, following the guidelines from here: https://www.ghostscript.com/doc/current/Make.htm#Shared_object
These were the exact commands:
./configure --without-luratech --with-system-libtiff --with-drivers=PCLXL
make so
and then, in the sobin folder, you have libgs.so, that works as expected. But sad it's not possible to download it from the official site.
I'm porting an SDK written in C++ from Windows to Linux. There are other binaries, but at its simplest, our SDK is this:
core.dll - implicitly loaded DLL ("libcore.so" shared library on Linux)
tests.exe - an app use to test the DLL (uses google test)
All of my binaries must live in one folder somewhere that apps can find. I've achieved that on Windows. I wanted to achieve the same thing in Linux. I'm failing miserably
To illustrate, Here's the basic project tree. We use CMake. After I build I've got
mysdk
|---CMakeLists.txt (has add_subdirectory() statements for "tests" and "core")
|---/tests (source code + CMakeLists.txt)
|---/core (source code + CMakeLists.txt)
|---/build (all build ouput, CMake output, etc)
|---tests (build output)
|---core (build output)
The goal is to "flatten" the "build" tree and put all the binary outputs of tests, core, etc into one folder.
I tried adding CMake's "install" command, to each of my CMakeLists.txt files (e.g. install(TARGETS core DESTINATION bin). I then then executed sudo make install after my normal build. This put all my binaries in /usr/local/bin with no errors. But when I ran tests from there, it failed to find libcore.so, even though it was sitting right there in the same folder
tests: error while loading shared libraries: libcore.so: Cannot open shared object file: No such file or directory
I read up on the LD_LIBRARY_PATH environment variable and so tried adding that folder (/usr/local/bin) into it and running. I can see I've properly altered LD_LIBRARY_PATH but it still doesn't work. "tests" still can't find libcore.so. I even tried changing the PATH environment variable as well. Same result.
In frustration, I tried brute-force copying the output binaries to a temporary subfolder (of /mysdk/build) and running tests from there. To my surprise it ran.
Then I realized why: Instead of loading the local copy of libcore.so it had loaded the one from the build output folder (as if the full path were "baked in" to the app at build time). Subsequently deleting that build-output copy of libcore.so made "tests" fail altogether as before, instead of loading the local copy. So maybe the path really was baked in.
I'm at a loss. I've read the CMake tutorial and reference. It makes this sound so easy. Aside from the obvious (What am I doing wrong?) I would appreciate if anyone could answer any of the following questions:
What is the correct way to control where my app looks for my shared libraries?
Is there a relationship between my project build structure and how my binaries must then appear when installed?
Am I even close to the right way of doing this?
Is it possible I've somehow inadvertently "baked" (into my app) full paths to my shared libraries? Is that a thing? I use all CMAKE variables in my CMakeLists files.
You can run ldd file to print the shared object dependencies for file. It will tell you where are its dependencies being read from.
You can export the environment variable LD_LIBRARY_PATH with the paths you want the linker to look for. If a dependency is not found, try adding the path where that dependency is located at to LD_LIBRARY_PATH and then run ldd again (make sure you export the variable).
Also, make sure the dependencies have the right permissions.
Updating LD_LIBRARY_PATH is an option. Another option is using RPATH. Please check the example.
https://github.com/mustafagonul/cmake-examples/blob/master/005-executable-with-shared-library/CMakeLists.txt
cmake_minimum_required(VERSION 2.8)
# Project
project(005-executable-with-shared-library)
# Directories
set(example_BIN_DIR bin)
set(example_INC_DIR include)
set(example_LIB_DIR lib)
set(example_SRC_DIR src)
# Library files
set(library_SOURCES ${example_SRC_DIR}/library.cpp)
set(library_HEADERS ${example_INC_DIR}/library.h)
set(executable_SOURCES ${example_SRC_DIR}/main.cpp)
# Setting RPATH
# See https://cmake.org/Wiki/CMake_RPATH_handling
set(CMAKE_INSTALL_RPATH ${CMAKE_INSTALL_PREFIX}/${example_LIB_DIR})
# Add library to project
add_library(library SHARED ${library_SOURCES})
# Include directories
target_include_directories(library PUBLIC ${CMAKE_CURRENT_SOURCE_DIR}/${example_INC_DIR})
# Add executable to project
add_executable(executable ${executable_SOURCES})
# Linking
target_link_libraries(executable PRIVATE library)
# Install
install(TARGETS executable DESTINATION ${example_BIN_DIR})
install(TARGETS library DESTINATION ${example_LIB_DIR})
install(FILES ${library_HEADERS} DESTINATION ${example_INC_DIR})
When I tried to run an installer that uses GLEW as one of its dependencies, I got:
fatal error: GL/glew.h: No such file or directory
Downloaded glew1.10 from the official site and installed according to given instructions.
After that I got the same error again- did some research and copied glew.h to /usr/include/GL/glew.h. Ran the installer again and this time got:
/usr/bin/ld: error: cannot find -lGLEW
To my understanding this is a a common error in Linux for many projects and many libraries, probably I should copy some files from the source folder or add some path to an environment variable, what should i do?
I know that there are apt-get packages- libglew1.6-dev and libglew1.6, but its built upon glew1.6, which works but is probably out-dated for what i'm trying to build.
The automatic installer is node.js's npm, and what causes this error is trying to install node-webgl module.
Solved.
As it turned out, the installation seems to have placed the needed files inside /usr/lib64, and the linker searched for those files inside /usr/lib/ which probably is the right behavior in most cases.
Since i'm not familiar with node.js's npm (and with linking in general), my fix was as follows:
sudo cp /usr/lib64/libGLEW* /usr/lib/
sudo cp /usr/lib64/pkgconfig/* /usr/lib/pkgconfig/
Meaning, I reconstructed the same hirarchy inside the /usr/lib folder. This is probably not a best practice, but it works.
I want to compile a Haskell program on one Linux box, and then run it on another Linux box. However, this doesn't seem to work at all. I get errors about missing libraries.
Presumably when I install GHC, the package manager also installs all the libraries and stuff that it needs. [I note with some irritation that at least one packaging system fails to install GCC, which GHC apparently can't function without...] But of course, the target system does not have these dependencies installed. So if I copy the compiled binary to the target system, it just fails to run.
Is there some way around this problem? I'm used to working with Windows, where if you compile something, it just works on all Windows systems. (At least, it does until you actually try to use non-standard facilities like database access or something...) I compiled Hello World in Haskell, copied it to another Linux box, and it complained about libgmp.so.10 missing or some cryptic mumbo-jumbo like that.
Just to make things interesting: I only have FTP access to the target machine, not shell access. I'm not even completely sure what OS it's running. So I can change my build machine any way I want, but I can't do anything to the target machine other than copy files to it.
Linux behaves just like Windows in this regard. If you compile a Haskell executable on Linux, it will run on any Linux distribution with the right libraries. The problem is that in Windows, the Haskell executables aren't compiled with a dynamic version of libgmp; they are compiled with a static version (so that the library is compiled into the executable) exactly because it can be so difficult to handle dlls on Windows when distributing executables. It is comparably easy to handle the installation of new libraries on Linux.
What you can do is to copy the libgmp.so.10 (which might be a symbolic link to a different file) out of /usr/lib into the same directory as your executable. You can then set the LD_LIBRARY_PATH environment variable to ".", meaning the current directory, before launching your executable. This will make Linux look for libraries in the same directory as executables that it launches, making it find the library. This can be done with a launcher script:
#!/bin/sh
export LD_LIBRARY_PATH=.
`dirname "$0"`/myexecutable "$#"
Saving this script and marking it as executable with chmod +x myscript will make your executable work.
You can use the ldd command to check what other libraries your executable might need and that aren't on the target system.
If you wish to move executable between machines, you have to link in statically, making single executable without external library dependencies. How to do it depends on compiler, and ghc has -static flag, that 'links static version of haskell libraries'.
btw, check, that you do not try to run 64-bit executable on 32 bit machine. 32-bit executable on 64 bit machine should work in most cases, but... well, it depends on configuration of target box, so check that this is not the case as well.
I'm trying to build a Win32 DLL from an audio-DSP related Linux library (http://breakfastquay.com/rubberband/). There are makefiles and config scripts for Linux, but no help for Windows. The author provides a Win32 binary of a sample app using the library, and I see a number of "#ifdef MSVC" and "#ifdef WIN32" scattered around, so I don't think I'm starting completely from scratch but I'm stuck nevertheless.
As my programming knowledge in either platform is rather limited, I'd appreciate any help.
First of all, what is the right way to get started here? Visual Studio? Cygwin? Initially I started off creating a Win32 DLL project in Visual Studio, adding the source files, thinking about adding a .def file, etc, but at some point I felt like this was going nowhere.
As for Cygwin, this was the first time using it, and I don't even know if this is the sort of thing that Cygwin is designed for. Is it?
On Cygwin, I ran ./configure and got stuck at something like this:
"checking for SRC... configure: error: Package requirements (samplerate) were not met: No package 'samplerate' found"
After looking through the log, it appears that pkg-config is looking for samplerate.pc. How do I handle packages in Windows? libsamplerate is just an open source library, and I have source and a DLL for this. But I'm not sure how to use them to satisfy the dependency requirements for librubberband (which is what I'm trying to build)
I'm completely lost at this point and if anyone can give me a nudge in the right direction... and, is there an easier way to do this?
Many thanks in advance.
If you're still stuck on this I can throw a little light.
You may have to build everything from sources (or have the libraries installed in your environment). You're using Cygwin, I would recommend MinGW and MSYS too, but sometimes it's just not possible to use this combination to build the program or library.
So if using Cygwin, first ensure that you have a proper environment installed. This is that you have the correct development headers installed.
Then download libsndfile. Extract the sources to a directory and from the Cygwin bash shell navigate to that directory. There perform:
./configure
make
make install prefix=/cygdrive/c/cygwin
Notice that I use a prefix, that prefix should point to the directory Cygwin is installed in order to correctly install the libraries (the same happens to MinGW and MSYS, the prefix should point to the MinGW installation directory). Maybe using the usr directory in the prefix works too, I've never tried it.
Now download FFTW, as it will be needed for libsamplerate and rubberband. Same procedure as with libsndfile: extract, configure, make & make install using the prefix. Now copy the header files of FFTW (in the example they'd be in /cygdrive/c/cygwin/include) to the include directory in the usr directory (in the example /cygdrive/c/cygwin/usr/include).
Next SRC (libsamplerate), same procedure.
Then the Vamp plugin SDK. In order to compile the it you may need to edit the file src\vamp-hostsdk\PluginLoader.cpp, deleting RTLD_LOCAL from a dlopen() call (it's safe, it's already the default behaviour).
Also, you may need to install it by hand (in my experiences it didn't like the prefix). Or set the environmental variable PKG_CONFIG_PATH pointing to the paths of pkgconfig, e.g.:
set PKG_CONFIG_PATH=/cygdrive/c/cygwin/lib/pkgconfig:/usr/local/lib/pkgconfig
Now, create a file called ladspa.h in the include directory with the contents of the LADSPA header
Finally, configure and build rubberband, it should find everything it needs.
To build in MSYS using MinGW follow the same procedure, using the according prefix. Using Visual Studio is another alternative, but you may need to use some of the pre-built libraries (for example for libsndfile) as building Linux libraries natively in Windows may be complicated or even impossible (without hacking the source code) in VS.
Anyway, the autor of rubberband provides binaries; I think you should consider use them instead of going through all of this.
Linux to w32 is mostly a tricky thing.
For each of your dependencies, download the source and:
./configure
make
sudo make install
Also, I recommend you to use MinGW + msys in place of CygWin (as the latter produces executables that depend on its libraries). However in your situtation, use the VS approach -- 't will save you a lot of time.