[CMake] Dependency not executed, why?

Michael Wild themiwi at gmail.com
Fri Nov 19 03:29:56 EST 2010


Hi

On 11/19/2010 08:22 AM, Thomas Lehmann wrote:
> Hi,
> 
> I’ve found an example to use bison and flex in cmake.
> I have a static library where I want to add the generated
> sources but the dependencies are not triggered. Why?

Let's see:

> project(test)
> 
> include_directories(.
>                     ${CMAKE_BINARY_DIR}/libs/test)
> 
> add_custom_target(ScannerAndParser
>     echo "Creating scanner.cxx and parser.cxx")

Put above custom target below the custom commands and use the DEPENDS
option to depend on the output of the custom commands. Otherwise the
target will run, but won't trigger anything. But actually, this target
is not necessary, although you might still want to keep it as a
"convenience" target, though.

> add_custom_command(
>     SOURCE ${CMAKE_CURRENT_SOURCE_DIR}/scanner.l
>     COMMAND flex
>     ARGS -o ${CMAKE_BINARY_DIR}/libs/test/scanner.cxx
>             ${CMAKE_CURRENT_SOURCE_DIR}/scanner.l
>     TARGET ScannerAndParser
>     DEPENDS ${CMAKE_BINARY_DIR}/libs/test/scanner.cxx
>     OUTPUTS ${CMAKE_BINARY_DIR}/libs/test/scanner.cxx)

You should read this:
http://www.cmake.org/cmake/help/cmake-2-8-docs.html#command:add_custom_command

There is no SOURCE option, and as Eric already mentioned, it should be
OUTPUT instead of OUTPUTS. Also, remove the TARGET option, and make the
ScannerAndParser target DEPENDS on the OUTPUT of this command instead.
Also, this command should DEPENDS on the source, not the output!

>  
> add_custom_command(
>     SOURCE ${CMAKE_CURRENT_SOURCE_DIR}/parser.y
>     COMMAND bison
>     ARGS -y -d ${CMAKE_CURRENT_SOURCE_DIR}/parser.y
>          -o ${CMAKE_BINARY_DIR}/libs/test/parser.cxx
>     TARGET ScannerAndParser
>     DEPENDS ${CMAKE_BINARY_DIR}/libs/test/parser.cxx
>     OUTPUTS ${CMAKE_BINARY_DIR}/libs/test/parser.cxx)

Ditto as above.

>  
> file(GLOB lib_sources *.cxx ${CMAKE_BINARY_DIR}/libs/test/scanner.cxx
>                             ${CMAKE_BINARY_DIR}/libs/test/parser.cxx)

***NEVER ERVER USE FILE(GLOB)!*** It is evil and causes a whole lot of
problems. List the sources explicitly.

> 
> set_source_files_properties(${CMAKE_BINARY_DIR}/libs/test/parser.cxx
> GENERATED)

That's superfluous, as it's taken care of by the ADD_CUSTOM_COMMAND.

> 
> 
> add_library(test STATIC ${lib_sources})
> add_dependencies(test ScannerAndParser)

That's not necessary since CMake knows that scanner.cxx and parser.cxx
are GENERATED files and how to generate them (thanks to the
ADD_CUSTOM_COMMAND calls).

>
>
> Thomas Lehmann
> Scrum Master
>

That said, I think you would be far better off using the standard
FindFLEX and FindBISON modules instead. It would simplify your code to
the following:

project(test CXX)

# find required packages
find_package(FLEX REQUIRED)
find_package(BISON REQUIRED)

# create parser and scanner sources
bison_target(parser parser.y ${CMAKE_CURRENT_BINARY_DIR}/parser.cxx)
flex_target(scanner scanner.l ${CMAKE_CURRENT_BINARY_DIR}/scanner.cxx)
# probably the scanner depends on headers from the parser
add_flex_bison_dependency(scanner parser)

# define all sources here
set(lib_sources)
  a.cxx
  b.cxx
  ${BISON_parser_OUTPUTS}
  ${FLEX_scanner_OUTPUTS})

# set up include directories
include_directories(
  ${CMAKE_CURRENT_SOURCE_DIR}
  ${CMAKE_CURRENT_BINARY_DIR})

# create the library
add_library(test STATIC ${lib_sources})


HTH

Michael


More information about the CMake mailing list