Given a binary, is it possible to find the make recipe that generated it? - gcc

Looking for something kind of like rpm -q that tells you where a package came from, but instead of package info, I want compiler information.
I've looked in man page for make, but i don't see/understand-if-there-are any reverse options. https://linux.die.net/man/1/make
Is it possible to have gcc compiler tell you? The reason I'm asking is because I've a binary that was built agains some *.so and I know i can use ldd on the binary to find those shared objects, but it would be nice to see the compile command. I don't understand a lot about .so, so any descriptive /background information would be useful.

Related

How to compile srlua (or a link to the binaries)

Related:
How to compile srlua?
How do I Make an executable Lua script using srlua?
The first link is the exact question I am asking here. However, the sole answer is unsatisfactory as it assumes multiple things, namely that the OP is already using Cmake (a fact disproved by the OP's comment on the answer). The second link seems to already be most of the way through a tutorial, and while a link to precompiled binaries for both srlua.exe and srglue.exe are provided, the link no longer contains binaries but instead the source.
I have found several other threads on various websites all asking the same thing, but all of them either assume that you essentially already know how, or explain nothing (many have potentially helpful links, but they are old and no longer work).
I have already tried to compile srlua, and got a srglue.exe, but when I tried srlua.c I ended up with a list of undefined references (such as "lua_type" or "lua_getfield").
lua_getfield, lua_type, lua_settop, lua_getfield, lua_type, lua_settop, lua_pushstring, lua_pushinteger, lua_call, lua_pushfstring, lua_load, lua_tolstring, lua_tointeger, lua_touserdata, luaL_openlibs, lua_createtable, lua_pushstring, lua_rawseti, lua_setfield, luaL_checkstack, lua_pushstring, lua_call, lua_tolstring, luaL_callmeta, lua_type, lua_type, lua_typename, lua_pushfstring, luaL_newstate, lua_pushcclosure, lua_pushcclosure, lua_pushinteger, lua_pushlightuserdata, lua_pcall, lua_tolstring, lua_close
My question is this:
How does one use a C compiler (I know the basics of gcc) to compile srlua specifically? Or, if anyone has a functioning link to either precompiled binaries or a tool to compile the binaries, could they share it?
Important: I am on Windows. Thus, I cannot just use make. I must actually compile the .c files to .exe files. I am asking how. If you simply provide links to threads with the aforementioned problems, you are not helping. If you give an answer that assumes in-depth prior knowledge of a particular tool that does not have good documentation, you are not being helpful. If you tell me tools to use, but not the specific procedure for compiling srlua, you are not being helpful. If there is a better place for this, tell me and I can move it there.
I don't know any Windows pre-compiled binaries for srLua.
To compile srLua, you should first install the Mingw compiler to use GCC as a C compiler : you can install TDM-GCC (https://jmeubank.github.io/tdm-gcc) or http://winlibs.com.
You can then open a Console prompt. Enter the "gcc" command to be sure that the compiler is working (and that the PATH is correctly set).
Then go to the directory you extracted the srLua source files and type the command :
mingw32-make
Cross your fingers and it should compile everything :)
When linking, you should include the Lua libraries with the -l Switch : -llua54 for Lua 5.4 library for examples.
I found this already compiled release on webarchive, it's kinda old but works:
https://web.archive.org/web/20130721014948/http://www.soongsoft.com/lhf/lua/5.1/srlua.tgz

using my own static/dinamic library: HOW TO compile and link against (the right way to do the things properly)

Sorry for this newbie question.
Context:
I have just created my own library (using CMake):
libmyownsomething.a <--- static version of the compiled library
libmyownsomething.so <--- dinamic version of the same library
libmyownsomething.h <--- the header file to be included in other project
Questions:
Where is the right place where the files should be placed? ( I guest /usr/local/include/ and /usr/local/lib/
How to compile other lib/projects against this one by inserting only #include <myownsomething.h> and a right flag LDFLAGS=-lmyownsomething?
To be able to link agains your library with just -lmyownsomething, you need to have libmyownsomething.so (or .a, for static linking) in one of the directories you linker searches by default.
I found this in texinfo documentation for GNU ld (library search path in linker script):
'SEARCH_DIR(PATH)'
The 'SEARCH_DIR' command adds PATH to the list of paths where 'ld'
looks for archive libraries. Using 'SEARCH_DIR(PATH)' is exactly
like using '-L PATH' on the command line
Now, GNU ld (ld.bfd to be precise) uses a default linker script, which can be obtained with --verbose. Let's see what search dirs there are by default (on my system, anyways -- that might well depend on configuration; if you are going to distribute your library, you probably want to make the most portable choice):
$ ld --verbose |& grep SEARCH_DIR
SEARCH_DIR("/usr/x86_64-pc-linux-gnu/lib64"); SEARCH_DIR("/usr/lib"); SEARCH_DIR("/usr/local/lib"); SEARCH_DIR("/usr/x86_64-pc-linux-gnu/lib");
To answer the question about #includeing files, you need to consult the compiler documentation, or perhaps the POSIX standard. (However, I'd recommend either going with the simplest choices -- see below -- or providing a configurable way to install your files e.g. with --prefix build time option. Then the user/packager can decide the best place to put them for themselves. But nothing keeps you from providing sane defaults. Same goes for libraries, but I tried to address that part of the question exactly how it was asked.)
Generally, this stuff varies from system to system, but they usually follow the Filesystem Hierarchy Standard. I think, /usr/include and /usr/lib is the safest choice. Another good practice is using e.g. pkgconf mechanism.
Hope this helps. I really should have asked about your use-case first: who are you going to distribute your software to, and how? Anyway, be sure to post comments. Also, I wonder if this is Stackoverflow material; perhaps it needs moving some place else.

setting up autotools to link single system library statically

I have a project, where I want to link one of system libraries statically. The project uses GNU build system.
In configure.ac I have:
AC_CHECK_LIB(foobar, foobar_init)
On development machine this library is installed in /usr/lib/x86_64-linux-gnu. It is detected, but it is linked dynamically, which causes issues, as it is not present on some machines. Linking it statically (-Wl,-Bstatic etc.) works fine, but I don't know how to set this up in autotools. I tried forcing this into Makefile.am link flags for the project, but it still gives a preference to dynamic library.
I also tried using --enable-static with ./configure, but it seems to have no effect on system libraries.
If you want to link the whole program statically, then you should pass the --disable-shared option to configure. You might or might not need also to pass --enable-static, depending on the default value for that option (which you can influence via your configure.ac file). You really should consider doing this.
You should also consider making this the installer's problem, not the build system's. Let it be the installer's responsibility to ensure that all the shared libraries needed by the program are provided by the systems where it is installed. This is very common; in fact, it is one of the inspirations for package-management systems such as yum / dnf and apt, and their underlying packaging formats.
If you insist on linking only one library statically, while linking everything else dynamically, then you'll need to jump through a few more hoops. The objective will be to emit link options that cause just that library to be linked statically, without changing other libraries' linking. With the GNU toolchain, and supposing that the program is otherwise being linked dynamically, that would be this combination of options:
-Wl,-Bstatic -lfoobar -Wl,-Bdynamic
Now consider the documentation of the AC_CHECK_LIB() macro:
Macro: AC_CHECK_LIB (library, function, [action-if-found],
[action-if-not-found], [other-libraries])
[...] action-if-found is a list of shell commands to run if the link with the library succeeds; action-if-not-found is a list of shell
commands to run if the link fails. If action-if-found is not
specified, the default action prepends -llibrary to LIBS and defines
'HAVE_LIBlibrary' (in all capitals). [...]
Note in particular the default behavior in the event that the optional arguments are not provided (your present case) -- that's not quite what you want, at least not by itself. I suggest providing at least an alternative behavior for action-if-found case, and you could consider also making configure fail in the action-if-not-found case. The latter is left as an exercise; implementing just the former might look like this:
AC_CHECK_LIB([foobar], [foobar_init], [
LIBS="-Wl,-Bstatic -lfoobar -Wl,-Bdynamic $LIBS"
AC_DEFINE([HAVE_LIBFOOBAR], [1], [Define to 1 if you have libfoobar.])
])
You should also pay attention to the order of your AC_CHECK_LIB() invocations. As its docs go on to say:
This macro is intended to support building LIBS in a right-to-left
(least-dependent to most-dependent) fashion such that library
dependencies are satisfied as a natural side effect of consecutive
tests. Linkers are sensitive to library ordering so the order in which
LIBS is generated is important to reliable detection of libraries.
If you find that you still aren't getting what you want, then have a look at the link commands that make actually executes. You need to understand what's wrong about them before you can determine how to fix the problem.
With all that said, I observe that the above treatment is basically a hack, and it makes your build system much less resilient. It introduces dependencies on GNU toolchain options (which some other toolchains may nevertheless accept), and it assumes dynamic linking is being performed overall. It may be possible to resolve those issues with additional Autoconf code, but I urge you to instead go with one of the first two alternatives I described.

Proper way to link a static library using GCC

Why is it that some static libraries (lib*.a) can be linked in the same way that shared libraries (lib*.so) are linked (ld -l switch), but some can not?
I had always been taught that all libraries, static or not, can be linked with -l..., however I've run into one library so far (GLFW), which does nothing but spew "undefined reference" link errors if I attempt to link it this way.
According to the response on this question, the "proper" way to link static libraries is to include them directly, along with my own object files, rather than using -l. And, in the case of the GLFW library, this certainly solves the issue. But every other static library I'm using works just fine when linked with -l.
So:
What could cause this one library to not work when linked rather than included directly? If I knew the cause, maybe I could edit and recompile the library to fix the issue.
Is it true that you're not supposed to link static libraries the same way you link shared libraries? (And if not, why not?)
Is the linker still able to eliminate unused library functions from the output executable when the library is directly included in this way?
Thanks for the replies! Turns out the problem was due to link order. Apparently, if you use a library which in turn has other library dependencies, those other dependencies must be listed after the library, not before as I had been doing. Learned something new!
Have you cared to indicate to GCC the path of your library (using -L) ? By using -l solely, GCC will only be able to link libraries available in standard directories.
-L[path] -l[lib]
The correct way to link a static library is using -l, but that only works if the library can be found on the search path. If it's not then you can add the directory to the list using -L or name the file by name, as you say.
The same is true for shared libraries, actually, although they're more likely to be found, perhaps.
The reason is historical. The "ar" tool was original the file archive tool on PDP11 unix, though it was later replaced entirely by "tar" for that purpose. It stores files (object files, in this case) in a package. And there's a separate extension containing the symbol table for the linker to use. It's possible if you are manually managing files in the archive that the symbol table can get out of date.
The short answer is that you can use the "ranlib" tool on any archive to recreate the symbol table. Try that. More broadly, try to figure out where the corrupt libraries are coming from and fix that.

Problem with linking in gcc

I am compiling a program in which a header file is defined in multiple places. Contents of each of the header file is different, though the variable names are the same internal members within the structures are different .
Now at the linking time it is picking up from a library file which belongs to a different header not the one which is used during compilation. Due to this I get an error at link time.
Since there are so many libraries with the same name I don't know which library is being picked up. I have lot of oems and other customized libraries which are part of this build.
I checked out the options in gcc which talks about selecting different library files to be included. But no where I am able to see an option which talks about which libraries are being picked up the linker.
If the linker is able to find more than one library file name, then which does the linker pick up is something which I am not able to understand. I don't want to specify any path, rather I want to understand how the linker is resolving the multiple libraries that it is able to locate. I tried putting -v option, but that doesn't list out the path from which the gcc picks up the library.
I am using gcc on linux.
Any help in this regard is highly appreciated.
Regards,
Chitra
Passing -Wl,-t to gcc will tell ld to dump which files it's reading.

Resources