野牛目标的 CMake 自定义命令
CMake custom command for bison target
我正在尝试将旧的 Autotools 项目转换为 CMake。在其中一个 Makefile 中,有一些使用 lex 和 yacc 的规则。
我发现 CMake 有 bison_target
和 flex_target
。但是,在 Makefile 中有一条规则 sed
用于编辑生成的文件。
这是 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
我是这样翻译的:
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
)
问题是 CMake 没有将 readlib
和 readliblex
视为目标:
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.
我哪里错了?
尽管名称如此,bison_target
不会创建 CMake target。它只是 add_custom_command()
调用 OUTPUT 文件,列在 BISON_<name>_OUTPUT
变量中。
鉴于 bison_target
没有创建目标,我最终使用了不同的解决方案:
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
)
与其更改生成的源代码以替换'yy'
前缀,不如告诉bison在生成代码时使用前缀:
对于 2.6 之前的 bison:
bison --name_prefix=GENLIB_yy
对于 2.6 之后的 bison:
bison -Dapi.prefix=GENLIB_yy
我正在尝试将旧的 Autotools 项目转换为 CMake。在其中一个 Makefile 中,有一些使用 lex 和 yacc 的规则。
我发现 CMake 有 bison_target
和 flex_target
。但是,在 Makefile 中有一条规则 sed
用于编辑生成的文件。
这是 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
我是这样翻译的:
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
)
问题是 CMake 没有将 readlib
和 readliblex
视为目标:
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.
我哪里错了?
尽管名称如此,bison_target
不会创建 CMake target。它只是 add_custom_command()
调用 OUTPUT 文件,列在 BISON_<name>_OUTPUT
变量中。
鉴于 bison_target
没有创建目标,我最终使用了不同的解决方案:
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
)
与其更改生成的源代码以替换'yy'
前缀,不如告诉bison在生成代码时使用前缀:
对于 2.6 之前的 bison:
bison --name_prefix=GENLIB_yy
对于 2.6 之后的 bison:
bison -Dapi.prefix=GENLIB_yy