Thanks Joseph, that was quite helpful. There was a lot of jargon in there that I’ve seen before, but wasn’t sure how it all came together until now.
So that reminded me of another, similar question that I was planning to ask:
What is the best way to organize a C project for distributing to multiple platforms? I’m planning on building a command-line tool with C that uses SDL that will be distributed to lots of different OSes. I’d rather not require that SDL already be installed, but find a way to distribute it with my program. It would be even better if my users didn’t have to compile anything because it was “precompiled”. How can I simplify the installation process for my users and account for the variations in platforms?
Thanks,
Andrew HavensOn October 16, 2013 at 3:44:08 PM, T. Joseph Carter (tjcarter at spiritsubstance.com) wrote:
First the easy answer: Lots of libraries began shipping themselves
with *-config programs. They all took basically the same args,
–cflags and --libs. They were so similar and so common that someone
got a brilliant idea: let’s produce ONE program, call it pkg-config,
that does it in a common, standard way.
So they’re basically the same thing. If you use pkg-config, it
becomes absolutely trivial to write a configure test for a library.
Now?
The limitations of make
CMake isn’t necessarily better than make for what make does. Well,
except that telling make about your source code’s header dependencies
in an automatic fashion is not as trivial as we’d like.
It is better than make for what it does NOT do, however. If you look
at a pristine SDL source tree, it contains no makefiles. The reason
is that it doesn’t know what to build, what features to include, etc.
CMake and premake exist to solve that problem. The alternative
are autoconf/automake/etc., and these are considered standard tools.
Why autotools suck
(Sorry in advance for the novel?)
The standard way to get those on UNIXy systems involves running a
shell script, ./configure, which generates the makefiles using a
macro language called m4. Basically imagine if C/C++ preprocessor
directives like #include and #ifdef were a full scripting language
unto themselves for generating C/C++ source. Yikes.
But you can’t just write a configure script, because it too must be
generated using m4 and other things by running a program called
autoconf. And all of that is assuming you’re just writing a simple
program. If you’re writing a library, or you want to avoid writing
messy Makefile’s, you use another layer on top of that called
automake. Same deal, only it kind of generates input for autoconf.
Of course all of these may pull in dependencies on UNIX programs like
sed, awk, and sometimes a whole scripting programming infrastructure
called perl. In fact, if you want to build a dynamic library in an
intelligent fashion, you’re kind of best off using another add-on
called libtool. Whether or not libtool constitutes doing something
in an intelligent fashion is a matter of some debate, but what’s not
up for debate is that it DOES bring in a dependency on perl.
You may also have a dependency on stuff like pkg-config, which isn’t
really a classic UNIX “standard”, but it makes configure test writing
so easy that it’s very common. And often, then you go and write the
fallback if pkg-config is NOT installed. But not always.
And if all systems were UNIX, the dependencies aren’t a big deal
because? well, you’ve got them. But Bourne shell is a language, m4
is a language, perl is a language, awk is a language, and sed is kind
of almost a language. (Basically, it’s mini like a mini subset
of vi’s predecessor, ed. Think MS-DOS EDLIN, but for working with
stdin/stdout.)
You’ve got to know about three languages, in addition to the one
you’re writing your code with, in order to compile it. And if there
is a bug in your build system, you might need to know all of them!
It’s also not conducive to using an IDE. Any IDE. If you’re using
that stinking heap of legacy crap left over from the 1970s, your
development environment is the UNIX shell. Even if you use an IDE
that cleverly tries to generate automake-compatible stuff in the
background, I promise you, you WILL be using the command line to sort
out your projects sooner or later.
Why CMake is better but not perfect
ONE language. The CMake interpreter has most of the features needed
to reproduce all of the above autotools stuff built-in. It can build
static libraries, shared libraries, packages, and even Mac frameworks
and app bundles. Languages and compilers are just structures
defining variables and a few test to find the appropriate compilers
and whatnot for using that language on your system.
It has the same sort of include path setup autoconf/automake use, to
find cmake macros/plugins, but these are all written in cmake’s
single language.
You’re not forced to break up your project’s build files all over the
tree. You can make your build as modular as you want, or not, as you
choose. While it’s technically possible to do that with make, it’s
considered doing it wrong. There is no recursive make, nor is
there need for it.
And dependencies? You’ve got one: CMake itself. That, your
compiler, and your linker are all you need. Plus, CMake CAN generate
make, MSVC, and XCode project files if you want it to. No IDE does
(nor likely realistically could) read and write CMakeLists.txt (the
CMake equivalent of a Makefile, ./configure, and everything), but an
IDE could at least read that file and figure out what was part of
your project easily enough.
Other alternatives
There’s a few. SCons, premake, others? But it’s kind of like
alternatives for Subversion and CVS: There are many, but git has kind
of risen to the top. Almost to the point that CVS and Subversion are
considered inferior alternatives to git, whereas Mercurial would be
considered fairly comparable.
CMake hasn’t reached that level of prominence. Autotools are still
the standard, even if CMake is simply a better choice. But there
isn’t a perfect solution out there that meets everyone’s needs. When
there is, there will be much rejoicing.
Joseph
On Tue, Oct 15, 2013 at 10:03:58PM -0700, Andrew Havens wrote:
Yeah, I’m not interested in using XCode either. I’d rather not depend on an IDE. I’ve got a Makefile for automating the compile task. I’ve seen other projects use cmake, but I’m not familiar with what makes it different/better than make.
The pkg-config and sdl-config look awfully similar?what’s the difference? Why would I want to use sdl-config instead?
SDL mailing list
SDL at lists.libsdl.org
http://lists.libsdl.org/listinfo.cgi/sdl-libsdl.org