From 08b3dcd745a845e847ae9657da61c7b56947fa14 Mon Sep 17 00:00:00 2001
From: Anonymous Maarten <[EMAIL REDACTED]>
Date: Tue, 22 Nov 2022 21:02:20 +0100
Subject: [PATCH] cmake: find lemon and re2c using CMake module + build lemon
as subproject
---
CMakeLists.txt | 74 +++++++++++++++++++++++++++++++-------------
cmake/Findre2c.cmake | 19 ++++++++++++
lemon/CMakeLists.txt | 14 +++++++++
3 files changed, 86 insertions(+), 21 deletions(-)
create mode 100644 cmake/Findre2c.cmake
create mode 100644 lemon/CMakeLists.txt
diff --git a/CMakeLists.txt b/CMakeLists.txt
index 3df126e..2975cbf 100644
--- a/CMakeLists.txt
+++ b/CMakeLists.txt
@@ -1,33 +1,67 @@
-CMAKE_MINIMUM_REQUIRED(VERSION 3.16)
-PROJECT(SDL_shader_tools)
+cmake_minimum_required(VERSION 3.16)
+project(SDL_shader_tools LANGUAGES C)
+
+list(APPEND CMAKE_MODULE_PATH "${CMAKE_CURRENT_LIST_DIR}/cmake")
+
+include(ExternalProject)
+
+if(CMAKE_CROSSCOMPILING)
+ set(BUILD_CMAKE_TOOLCHAIN_FILE "" CACHE FILEPATH "CMake toolchain file for build machine")
+ if(NOT BUILD_CMAKE_TOOLCHAIN_FILE)
+ message(FATAL_ERROR "When cross compiling, need a CMake toolchain file for the build machine in BUILD_CMAKE_TOOLCHAIN_FILE")
+ endif()
+endif()
find_package(SDL2 REQUIRED)
+find_package(re2c)
-find_program(RE2C re2c DOC "Path to re2c command line app: https://re2c.org/")
-if(NOT RE2C)
+if(NOT TARGET SDL2::SDL2)
+ find_library(SDL2_LIBRARY NAMES SDL2 SDL2-static)
+ add_library(SDL2::SDL2 UNKNOWN IMPORTED)
+ set_target_properties(SDL2::SDL2 PROPERTIES IMPORTED_LOCATION "${SDL2_LIBRARY}")
+ set_target_properties(SDL2::SDL2 PROPERTIES INTERFACE_INCLUDE_DIRS "${SDL2_INCLUDE_DIRS};${SDL2_INCLUDE_DIR}")
+endif()
+
+if(NOT re2c_FOUND)
message(STATUS "re2c missing. You can go on, but can't rebuild the lexer.")
else()
- mark_as_advanced(RE2C)
add_custom_command(
OUTPUT "${CMAKE_CURRENT_SOURCE_DIR}/SDL_shader_lexer.c"
DEPENDS SDL_shader_lexer.re
- COMMAND "${RE2C}"
- ARGS -is --no-generation-date -o "${CMAKE_CURRENT_SOURCE_DIR}/SDL_shader_lexer.c" "${CMAKE_CURRENT_SOURCE_DIR}/SDL_shader_lexer.re"
+ COMMAND re2c::re2c ARGS -is --no-generation-date -o "${CMAKE_CURRENT_SOURCE_DIR}/SDL_shader_lexer.c" "${CMAKE_CURRENT_SOURCE_DIR}/SDL_shader_lexer.re"
)
endif()
-# We build lemon, then use it to generate parser C code.
-# !!! FIXME: this needs to build for the current platform if cross-compiling.
-add_executable(lemon "lemon/lemon.c")
+# lemon contains SDL_shader_tools-specific hacks
+if(CMAKE_CROSSCOMPILING)
+ ExternalProject_Add(lemon
+ SOURCE_DIR "${PROJECT_SOURCE_DIR}/lemon"
+ BINARY_DIR "${PROJECT_BINARY_DIR}/lemon"
+ PREFIX "${PROJECT_BINARY_DIR}/lemon"
+ CMAKE_ARGS
+ "-DCMAKE_BUILD_TYPE:STRING=Release"
+ "-DCMAKE_TOOLCHAIN_FILE:FILEPATH=${BUILD_CMAKE_TOOLCHAIN_FILE}"
+ "-DLEMON_INSTALL:BOOL=ON"
+ "-DCMAKE_INSTALL_PREFIX:PATH=${PROJECT_BINARY_DIR}/lemon/prefix"
+ BUILD_ALWAYS 1
+ STEP_TARGETS install
+ )
+ add_executable(lemon::lemon IMPORTED)
+ set_target_properties(lemon::lemon PROPERTIES IMPORTED_LOCATION "${PROJECT_BINARY_DIR}/lemon/prefix/bin/lemon")
+ add_dependencies(lemon::lemon lemon-install)
+else()
+ add_subdirectory(lemon EXCLUDE_FROM_ALL)
+endif()
+
add_custom_command(
OUTPUT "${CMAKE_CURRENT_SOURCE_DIR}/SDL_shader_parser.h"
MAIN_DEPENDENCY "${CMAKE_CURRENT_SOURCE_DIR}/SDL_shader_parser.lemon"
- DEPENDS lemon "${CMAKE_CURRENT_SOURCE_DIR}/lemon/lempar.c"
- COMMAND lemon
- ARGS -q "-T${CMAKE_CURRENT_SOURCE_DIR}/lemon/lempar.c" "${CMAKE_CURRENT_SOURCE_DIR}/SDL_shader_parser.lemon"
+ DEPENDS "${CMAKE_CURRENT_SOURCE_DIR}/lemon/lempar.c"
+ COMMAND lemon::lemon ARGS -q "-T${CMAKE_CURRENT_SOURCE_DIR}/lemon/lempar.c" "${CMAKE_CURRENT_SOURCE_DIR}/SDL_shader_parser.lemon"
)
add_executable(sdl-shader-compiler
+ "${CMAKE_CURRENT_SOURCE_DIR}/SDL_shader_parser.h"
utils/sdl-shader-compiler.c
SDL_shader_common.c
SDL_shader_lexer.c
@@ -35,17 +69,15 @@ add_executable(sdl-shader-compiler
SDL_shader_ast.c
SDL_shader_compiler.c
)
+target_include_directories(sdl-shader-compiler PRIVATE "${CMAKE_CURRENT_SOURCE_DIR}")
+target_link_libraries(sdl-shader-compiler PRIVATE SDL2::SDL2)
target_include_directories(sdl-shader-compiler PRIVATE ${SDL2_INCLUDE_DIRS} ${SDL2_INCLUDE_DIR})
-target_include_directories(sdl-shader-compiler PRIVATE ${CMAKE_CURRENT_SOURCE_DIR})
-target_link_libraries(sdl-shader-compiler ${SDL2_LIBRARIES} ${SDL2_LIBRARY})
-
-SET_SOURCE_FILES_PROPERTIES(SDL_shader_ast.c PROPERTIES OBJECT_DEPENDS "${CMAKE_CURRENT_SOURCE_DIR}/SDL_shader_parser.h")
+target_compile_definitions(sdl-shader-compiler PRIVATE SDL_MAIN_HANDLED)
add_executable(sdl-shader-bytecode-dumper
utils/sdl-shader-bytecode-dumper.c
)
-target_include_directories(sdl-shader-bytecode-dumper PRIVATE ${CMAKE_CURRENT_SOURCE_DIR})
+target_include_directories(sdl-shader-bytecode-dumper PRIVATE "${CMAKE_CURRENT_SOURCE_DIR}")
+target_link_libraries(sdl-shader-bytecode-dumper PRIVATE SDL2::SDL2)
target_include_directories(sdl-shader-bytecode-dumper PRIVATE ${SDL2_INCLUDE_DIRS} ${SDL2_INCLUDE_DIR})
-
-# end of CMakeLists.txt ...
-
+target_compile_definitions(sdl-shader-bytecode-dumper PRIVATE SDL_MAIN_HANDLED)
diff --git a/cmake/Findre2c.cmake b/cmake/Findre2c.cmake
new file mode 100644
index 0000000..af4599b
--- /dev/null
+++ b/cmake/Findre2c.cmake
@@ -0,0 +1,19 @@
+find_program(RE2C_BINARY
+ NAMES re2c
+ DOC "Path to re2c command line app: https://re2c.org/"
+)
+
+include(FindPackageHandleStandardArgs)
+find_package_handle_standard_args(re2c
+ FOUND_VAR re2c_FOUND
+ REQUIRED_VARS RE2C_BINARY
+)
+
+if(re2c_FOUND)
+ if(NOT TARGET re2c::re2c)
+ add_executable(re2c::re2c IMPORTED)
+ set_property(TARGET re2c::re2c PROPERTY IMPORTED_LOCATION "${RE2C_BINARY}")
+ endif()
+endif()
+
+mark_as_advanced(RE2C_BINARY)
diff --git a/lemon/CMakeLists.txt b/lemon/CMakeLists.txt
new file mode 100644
index 0000000..d6289b1
--- /dev/null
+++ b/lemon/CMakeLists.txt
@@ -0,0 +1,14 @@
+cmake_minimum_required(VERSION 3.16)
+project(lemon LANGUAGES C)
+
+option(LEMON_INSTALL "Install lemon")
+
+add_executable(lemon lemon.c)
+add_executable(lemon::lemon ALIAS lemon)
+
+if(LEMON_INSTALL)
+ include(GNUInstallDirs)
+ install(TARGETS lemon
+ RUNTIME DESTINATION "${CMAKE_INSTALL_BINDIR}"
+ )
+endif()