简体   繁体   中英

CMake project with flex/bison

I'm working on an hobby project in C++, using flex and bison . I'm using CMake as my build system, and I had struggle in making all work together.

I'm quite new to CMake so the documentation seems quite minimal to me. It is showed how to link everything in one executable. But I'm trying to keep all the parts of my code separated, so I would like to have my flex / bison file in a subfolder. My structure is this:

.
├── build
|   └-- ...
├── CMakeLists.txt
├── flexbison
│   ├── CMakeLists.txt
│   ├── lexer.ll
│   └── parser.yy
├── lib
│   ├── CMakeLists.txt
│   └── ...
├── main.cpp
└── run.sh

So I want to have my yyparse function separate from my main.cpp , as well as my other C++ files. I managed to get it done in this way:

  • project_root/CMakeLists.txt :
cmake_minimum_required(VERSION 3.10)

# set the project name
project(progetto-di-prova VERSION 0.1)

add_subdirectory(flexbison)

add_executable(executable main.cpp)

target_include_directories(executable PUBLIC
  "${PROJECT_BINARY_DIR}"
  "${PROJECT_BINARY_DIR}/flexbison"
  )


set_target_properties(executable PROPERTIES CXX_STANDARD 11)

target_link_libraries(executable parserlib)

set(CMAKE_EXPORT_COMPILE_COMMANDS ON)
  • flexbison/CMakeLists.txt :
find_package(FLEX)
find_package(BISON)

flex_target(lexer lexer.ll "${CMAKE_CURRENT_BINARY_DIR}/lexer.cpp")
bison_target(parser parser.yy ${CMAKE_CURRENT_BINARY_DIR}/parser.cpp
  DEFINES_FILE ${CMAKE_CURRENT_BINARY_DIR}/parser.h)

add_flex_bison_dependency(lexer parser)

add_library(parserlib STATIC
  ${FLEX_lexer_OUTPUTS}
  ${BISON_parser_OUTPUTS}
)
  • the main.cpp file:
#include <parser.h>     //  <-this was the line causing troule
#include <iostream>

extern int yylex(void);

int main(int argc, char *argv[])
{
  yyparse();
  return 0;
}

Now, the point is: is this the correct way of doing so ? Is it better to put the main function in the bison code?

My main problem, as highlighted in the code, was to include the parser.h header file in the main.cpp . Is this the CMake-way to do it ?

Thanks in advance!

If I were you I would have:

flexbison/CMakeLists.txt :

...
add_library(parserlib STATIC
  ${FLEX_lexer_OUTPUTS}
  ${BISON_parser_OUTPUTS}
)
target_include_directories(parserlib PUBLIC 
  $<BUILD_INTERFACE:${CMAKE_CURRENT_SOURCE_DIR}>
  $<BUILD_INTERFACE:${CMAKE_CURRENT_BINARY_DIR}>
  $<INSTALL_INTERFACE:include/parserlib> # <prefix>/include/parserlib
)

note: $<INSTALL_INTERFACE:include/parserlib> need to be adapted if you want and how you install parserlib...

project_root/CMakeLists.txt :

...
target_include_directories(executable PUBLIC
  $<BUILD_INTERFACE:${CMAKE_CURRENT_BINARY_DIR}>)
...

Since executable is "target_link" against parserlib which provides public include directories, you don't need to list these directories anymore in executable 's include dirs.

ref: https://cmake.org/cmake/help/latest/command/target_include_directories.html

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM