trouble installing old 2005 BOOST library - c++

Gooday everyone
I'm fairly new to ubuntu C programing although I'm
rather experienced in C programing in windows.
I have recently come accross a number of codes written
in 2005 which I'm interested in learning how they work.
Those codes needs BOOST library to compile, however they won't
compile on the newest BOOST version present on my ubuntu 12.04.
I set the gcc compiler on lenient so that it ignores all those error
messages. The code did compile and ran afterwards.
However, when I used GDB debugger to watch how the program flows
I noticed that there are likely errors in the way the program runs
due to using a different BOOST version rather than it's original. Hence
I like to install the BOOST version corresponding to the code I downloaded.
To do that, I installed Ubuntu 5.04 and BOOST 1.33.0 which seemed to have been created in late 2005. I downloaded it
but I didnt found any detailed instruction on how to install it.
Only vague description on using BOOST jam, I played around with BOOST
jam for quite awhile without success.
And this old BOOST does not have installation commands like
"sudo apt-install boost-dev" style option
Thus I like to ask if anyone can give a easy to understand step by step instruction
on how to install the BOOST library downloaded from the above link.
like.....
step1: download boost jam from boost webpage
step2: unpack it in home/boost/ then type make configure
...and so on...
Big thanks for any useful info.
New Contents appended here
in response to the comments given
Hi, I went through the info given by your link and
managed to run the boost library examples given by your link.
That is, I can compile a single cpp file with the command
g++ -I boost_1_33_0 test.cpp -o test
(I'm keeping the boost library and the cpp file to be compiled in the
same folder)
However, the program package I'm interested in is build with make (not cmake).
I have some experience writting cmake files but not make files.
And I do not see any link to boost library command in the make file of the
program package. The readme file only has one sentence that says I
need to have boost installed without explaining what that meant.
I assume it means that either I have to build and do makeinstall the boost or
I could add some lines in the makefile for a link. I thought
maybe you can quickly point out whats missing in the makefile.
The readme file:
To compile, go into the moses directory and do 'make'. You'll need the
latest boost libraries. If compilation still fails for weird reasons,
you could try g++ with the -fpermissive (newer versions reject lots of
code that was ok with older ones). If you are going to be making
changes and recompiling frequently you'll probably want to disable -O3
in the makefile (I use templates liberally, so -O3 really speeds up
the code, but really slows down compilation).
And the makefile:
CC = g++
PROJ_NAME = moses
LINK_FLAGS = -Wall -Iutils/ -Itrees/ -Irewrite -I./ -Imodeling/ -Ifitness/ \
-Ialignment/ -Isim/ -Ilocal/ -O3
COMP_FLAGS = -Wall -Wno-sign-compare -Iutils/ -Itrees/ -Irewrite -I./ \
-Imodeling/ -Ifitness/ -Ialignment/ -Isim/ -Ilocal/ -O3
src := $(wildcard *.cc) $(wildcard utils/*.cc) $(wildcard trees/*.cc) $(wildcard modeling/*.cc) $(wildcard fitness/*.cc) $(wildcard alignment/*.cc) $(wildcard main/*.cc) $(wildcard rewrite/*.cc) $(wildcard sim/*.cc) $(wildcard local/*.cc)
obj := $(patsubst %.cc,%.o,$(src))
all: $(PROJ_NAME)
%.o: %.cc
$(CC) $(COMP_FLAGS) $< -c -o $#
$(PROJ_NAME): $(obj)
$(CC) $(LINK_FLAGS) $^ -o $(PROJ_NAME)
run:
$(PROJ_NAME)
clean:
find -regex ".*~\|.*\.o"|xargs rm -f
rm -f $(PROJ_NAME)
rm -f $(PROJ_NAME).exe*
depend:
makedepend -Y -- $(COMP_FLAGS) -- $(src)
utils/exceptions.o: utils/exceptions.h utils/utils.h
utils/io_util.o: utils/io_util.h utils/tree.h utils/basic_types.h
# ......lots more lines like that.........

I have an old instruction flying around here for Boost 1.34.1, which reads like this (project-specific stuff cut away):
unpack boost sources
cd into tools/jam/src
run ./build.sh to build bjam
cd into the main source directory
tools/jam/src/bin.linux/bjam threading=multi --layout=system --toolset=gcc --without-python variant=release --prefix=/usr/local install
The --without-python was necessary as the target system didn't have Python installed, which caused the build to fail messily.
Obviously you can / need to fiddle with the individual settings (like threading support, release vs. debug variant) to suit your needs, but it should be a good starting point.
If you need ICU support (for Boost.Regex and Boost.Locale), it gets more complicated...
Note that the build process has changed over the years; you shouldn't use the same procedure for more up-to-date boost versions. It's just what I used back then.
Edit:
As for the second part of your question, the Makefile doesn't need to refer to Boost explicitly if boost is installed in the standard system directories.
You do not have to state -I /usr/include for compilation as that is searched automatically; the same goes for -L /usr/lib during linkage.
The fact that the author of the Makefile copied the compiler flags into the linker flags verbatim doesn't really help intuitivity either... ;-)
If you have Boost in a custom directory (either the headers only, or by stating a custom directory in the --prefix option of my build instructions), you need to make the following modifications (look for "boost"):
LINK_FLAGS = -Wall -Iutils/ -Itrees/ -Irewrite -I./ -Imodeling/ -Ifitness/ \
-Ialignment/ -Isim/ -Ilocal/ -L /path/to/boost/libs -O3
COMP_FLAGS = -Wall -Wno-sign-compare -Iutils/ -Itrees/ -Irewrite -I./ \
-Imodeling/ -Ifitness/ -Ialignment/ -Isim/ -Ilocal/ \
-I /path/to/boost/includes -O3
That should do the trick. As the Makefile does not link any of the Boost binaries (e.g. -l boost_program_options or somesuch), it seems that it makes use of the Boost headers only, which would make the -L /path/to/boost/libs part (and, actually, the whole compilation step detailed above) superfluous. You should be able to get away with simply unpacking the sources and giving the header directory as additional include directory using -I /path/to/boost/headers.

Related

Compiling standalone ASIO with Makefile on Linux

I'm trying to compile a small c++ program that captures an image from a camera using libv4l2 and then sends it over UDP to a separate computer using asio.
The file structure of the project is:
project/
dependencies/
asio/
cpp/
cpp_server/
cpp_client/
Makefile
src/
cpp_client.cpp
ImageClient.cpp
ImageClient.h
ImageProtocol.h
My Makefile for the project is:
CC=g++
CPP_FILES := $(wildcard src/*.cpp)
OBJ_FILES := $(addprefix obj/,$(notdir $(CPP_FILES:.cpp=.o)))
LD_FLAGS := -L../../dependencies/asio/asio
INCLUDES := -I../../dependencies/asio/asio/include
CC_FLAGS := -Wall $(INCLUDES) -fpermissive -std=c++14 -DASIO_STANDALONE
client.exe : $(OBJ_FILES)
$(CC) $(LD_FLAGS) -o $# $^
obj/%.o: src/%.cpp
$(CC) $(CC_FLAGS) -c -o $# $<
However, when I try to compile this, my compiler spits on dozens of undefined reference errors for ASIO functions:
cpp_client.cpp:(.text+0x15dc): undefined reference to `asio::error::get_netdb_category()'
cpp_client.cpp:(.text+0x15ec): undefined reference to `asio::error::get_addrinfo_category()'
cpp_client.cpp:(.text+0x15fc): undefined reference to `asio::error::get_misc_category()'
obj/cpp_client.o: In function `asio::error::get_system_category()':
cpp_client.cpp:(.text._ZN4asio5error19get_system_categoryEv[_ZN4asio5error19get_system_categoryEv]+0x8): undefined reference to `asio::system_category()'
obj/cpp_client.o: In function `asio::detail::posix_tss_ptr<asio::detail::call_stack<asio::detail::thread_context, asio::detail::thread_info_base>::context>::posix_tss_ptr()':
cpp_client.cpp:(.text._ZN4asio6detail13posix_tss_ptrINS0_10call_stackINS0_14thread_contextENS0_16thread_info_baseEE7contextEEC2Ev[_ZN4asio6detail13posix_tss_ptrINS0_10call_stackINS0_14thread_contextENS0_16thread_info_baseEE7contextEEC5Ev]+0x20): undefined reference to `asio::detail::posix_tss_ptr_create(unsigned int&)'
obj/cpp_client.o: In function `asio::detail::posix_tss_ptr<asio::detail::call_stack<asio::detail::thread_context, asio::detail::thread_info_base>::context>::~posix_tss_ptr()':
cpp_client.cpp:(.text._ZN4asio6detail13posix_tss_ptrINS0_10call_stackINS0_14thread_contextENS0_16thread_info_baseEE7contextEED2Ev[_ZN4asio6detail13posix_tss_ptrINS0_10call_stackINS0_14thread_contextENS0_16thread_info_baseEE7contextEED5Ev]+0x1c): undefined reference to `pthread_key_delete'
obj/cpp_client.o: In function `asio::detail::posix_global_impl<asio::system_executor::context_impl>::~posix_global_impl()':
cpp_client.cpp:(.text._ZN4asio6detail17posix_global_implINS_15system_executor12context_implEED2Ev[_ZN4asio6detail17posix_global_implINS_15system_executor12context_implEED5Ev]+0x24): undefined reference to `asio::system_executor::context_impl::~context_impl()'
obj/ImageClient.o: In function `ImageClient::ImageClient(FHCamera, unsigned short, std::string const&, unsigned short)':
ImageClient.cpp:(.text+0x898): undefined reference to `asio::io_context::io_context()'
I imagine that the issue is that my Makefile still isn't properly finding ASIO and trying to compile it standalone. That said, I'm not really sure what else to try -- does anyone else have suggestions for what I need to do to get ASIO to compile standalone with a Makefile?
thanks!
The Standalone Asio library is a dependancy of your program. When building
a program, one does not also build the dependancies (unless in exceptional
circumstances). If that were necessary, then building almost any program would
recursively require probhibitively huge amounts of rebuilding dependencies.
If your program has a dependency on a library that is not provided packaged
by the package manager of your Linux distro then you must get the source package
of that library and build and install on your system as per its instructions.
Then you build your own program on the (true) assumption that your system satisfies
the library dependency. You do not repeat the building of the library dependency
in the building of your program.
The standalone moniker might have suggested to you that this library is
meant to be rebuilt in every application that uses it. It's not. It's
standalone asio in the sense that it's not itself dependent on any
boost libaries, unlike boost::asio, from it is derived. Standalone
doesn't even imply that the library does not have dependencies on other
non-boost libraries. E.g. amongst your linkage errors are some that
report undefined references from asio functions to pthread_key_delete,
which means asio is dependent on the Posix threads library, libpthread,
and you're not linking it.
The Standalone Asio library may well be provided by in a development package
by the package manager of your Linux distro. For example, Debian/Ubuntu distros
provide it in libasio-dev and you install it simply with:
sudo apt-get install libasio-dev
Investigate whether your distro does likewise, and if so install the library
with your package manager.
Otherwise you must install the library from source. It is a
GNU autotools source package,
so to build and install it you must have previously installed:
- GCC C++ toolchain
- GNU make
- GNU autotools (autoconf, automake at least)
Then:
Download the source tarball e.g asio-1.10.8.tar.bz2, from its
Sourceforge page and
extract the package directory, e.g. asio-1.10.8
cd into the the package directory and run:
$ autoreconf -i
$ ./configure
Errors from ./configure will indicate dependancies or other requirements
that your system does not satisfy. Fix and repeat until success. Then run
$ make
to build the package. If all is well, as root run:
$ make install
to install the package.
Once you have installed Standalone Asio either from a dev package or from
source, delete project/dependencies/asio and build your program
in project/cpp/cpp_client with a makefile like this:
Makefile
CXX=g++
SRCS := $(wildcard src/*.cpp)
OBJS := $(addprefix obj/,$(notdir $(SRCS:.cpp=.o)))
CXXFLAGS := -pthread
LDFLAGS := -pthread
#LDFLAGS := -L/path/to/your/libv4l2
#LDLIBS := -libv4l2
.PHONY: all clean
CXXFLAGS := -Wall -std=c++14 -DASIO_STANDALONE
all: client
client : $(OBJS)
$(CXX) $(LDFLAGS) -o $# $^ $(LDLIBS)
obj/%.o: src/%.cpp | obj
$(CXX) $(CXXFLAGS) -c -o $# $<
obj:
mkdir -p $#
clean:
rm -f obj/* client
For a rehearsal, I suggest using this makefile first to build the asio chat-client
that's provided in /asio-package-dir/src/examples/cpp11/chat. Put just chat_client.cpp
chat_message.hpp in your src folder for this.
Notice the commented out lines:
#LDFLAGS := -L/path/to/your/libv4l2
#LDLIBS := -lv4l2
You indicated that your program needs to be linked with library libv4l2
but your own makefile does not mention any such linkage. If you do need to
link with it then you must at least inform the linker of that fact by
uncommenting:
LDLIBS := -lv4l2
If you can install dev a package of this library from your package manager, do so. Otherwise
build and install it from source. Debian/Ubuntu does not provide such
a library package, although they do provide libv4l-0, libv4l-dev
and libv4l2rds0. Perhaps you're not precisely sure yet what library you need.
If you install this library from source and decide to install it in
some directory that is not one of the linker's default search paths
(/usr/lib, /usr/local/lib/ etc...) then you will also need to inform
the linker where it is, by uncommenting:
LDFLAGS := -L/path/to/your/libv4l2
Be aware that by adding libv4l2 to the linkage with -lv4l2, you
oblige the linker to find any other library that libv4l2
in turn depends on. So if your linkage now fails with undefined references
from libv4l2 to symbols in some other library libfoo, you need to
extend LDLIBS like:
LDLIBS := -lv4l2 -lfoo
and, if necessary, tell the linker where to find libfoo:
LDFLAGS := -L/path/to/your/libv4l2 -L/path/to/libfoo
And so on until the linkage succeeds.
In this light, you may wonder why the asio library doesn't similarly figure
in the linkage. No linker option -lasio needed? Your own makefile suggests that you
believe the linker needs to be told where to look for such a library, with
its setting:
LD_FLAGS := -L../../dependencies/asio/asio
though having told the linker to look there for libraries, you don't tell it link any
libraries at all.
No -lasio is needed because this library - untypically in general, but not
untypically for boost or boost-ish libraries - is a header only library.
It provides no shared object file libasio.so, nor any object file archive
libasio.a that you must link to get the definitions of functions. Instead,
they are wholly implemented by inline definitions in its header files. Thus,
any of them that you need to call in your program will be compiled straight
into it if you just #include <asio.hpp> in the source(s) file that make
those calls.
As it's a header only library, it is possible to use it to build your own
programs just by extracting the source package, skipping the usual autotools ./configure;
make;make install procedure, and setting up the preprocessor -I options
in your own makefile correctly (in CPPFLAGS - C PreProcessor Flags)
for it to locate the asio headers in, say,
/home/me/downloads/asio/asio-1.10.8. But if you were aiming to achieve
that, you made some mistake(s) en route; and if a package is autotooled -
as asio is - then all bets are off if you try to use it except as provided by the autotools
installation procedure. Installing a library in your system also has
the upside that once you've done it, you can forget about setting up peculiar
compiler and linker options in every project that uses it and the
like of /home/me/downloads/asio/asio-1.10.8 doesn't need become a
fixture of your home directory.
Your makefile and what you say about its problems suggests that you're
trying to use GCC and GNU Make by guesswork, trial and error. Here is
a fairly good starter tutorial in the use of those tools.
For authoritative documentation, here is the GNU Make manual and
here is the GCC manual
Incidentally, in Linux an executable is distinguished simply by its file
attributes and not by having an .exe extension as in Windows, so
your program target can and normally would be called simply client, not client.exe. The linker will make it executable when it creates it.
You are getting errors because on the link step you didn't supply all symbols (global variables or functions) needed to generate the final executable file.
You either need to add the ASIO library to the link step or, as your Makefile suggests by defining the ASIO_STANDALONE macro, need to include ASIO's standalone header in one of your source files to compile it.

Rcpp Library Won't Build (Can't find Compiler) on Ubuntu

I have a package that depends on Rcpp and uses two other libraries compiled from sub-directories in src/. The package builds fine on Mac OSX using a clang compiler. However, on an RStudio Ubuntu server, it fails to build. The build's first two steps (creating the static libraries in the sub directories to link in) work fine and I can see sensible build commands like the following taking place:
g++ -Wall -I../../inst/include/ --std=c++11 -lhts -L../htslib/ -lz -lm -c -o someLibFile.o someLibFile.cpp
However, in the very last step of the build process where it tries to build the Rcpp code and bind to the library, for some reason it appears to compleletey fail to put the compiler command in front (g++) and only outputs the second half of the command.
-o mypackage.so RcppExports.o temp.o -lhts -lpbbam -Lpbbam/ -L/htslib/ -Lpbbam/ -L/mnt/software/r/R/3.1.1/usr/lib/R/lib -lR
In contrast, on the Mac it builds just fine, appending clang++ and other flags in front of this final command:
clang++ -std=c++11 -dynamiclib -Wl,-headerpad_max_install_names -undefined dynamic_lookup -single_module -multiply_defined suppress -L/Library/Frameworks/R.framework/Resources/lib -L/usr/local/lib -o pbbamr.so LoadData.o RcppExports.o temp.o -lhts -lpbbam -Lpbbam/ -Lhtslib/ -Lpbbam/ -F/Library/Frameworks/R.framework/.. -framework R -Wl,-framework -Wl,CoreFoundation
How do I make it use the g++ compiler on Ubuntu at this step? I have a custom Makevars file, but it is there just to build the dependencies in the sub-directory, so I don't know why that would cause any problems (since it works on Mac OSX).
More Information
The compiler seems to be found if I delete my Makevars file. However, the Makevars file I am using is essentially a direct copy of the example given in the R extensions guide with one addition to enable C++11:
CXX_STD = CXX11
.PHONY: all mylibs
all: $(SHLIB)
$(SHLIB): mylibs
mylibs:
(cd subdir; make)
With the line CXX_STD removed, it does stick a compiler in front of the command.
Briefly:
What is your R installation? You should probably run the binaries provided by Michael via CRAN; they are based on my Debian upload; I run these too on a bunch of machines
The reason is that R 'remembers' its compile-time settings via $RHOME/etc/Makefconf. This should just be CXX=g+=.
When you install r-base-dev (from Ubuntu or the newer version from CRAN) you also get the build-essential package as well as all common dependencies. With that things just work.
If however you are doing something special or local, well then you have to deal with your local changes. The basic Ubuntu setup is used by thousands of people and daily jobs--including eg Travis builds for countless GitHub repos.
This is caused by using an outdated/unusual R installation which has poor support for C++11. The best way to resolve his is to upgrade to a more recent version of R, or use a standard R install (sudo apt-get install r-base-dev). A poor work around is described below.
Problems Cause and Bad Work Around
When writing R extension that use C++11, one often sets CXX_STD = CXX11 in the Makevars file or list SystemRequirements: C++11 in the DESCRIPTION file. These will trigger R to use the compiler set by the following flags in the Makeconf file (located at file.path(R.home(), "etc/Makeconf")).
CXX1X
CXX1XFLAGS
CXX1XPICFLAGS
CXX1XSTD
Note that some of these may be set in this file, but not all of them might be there indicating a problem. In the event there is a problem with these settings or they are not set, R appears to use the empty string "" as the compiler/linker for the C++ code, leading to the problem shown above where no compiler argument is given.
If upgrading is not an option and you need to deploy on a known machine, one work around is to manually setup for C++11 by making a more idiosyncratic Makevars file. For example, you could:
Remove the CXX_STD=CXX11 line from the Makevars file.
Remove SystemRequirements: C++11 from the DESCRIPTION file.
Add --std=c++11 and any other requirements needed to PKG_CPPFLAGS, PKG_CFLAGS, PKG_CXXFLAGS or whatever variable is being used to compile your code, to manually set the needed flags (assuming the machine's compiler actually does support C++11).
The above solution is not particularly robust, but can be used as a work around in case the machine cannot be upgraded.
Thanks to #DirkEddelbuettel for not only writing Rcpp but being willing to support it on StackOverflow and help with issues like this.

Building and linking shared libraries in an R package - code compiles, links, but won't load

Platforms tested: Linux Mint 17, Ubuntu 14.04
Full example: this repository.
What am I doing and why?
I'm trying to build an R package which wraps a subset of the CAF library using Rcpp and RcppEigen.
I have successfully linked an R package to a system level install of CAF (example here) (Note: ABSEIR no longer uses CAF, 2/5/2015), but I'd like to have a good way to deploy CAF to machines without administrator access, and as a result simplify the installation of other CAF dependent packages (yes, I'm aware that R doesn't directly support linking against other compiled packages, but it seems like others have successfully circumvented this limitation).
What's the problem?
I'm building two shared objects during package compilation in addition to the package shared object (RcppCAF.so): libcaf_core.so and libcaf_io.so. These are successfully compiled and linked, but the package fails to load, claiming:
** testing if installed package can be loaded
Error in dyn.load(file, DLLpath = DLLpath, ...) :
unable to load shared object '/home/grantbrown/R/x86_64-pc-linux-gnu-library/3.2/RcppCAF/libs/RcppCAF.so':
librcaf_core.so: cannot open shared object file: No such file or directory
What have I tried?
In addition to numerous failed Makevars configurations, I've found that
if I manually set LD_LIBRARY_PATH to the folder containing the compiled code, the package will successfully install. Obviously, I'd like to avoid this step by finding a way to tell R where to look for these dependencies. I have attempted to use the inst folder for this purpose to no effect. My Makevars file is as follows:
ROOT_DIR := $(abspath .)
$(info The compilation root directory is: $(ROOT_DIR))
$(info The name of the shared library to be created is: $(SHLIB))
$(info The place R should look for librcaf_core.so is: $(abspath ./libcaf_core))
$(info The place R should look for librcaf_io.so is: $(abspath ./libcaf_io))
SOURCES = $(wildcard ./*.cpp)
SOURCES1 = $(wildcard ./libcaf_core/*.cpp)
SOURCES2 = $(wildcard ./libcaf_io/*.cpp)
OBJECTS = $(SOURCES:.cpp=.o)
OBJECTS1 = $(SOURCES1:.cpp=.o)
OBJECTS2 = $(SOURCES2:.cpp=.o)
PKG_CPPFLAGS+= -std=c++11 -Dlibcaf_core_shared_EXPORTS -Wall -pedantic -pthread -fPIC -O2 -g -fPIC -I../inst -I../inst/libcaf_core -I../inst/libcaf_io
PKG_LIBS += -L$(abspath ./libcaf_core) -lrcaf_core -L$(abspath ./libcaf_io) -lrcaf_io
all: $(SHLIB)
$(SHLIB): $(OBJECTS) libcaf_core/librcaf_core.so libcaf_io/librcaf_io.so
libcaf_core/librcaf_core.so: $(OBJECTS1)
g++ -o libcaf_core/librcaf_core.so $(OBJECTS1) $(PKG_CPPFLAGS) -shared
libcaf_io/librcaf_io.so: $(OBJECTS2)
g++ -o libcaf_io/librcaf_io.so $(OBJECTS2) $(PKG_CPPFLAGS) -shared
There are a lot of threads on StackOverflow and mailing lists which deal with problems loading shared objects, but I couldn't find anyone with precisely the same issue. I've even done similar things in the past with no issues, so I'm having trouble figuring out why R can't find my shared objects. Any suggestions?
Edit
Dirk has suggested compiling to a single shared object, which I'm now working on. In the "Using Makevars" section of "Writing R Extensions", however, it does seems to imply that building dependencies should be possible:
"If you want to create and then link to a library, say using code in a subdirectory, use something like
.PHONY: all mylibs
all: $(SHLIB)
$(SHLIB): mylibs
mylibs:
(cd subdir; make)
"
The easiest approach, which you also seem to have found as per your most recent commit is to just have R 'glue' all object code into a single shared library.
That tends to "just work" but it is a little costly as the library needs to be rebuilt. We could look into packaging CAF as an external library which would make RcppCAF more lightweight.

ARM GNU Compiler -j[jobs] option exist

I cannot find an option for the ARM GNU toolchain to compile multiple c files at the same time. I use make -j5 all the time when compiling using gcc. Helps speed up compile time dramatically. Be nice if ARM GNU had a similar option.
Here is my setup:
--Fedora 20
--Core i5
--Eclipse with ARM GNU plugin
--ARM GNU 4.8-2014-q1-update (from here: https://launchpad.net/gcc-arm-embedded)
--Target uP: STM32F205RB
I've tried to get CodeSourcery GCC working, unsuccessfully. ARM GNU seemed to work well after little setup. CodeSourcery GCC should have a -j option, as we cross compile all the time for embedded linux.
GCC is not multi-threaded. The -j<n> switch is specific to make build system, not the compiler. It tells make how many tasks it can run in parallel.
If you run make -j4 you can observe in your task manager/top/process list that it tries to run 4 instances of GCC compiling 4 independent *.c files at the same time.
To make use of -j command you must have a Makefile in your project that can benefit from it. It should have multiple independent targets, so that they can be launched in parallel.
If you are lost in the terminology, I advice you to look at make tutorial, such as this one:
http://mrbook.org/tutorials/make/
The usual strategy here is to have a separate target for every c or cpp file in our project. That way make can easily spawn multiple compiler processes for each compilation unit. Once all *.o files are generated, they are linked.
Let's see at this example snippet:
SRCS := main.c func.c other.c another_file.c ...
OBJS := $(SRCS:.c=.o)
objects: $(OBJS)
%.o: %.c
gcc -o $(#) -c $(<)
We pass a list of c files, change them to corresponding o file using suffix substitution and treat the list of *.o files as targets. Now the make can compile each c file in parallel.
In contrast, if we do something like this:
SRCS := main.c func.c other.c another_file.c ...
all:
gcc $(SRCS) -o a.out
...we won't benefit from -j switch at all, because there is only one target.

Simple libtool alternative?

Being perfectly satisfied with old-style Makefiles, I am looking for a simple alternative to libtool. I do not want to switch to automake, and I keep running into problems with libtool when I try to use it directly. The latest one is 'unsupported hardcode properties', and I am getting fed up with the lack of complete documentation that just tells me what is wrong this time...
I only want to compile a bunch of .o files with the right flags and then link them into a shared library, such that it works on as many platforms as possible. Is there anything out there that does just that and not force me to switch all of my other tools at the same time?
I not sure if it would fit info your workflow but I'd recommend looking at CMake. It works on Windows, Linux and Mac and should not force you to change any of your other tools. You'll have to judge its suitability yourself though.
There's jlibtool (which has nothing to do with java).
It's written in C, and can just be bundled with your source.
It was originally an apache project, but whoever was working it there seems to of abandoned it around 2004.
It was taken over by FreeRADIUS project maintainer Alan Dekok, who modernised the code and fixed a few niggling issues. We use it for the FreeRADIUS project (>= 3.0.0) to do all the build time linking.
Given your description in the comment to Milliams' answer,
I just want one tool that I tell: "give me the compiler flags so that I can compile these n files for use in a shared library, and then give me the commands to link them together",
then libtool may well be the simplest tool for the job. I know of no other alternative.
You are right that the documentation for using libtool with plain makefiles is practically nonexistent, but libtool certainly does not require you to switch to automake. Cross-platform libraries are difficult, and the price you have to pay for them is libtool. (Or maybe the discount price is libtool+automake+autoconf or CMake or Jam.)
slibtool (dl.midipix.org/slibtool, git://midipix.org/slibtool) is a libtool drop-in replacement, written in C. A single slibtool binary aims to seamlessly support both native and cross-builds, and the utility also provides some additional features (installation of .la files is optional, optional color-coded annotation, etc). The following minimal plain makefile demonstrates how to (cross-) build a library using slibtool.
CC = cc
LIBTOOL = slibtool
DESTDIR = destdir
all: libfoo.la
a.lo:
$(LIBTOOL) --mode=compile --tag=CC $(CC) -c a.c
libfoo.la: a.lo
$(LIBTOOL) --mode=link --tag=CC $(CC) -o libfoo.la -rpath /lib
install: all
mkdir -p destdir
$(LIBTOOL) --mode=install cp libfoo.la $(DESTDIR)
# the -rpath argument is required for semantic compatibility with libtool.
native build, default (both shared library and static library)
$ make
$ make install
native build, shared library only
$ make LIBTOOL=slibtool-shared
$ make install
native build, static library only
$ make LIBTOOL=slibtool-static
$ make install
cross-build, default
$ make CC=some-target-tuple-gcc
$ make install
cross-build, default, with lots of colors
$ make LIBTOOL=dlibtool CC=some-target-tuple-gcc
$ make install