[Cmake] Help for a newbie - and discovered an interesting bug(?) in cmake 1.8.3

Schumacher, Gordon gordon_schumacher at maxtor.com
Tue, 20 Apr 2004 17:26:43 -0600


So, I'm doing something that I perhaps shouldn't be... but I'm new to CMake,
and I perhaps don't know the "right" way to go about this behaviour.

I have a project with many subdirectories that I'd like to build
recursively, and initially, I thought that just doing SUBDIRS(...) calls,
and having each subdir add source files to a PRJ_SRCS variable was the way
to do that.  But I found, due to the "empty" message output in the example
below, that the parent makefile seemed to be processed to completion before
the SUBDIRS() calls were performed.  Hence:

### Parent-level CMakeLists.txt:
SET(PRJ_SRCS)
SUBDIRS(foo)
MESSAGE(STATUS ${PRJ_SRCS})
ADD_EXECUTABLE(out ${PRJ_SRCS})

### CMakeLists.txt in directory"foo":
SET(PRJ_SRCS ${PRJ_SRCS} some.c)
MESSAGE(STATUS ${PRJ_SRCS})

This produces the following:
$ cmake -G"Unix Makefiles"
-- Check for working C compiler: gcc.exe
-- Check for working C compiler: gcc.exe -- works
-- Check for working CXX compiler: c++.exe
-- Check for working CXX compiler: c++.exe -- works
--
CMake Error: Error in cmake code at
j:/test/CMakeLists.txt:5:
ADD_EXECUTABLE called with incorrect number of arguments
-- some.c
-- Configuring done

So, I thought that the following would be a good, clever way to do the same
thing with includes, without having to "hard-wire" all the directory names.

SET(CMAKE_CURRENT_SOURCE_DIR ${CMAKE_CURRENT_SOURCE_DIR}/src}
INCLUDE(${CMAKE_CURRENT_SOURCE_DIR}/CMakeLists.txt)
SET(CMAKE_CURRENT_SOURCE_DIR ${CMAKE_CURRENT_SOURCE_DIR}/..)

This, however, didn't work.  So I started adding some MESSAGE calls around
it... and got some *very* interesting results.

The following snippet:

### Warning, bogus, barf! ###
MESSAGE(STATUS ${CMAKE_CURRENT_SOURCE_DIR})
SET(CMAKE_CURRENT_SOURCE_DIR ${CMAKE_CURRENT_SOURCE_DIR}/src}
MESSAGE(STATUS ${CMAKE_CURRENT_SOURCE_DIR})
MESSAGE(STATUS ${CMAKE_CURRENT_SOURCE_DIR})
MESSAGE(STATUS ${CMAKE_CURRENT_SOURCE_DIR})
MESSAGE(STATUS ${CMAKE_CURRENT_SOURCE_DIR})
SET(CMAKE_CURRENT_SOURCE_DIR ${CMAKE_CURRENT_SOURCE_DIR}/..)

produces the following spew:

-- j:/MCCL/Timer
-- j:/MCCL/Timer/src}MESSAGE(STATUSj:/MCCL/Timer
-- j:/MCCL/Timer/src}MESSAGE(STATUSj:/MCCL/Timer
-- j:/MCCL/Timer/src}MESSAGE(STATUSj:/MCCL/Timer

Interesting, no?

I've logged it as a bug in the Bug Tracker, but I'm guessing that I'm not
doing this in any of the Officially Recognized Ways(tm).

I've got "Mastering CMake"... but the examples in the book seems to require
that you collect *all* of the subdirectories, down all the way to the
deepest level, into the top-level CMakeLists.txt.  I'd really, really prefer
to collect level 4 into level 3's CMakeLists.txt, and level 3 into level
2's, and so on and so forth.  That way, the top-level doesn't need to "know"
what the lower-level directory structure looks like.  There must be a way to
do this, yes?

Meanwhile, I've proven my long-recognized talent for breaking things :)

Thanks all, meanwhile, I'm trying to build the nightly CVS code to see if I
can reproduce the bug on that version too.