How to force the linker to treat an archive file like many object files? - archive

In my homemade build system, I create many .a files. I then want to link these into one final image.
The issue is that ld naturally assumes these are libraries, and therefore links none of the symbols in, producing an empty image as output.
Can I force ld to treat these as groups of object files?

It seems to me only answer is: you can't put the main in a library!
If you keep main as object file, then it will pull the threads of the whole program, and even if the rest of it is in .a files it should link just fine.

Related

Why do I need to manually link the C runtime library when creating an EXE out of static libraries without any object files?

I'm pretty new to working with libraries and I'm in the process of trying to understand some specifics regarding static libraries and object files.
Summary
The behavior I'm noticing is that I can link several objects to make an executable with no problem, but if I take an intermediate step of combining those objects into static libraries, I cannot link those static libraries to make an executable without additionally specifying the needed C Run-time library in the link command.
Also, or the record, I'm doing the compiling/linking with Visual Studio 2010 from the command line. More details of the process I'm following are below.
First, let's say I have four source files in a project: main.c, util1.c, util2.c, and util3.c.
What works
I can compile these sources with the following command:cl -c main.c util1.c util2.c util3.cAs a result, I now have four object files: main.obj, util1.obj, util2.obj, and util3.obj. These object files each contain a DEFAULTLIB statement intended to inform the linker that it should additionally check the static C Run-time library libcmt.lib for any unresolved external dependencies in these object files when linking them.
I can create an executable named "app_objs.exe" by linking these objects with the following command:
link -out:app_objs.exe main.obj util1.obj util2.obj util3.obj
As mentioned in step 1, the linker used the runtime library due to the compiler's step of adding a default library statement to the objects.
Where I'm confused
Let's say I want to have an intermediate step of combining these objects into static libraries, and then linking those resulting LIB files to create my executable. First, I can create these libraries with the following commands:
link -lib -out:main.lib main.obj
link -lib -out:util.lib util1.obj util2.obj util3.obj
Now, my original thought was that I could simply link these libraries and have the same executable that I created in step 2 of "What works". I tried the following command and received linker error LNK1561, which states that an entry point needs to be specified:
link -out:app_libs.exe main.lib util.lib
From Microsoft's documentation, it is evident that linking libraries without any object files may require entry points to be specified, so I modified the command to set the subsystem as "console" to specify that the executable in intended to be a console application (which seems to imply certain entry points, thereby resolving that error):link -out:app_libs.exe -subsystem:console main.lib util.libUnfortunately, now I get a linker error stating that mainCRTStartup is an unresolved external symbol. I understand that this is defined in the C runtime library, so I can resolve this issue by manually specifying that I want to link against libcmt.lib, and this gives me a functioning executable:link -out:app_libs.exe -subsystem:console main.lib util.lib libcmt.lib
What I'm not understanding is why the default library info that the compiler placed in each object file couldn't be used to resolve the dependency on libcmt.lib. If I can link object files without explicitly stating I want libcmt.lib, and I created static libraries that are containers for the object files, why can't I link those static libraries without having to explicitly state that I want libcmt.lib? Is this just the way things are, or is there some way I could create the static libraries so that the linker will know to check for unresolved symbols in the runtime library?
Thanks for your help. If I have some fundamentally incorrect ideas here, I'd love suggestions on good references to learn all of this correctly.
Well the answer to your misunderstanding is that .lib files are often a product in themselves, and the compiler can't make those assumptions safely. That's what "external" is for.
If I produce binaries for someone's platform because its users are totally helpless, and they want/need static linkage, I have to give them foo.h and libfoo.lib without tying them to a specific runtime entry point. They may very well have defined their own entry point already for their final product, whether DLL or EXE.
You either want the runtime, or you want your own .obj that contains your entry point. Be warned that declaring and defining mainCRTStartup on your own may mean you're not executing important instructions for the target platform.

What are the relationship between LIS, OBJ and EXE files?

I am working with a different compiler CC. It doesn't work like GCC.
When I was using GCC, I can do "gcc -o exe_filename source_filename" and the output would be a exe file.
When I use CC, I need 2 steps. First I compile the source files (suppose it involve a .c and a .h file ) and it create a .lis file and a .obj file. Then I do a link command which created a .exe file.
What is the relationship between LIS, OBJ and EXE files? I ask this because I wonder which files do I need if I want to use the exe in another machine without including unnecessary files. If LIS and OBJ were only used for compilation, I don't need it in another machine.
The compiler takes C files (and includes H files as referenced) and produces object (OBJ) and listing (LIS) files. The object file contains the code and data, but has unresolved external references. The listing typically includes line numbers, error and warning messages, and optional sections such as a type and variable cross-reference.
The linker combines object files and resolves external references to libraries. The result is an executable (EXE) image. (Or shareable image when creating libraries.)
Only the executable file needs to be copied from one system to another to run the application. The listing may be useful for interpreting error messages as it provides the properly correlated line numbers. The object could be useful if the application needs to be relinked due to changes in libraries, particularly if the target system has older versions than the original system.
the OBJ files are the compiled C files in a format that they can be "Linked" together by a linker and turned into an EXE.
Compile -> OBJ -> Link -> EXE
the LIS file is just informational output of the C that the compiler ends up compiling.
All you need once compiled and linked is the EXE
You don't need the other files. The exe will work fine by itself.
I don't have much idea on LIS. But the difference between OBJ and EXE is OBJ file may contain unresolved symbols and in EXE file all symbols are linked and resolved.
If another machine also has same hardware then u can use direct exe to run else you have to cross compile

Compaq Visual Fortran - Crashes During Linking A .LIB File

When I compile with Compaq Visual Fortran, I get these errors (when it starts the linker process) that should be located in a .lib file I thought I added to the workspace:
X30XFULL.OBJ : error LNK2001: unresolved external symbol _BCON#4
X30XFULL.OBJ : error LNK2001: unresolved external symbol _RCON#16
According to where I've googled about, it looks like Compaq Visual Fortran (Version 6, FYI) can't find the library files...
My main question is, how do I use them? Could there possibly be other missing files? Here is what I've tried:
Right Click->Adding the files in the FileView window
Going under Project->Settings, Clicking the Link tab, and under the input category, adding the library files under object/library modules (bprop.lib rprop.lib) and having the Additional Library Path point to where the files are. I also did this under the Resources tab and where it says "Additional Resource Include Directories," I put the directory of where these files were located.
To cover my bases, I also put these files in where the project workspace file, where the compiled executable file would be generated, and pretty much any place I could think of that CVF might possibly look to in order to find these files.
A little background:
I have this Fortran executable that was last compiled in the 90s. From my research, it's a 16-bit compiled one which won't work on a 64-bit machine.
The original code has, at least from what we can gather, 16 bit compiled libraries. Without the original compiler, we can't figure out how to look at or use them. We also have a (semi)equivalent library file that's actually a .FOR file. For all we know, the BPROP.FOR and BPROP.LIB could be the same file (they were found in the same source code area). If we use the BPROP.FOR file, the program can compile, but we are having issues with results that we've traced down to information that is used/gathered/processed in that file.
However, we do have 32-bit versions of (what we think) are the same .lib files. So, we're trying to use that, which is what is being used to compile the Fortran executable which results in the errors above.
Found the answer, at least for me. I don't know how easy it'll be to extrapolate if anyone else finds these answers, but this is how I solved it.
With the old Fortran libraries, all I had to do was add them to the FileList view that has all of the different fortran files (.FOR, etc). I did not have to add these libraries in the settings like I mentioned, but that will work as well. Other then that, I didn't need to add any extra declarations or anything similar.
What we did find out is that the function in question (BCON and RCON) that calls those .LIB files required an additional argument. The only way I found this out was examining other source code that used those libaries, so if anyone is stuck like I was, that would be a good place to start. Alternatively, if you can read the .lib file in a hex editor, you can kind of make out functions and their arguments.
Of course, if you have the original source code for said arguments, that's even better. :)

linking object files and linking static libraries containing these files

Hello Stack Overflow Community,
i am working on a c project to interleave multiple c programs into one binary, which can run the interleaved programs as treads or forks for benchmarking purposes.
Therefore i run make in each program folder of the desired programs and prelink all .o files with "ld -r" to one new .o file. After that i add a specific named function to each of these "big" .o files, which does nothing but run the main() of each program and providing the argc and argv. Then i use objcopy to localize every global Symbol except the unknown ones and the one of my specific function which shall run the main(). At last i link these manipulated .o files together with my program which runs the specific named functions as threads, or forks or after another.
Now to my Question/Problem:
I ran into a problem with static libs. I was using ffmpeg for testing, and it builds static libs such as libavcodc and libavutil and so on. Unfortunately, "ld -r" does not link .a files. So i tried to extract these libs with ar -x and then link the extracted .o files in the way mentioned above to the "big" new .o file. But i did not work because libavcodec and libavutil both include the file ff_inverse.o. That is obviously not a problem when i just build ffmpeg, which will link these static libraries. But still, both libraries include it, so there must be a machanism which makes the choice, which ff_inverse.o to use and to link. So my Question: How does this work? Where is the difference?
The way ld does it with normal linking is to prioritize the libraries. Libraries listed first in the command line are linked in first, and only if symbols still are unresolved does it move on to the next library. When linking static libraries, it ignores the name of each .o file, because the name is unnecessary, only the exported symbols are necessary. You may want to emulate that behavior, by extracting libraries in a sorted order.

What exactly does "ar" utility do?

I don't really understand what ar utility does on Unix systems.
I know it can be somehow used for creating c libraries, but all that man page tells me is that it is used to make archives from files, which sounds similar to, for example, tar....
The primary purpose is to take individual object files (*.o) and bundle them together into a static library file (*.a). The .a file contains an index that allows the linker to quickly locate symbols in the library.
Tar doesn't create files that linkers understand.
ar is a general purpose archiver, just like tar. It just "happens" to be used mostly for creating static library archives, one of its traditional uses, but you can still use it for general purpose archiving, though tar would probably be a better choice. ar is also used for Debian .deb packages.
Exactly, ar is an archiver. It simply takes a set of object files (*.o) and put them in an archive that you call a static library.
It takes code in the form of object files (.obj, .o, etc) and makes a static library (archive). The library can then be included when linking with ld to include the object code into your executable.
Take a look at the example usage in the Wikipedia article.
You might want to run man ar to get the full picture. Here's a copy of that on the web.
To quote:
The GNU ar program creates, modifies, and extracts from archives. An
archive is a single file holding a collection of other files in a
structure that makes it possible to retrieve the original individual
files (called members of the archive).
ar is considered a binary utility because archives of this sort are
most often used as libraries holding commonly needed subroutines.
ar is specifically for archives (or libraries) of object code; tar is for archives of arbitrary files. Anybody's guess why GNU refers to these as 'archives', in other environments this utility is called the 'librarian', and the resulting files just libraries.

Resources