Linux GNU Build: Build Dynamic Library from a Set of Static Libraries - gcc

I have a make system I just completed, and my goal is to have one Monalithic .so file at the end. So far I have compiled all the seperate parts into .a files. I did this just to compact the number of .o files I would have to work with.
My idea so far is to just unpack the .a files at the end and then rebuild all of them into the large .so file. Is this sincable or is there another (better) way to do this?

See the --whole-archive option in the man page for the ld command to combine static libs into a dynamic lib.

Related

libtool: convert/extract la to a

Is it possible to convert or maybe extract a file from .la library to .a?
I've a project where I have my application linked statically against all libraries, but some of them are generated with libtool (.la libs), while others are created with gcc (.a lib). In this answer one says, that in the .libs subdirectory should be .a libfile, but I've found there only .la, .so, and .o files, probably because the lib project was not configured with --enable-static.
that in the .libs subdirectory should be .a libfile, but I've found there only .la, .so, and .o files, probably because the lib project was not configured with --enable-static.
That's what it sounds like to me as well. You'll need to do that to get a .a file. The libs you are building with libtool are probably being compiled with gcc.
Is it possible to convert or maybe extract a file from .la library to .a?
No. There's no object code in a .la file to extract to a .a file. As the link to the other answer says, it's basically a metadata file of how to link and where the files are, etc. A .la file is humanly readable, so if you really want to know what's going in there you can examine it.

Link multiple object files in gfortran

I have "library" folder with multiple object (.o) files. These files contain subroutines which are not changing from project to project. Each new project uses some of those object files, but not all of them.
Could you please tell me is there any way to tell gfortran to look up that folder for necessary .o files?
I've tried -I and -L options, but no way. When I write .o names directly, it works:gfortran main.for ./library/obj1.o ./library/obj2.o but I have many of .o files and write all of them waste time.
I could write gfortran main.for ./*.o but then main program will be linked with all .o files, but it needs only some of them.
I hoped that something like gfortran main.for -L./library/ will work, but it doesn't.
I use OS X with gcc version 5.1.0.
And I'm pretty sure that I should use makefile for such case
You are confusing object files with static libraries. An object file
is not a static library and the gfortran linker - which is simply
the GNU system linker, invoked by gfortran - will not treat it as such.
You need a static library and you are trying to use object files in lieu.
The linker recognizes an object file by the extension .o. It recognizes
a static library by the extension .a, and it expects the contents of an .a file
to have the form of a static library, not the format of an object file. (So you
cannot make an object file into a static library just by renaming it).
The linker will link into your program every object file that appears on its
commandline, whether or not it is needed. It does not expect you to mention
object files if you don't want them linked. The linker options -L and -l for
locating libraries have no application to object files.
A static library is a fairly simple archive containing some number of
object files, plus a house-keeping header and typically an index of the
public symbols defined in the contained object files.
When the linker encounters a static library on its commandline, it does not
link the entire contents of the library (unless you expressly tell it to). It inspects
the contained object files to determine which, if any, of them contain
definitions for symbols that are as yet undefined at that point in the linkage
of the program. If any object file in the library is found to provide any
of the missing definitions, then that object file is extracted from the library
and linked into the program. Object files in the library that provide no
missing definitions are not linked. Libraries on the commandline are sequentially
inspected in this way until either all the symbols referred to by the program
have definitions in linked object files or there are no more libraries.
If as you say the object files that you are trying to use as libraries are stable
resources that you never have to build for your projects, then you can just make a static
library out of them and link that library with your per-project programs.
To make a static library from object files, use the ar tool.
See man ar.
When you have made your library, say, libsubs.a, and have decided it shall reside
in some directory, /path/to/subs, then you link it with a program by adding
-L/path/to/subs -lsubs
to the commandline in which your program is linked. This will cause the linker
to search for a library called libsubs.a in directory /path/to/subs.
So if you are compiling and linking in a single step, use it like:
gfortran -o myprog myprog.f90 -L/path/to/subs -lsubs
And if you are compiling and linking in distinct steps, use it like:
gfortran -c -o myprog_1st_file.o myprog_1st_file.f90
gfortran -c -o myprog_2nd_file.o myprog_2nd_file.f90
gfortran -o myprog myprog_1st_file.o myprog_2nd_file.o -L/path/to/subs -lsubs
This is how you are supposed to use a set of object file resources of which
different subsets will be required for linkage with different programs: you put
them in a library and link the library.

How to build a C dependency of go project in a subdirectory

I am writing a Go wrapper for a C library in Go. The problem is, that the C library is not available on many Linux distributions, so I want a solution where i "go get github.com/me/mylibrary" does not require anybody to have the library installed.
One solution would be to just add the source of the library into a sub directory. Then when my project is build with go get I need to automatically build this library, too. But I have no idea how I can automate this.
Alternatively I could have a script that downloads the source, extracts and builds it
But I have no Idea how to connect these build steps with the go build tool.
linking a static library is also not the easiest.
#cgo linux LDFLAGS: ./MyLib/lib/libMyLib.a -lstdc++ -lm -lX11
works as long as i build from my library, but as soon as I want to build from another project the relative path is from that project and not from my library, so it fails.
As per http://golang.org/cmd/cgo/#hdr-Using_cgo_with_the_go_command
When the Go tool sees that one or more Go files use the special import
"C", it will look for other non-Go files in the directory and compile
them as part of the Go package. Any .c, .s, or .S files will be
compiled with the C compiler. Any .cc, .cpp, or .cxx files will be
compiled with the C++ compiler.
So you can include the C library source in your repository and go will build it automatically. That page also explains how to pass build flags to the compilers and probably anything else you might need to know.

Building a Shared Library but linking against a Static One

I have an Autogen Makefile.am that I'm trying to use to build a test program for a shared library. To build my test binary, I want to continue building the shared library as target but I want the test program to be linked statically. I've spent the last few hours trying to craft my Makefile.am to get it to do this.
I've tried explicitly changing the LDADD line to use the .a version of the library and get a file not found error even though I can see this library is getting built.
I try to add the .libs directory to my link path via LDFLAGS and still it can't find it.
I tried moving my library sources to my test SOURCES list and this won't work because executable object files are built differently than those for static libraries.
I even tried replicating a lib_LIBRARIES entry for the .a version (so there's both a lib_LTLIBRARIES and a lib_LIBRARIES) and replicate all the LDFLAGS, SOURCES, dir and HEADERS for the shared version as part of the static version (replacing la with a of the form _a_SOURCES = _la_SOURCES. Still that doesn't work because now it can't figure out what to build.
My configure.ac file is using the default LT_INIT which should give me both static and dynamic libraries and as I said it is apprently building both even if the libtool can't see the .a file.
Please, anyone know how to do this?
As #Brett Hale mentions in his comment, you should tell Makefile.am that you want the program to be statically linked.
To achieve this you must append -static to your LDFLAGS.
Changing the LDFLAGS for a specific binary is achieved by changing binary_LDFLAGS (where binary is the name of the binary you want to build).
so something like this should do the trick:
binary_LDFLAGS = $(AM_LDFLAGS) -static

What is the difference between make and gcc?

The last sentence in the article caught my eye
[F]or C/C++ developers and
students interested in learning to
program in C/C++ rather than users of
Linux. This is because the compiling
of source code is made simple in
GNU/Linux by the use of the 'make'
command.
I have always used gcc to compile my C/C++ programs, whereas javac to compile my Java programs. I have only used make to install programs to my computer by configure/make/make install.
It seems that you can compile apparently all your programs with the command make.
What is the difference between make and gcc?
Well ... gcc is a compiler, make is a tool to help build programs. The difference is huge. You can never build a program purely using make; it's not a compiler. What make does it introduce a separate file of "rules", that describes how to go from source code to finished program. It then interprets this file, figures out what needs to be compiled, and calls gcc for you. This is very useful for larger projects, with hundreds or thousands of source code files, and to keep track of things like compiler options, include paths, and so on.
gcc compiles and/or links a single file. It supports multiple languages, but does not knows how to combine several source files into a non-trivial, running program - you will usually need at least two invocations of gcc (compile and link) to create even the simplest of programs.
Wikipedia page on GCC describes it as a "compiler system":
The GNU Compiler Collection (usually shortened to GCC) is a compiler system produced by the GNU Project supporting various programming languages.
make is a "build tool" that invokes the compiler (which could be gcc) in a particular sequence to compile multiple sources and link them together. It also tracks dependencies between various source files and object files that result from compilation of sources and does only the operations on components that have changed since last build.
GNUmake is one popular implementation of make. The description from GNUmake is as follows:
Make is a tool which controls the generation of executables and other non-source files of a program from the program's source files.
Make gets its knowledge of how to build your program from a file called the makefile, which lists each of the non-source files and how to compute it from other files.
gcc is a C compiler: it takes a C source file and creates machine code, either in the form of unlinked object files or as an actual executable program, which has been linked to all object modules and libraries.
make is useful for controlling the build process of a project. A typical C program consists of several modules (.c) and header files (.h). It would be time-consuming to always compile everything after you change anything, so make is designed to only compile the parts that need to be re-compiled after a change.
It does this by following rules created by the programmer. For example:
foo.o: foo.c foo.h
cc -c foo.c
This rule tells make that the file foo.o depends on the files foo.c and foo.h, and if either of them changes, it can be built by running the command on the second line. (The above is not actual syntax: make wants the commands indented by a TAB characters, which I can't do in this editing mode. Imagine it's there, though.)
make reads its rules from a file that is usually called a Makefile. Since these files are (traditionally) written by hand, make has a lot of magic to let you shorten the rules. For example, it knows that a foo.o can be built from a foo.c, and it knows what the command to do so is. Thus, the above rule could be shortened to this:
foo.o: foo.h
A small program consisting of three modules might have a Makefile like this:
mycmd: main.o foo.o bar.o
$(CC) $(LDFLAGS) -o mycmd main.o foo.o bar.o
foo.o: foo.h bar.h
bar.o: bar.h
make can do more than just compile programs. A typical Makefile will have a rule to clean out unwanted files:
clean:
rm -f *.o core myapp
Another rule might run tests:
check: myapp
./myapp < test.input > test.output
diff -u test.correct test.output
A Makefile might "build" documentation: run a tool to convert documentation from some markup language to HTML and PDF, for example.
A Makefile might have an install rule to copy the binary program it builds to wherever the user or system administrator wants it installed.
And so on. Since make is generic and powerful, it is typically used to automate the whole process from unpacking a source tarball to the point where the software is ready to be used by the user.
There is a whole lot of to learn about make if you want to learn it fully. The GNU version of make has particularly good documentation: http://www.gnu.org/software/make/manual/ has it in various forms.
Make often uses gcc to compile a multitude of C or C++ files.
Make is a tool for building any complex system where there are dependancies between the various system components, by doing the minimal amount of work necessary.
If you want to find out all the things make can be used for, the GNU make manual is excellent.
make uses a Makefile in the current directory to apply a set of rules to its input arguments. Make also knows some default rules so that it executes even if it doesn't find a Makefile (or similar) file in the current directory. The rule to execute for cpp files so happens to call gcc on many systems.
Notice that you don't call make with the input file names but rather with rule names which reflect the output. So calling make xyz will strive to execute rule xyz which by default builds a file xyz (for example based on a source code file xyz.cpp.
gcc is a compiler like javac. You give it source files, it gives you a program.
make is a build tool. It takes a file that describes how to build the files in your project based on dependencies between files, so when you change one source file, you don't have to rebuild everything (like if you used a build script). make usually uses gcc to actually compile source files.
make is essentially an expert system for building code. You set up rules for how things are built, and what they depend on. Make can then look at the timestamps on all your files and figure out exactly what needs to be rebuilt at any time.
gcc is the "gnu compiler collection". There are many languages it supports (C, C++, Ada, etc depending on your setup), but still it is just one tool out of many that make may use to build your system.
You can use make to compile your C and C++ programs by calling gcc or g++ in your makefile to do all the compilation and linking steps, allowing you to do all these steps with one simple command. It is not a replacement for the compiler.
'gcc' is the compiler - the program that actually turns the source code into an executable. You have to tell it where the source code is, what to output, and various other things like libraries and options.
'make' is more like a scripting language for compiling programs. It's a way to hide all the details of compiling your source (all those arguments you have to pass the compiler). You script all of the above details once in the Makefile, so you don't have to type it every time for every file. It will also do nifty things like only recompile source files that have been updated, and handle dependancies (if I recompile this file, I will then need to recompile THAT file.)
The biggest difference is that make is turing complete (Are makefiles Turing complete?) while gcc is not.
Let's take the gcc compiler for example.
It only knows how to compile the given .cpp file into .o file given the files needed for compilation to succeed (i.e. dependencies such as .h files).
However, those dependencies create a graph. e.g., b.o might require a.o in the compilation process which means it needs to be compiled independently beforehand.
Do you, as a programer want to keep track of all those dependencies and run them in order for your target .o file to build?
Of course not. You want something to do that task for you.
Those are build tools - tools that help making the build process (i.e. building the artifacts like .o files) easier. One such tool is make.
I hope that clarifies the difference :)

Resources