why does the order of '-Lpath/to/lib' matter? - gcc

I'm getting a linker error 'undefined reference to' when linking a library with my program. I've read this post and I understand that the order of libraries matter. Does the order of '-Lpath/to/lib' also matter? The problem i'm facing solved when I change the order of '-L..' option rather than '-l'. please shed some light.

-L controls link directories, -l for link libraries (actual files). So, by changing order of -L flags, you can cause a different library with the same filename to be selected - directories are searched by the order provided with -L (left to right)
In your case, sounds like the library file originally selected did not contain some of the functionality - that's why you got 'undefined reference to'.
In general it may be worth either using -l with full path to the specific library, or a build system (I like CMake) where you can set this as an explicit option (and maybe print the selected file in a message during build).

Related

Linking against an external object file (.o) with autoconf

For work purposes I need to link against an object file generated by another program and found in its folder, the case is that I did not find information about this kind of linkage. I think that if I hardcode the paths and put the name-of-obj.o in front of the package_LDADD variable should work, but the case is that I don't want to do it that way.
If the object is not found I want the configure to fail and tell the user that the name-of-obj.o is missing.
I tried by using AC_LIBOBJ([name-of-obj.o]) but this will try to find in the root directory a name-of-obj.c and compile it.
Any tip or solution around this issue?
Thank you!
I need to link against an object file generated by another program and
found in its folder
What you describe is a very unusual requirement, not among those that the Autotools are designed to handle cleanly or easily. In particular, Autoconf has no mechanisms specifically applicable to searching for bare object files, as opposed to libraries, and Automake has no particular automation around including such objects when it links. Nevertheless, these tools do have enough general purpose functionality to do what you want; it just won't be as tidy as you might like.
I think that if I hardcode the paths and put the
name-of-obj.o in front of the package_LDADD variable should work, but
the case is that I don't want to do it that way.
I take it that it is the "hardcode the paths" part that you want to avoid. Adding an item to an appropriate LDADD variable is not negotiable; it is the right way to get your object included in the link.
If the object is not found I want the configure to fail and tell the
user that the name-of-obj.o is missing.
Well, then, the key thing appears to be to get configure to perform a search for your object file. Autoconf does not have a built-in mechanism to perform such a search, but it's just a macro-based shell-script generator, so you can write such a search in shell script + Autoconf, maybe something like this:
AC_MSG_CHECKING([for name-of-obj.o])
OTHER_LOCATION=
for my_dir in
/some/location/other_program/src
/another/location/other_program.12345/src
$srcdir/../relative/location/other_program/src; do
AS_IF([test -r "${my_dir}/name-of-obj.o"], [
# optionally, perform any desired test to check that the object is usable
# ... perhaps one using AC_LINK_IFELSE ...
# if it passes, then
OTHER_LOCATION=${my_dir}
break
])
done
# Check whether the object was in fact discovered, and act appropriately
AS_IF([test "x${OTHER_LOCATION}" = x], [
# Not found
AC_MSG_RESULT([not found])
AC_MSG_ERROR([Cannot configure without name-of-obj.o])
], [
AC_MSG_RESULT([${OTHER_LOCATION}/name-of-obj.o])
AC_SUBST([OTHER_LOCATION])
])
That's functional, but of course you could embellish, such as by providing for the package builder to specify a location to use via a command-line argument (AC_ARG_WITH(...)). And if you want to do this for multiple objects, then you would probably want to wrap up at least some of that into a custom macro.
The Automake side is much less involved. To get the object linked, you just need to add it to the appropriate LDADD variable, using the output variable created by the above, such as:
foo_LDADD = $(OTHER_LOCATION)/name-of-obj.o
Note that if you're building just one program target then you can use the general LDADD instead of foo_LDADD, but note that by default these are alternatives not complements.
With that said, this is a bad idea overall. If you want to link something that is not part of your project, then you should get it from an installed library. That can be a local, custom-built library, of course, so long as it is a library, not a bare object file, and it is installed. It can be a static library if you don't want to rely on or distribute a separate shared library.
On the other hand, if your project is part of a larger build, then the best approach is probably to integrate it into that build, maybe as a subproject. It would still be best to link a library instead of a bare object file, but in a subproject context it might make sense to use a lib that was not installed to the build system. In conjunction with a command-line argument that tells it where to find the wanted lib, this could make the needed Autoconf code much cleaner and clearer.

How to link a library by its exact name with gcc?

I am trying to generate a dynamic library target.so and to do this I need to link it dynamically to a library in which the version number appears at the end:
/path/to/library/lib_with_version_number.so.28
If the name of the library was only,
/path/to/library/lib_without_version_number.so
I can use
-L/path/to/library/ -l_without_version_number
(because I don't wan't to have the complete library path when I run ldd command).
My question is: How to do the same with the version number?
If you have an unavoidable need to link a library libfoo.a or libbar.so.x.y.z
by exactly that name, rather than by following the usually wiser -lfoo convention, you can do so by using the -l: option instead, e.g.
-l:libfoo.a -l:libbar.so.x.y.z
This choice makes no difference to the behaviour of the -L option.

Rust library for inspecting .rlib binaries

I'm looking for a way to load and inspect .rlib binaries generated by rustc. I've hunted around the standard library without much luck. My assumption is that an .rlib contains all the type information necessary to statically type check programs that "extern crate" it. rustc::metadata is where my hunt ended. I can't quite figure out if the structures available at this point in the compiler are intended as entry points for users, or if they are solely intermediate abstractions depending on a chain of previously initialized data.
Alternatively, If there's a way to dump an .rlib to stdout in a parsable form then that's also fantastic. I tried /usr/bin/nm, but it seemed to be excluding function type signatures. Maybe I'm missing something.
Anyways, I'm working on an editor utility for emacs that I hope at some point will provide contextually relevant information such as available methods, module items and their types, etc. I'd really appreciate any hints anyone has.
The .rlib file is an ar archive file. You can use readelf to read its content.
Try readelf -s <your_lib>.rlib. The type name may be mingled/decorated by the compiler so it may not be exactly the same as in .rs file.

How to find the version number of libxxx.a

I'm probably not finding the right search words, but I can't find out how to get
the version number of a static (or dynamic ) lib without writing a program. Surely there must be a unix application to do this (with equivalent on os x). (I tried the finder info, and
it told me that .a files are files to be opened by text wrangler!).
Thanks.
A static lib is just an archive of object files; it doesn't have an implicit version number. Many libraries will have an explicit version number, some symbol like FOO_VERSION_ with contents "1.2.3", but there's obviously no generic way to find any such symbols.
Dynamic libs are a different story. They have two version numbers, "current" and "compatibility". See the manpage for otool, but you can easily parse whichever one you want out of the -l (in the LC_ID_DYLIB command) or -L output (look for the library's own name).

Debugging a Makefile

Let me prefice this question with the comment that I know very little about Makefiles or make.
There is a very large project that is automatically built nightly. It is built in both Debug and Release mode, Debug being used for utilities like Valgrind to provide code analysis. Somehow, some of the built libraries are losing the debug flag during the make process, which makes some analysis output unhelpful. I was tasked with finding the bug and I need some suggestions on how to go about locating/repairing the issue.
Thanks in advance
make itself also supports a debug flag, -d; depending on how your Makefiles call each other, it may be possible to pass it through (and if not, you can rewrite them to do so with a script); then if you feed the resulting output to a file you can start looking for clues.
Given the sparse information, I can only sketch a very general strategy based on what I've seen in terms of Makefile usage for a handful of large projects.
If you don't already know where the flags originate, search through the Makefiles to find out.
Something like:
find . -name Makefile -exec grep -nH -- -g {} \;
(Adjusting the -name pattern if your project uses included Makefiles like foo.mk or bar.mak or something. And adjusting the "-g" if your debug flag is something else.)
You'll probably find it assigned to a variable like CFLAGS. Look around the spot where this variable is assigned, it is probably set conditionally (e.g. ifeq($(RELEASE),1)).
Now look at the Makefile(s) in the library that isn't getting those flags. Find the spot where the compile command lives. Is it using the right variable? Are these Makefiles overriding the variable?
It may also be helpful to capture the output of a build to a file and search around for any other places that might not have the debug flags set.
use remake, its really good

Resources