MinGW msys package not found: General advice how to proceed - c++

Every now and then I want to compile something from source with mingw (on windows). I open msys, type ./configure, and it says
checking for...xxxxxx
There I have the first questions:
Where does mingw check?
What does it check for? .dll, .a, .o.,... what ever?
Occassionally there is an error like
configure: error: Package requirements <ogg >= 1.3> were not met:
No package 'ogg' found.
Well then I google and find "you can output the default lookup directories" so okay, I type gcc -print-search-dirs and see a list of directories, for example C:/mingw/lib, C:/mingw/lib/gcc, ...
Those folders contain .a-files. And guess what, some of them also contain libogg.a. So why is it complaining? Perhaps the version number? No, I downloaded the newest source and compiled it, and put the .a file into the directories. Same error. It drives me crazy! Please give some advice what to do.

Traditionally and typically, when a ./configure script checks for a library that the
package you are configuring needs to link against, it checks at least for the presence and usability of the library itself and also
for the header file(s) of the library, without which the compiler cannot use the
library's API. (I say typically, because what any given ./configure check
actually does is programmed by the package maintainer. It has nothing to do with your compiler).
Checking for the presence and usability of libfoobar normally does not mean that the ./configure check searches the filesystem for libfoobar.dll, libfoobar.a, or whatever. It means that the ./configure check simply attempts to compile and link a specimen program against libfoobar using the commands that are appropriate for doing so, when libfoobar is installed.
Often too (and increasingly), a ./configure check for a library libfoobar invokes the
pkg-config tool to attempt to
retrieve the correct compiler and linker flags for use with libfoobar. For this attempt to succeed, a pkg-config meta-data
file associated with the library package, foobar.pc, must be found in a standard
place in the filesystem, e.g. /usr/lib/pkgconfig, /usr/share/pkgconfig
For the library, plus its headers, plus its pkg-config meta-data (if any)
all to be available for ./configure it is necessary to install the development package
of libfoobar, as opposed to the basic package. The development package
usually has the same name as the basic package with the addition of a -dev
or -devel component, e.g. libfoobar-dev
If a ./configure check fails with an error of the form:
No package 'foobar' found.
it means that the check attempted to retrieve pkg-config meta-data for
foobar and none was found. That will usually be because the development
package libfoobar-dev is not installed, even if libfoobar is.

Related

Installing gfortran in Cygwin

I am trying to compile a modelling program in Cygwin using either a gfortran or g95 compiler. I have installed both compilers, but when I go to configure the program, it checks for the compilers and does not find then (error: Fortran compiler cannot create executables). I am new to Cygwin-- I suspect it is something with how/where I installed the compilers...Any ideas?
Thank you,
L.
For me, it's more helpful to have executable code to go through the process, so I'm going to put some in. This is addressing your concern,
I suspect it is something with how/where I installed the compilers...
because the installation from apt-cyg should be helpful in letting the system know where to look for the compilers. I'm also addressing a possible linkage issue.
bballdave025#MY-MACHINE /cygdrive/c/bballdave025
$ apt-cyg install gcc-fortran libgfortran5
If you don't have apt-cyg yet, follow these instructions from another answer.
# Get to where your setup executable lives.
# This is what you used to install Cygwin the first time.
# Note that mine is for the 64-bit version, and that
# I keep mine in C:\cygwin64. Your path might be
# different. You also might need to re-download
# The setup executable from Cygwin.
$ cd /path/to/setup_install/setup_x86-64.exe -q -P wget
$ wget https://raw.githubusercontent.com/transcode-open/apt-cyg/master/apt-cyg
$ chmod +x apt-cyg
$ mv apt-cyg /usr/local/bin
The libgfortran5 (or a more recent version, if available when you search) might be necessary. Here's why I think this might be the case.
bballdave025#MY-MACHINE /cygdrive/c/bballdave025
$ man gcc | grep -A 3 "[ ]*[-]l[ ]\{0,2\}library$"
-llibrary
-l library
Search the library named library when linking. (The second
alternative with the library as a separate argument is only for
POSIX compliance and is not recommended.)
(Note that I haven't included some parts of the result that aren't useful and can be fixed by prefixing the command with MANWIDTH=160, cf here.)
There is a little more detail and a little different result from the answer to a question about the lib prefix on files:
You can name a library whatever you want, but if you want gcc's -l flag to find the right one, you need to name it the way that link describes. For example, gcc -o myapp myapp.c -lm, [w]ill compile myapp.c, link the resulting object with libm.a, and output an executable called myapp. These days, there might be a more complicated search path involving dynamic library names, etc., but you should get the basic idea from this example. [In addition, you can look at this section f]rom the gcc man page:
-l library ...
... surrounds library with lib and .a and searches several directories.
The basic reason for all of that info is this: it is very possible that, in order to link with the gfortran library, you need to have installed a package named something like libgfortran. I don't know for sure how this works, especially with the Cygwin man page being slightly different, but it's worth a try. The likely extra thing you would need in this case is something like
apt-cyg install libgfortran
or
apt-cyg install libgfortran5
Here's some helpful info on how I found what to install. When I had a similar problem, I went to the Cygwin package search, but I only got three entries with three versions of netcdf-fortran
(archived). I wanted gfortran, so I kept looking
I found a great gfortran answer in this SO answer. With that answer, I went back to the Complete Cygwin Package List, armed with my trusty Ctrl + F, since I knew there were packages different from what came back from the search. The complete list had
cygwin64-gcc-fortran GCC for Cygwin 64bit toolchain (Fortran)`
gcc-fortran GNU Compiler Collection (Fortran)
and entries for libgfortran.
Hopefully some of this information will be helpful, or at least educational.
This problem is common for beginners with autotools. It can be:
missing libraries; this can be missing libraries for your project or compiler/system libraries, like libgfortran or similar for g95.
autotools can not detect your compiler;
dynamic libraries problem; runtime path to the dynamic libraries not set. See LD_LIBRARY_PATH for linux environment.
cross-compiling problem, I do not know much about cygwin but that can be an issue. I am not expert of cross-compiling either. It can also be another situation that I am not aware of.
I ran into the 1st and 3rd situations.
Approaches of solutions.
make sure you can manually compile and run a simple hello world program. Install the missing libraries if necessary. Also make sure that you can link your hello world program against the same libraries used by your modelling program, this last statement could lead you to the 3rd situation.
add the path to your compiler to the PATH variable or similar variable in cygwin. Or explicitly give the full path to your compiler to configure.
add the path to your libraries to the runtime libraries path LD_LIBRARY_PATH for linux environment or similar variable in cygwin. In one of my cases, the problem was that the test program that autotools uses to test the compiler could not run. It was successfully compiled but could not run. I installed all the libraries that my project uses in a path that was not included in library path. What happened was that the path to those libraries were set in the configure.ac or makefile.am so that the compiling was OK. But the running of the test program included in configure could not find them. This is a problem mostly for dynamically linked libraries. Adding the path to my .so to the LD_LIBRARY_PATH solved the problem.
well, I can not really help. The only solution that I can suggest is to install a linux system (dual boot or virtual machine) if you know how to do it, because I will not be there to help.
The following link can also help.

How can I link to an older version of a shared library

I'm building my program on my computer, on which libtiff.so -> libtiff.so.5.
And then pushing the builds on another machine on which libtiff.so -> libtiff.so.4.
At runtime, my program exists : « error while loading shared libraries: libtiff.so.5: cannot open shared object file: No such file or directory ».
I cannot upgrade the other machine, and I would like to avoid compiling on a virtual machine (with the same linux version than the executing machine). Therefore, I would like to force the compiler to use the libtiff.so.4 instead of libtiff.so.5.
I have libtiff.so.4 installed on my computer (as well as libtiff.so.5). How can I force the linkage with this version instead of the newer version. I thought about moving the libtiff.so -> libtiff.so.4, but I'm afraid of breaking my system if it needs the latest version (apt-get purge libtiff5 gives an error because some other package needs it).
Is it possible to link with an older (installed) version of a library? If yes, how?
And is it harmfull to change the symbolic link of libtiff.so to the older version? If not, will it solve my issue?
You can use this syntax to link to a specific version of a library:
gcc [other options] -l:libtiff.so.4
You do not need to specify a path; the usual directories are searched in order to find the library.
Note: as Michael Wild mentioned, you should have the header files for that version installed instead of the newest ones.
As others have mentioned, you can force the linker by specifying the full versioned name, or even the absolute path.
However, I would strongly advice against doing so. The problem is, that the installed headers correspond to the newer version of the library. If there have been API/ABI-breaking changes between these library versions, the program might work, crash intermittently, or if you're lucky, not work at all.
Instead you should temporarily install the development package that corresponds to the libtiff.so.4 library. If on Debian/Ubuntu or similar, this would be the libtiff4-dev package.
Specify the full path to the .so: instead of -ltiff pass /lib64/libtiff.so.4 to the linker.
You see that error when application is running. So you can either stop your application and then exrract your library tar file. Or, force to link the lib file to the newer version after you extract. In second case, you will use something like:
ln -fs libversionname libfile
Example:
ln -fs libomyapp.1.1.3 libomyapp.lib
This links your libomyapp.lib to the version specified. This can be your older vsersion or your newer version.
But as said, best way to work is to bring down your application to properly match to the expected lib functionality to work without errors or issues.

How do you link to a library from the software manager on Linux?

So I recently got fed up with Windows and installed Linux Mint. I am trying to get a project to build I have in Code::Blocks. I have installed Code::Blocks but I need glew(as well as a few other libraries). I found it in the software manager and installed it. I've managed to locate and include the header files. But I feel like the next step should be relatively straightforward and all over the internet but (perhaps due to lack of proper terminology) I have been as of yet unable to locate an answer.
Do I need to locate the files on my system and link to each library manually? This is what I did on windows but I just downloaded the binaries and knew where they were. I found one library from the software manager and linked to it manually but it just feels like I'm doing it the wrong way. Since it's "installed" on the system is there some quick way to link?
You should use two flags for linker '-l' and '-L'. You can set these flags somewhere in project properties.
The first one '-l' tells linker to link with particular library. For example glew, probably in /usr/lib is a file named libglew.so, when you link your program with '-lglew' flag, it will link it with glew library. Linker looks for libraries in few standard places: /usr/lib, /usr/local/lib and few extra. If you have your libs in nonstandard place, use '-L' flag to point these dirs.
Many linux distributions provide two kinds of packages with libraries, regular ones just with runtime, and devel ones (usually prefixed or suffixed with dev or devel) with header files and development version of libraries.
use build systems, Luke!
the typical way to develop/build software in *nix world is 3 steps:
configure stage -- before building smth you have to realize in what environment you are going to build your software... is everything that required is installed... it wouldn't be good if at compile stage (after few hours of compilation) you (or user who build your soft) got an error: unable to #include the 'xxx.h'. the most popular build systems are: cmake, my favorite after autotools. yout may try also scons or maybe crazy (b)jam...
compile stage -- usually just make all
install stage -- deploy just built software into the system. or other way: build packages for target distro (.deb/.rpm/&etc)
at configuration stage using test scripts (don't worry there are plenty of them for various use cases) you can find all required headers/libraries/programs/compiler options/whatever you need to compile your package... and yes: do not use hardcoded paths in your Makefiles (or whatever you use to make your binaries)
Answer to this question really depends on what you want to achieve. If you want just to build you app by yourself then you can just write path to libraries in your makefile, or your code editor settings. You may not even have to do that as if libraries installed by your linux distribution package manager, headers usually go to /usr/include and libraries to /usr/lib or /urs/lib64 etc. That locations are standard and you do not need to specify them explicitly. Anyway you need to specify libraries you want to link to.
If you want to create application that can be build by others, or by you on many different configurations/environments using something like cmake would be very helpful.

Linux C++ linker /usr/bin/ld

I wrote a small application on Redhat Linux 6 using g++ 4.4.6. After compilation, I received an error
/usr/bin/ld: cannot find -lcrypto
I did a search for the crypto library and find them here,
[root#STL-DUNKEL01 bin]# find / -name libcrypto*
/usr/lib64/libcrypto.so.0.9.8e
/usr/lib64/libcrypto.so.10
/usr/lib64/libcrypto.so.6
/usr/lib64/libcrypto.so.1.0.0
My question is whether the compilation error is caused by /usr/bin/ld not having /usr/lib64/ in the search path? If yes, how can I add it?
Thanks.
No, you have likely incorrectly diagnosed the cause.
You need a libcrypto.so to link against. This is usually a symlink to one of the actual libraries, whose soname (libcrypto.so.??) will be embedded into the binary. Only that library is needed at runtime, but the symlink is necessary to compile.
See Diego E. Pettenò: Linkers and names for more details.
You have to add -L/usr/lib64 when calling gcc or ld.
Note, you can specify LD_LIBRARY_PATH as well/instead, but it is considered harmful to do so. (The link mentions Solaris specifically, but the issues apply to other OSs as well.)
Quote:
LD_LIBRARY_PATH is used in preference to any run time or default system linker path. If (God forbid) you had it set to something like /dcs/spod/baduser/lib, if there was a hacked version of libc in that directory (for example) your account could be compromised. It is for this reason that set-uid programs completely ignore LD_LIBRARY_PATH.
When code is compiled and depends on this to work, it can cause confusion where different versions of a library are installed in different directories, for example there is a libtiff in /usr/openwin/lib and /usr/local/lib. In this case, the former library is an older one used by some programs that come with Solaris.
Sometimes when using precompiled binaries they may have been built with 3rd party libraries in specific locations; ideally code should either ship with the libraries and install into a certain location or link the code as a pre-installation step. Solaris 7 introduces $ORIGIN which allows for a relative library location to be specified at run time (see the Solaris Linker and Libraries Guide). The alternative is to set LD_LIBRARY_PATH on a per-program basis, either as a wrapper program to the real program or a shell alias. Note however, that LD_LIBRARY_PATH may be inherited by programs called by the wrapped one ...
Add the directory to /etc/ld.so.conf
then run "sudo ldconfig" to make the changes take effect.
You can provide the directories to search for the libraries in as a parameter to gcc like so -L<directory_to_search_in>. And note that there can be multiple parameters to -L. Also, are you trying to build a 32-bit application or a 64-bit one?

library location for project

I have started an C++ SFML project for linux. I was wondering where the .so's should go.
Should they go inside the project folder so a user can simply run the program after they get it? Or should the user have the SFML library installed on there linux machine before they run my program?
Even if you did include the .so files, you have no guarantee that the user will be able to run it (different architecture, libraries linked against different libc, ...). Either link statically, or better yet, just let them provide the supporting libraries themselves.
#Joel J. Adamson's answer to use autoconf is a good idea. SFML doesn't come with a pkg-config file, so you will check for SFML as follows:
dnl Checking for a C++ compiler
AC_PROG_CXX
dnl Checking C++ features. This tells configure to use the C++ compiler for checks.
AC_LANG_PUSH([C++])
dnl Check for a SFML header.
AC_CHECK_HEADER([SFML/Config.hpp], [], [AC_MSG_ERROR([SFML headers not found.])])
AC_LANG_POP([C++])
Checking for the libraries is a bit more difficult because of name mangling and so on. Tyler McHenry wrote a good article on this part, if you want to be thorough.
At the distribution level SFML will be a dependency, i.e. a user will have to install it (or their package manager will have to install it) before compiling your program. If a user wants to compile it, they will also need the header files (often there's a separate "devel" package to install). You shouldn't have to distribute the .so files, and it's probably better (for everybody) if you don't.
You will need to check if the user has it, e.g. using autoconf you need to check for the relevant headers in your configure.ac for the application project. For example, to check for the math library, because I'm using the exp() function, I'll use
AC_CHECK_LIB([m], [exp])
to create a check during the configure step. Luckily autoscan can check this for you and create a skeleton configure.ac file called configure.scan. See also Cmake.
HTH.
You should make your program depend on the specific library (and version) that it needs. If you're planning to package it into an rpm/deb file you should add the dependency there too so that it can be checked and applied by package managers (e.g. apt can install all the dependency packages of a given package)