[CMake] Why doesn't cmake generate the file?

Jörg Förstner Joerg.Foerstner at ubidyne.com
Thu Dec 3 11:32:51 EST 2009


Hi,

> [Tyler] Have you tried this with a custom command that actually creates gen.h?
> [Michael] ...use full paths to gen.h ...
> [Michael] ...don't need to set the source file property GENERATED ...
   
Thank you for your hints, I've added them to the example code below and tested it.
(also had to add the binary dir to the include path)

Now there are two possibilities:

1.) If I use the new example as noted below, CMake creates the file "gen.h", and everything works fine. 

 [ 50%] Generating gen.h
 [100%] Building CXX object testjf/CMakeFiles/foo.dir/foo.cpp.o
 Linking CXX shared library ../lib/libfoo.so
 [100%] Built target foo

2.) I thought CMake scans cpp files for their #include lines and automatically generates rules. So a rule for "gen.h" must be generated somewhere. And I would further expect that CMake itself would find the custom command to build "gen.h", if "gen.h" doesn't exist or the depended files have changed.

But if I remove "gen.h" from the ADD_LIBRARY() command...
 ADD_LIBRARY( foo SHARED ${SRCS} )
...then CMake does not create "gen.h" any more and the build fails:

 [100%] Building CXX object testjf/CMakeFiles/foo.dir/foo.cpp.o
 /home/jf0068/ws1src/testjf/foo.cpp:2:17: error: gen.h: No such file or directory
 /home/jf0068/ws1src/testjf/foo.cpp: In function âint main()â:
 /home/jf0068/ws1src/testjf/foo.cpp:8: error: âTESTSTRINGâ was not declared in this scope
 make[2]: *** [testjf/CMakeFiles/foo.dir/foo.cpp.o] Error 1
 make[1]: *** [testjf/CMakeFiles/foo.dir/all] Error 2
 make: *** [all] Error 2

-----------------------
So the big question is:
-----------------------
Why do I need to manually add "gen.h" to the ADD_LIBRARY() command?

Joerg


The example files:

---------------------
File: testjf/data.txt
---------------------
#define TESTSTRING "test"


--------------------
File: testjf/foo.cpp
--------------------
#include <iostream>
#include "gen.h"

using namespace std;

int main()
{
  cout << "Hello World, this is a " << TESTSTRING << endl;
  return 0;
}


---------------------------
File: testjf/CMakeLists.txt
---------------------------
# Set variable containing all source files
SET( SRCS
  foo.cpp
)

# Add current binary directory to the path for searching include files
INCLUDE_DIRECTORIES(
  ${CMAKE_CURRENT_BINARY_DIR}
)

# Define custom command to generate "gen.h" 
ADD_CUSTOM_COMMAND(
  OUTPUT  ${CMAKE_CURRENT_BINARY_DIR}/gen.h
  COMMAND cp ${CMAKE_CURRENT_SOURCE_DIR}/data.txt ${CMAKE_CURRENT_BINARY_DIR}/gen.h
  DEPENDS ${CMAKE_CURRENT_SOURCE_DIR}/data.txt
)

# Define to build a target shared object library named "libfoo.so" from the source files "${SRCS}".
# The file "foo.c" depends on the generated include file "gen.h"
ADD_LIBRARY( foo SHARED ${SRCS} ${CMAKE_CURRENT_BINARY_DIR}/gen.h )


More information about the CMake mailing list