First....My many thanks in advance...
Forgive me for the length of this question, as I’ve tried for some time now to do this on my own with minimal and varying success; therefore, I’d rather ask this completely so that I, and anyone else looking to achieve the same, will have the info to carry on.
I'm trying to educate myself a little with using the autotools and shared libraries; however, I’m having a bit of a difficult time in getting everything to come together correctly. I’m running fedora 5 with all the latest autotools.
Coming from the windows world, I understand how to do this without any problems. In the linux/unix world, I’m struggling with how to achieve it using the autotools. I can’t seem to get my configure.ac and Makefile.am files configured correctly.
I’ve read countless examples, tutorials, and message boards and they either use complex examples that hide what I’m looking for, don’t use the autotools, or simple don’t compile or work for one reason or another.
Can someone help me out with it?
I’m trying to utilize as many defaults as I can to maintain cross compatibility.
I’m trying to use pkgconf with versioning; although, I’m not changing any version numbers right now.
I’d like to include man, docs, etc…, but I’ll be happy with just getting it to work right now.
In short, I’m trying to following the ‘IDEAL’ correct way of doing this to maintain compatibility.
I’m trying to utilize the various library methods through the automake tools:
1) static from some project directory
2) static from the default library directory (/usr/local/lib)
3) implicitly dynamic loading (loaded when program is executed, from the default (from some directory)
4) implicitly dynamic loading (loaded when program is executed, from the default (/usr/local/lib)
5) explicitly dynamic loading (loaded from some directory when desired by the program)
6) explicitly dynamic loading (loaded from the default directory (/usr/local/lib) when desired by the program)
If someone can help me with this, I greatly appreciate it as it will give me all I need to see the differences in the files between the different methods. And that alone will clear the muddy water a bit.
Here is my project tree (broken out for separation and clarity of differences):
~/code/learn_lib/
-------executables/
-----------app1/
-----------app2/
-----------app3/
-----------app4/
-----------app5/
-----------app6/
-------libraries/
-----------mylib1/-static/not installed
-----------mylib2/-static/installed to default directory (usually (/usr/local/lib)
-----------mylib3/-implicitly shared/not installed
-----------mylib4/-implicitly shared/installed to default directory (usually /usr/local/lib)
-----------mylib5/-explicitly shared/not installed
-----------mylib5/-explicitly shared/installed to default directory (usually /usr/local/lib)
Below is a script file to setup the tree to match what I'm using. After running the setup script, I can go to any directory and perform the following. For simplicity of the script, the setup script configures all the libs the same and all the apps the same.
./autogen.sh
./configure
make
In the library directories, I can make install and the libraries appear in /usr/local/lib and the includes appear in /usr/local/include, but I can't do anything with them from the app. I've had too many variations to list the various errors I've seen. Suffice it say, I'm ready to pull my hair out.
setup script
Code:
#!/bin/bash
write_lib_proj_pc_file()
{
proj="$1"
exec 6>&1
exec 1>$proj.pc.in
echo #
echo prefix=@prefix@
echo exec_prefix=@exec_prefix@
echo libdir=@libdir@
echo includedir=@includedir@
echo #
echo Name: $proj
echo Description: Learn library $proj.
echo Version: 1.0.0
echo "Libs: -L\${libdir} -l$proj"
echo "Cflags: -I\${includedir} -I\${libdir}"
echo #
exec 1>&-
exec 1>&6
exec 6>&-
}
write_lib_proj_configure_file()
{
proj="$1"
exec 6>&1
exec 1>configure.ac
echo #
echo "AC_INIT(src/$proj.cpp)"
echo "AM_INIT_AUTOMAKE($proj,1.0.0, no-define)"
echo "AM_CONFIG_HEADER(config.h)"
echo #
echo AC_PROG_CC
echo AC_PROG_CXX
echo AC_PROG_INSTALL
echo AC_PROG_LIBTOOL
echo AC_LANG_CPLUSPLUS
echo "AC_OUTPUT(Makefile $proj.pc src/Makefile)"
echo #
exec 1>&-
exec 1>&6
exec 6>&-
}
write_app_proj_configure_file()
{
proj="$1"
exec 6>&1
exec 1>configure.ac
echo #
echo "AC_INIT(src/$proj.cpp)"
echo "AM_INIT_AUTOMAKE($proj,0.3)"
echo "AM_CONFIG_HEADER(config.h)"
echo #
echo AC_PROG_CC
echo AC_PROG_CXX
echo AC_PROG_INSTALL
echo AC_PROG_LIBTOOL
echo AC_LANG_CPLUSPLUS
echo "AC_OUTPUT(Makefile src/Makefile)"
echo #
exec 1>&-
exec 1>&6
exec 6>&-
}
write_lib_project_makefile()
{ proj="$1"
exec 6>&1
exec 1>Makefile.am
echo #
echo SUBDIRS = src
echo "pkgconfigdir = \$(libdir)/pkgconfig"
echo pkgconfig_DATA = $proj.pc
echo EXTRA_DIST=autogen.sh
echo #
exec 1>&-
exec 1>&6
exec 6>&-
}
write_app_project_makefile()
{ filename="$1"
app_name="$2"
lib_name="$3"
exec 6>&1
exec 1>Makefile.am
echo #
echo SUBDIRS = src
echo EXTRA_DIST=autogen.sh
echo #
exec 1>&-
exec 1>&6
exec 6>&-
}
write_lib_src_makefile()
{ proj="$1"
exec 6>&1
exec 1>Makefile.am
echo #
echo h_sources = $proj.h
echo cc_sources = $proj.cpp
echo
echo "library_includedir=\$(includedir)"
echo "library_include_HEADERS = \$(h_sources)"
echo
echo "INCLUDES = -I\$(top_srcdir)"
echo
echo lib_LTLIBRARIES = lib$proj.la
echo lib$proj"_la_SOURCES = $proj.cpp $proj.h"
echo lib$proj"_la_LDFLAGS = -version-info 1:0:0 -release 1:0"
echo #
exec 1>&-
exec 1>&6
exec 6>&-
}
write_app_src_makefile()
{
proj="$1"
lib_name="$2"
exec 6>&1
exec 1>Makefile.am
echo #
echo bin_PROGRAMS = $proj
echo $proj"_SOURCES = $proj.cpp"
echo $proj"_LDADD = $lib_name"
echo #
exec 1>&-
exec 1>&6
exec 6>&-
}
write_app_src_file()
{
proj="$1"
lib_name="$2"
exec 6>&1
exec 1>$proj.cpp
echo #
echo "#include <stdio.h>"
echo "#include \"config.h\""
echo "#include <$lib_name.h>"
echo #
echo "int main (int argc, char* argv[])"
echo {
echo " printf (\"The Result is %d\\n\",sumit(3,4));"
echo " return 0;"
echo }
echo #
echo #
exec 1>&-
exec 1>&6
exec 6>&-
}
write_lib_src_file()
{
proj="$1"
lib="$1"
exec 6>&1
exec 1>$proj.cpp
echo #
echo "#include <stdio.h>"
echo "#include \"config.h\""
echo "#include <$lib.h>"
echo #
echo "int sumit (int a, int b)"
echo {
echo " return a+b;"
echo }
echo #
echo #
exec 1>&-
exec 1>&6
exec 6>&-
}
write_lib_header_file()
{
proj="$1"
exec 6>&1
exec 1>$proj.h
echo #
echo "int sumit (int a, int b);"
echo #
echo #
exec 1>&-
exec 1>&6
exec 6>&-
}
set_dir()
{
if test ! -d $1;then mkdir $1; fi
cd $1
}
set_proj_dir()
{
set_dir $1
}
set_src_dir()
{
set_dir src
}
write_autogen()
{
exec 6>&1
exec 1>autogen.sh
echo #
echo "dir=`echo \"$0\" | sed 's,[^/]*$,,'`"
echo "test \"x${dir}\" = \"x\" && dir='.'"
echo #
echo "if test \"x`cd \"${dir}\" 2>/dev/null && pwd`\" != \"x`pwd`\""
echo then
echo echo "\"This script must be executed directly from the source
directory.\""
echo exit 1
echo fi
echo #
echo rm -f config.cache acconfig.h
echo #
echo touch NEWS README AUTHORS ChangeLog COPYING
echo #
echo "echo \"- libtoolize.\" && \\"
echo "libtoolize --force --copy && \\"
echo "echo \"- aclocal.\" && \\"
echo "aclocal && \\"
echo "echo \"- autoconf.\" && \\"
echo "autoconf && \\"
echo "echo \"- autoheader.\" && \\"
echo "autoheader && \\"
echo "echo \"- automake.\" && \\"
echo "automake --ignore-deps --add-missing --copy --gnu && \\"
echo "echo && \\"
echo "./configure \"$@\" && exit 0"
echo #
echo exit 1
echo #
exec 1>&-
exec 1>&6
exec 6>&-
chmod 755 autogen.sh
}
write_app_project()
{ proj=$1
lib=$2
set_proj_dir $proj
write_autogen
write_app_project_makefile $proj
write_app_proj_configure_file $proj
set_src_dir
write_app_src_makefile $proj $lib
write_app_src_file $proj $lib
cd ../..
}
write_lib_project()
{ proj=$1
set_proj_dir $proj
write_autogen
write_lib_project_makefile $proj
write_lib_proj_configure_file $proj
write_lib_proj_pc_file $proj
set_src_dir
write_lib_src_makefile $proj
write_lib_src_file $proj
write_lib_header_file $proj
cd ../..
}
if [ ! -n "$1" ]; then
echo " usage: script rootdir"
exit 0
fi
set_dir $1
app1=app_explic_defaultdir
app2=app_explic_projdir
app3=app_implic_defaultdir
app4=app_implic_projdir
app5=app_static_defaultdir
app6=app_static_projdir
lib1=mylib_explic_defaultdir
lib2=mylib_explic_projdir
lib3=mylib_implic_defaultdir
lib4=mylib_implic_projdir
lib5=mylib_static_defaultdir
lib6=mylib_static_projdir
write_app_project $app1 $lib1
write_app_project $app2 $lib2
write_app_project $app3 $lib3
write_app_project $app4 $lib4
write_app_project $app5 $lib5
write_app_project $app6 $lib6
write_lib_project $lib1
write_lib_project $lib2
write_lib_project $lib3
write_lib_project $lib4
write_lib_project $lib5
write_lib_project $lib6
cd ..