I know that when linking to multiple static libraries or object files, the order matters (dependent libraries should be listed before their dependencies). I want to know if, when creating a library file with ar, this same rule applies and the order within the library matters, or within the same .a file it doesn't make a difference.
I am packing 200+ object files with a complicated dependency graph, and doing
ar rcs mylib.a objs/*.o
is considerably easier then listing them in the correct order.
I am using gcc, if it makes a difference.
The order within the library used to matter long time ago.
It no longer matters on any UNIX system newer than ~15-20 years. From man ranlib:
An archive with such an index speeds up linking to the library
and allows routines in the library to call each other without
regard to their placement in the archive.
Most non-ancient UNIX systems either produce the __.SYMDEF (which contains above index) automatically while building the archive library, or build it in-memory at link time.
Related
I'm working on trying to fix/redo the makefile(s) for a legacy system, and I keep banging my head against some things. This is a huge software system, consisting of numerous executables, shared objects, and libraries, using C, Fortran, and a couple of other compilers (such as Motif's UIL compiler). I'm trying to avoid recursive make and I would prefer "one makefile to build them all" rather than the existing "one makefile per executable/.so/.a" idea. (We call each executable, shared object, library, et al a "task," so permit me to use that term as I go forward.)
The system is scattered across tons of different source subdirectories, with includes usually in one of 6 main directories, though not always.
What would be the best way to deal with the plethora of source & target directories? I would prefer including a Task.mk file for each task that would provide the task-specific details, but target-specific variables don't give me enough control. For example, they don't allow me to change the source & target directories easily, at least from what I've tried.
Some things I cannot (i.e., not allowed to) do include:
Change the structure of the project. There's too much that would need to be changed everywhere to pull that off.
Use a different make. The official configuration (which our customer has guaranteed, so we don't need to deal with unknown configurations) uses gmake 3.81, period.
We have the situation where we have a large number of inter-related DLLs that form our product. This is a very "old" product (as in it has been developed over 20 years) and has suffered in the past from different defaults for structure packing over several versions of Visual Studio.
So, in the many cases where #pragma pack has not been used in the DLL header files, but the structure alignment has been set instead in the project properties, we can have the situation where a project that imports the DLL (via its lib and header) has a different structure alignment and potentially results in mismatched structure sizes.
This is complicated by the fact that structs can be sized correctly by "accident" - e.g. if all members of the struct are unsigned int then pack(4) in the DLL and pack(2) in the importing project can work ok. Until, of course, someone amends a struct to add a bool for example.
I would like to remove all of this potential confusion by adding #pragma pack statements to the header files of all exporting modules but would first like to assess whether we have any such exposures in our current code (thinking about hard-to-track runtime bugs here). Also, it may be useful to introduce some automated checking into our build process to make sure we never hit these situations, even with third-party DLLs or LIBs.
So, my question:
Is it possible, from a compiled DLL, or its associated LIB, to determine what structure alignment was in force at the time the DLL was compiled? Similarly, is it possible to discover this for an EXE?
What am I wondering is if there is anything in the PE format or LIB (is that COFF?) that can be used to find this information?
UPDATE
Well, no good came from examining libs and dlls with dumpbin, so I'm going to try to get some info from the PDB files we generate from our Release builds. I found this as a starting point...
I would say that is not possible. C++ doesn't have type-information applied to it (unless enabled with RTTI, but won't be of much help for this problem). Structure is nothing but a sequence of bytes, for the programmer. Compiler will replace the variable.member with appropriate byte-alignment to access that data.
I doubt you have correct debugging information (i.e. PDB file) for the DLL to lookup the symbols. Even with that, it is not possible to find "packing" of a structure.
I have faced problem with structure sizes in different EXE/DLLs (having full source code), where sizeof is only tool we can use to find the difference (and go nested to find the root of problem). Even with this technique, it it not possible which packing is enabled for a particular structure.
I apologize ahead of time if my terminology is incorrect.
Let's say I have a shared library called libVectorMath.so. In it are two interesting functions, addVector() and subtractVector(). The two functions are prototyped in vectorMath.h. I also have an executable called testVectorMath, which uses those two functions, and is dynamically linked to libVectorMath.so.
Generally speaking, to build testVectorMath, I need to build libVectorMath.so as well. Why is this? Is the header file vectorMath.h not sufficient to tell testVectorMath what symbols it should expect to find in libVectorMath.so?
In other words, can't testVectorMath have some instructions in it to say "look for a library called libVectorMath.so and then look for symbols named addVector() and subtractVector() within it"?
Read this link. Its tells about the same in a very good way!
An Excerpt from above is as follows:
All shared library schemes work essentially the same way. At link time, the linker searches through libraries as usual to find modules that resolve otherwise undefined external symbols. But rather than copying the contents of the module into the output file, the linker makes a note of what library the module came from, and puts a list of the libraries in the executable. When the program is loaded, startup code finds those libraries and maps them into the program's address space before the program starts, Figure 1. Standard operating system file mapping semantics automatically share pages that are mapped read-only or copy-on-write. The startup code that does the mapping may be in the operating system, the executable, in a special dynamic linker mapped into the process' address space, or some combination of the three.
I have worked with OpenCL on a couple of projects, but have always written the kernel as one (sometimes rather large) function. Now I am working on a more complex project and would like to share functions across several kernels.
But the examples I can find all show the kernel as a single file (very few even call secondary functions). It seems like it should be possible to use multiple files - clCreateProgramWithSource() accepts multiple strings (and combines them, I assume) - although pyopencl's Program() takes only a single source.
So I would like to hear from anyone with experience doing this:
Are there any problems associated with multiple source files?
Is the best workaround for pyopencl to simply concatenate files?
Is there any way to compile a library of functions (instead of passing in the library source with each kernel, even if not all are used)?
If it's necessary to pass in the library source every time, are unused functions discarded (no overhead)?
Any other best practices/suggestions?
Thanks.
I don't think OpenCL has a concept of multiple source files in a program - a program is one compilation unit. You can, however, use #include and pull in headers or other .cl files at compile time.
You can have multiple kernels in an OpenCL program - so, after one compilation, you can invoke any of the set of kernels compiled.
Any code not used - functions, or anything statically known to be unreachable - can be assumed to be eliminated during compilation, at some minor cost to compile time.
In OpenCL 1.2 you link different object files together.
I compiled my code using the make utility and got the binaries.
I compiled the code again with a few changes in makefile (-j inserted at some points) and got a slight difference in the binaries. The difference was reported by "beyond compare". To further check in, I compiled the code again without my changes in makefile and found that the binaries are still differing.
Why is it happening that the same code compiled at different times is resulting into slightly different (in size and content) binaries? How should if check if the changes i have made are legitimate and the binaries are the same logically?
Do ask me for any further explanation.
You haven't said what you're building (C, C++ etc) but I wouldn't be surprised if it's a timestamp.
You could find out the format for the binary type you're building (which will depend on your operating system) and see whether it makes sense for there to be a timestamp in the place which is changing.
It's probably easiest to do this on a tiny sample program which will produce a very small binary, to make it easier to work out what everything means.
ELF object files contain a timestamp for when they are compiled. Thus, you can expect a different object file each time you compile (on Linux or Solaris). You may find the same with other systems of object files too.