What is the difference between a .o object file and a .so library file? - executable

Like the title says, what is the difference between a "program object file" (.o extension) and a "library file" (.so extension)

Well, its been a while so forgive me if I am totally wrong but it would essentially mean that the code inside the .so can be relocatable.
The .so is essentially a DLL that can be used by many applications but only loaded once into memory. The .o has to be linked into an application to have the code functionality made available.
This is called static linking (.o) vs dynamic linking (.so)
See: IBM Developer Works or Uni of Calgary or IECC for further information
Hope this answers your questions (and I hope my explaination is correct!)

Related

How to identify implemented code location in open source project binaries?

There is a c code in wireshark packet-s7comm.c, after building how i will identify which generated binary is having its implementation ?
The packet-s7comm.c file should be compiled into the epan library, as seen in the CMake code here:
add_library(epan
#Included so that Visual Studio can properly put header files in solution
${LIBWIRESHARK_HEADER_FILES}
${LIBWIRESHARK_FILES}
$<TARGET_OBJECTS:crypt>
$<TARGET_OBJECTS:dfilter>
$<TARGET_OBJECTS:dissectors>
$<TARGET_OBJECTS:dissectors-corba>
$<TARGET_OBJECTS:ftypes>
$<TARGET_OBJECTS:version_info>
$<TARGET_OBJECTS:wmem>
$<$<BOOL:${LUA_FOUND}>:$<TARGET_OBJECTS:wslua>>
${CMAKE_BINARY_DIR}/image/libwireshark.rc
)
You can't see the packet-s7comm.c file included specifically here, because it is contained in the dissectors object library target.

How to reuse Fortran modules without copying source or creating libraries

I'm having trouble understanding if/how to share code among several Fortran projects without building libraries or duplicating source code.
I am using Eclipse/Photran with the Intel compiler (ifort) on a linux system, but I believe I'm having a bigger conceptual problem with modules than with the specific tools.
Here's a simple example: In ~/workspace/cow I have a source directory (src) containing cow.f90 (the PROGRAM) and two modules m_graze and m_moo in m_graze.f90 and m_moo.f90, respectively. This project builds and links properly to create the executable 'cow'. The executable and modules (m_graze.mod and m_moo.mod) are stored in ~/workspace/cow/Debug and object files are stored under ~/workspace/cow/Debug/src
Later, I create ~/workplace/sheep and have src/sheep.f90 as the program and src/m_baa.f90 as the module m_baa. I want to 'use m_graze, only: ruminate' in sheep.f90 to get access to the ruminate() subroutine. I could just copy m_graze.f90 but that could lead to code getting out of sync and doesn't take into account any dependencies m_graze might have. For these reasons, I'd rather leave m_graze in the cow project and compile and link sheep.f90 against it.
If I try to compile the sheep project, I'll get an error like:
error #7002: Error in opening the compiled module file. Check INCLUDE paths. [M_GRAZE]
Under Properties:Project References for sheep, I can select the cow project. Under Properties:Fortran Build:Settings:Intel Compiler:Preprocessor I can add ~/workspace/cow/Debug (location of the module files) to the list of include directories so the compiler now finds the cow modules and compiles sheep.f90. However the linker dies with something like:
Building target: sheep
Invoking: Intel(R) Fortran Linker
ifort -L/home/me/workspace/cow/Debug -o "sheep" ./src/sheep.o
./src/sheep.o: In function `sheep':
/home/me/workspace/sheep/src/sheep.f90:11: undefined reference to `m_graze_mp_ruminate_'
This would normally be solved by adding libraries and library paths to the linker settings except there are no appropriate libraries to link to (this is Fortran, not C.)
The cow project was perfectly capable of compiling and linking together cow.f90, m_graze.f90 and m_moo.f90 into an executable. Yet while the sheep project can compile sheep.f90 and m_baa.f90 and can find the module m_graze.mod, it can't seem to find the symbols for m_graze even though all the requisite information is present on the system for it to do so.
It would seem to be an easy matter of configuration to get the linker portion of ifort to find the missing pieces and put them together but I have no idea what magic words need to be entered where in the Photran UI to make this happen.
I confess an utter lack of interest and competence in C and the C build process and I'd rather avoid the diversion of creating libraries (.a or .so) unless that's the only way to make this work.
Ultimately, I'm looking for a pure Fortran solution to this problem so I can keep a single copy of the source code and don't have to manually maintain a pile of custom Makefiles.
So can this be done?
Apologies if this has already been documented somewhere; Google is only showing me simple build examples, how to create modules, and how to link with existing libraries. There don't seem to be (m)any examples of code reuse with modules that don't involve duplicating source code.
Edit
As respondents have pointed out, the .mod files are necessary but not sufficient; either object code (in the form of m_graze.o) or static or shared libraries must be specified during the linking phase. The .mod files describe the interface to the object code/library but both are necessary to build the final executable.
For an oversimplified toy problem such as this, that's sufficient to answer the question as posed.
In a larger project with more complex dependencies (in my case, 80+KLOC of F90 linking to the MKL version of LAPACK95), the IDE or toolchain may lack sufficient automatic or user-interface facilities to make sharing a single canonical set of source files a viable strategy. The choice seems to be between risking duplicate source files getting out of sync, giving up many of the benefits of an IDE (i.e. avoiding manual creation of make/CMake/SCons files), or, in all likelihood, both. While a revision control system and good code organization can help, it's clear that sharing a single canonical set of source files among projects is far from easy given the current state of Eclipse.
Some background which I suspect you already know: Typically (including ifort) compiling the source code for a Fortran module results in two outputs - a "mod" file that contains a description of the Fortran entities that the module defines that the compiler needs to find whenever it sees a USE statement for the module, and object code for the linker that implements the procedures and variable storage, etc., that the module defines.
Your first error (the one you solved) is because the compiler couldn't find the mod file.
The second error is because the linker hasn't been told about the object code that implements the stuff that was in the source file with the module. I'm not an Eclipse user by any means, but a brute force way of specifying that is just to add the object file (xxxxx/Debug/m_graze.o) as an additional linker option (Fortran Build > Settings, under Intel Fortran Linker > Command Line). (Other tool chains have explicit "additional object file" properties for their link stage - there may well be a better way of doing this for the Intel chain.)
For more involved examples you would typically create a library out of the shared code. That's not really C specific, the only Fortran aspect is that the libraries archive of object code needs to be provided alongside the mod files that the Fortran compiler generates.
Yes the object code must be provided. E.g., when you install libnetcdf-dev in Debian (apt-get install libnetcdf-dev), there is a /usr/include/netcdf.mod file that is included.
You can now use all netcdf routines in your Fortran code. E.g.,
program main
use netcdf
...
end
but you'll have link to the netcdf shared (or static) library, i.e.,
gfortran -I/usr/include/ main.f90 -lnetcdff
However, as user MSB mentioned the mod file can only be used by gfortran that comes with the distribution (apt-get install gfortran). If you want to use any other compiler (even a different version that you may have installed yourself) then you'll have to build netcdf yourself using that particular compiler.
So creating a library is not a bad solution.

How do I link multiple libraries in a Firebreath plugin?

Does anyone know where I can find a Firebreath sample (either Mac OS X or Windows) that illustrates how to create a plugin that includes 1 or more other libraries (.DLLs or .SOs) that each rely on other sub-projects built as static libraries (LIBs)?
For example, let's say that the Firebreath plugin is called PluginA, and that PluginA calls methods from DLL_B and DLL_C. DLL_B and DLL_C are C++ projects. DLL_B calls methods from another project called LIB_D, and DLL_C calls methods from a project called DLL_E.
Therefore, the final package should contain the following files:
PluginA.dll
DLL_B.dll (which also incorporates LIB_D)
DLL_C.dll
DLL_E.dll
I am currently forced to dump all source files in the pluginA solution, but this is just a bottleneck (for example I cannot call libraries written in other languages, such as Objective-C on Mac OS X).
I tried following the samples on Firebreath, but couldn't get them to work, and I found no samples from other users that claimed they were able to get it to work. I tried using CMAKE, and also running the solutions directly from X-Code, but the end result was the same (received linking errors, after deployment DLL_C couldn't find DLL_E etc.)
Any help would be appreciated - thank you,
Mihnea
You're way overthinking this.
On windows:
DLLs don't depend on a static library because if they did it would have been compiled in when they were built.
DLLs that depend on another DLL generally just need that other DLL to be present in the same location or otherwise in the DLL search path.
Those two things taken into consideration, all you need to do is locate the .lib file that either is the static library or goes with the .dll and add a target_link_library call for each one. There is a page on firebreath.org that explains how to do this.
On linux it's about the same but using the normal rules for finding .so files.

how to import COM dll in D

I'm trying to create an D application which uses a (third party) COM .dll so I can scrape a text box of another application so I can sound an error when a certain string shows up.
However the third party doesn't provide .lib, .def or .h files that go with the dll (atleast with the free trial version). I can create the .lib file with the implib tool but I don't see any of the library's functions in the created .lib.
Their (visual c++) samples use the #import directive to link it in however that is of no use for me ...
On a side note how can I get the proper interfaces (in a .di with boilerplate that does the linking) of the dll automatically? I ask so the correctness of the linkage doesn't depend on my (likely to be incorrect) translation of the functions. They do have a webpage which gives all functions but the object model is a bit chaotic to say the least.
From what I know, COM libraries only expose a few functions, required to (un)register the library and to create objects.
You can however view the interfaces and functions in a COM .dll using the OLE/COM Object Viewer. It seems it might be able to output header files (.h). Afterwards, maybe you could use htod as a starting point to converting everything to D interfaces.
The DMD distribution seems to include a .COM sample (chello.d, dclient.d, dserver.d), and at first glance it doesn't look like it would require any LIBs explicitly.
Unfortunately, I've never actually used COM in D, so I can't advise any further. I hope this helps in some way.
While I have yet to actually do COM work myself, I am trying to revive Juno over on Github/he-the-great. Part of the project is tlbimpd which is what will output a D file from a DLL.
I've tested the examples and successfully run tlbimpd. Please do try things out for your use and submit any issues.

Meaning of building a dll as export library

What is the meaning of building a dll as export library ? I just googled it.I found its a dynamic link library.Can anyone please explain what actually dll is ? and why do we need to add these statement in the .dll file
extern "c" _declspec(dllexport)
I studied the static and shared libraries but Im not sure why do we go for dll files.I learnt .dll is used for the run time. But can you help me and give me more information.Thank you in advance
I may have been a bit harsh in my comments. I am not an authority on dlls, but I have a bit of working knowledge of them, so I will try to give a short explanation.
The difference between static and shared libraries should be easy to find in a web search, but basically the code in a static library gets included into the final executable, so after the linking stage, the actual library file is not needed anymore to run the program; on the other hand, code in a shared library doesn't get included in the main program - the two parts remain separate, so the shared library (called dll on windows) will be needed every time the program is run.
"Building a dll as export library" is a bit of a confusing term. I had not heard of it before, and during a short search could only find it on a cygwin page, which you might have read, considering your initial tags. A dll can export some or all of its functions and data. Exporting means that they are available for other programs and dlls to use. Which names get exported can be controlled in various ways. One of those is inserting _declspec(dllexport) in the declaration of the function. Another way is by using a definition file with an exports section.
When creating a dll, an import library can be created. This is a file that can then be used when building an executable that uses the dll, during the linking stage, to let it know which names are exported from the dll, so the program knows how to resolve references to those functions; in other words: how to import them. (This is not always necessary. Many linkers allow you to directly link against the dll itself, thereby removing the need for an import library.)
I realize it can be confusing, but try to find a tutorial and some small examples to see how it works, and play with it a bit.