Tutorial :Autotools library and object file output control



Question:

My goal is to have all object files built in a .objs directory instead of the root of the Makefile, and to have the binaries (and libraries) copied into the project's bin/ directory. But I have been unable to find any resources to explain how to do this. How would I go about doing this?

Here is my configure.ac and src/Makefile.am - I have similar Makefile.am files for two shared libraries that are referenced. They compile, and after copying them to the bin/ directory work as they should. I'm just looking to automate this process.

configure.ac

AC_PREREQ([2.63])  AC_INIT([gtkworkbook], [0.12], [j_bellone@users.sourceforge.net])  AC_CONFIG_SRCDIR([gtkworkbook/cell.c])  AM_INIT_AUTOMAKE([gtkworkbook], [0.12])    # Checks for programs.  AC_PROG_CXX  AC_PROG_CC  AC_PROG_INSTALL  AC_PROG_MAKE_SET  AC_PROG_RANLIB  AC_PROG_LIBTOOL  AC_PROG_CC_C_O    AC_CHECK_LIB([pthread], [pthread_mutex_init], [], [              echo "pthread library is missing. pthread is required for this program"              exit -1])    # Checks for header files.  AC_CHECK_HEADERS([arpa/inet.h netdb.h netinet/in.h stdlib.h string.h sys/socket.h unistd.h])    # Checks for typedefs, structures, and compiler characteristics.  AC_HEADER_STDBOOL  AC_C_INLINE  AC_TYPE_SIZE_T    # Checks for library functions.  AC_CHECK_FUNCS([gethostbyname memset socket])    AC_OUTPUT([Makefile         csv/Makefile         gtkworkbook/Makefile         src/Makefile])  

src/Makefile.am

AUTOMAKE_OPTIONS= foreign    C_FLAGS= -I/usr/local/include -I/usr/include -I/usr/local/include/gtkextra-2.0 -I$(top_srcdir)/include `pkg-config gtk+-2.0 glib-2.0 --cflags`  L_FLAGS= -L/usr/local/lib -L/usr/lib -L$(top_srcdir)/lib `pkg-config gtk+-2.0 glib-2.0 --libs` -lgtkextra-x11-2.0    bin_PROGRAMS= gtkworkbook  gtkworkbook_SOURCES= application.c config.c main.c parse.c plugin.c  gtkworkbook_CFLAGS= -Wall -lgthread-2.0 -std=c99 $(C_FLAGS)    gtkworkbook_LFLAGS= -ldl $(L_FLAGS)  gtkworkbook_LDFLAGS= $(L_FLAGS)  gtkworkbook_LDADD= ../gtkworkbook/libgtkworkbook.la ../csv/libcsv.la    lib_LTLIBRARIES= realtime.la  realtime_la_SOURCES= realtime/CsvParser.cpp realtime/Network.cpp realtime/Packet.cpp realtime/plugin_main.cpp \      realtime/thread_main.cpp realtime/concurrent/Mutex.cpp realtime/concurrent/Semaphore.cpp \      realtime/concurrent/Thread.cpp realtime/concurrent/ThreadGroup.cpp realtime/concurrent/ThreadPool.cpp \      realtime/proactor/Dispatcher.cpp realtime/proactor/Event.cpp realtime/proactor/Proactor.cpp \      realtime/proactor/InputDispatcher.cpp realtime/proactor/Worker.cpp realtime/network/Tcp.cpp  realtime_la_CPPFLAGS= -Wall -Wno-write-strings $(C_FLAGS)  realtime_la_LFLAGS= -lgtkworkbook -lcsv $(L_FLAGS)  realtime_la_LDFLAGS= -module -export-dynamic   realtime_la_LIBADD= ../gtkworkbook/libgtkworkbook.la ../csv/libcsv.la  

So, my question is how to specify the output directories for the compile results of each Makefile (I wish them to be copied to bin/, and for the object files to be in .obj of each project instead of in the root of the Makefile.

Thanks for the help thus far.. this website has been a great resource, and I have learned a lot from the links provided already.


Solution:1

The GNU Build System does not use obj/ directories, so the autotools are not designed to support that.

However I can think of two ways to work around this.

As an installer, you can build any package out of its source directory by typing

mkdir builddir  cd builddir  ../path-to-sourcedir/configure  make  

Then any output file will be created in the builddir/ directory. This compilation scheme makes it possible to compile source code out stored in a readonly directory (this made more sense back in the years where the FSF was distributing CDs with uncompressed source code), or to compile the same source with differents settings (or even for different architectures).

As a packager, the only way you could force your package to build everything in obj/ is to put your Makefile.am in obj/, and declare all your build rules there. This would mean a obj/Makefile.am looking like:

bin_PROGRAMS = foo bar  foo_SOURCES = ../src/foo/main.c ../src/foo/help.c ../src/foo/list.c  bar_SOURCES = ../src/bar/bar.c   

etc. I remember that 10 years ago, POSE, the Palm OS Emulator, was using a setup like the above. I don't recommend it as it's not really maintainable. It's really better to stick with the philosophy of the tools, and use a build systems that work like the other GNU packages.

For an introduction to the GNU Build System, I recommend reading the introduction of the Automake manual: http://www.gnu.org/software/automake/manual/automake.html#GNU-Build-System

Especially the Use-Cases section. If you don't care about these use cases, I think your best course is NOT to use Automake, and build your own Makefiles. Otherwise you will keep trying to force Automake doing something it is not designed for, and you'll quickly hate it.

EDIT 2013-08-26: Note that an Automake project using a subdirectory named using obj/ is not portable to BSD make.


Solution:2

The easiest way to do this would be to set "libdir" to the directory you want these files to end up in, and use the install target to copy them there.

This would prevent you from using the install target in the conventional sense though.


Note:If u also have question or solution just comment us below or mail us on toontricks1994@gmail.com
Previous
Next Post »