Search code examples
ccmakebisonflex-lexeryacc

CMake custom command for bison target


I'm trying to convert an old Autotools project to CMake. In one of the Makefiles, there are some rules that use lex and yacc. I found that CMake has bison_target and flex_target. However in the Makefile there's a rule with sed that edit the generated file. Here is the Makefile.am:

docdir = @SIS_DOCDIR@
AM_CPPFLAGS = -DSIS -I../include
AM_YFLAGS = -d

BUILT_SOURCES = readlib.c readlib.h readliblex.c
CLEANFILES = $(BUILT_SOURCES)

noinst_LIBRARIES = libgenlib.a
libgenlib_a_SOURCES = aoi.c com_genlib.c comb.c comb.h count.c genlib.c \
    genlib.h genlib_int.h io.c nand.c permute.c sptree.c sptree.h \
    readlib.y readliblex.l
dist_doc_DATA = genlib.doc

readlib.h: readlib.c
readlib.c readlib.h: readlib.y
    $(YACC) $(YFLAGS) $(AM_YFLAGS) $<
    sed 's/yy/GENLIB_yy/g' y.tab.c > readlib.c
    sed 's/yy/GENLIB_yy/g' y.tab.h > readlib.h
    $(RM) y.tab.c y.tab.h
readliblex.c: readliblex.l readlib.h
    $(LEX) $(LFLAGS) $(AM_LFLAGS) $<
    sed 's/yy/GENLIB_yy/g' lex.yy.c > readliblex.c
    $(RM) lex.yy.c

And this is how I translated it:

set(CMAKE_C_FLAGS -DSIS)
add_library(genlib STATIC
        aoi.c
        com_genlib.c
        comb.c
        count.c
        genlib.c
        io.c
        nand.c
        permute.c
        sptree.c

        readlib.y
        readliblex.l
        )
find_package(BISON)
find_package(FLEX)
bison_target(readlib readlib.y -d)
add_custom_command(TARGET readlib POST_BUILD
        COMMAND sed 's/yy/GENLIB_yy/g' y.tab.c > readlib.c
        COMMAND sed 's/yy/GENLIB_yy/g' y.tab.h > readlib.h
        COMMAND rm -f y.tab.c y.tab.h
        )
flex_target(readliblex readliblex.l lex.yy.c)
add_custom_command(TARGET readliblex POST_BUILD
        COMMAND sed 's/yy/GENLIB_yy/g' lex.yy.c > readliblex.c
        COMMAND rm -f lex.yy.c
        )

The problem is that CMake doesn't see readlib and readliblex as targets:

CMake Error at sis/genlib/CMakeLists.txt:28 (add_custom_command):
  No TARGET 'readlib' has been created in this directory.


CMake Error at sis/genlib/CMakeLists.txt:34 (add_custom_command):
  No TARGET 'readliblex' has been created in this directory.

Where am I wrong?


Solution

  • Given that bison_target didn't create a target, I ended up using a different solution:

    set(CMAKE_C_FLAGS -DSIS)
    
    find_package(BISON REQUIRED)
    find_package(FLEX REQUIRED)
    
    set(BISON_OUTPUT ${CMAKE_SOURCE_DIR}/sis/genlib/readlib.c)
    if (BISON_FOUND)
        add_custom_command(
                OUTPUT ${BISON_OUTPUT}
                COMMAND ${BISON_EXECUTABLE}
                --output=${BISON_OUTPUT}
                -d
                ${CMAKE_SOURCE_DIR}/sis/genlib/readlib.y
                COMMENT "Generating readlib.c"
        )
    endif ()
    
    set(FLEX_OUTPUT ${CMAKE_SOURCE_DIR}/sis/genlib/readliblex.c)
    if (FLEX_FOUND)
        add_custom_command(
                OUTPUT ${FLEX_OUTPUT}
                COMMAND ${FLEX_EXECUTABLE}
                --outfile=${FLEX_OUTPUT}
                ${CMAKE_SOURCE_DIR}/sis/genlib/readliblex.l
                COMMENT "Generating readliblex.c"
        )
    endif ()
    
    add_library(genlib STATIC
            aoi.c
            com_genlib.c
            comb.c
            count.c
            genlib.c
            io.c
            nand.c
            permute.c
            sptree.c
            ${BISON_OUTPUT}
            ${FLEX_OUTPUT}
            )
    add_custom_command(TARGET genlib POST_BUILD
            COMMAND sed -i 's/yy/GENLIB_yy/g' ${CMAKE_SOURCE_DIR}/sis/genlib/readlib.c
            COMMAND sed -i 's/yy/GENLIB_yy/g' ${CMAKE_SOURCE_DIR}/sis/genlib/readlib.h
            COMMAND sed -i 's/yy/GENLIB_yy/g' ${CMAKE_SOURCE_DIR}/sis/genlib/readliblex.c
            )