Genivia / RE-flex

A high-performance C++ regex library and lexical analyzer generator with Unicode support. Extends Flex++ with Unicode support, indent/dedent anchors, lazy quantifiers, functions for lex and syntax error reporting and more. Seamlessly integrates with Bison and other parsers.
https://www.genivia.com/doc/reflex/html
BSD 3-Clause "New" or "Revised" License
501 stars 86 forks source link

Ease of use with CMake #203

Open simmplecoder opened 3 months ago

simmplecoder commented 3 months ago

I am not sure if I overlooked it, but It would be great to have a cmake script that users could include and invoke functions to invoke reflex. I have something like this in mind:

include(ReflexSupport)

# The line below generates a target and a custom target which target will depend on
reflex_make_target(TARGET lexer [STATIC | SHARED | OBJECT]
    FILES myflex1.reflex myflex2.reflex
)

Then users could do stuff like

target_include_directories(lexer PUBLIC include/definitions)
target_link_libraries(myapp PRIVATE lexer)

I would be up to implement the above if desired.

genivia-inc commented 3 months ago

Love to see this materialize.

I would be up to implement the above if desired.

Yes, please do.

simmplecoder commented 3 months ago

I will give it a go then, should have something to show next week or so.

simmplecoder commented 3 months ago

I have a prototype that I have tested on a small toy project. At the moment, the function looks like this:

add_reflex_target(
    TARGET <target_name>
    LIBRARY_TYPE <whataever add_library accepts as type>
    FILES <list of reflex source files>
    INCLUDE_DIRECTORIES <list of public include directories>
    DEPENDENCY_TARGETS <list of targets to put inside target_link_libraries(<target_name> PUBLIC )>
)

Here is a usage example:

cmake_minimum_required(VERSION 3.20)
project(monkeylang)

set(CMAKE_CXX_STANDARD 20)

find_package(Reflex REQUIRED)

list(APPEND CMAKE_MODULE_PATH ${CMAKE_CURRENT_SOURCE_DIR}/cmake)
include(ReflexCMakeSupport)

add_reflex_target(
    TARGET lexer
    LIBRARY_TYPE SHARED
    FILES "reflex_input/lex.reflex"
    INCLUDE_DIRECTORIES include # provides token headers which are shared with parser
)

add_executable(app main.cpp)
target_link_libraries(app PRIVATE lexer)

The headers for each .l file will be generated inside CMAKE_CURRENT_BINARY_DIR/${_TARGET}/include/${_TARGET}, so anybody who links to the created target could use it like this (assuming lex.l input and lexer as target name):

#include <lexer/lex.hpp>

To incorporate the work into a PR I thought about applying the cmake script inside example, but I am unsure what targets I could create there. Could you please advise on a set of targets I should create inside examples directory? This would also serve second purpose for testing the script as well.

genivia-inc commented 3 months ago

Thank you for the update.

Target examples you could pick might be a mix of lexers and C++ applications

It's up to you. Thanks.