[CMake] Dependency tracking with constructed source headers...
Dan Katz
dkatz at profitlogic.com
Thu Oct 7 19:22:50 EDT 2004
Hi -
While trying to use CMake for a new C++ system, I ran into the
following issue:
I have a header file which is being generated automatically from some
other source, and I can't figure out how to get it to be built
correctly by CMAKE. I've boiled the issue down to a simple example.
Assume we have a single "project file" (foo.cpp) like so:
----------------- foo.cpp ------------------------------------
#include "bar.h"
#include <iostream>
using namespace std;
int
main()
{
cout << bar() << endl;
return 0;
}
---------------------------------------------------------------
The function "bar()" is in a dynamically generated header file "bar.h"
which is created from "bar.junk" In my sample, that creation happens
by renaming "bar.junk"; in the real system there's a bunch of m4 macro
hell involved. In any event, the trivial sample looks like this:
---------------- bar.junk --------------------------------------
#include <string>
using std::string;
string
bar()
{
return "fubar!!";
}
------------------------------------------------------------------
I then have a CMakeLists.txt which I think should build the system:
---------------- CMakeLists.txt ----------------------------------
PROJECT (foo)
# bar.h will be generated here...
INCLUDE_DIRECTORIES(${foo_BINARY_DIR})
# how to build bar.h
ADD_CUSTOM_COMMAND(
OUTPUT ${foo_BINARY_DIR}/bar.h
COMMAND cp
ARGS ${foo_SOURCE_DIR}/bar.junk ${foo_BINARY_DIR}/bar.h
MAIN_DEPENDENCY ${foo_SOURCE_DIR}/bar.junk)
ADD_EXECUTABLE(foo foo.cpp ${foo_SOURCE_DIR}/bar.junk)
-------------------------------------------------------------------
I now try to build the system and get the following session
transcript:
-----------------------building foo -------------------------------
$ pwd
/home/dkatz/foo_build
$ cmake ../foo # ../foo is where foo.cpp, bar.junk, and
# CMakeLists.txt all live
-- Check for working C compiler: gcc
-- Check for working C compiler: gcc -- works
-- Check for working CXX compiler: c++
-- Check for working CXX compiler: c++ -- works
-- Configuring done
-- Generating done
-- Build files have been written to: /home/dkatz/foo_build
$ make
Building dependencies. cmake.depends...
cmake.depends is up-to-date
Building object file foo.o...
/home/dkatz/foo/foo.cpp:1:17: bar.h: No such file or directory/home/dkatz/foo/foo.cpp: In function `int main()':
/home/dkatz/foo/foo.cpp:10: error: `bar' undeclared (first
use this function)
/home/dkatz/foo/foo.cpp:10: error: (Each undeclared
identifier is reported only once for each function it appears in.)
make[1]: *** [foo.o] Error 1
make: *** [default_target] Error 2
--------------------------------------------------------------------
After taking a look at the generated Makefile, I noticed that the
build target for bar.h was built correctly (i.e., worked if called by
hand via "make /path/to/build/bar.h", but that bar.h was never
constructed because it was not listed as a dependency for foo.o:
--------------------- foo.o target ---------------------------------
foo.o: /home/dkatz/foo/foo.cpp
@echo "Building object file foo.o..."
c++ -o foo.o $(INCLUDE_FLAGS) -c /home/dkatz/foo/foo.cpp
--------------------------------------------------------------------
So I guess the question is: why didn't the system pick up that foo.o
depends on bar.h? And how can I make it do so? I played around with
ADD_DEPENDENCIES a little bit, but couldn't figure out how to make it
work. Any help would be appreciated.
Dan
P.S. I did take a look at FAQ 2.4, and in fact I patterned my
CMakeLists.txt off of the snippets shown there. But with only a
generated header, I can't seem to get it to work...
More information about the CMake
mailing list