From f56035efbb6b5033639f118890d21f7e5f8aa03e Mon Sep 17 00:00:00 2001 From: Fuwn Date: Thu, 3 Feb 2022 10:54:07 +0000 Subject: chore: migrate to cmkr --- .gitignore | 1 + CMakeLists.txt | 127 ++++++++++++++++++++++++++++- cmake.toml | 29 +++++++ cmake/cmkr/cmkr.cmake | 222 ++++++++++++++++++++++++++++++++++++++++++++++++++ viv/CMakeLists.txt | 52 ------------ 5 files changed, 377 insertions(+), 54 deletions(-) create mode 100644 cmake.toml create mode 100644 cmake/cmkr/cmkr.cmake delete mode 100644 viv/CMakeLists.txt diff --git a/.gitignore b/.gitignore index d8dd2f5..923c104 100644 --- a/.gitignore +++ b/.gitignore @@ -3,3 +3,4 @@ # CMake /cmake-build-* +/build/ diff --git a/CMakeLists.txt b/CMakeLists.txt index ada4a13..0d42959 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -1,4 +1,127 @@ +# This file is automatically generated from cmake.toml - DO NOT EDIT +# See https://github.com/build-cpp/cmkr for more information + cmake_minimum_required(VERSION 3.13.4) -project(viv C) -add_subdirectory(${PROJECT_NAME}) \ No newline at end of file +if(CMAKE_SOURCE_DIR STREQUAL CMAKE_BINARY_DIR) + message(FATAL_ERROR "In-tree builds are not supported. Run CMake from a separate directory: cmake -B build") +endif() + +# Regenerate CMakeLists.txt automatically in the root project +set(CMKR_ROOT_PROJECT OFF) +if(CMAKE_CURRENT_SOURCE_DIR STREQUAL CMAKE_SOURCE_DIR) + set(CMKR_ROOT_PROJECT ON) + + # Bootstrap cmkr + include("cmake/cmkr/cmkr.cmake" OPTIONAL RESULT_VARIABLE CMKR_INCLUDE_RESULT) + if(CMKR_INCLUDE_RESULT) + cmkr() + endif() + + # Enable folder support + set_property(GLOBAL PROPERTY USE_FOLDERS ON) +endif() + +# Create a configure-time dependency on cmake.toml to improve IDE support +if(CMKR_ROOT_PROJECT) + configure_file(cmake.toml cmake.toml COPYONLY) +endif() + +project(viv + LANGUAGES + C + VERSION + 0.1.0 +) + +# Packages +find_package(OpenSSL REQUIRED) + +find_package(Curses REQUIRED) + +# Target viv +set(CMKR_TARGET viv) +set(viv_SOURCES "") + +list(APPEND viv_SOURCES + "viv/cli.c" + "viv/dynamic_array.c" + "viv/flag.c" + "viv/gemini.c" + "viv/log.c" + "viv/ssl.c" + "viv/ui.c" + "viv/viv.c" +) + +list(APPEND viv_SOURCES + cmake.toml +) + +set(CMKR_SOURCES ${viv_SOURCES}) +add_executable(viv) + +if(viv_SOURCES) + target_sources(viv PRIVATE ${viv_SOURCES}) +endif() + +get_directory_property(CMKR_VS_STARTUP_PROJECT DIRECTORY ${PROJECT_SOURCE_DIR} DEFINITION VS_STARTUP_PROJECT) +if(NOT CMKR_VS_STARTUP_PROJECT) + set_property(DIRECTORY ${PROJECT_SOURCE_DIR} PROPERTY VS_STARTUP_PROJECT viv) +endif() + +source_group(TREE ${CMAKE_CURRENT_SOURCE_DIR} FILES ${viv_SOURCES}) + +target_compile_options(viv PRIVATE + -std=c99 + -Wall + -Wextra + -Werror=pedantic + -Wno-unused-function + -Wpedantic + -pedantic-errors + -march=native + -D_XOPEN_SOURCE=500 +) + +target_include_directories(viv PRIVATE + "include/" +) + +if(CURSES_FOUND AND CURSES_HAVE_NCURSES_H) # curses + target_include_directories(viv PRIVATE + ncurses + menu + ) +endif() + +target_link_libraries(viv PRIVATE + OpenSSL::SSL + OpenSSL::Crypto +) + +if(CURSES_FOUND AND CURSES_HAVE_NCURSES_H) # curses + target_link_libraries(viv PRIVATE + ncurses + menu + ) +endif() + +target_link_options(viv PRIVATE + -fsanitize=address +) + +set_target_properties(viv PROPERTIES + CMAKE_C_STANDARD_REQUIRED + ON + CMAKE_C_STANDARD + 99 + CMAKE_C_EXTENSIONS + OFF + CURSES_NEED_NCURSES + ON +) + +unset(CMKR_TARGET) +unset(CMKR_SOURCES) + diff --git a/cmake.toml b/cmake.toml new file mode 100644 index 0000000..26c693a --- /dev/null +++ b/cmake.toml @@ -0,0 +1,29 @@ +# Reference: https://build-cpp.github.io/cmkr/cmake-toml + +[cmake] +version = "3.13.4" +cmkr-include = "cmake/cmkr/cmkr.cmake" + +[project] +name = "viv" +version = "0.1.0" +description = "" +languages = ["C"] + +[conditions] +curses = "CURSES_FOUND AND CURSES_HAVE_NCURSES_H" + +[find-package] +OpenSSL = { required = true } +Curses = { required = true } + +[target.viv] +type = "executable" +sources = ["viv/*.c"] +private-include-directories = ["include/"] +properties = { CMAKE_C_STANDARD_REQUIRED = true, CMAKE_C_STANDARD = "99", CMAKE_C_EXTENSIONS = false, CURSES_NEED_NCURSES = true } +compile-options = ["-std=c99", "-Wall", "-Wextra", "-Werror=pedantic", "-Wno-unused-function", "-Wpedantic", "-pedantic-errors", "-march=native", "-D_XOPEN_SOURCE=500"] # -03, -fsanitize=address +link-options = ["-fsanitize=address"] +link-libraries = ["OpenSSL::SSL", "OpenSSL::Crypto"] +curses.private-include-directories = ["ncurses", "menu"] +curses.private-link-libraries = ["ncurses", "menu"] diff --git a/cmake/cmkr/cmkr.cmake b/cmake/cmkr/cmkr.cmake new file mode 100644 index 0000000..e61bf99 --- /dev/null +++ b/cmake/cmkr/cmkr.cmake @@ -0,0 +1,222 @@ +include_guard() + +# Change these defaults to point to your infrastructure if desired +set(CMKR_REPO "https://github.com/build-cpp/cmkr" CACHE STRING "cmkr git repository" FORCE) +set(CMKR_TAG "v0.2.7" CACHE STRING "cmkr git tag (this needs to be available forever)" FORCE) + +# To bootstrap/generate a cmkr project: cmake -P cmkr.cmake +if(CMAKE_SCRIPT_MODE_FILE) + set(CMAKE_BINARY_DIR "${CMAKE_BINARY_DIR}/build") + set(CMAKE_CURRENT_BINARY_DIR "${CMAKE_BINARY_DIR}") + file(MAKE_DIRECTORY "${CMAKE_BINARY_DIR}") +endif() + +# Set these from the command line to customize for development/debugging purposes +set(CMKR_EXECUTABLE "" CACHE FILEPATH "cmkr executable") +set(CMKR_SKIP_GENERATION OFF CACHE BOOL "skip automatic cmkr generation") +set(CMKR_BUILD_TYPE "Debug" CACHE STRING "cmkr build configuration") + +# Disable cmkr if generation is disabled +if(DEFINED ENV{CI} OR CMKR_SKIP_GENERATION OR CMKR_BUILD_SKIP_GENERATION) + message(STATUS "[cmkr] Skipping automatic cmkr generation") + unset(CMKR_BUILD_SKIP_GENERATION CACHE) + macro(cmkr) + endmacro() + return() +endif() + +# Disable cmkr if no cmake.toml file is found +if(NOT CMAKE_SCRIPT_MODE_FILE AND NOT EXISTS "${CMAKE_CURRENT_SOURCE_DIR}/cmake.toml") + message(AUTHOR_WARNING "[cmkr] Not found: ${CMAKE_CURRENT_SOURCE_DIR}/cmake.toml") + macro(cmkr) + endmacro() + return() +endif() + +# Convert a Windows native path to CMake path +if(CMKR_EXECUTABLE MATCHES "\\\\") + string(REPLACE "\\" "/" CMKR_EXECUTABLE_CMAKE "${CMKR_EXECUTABLE}") + set(CMKR_EXECUTABLE "${CMKR_EXECUTABLE_CMAKE}" CACHE FILEPATH "" FORCE) + unset(CMKR_EXECUTABLE_CMAKE) +endif() + +# Helper macro to execute a process (COMMAND_ERROR_IS_FATAL ANY is 3.19 and higher) +function(cmkr_exec) + execute_process(COMMAND ${ARGV} RESULT_VARIABLE CMKR_EXEC_RESULT) + if(NOT CMKR_EXEC_RESULT EQUAL 0) + message(FATAL_ERROR "cmkr_exec(${ARGV}) failed (exit code ${CMKR_EXEC_RESULT})") + endif() +endfunction() + +# Windows-specific hack (CMAKE_EXECUTABLE_PREFIX is not set at the moment) +if(WIN32) + set(CMKR_EXECUTABLE_NAME "cmkr.exe") +else() + set(CMKR_EXECUTABLE_NAME "cmkr") +endif() + +# Use cached cmkr if found +if(DEFINED ENV{CMKR_CACHE} AND EXISTS "$ENV{CMKR_CACHE}") + set(CMKR_DIRECTORY_PREFIX "$ENV{CMKR_CACHE}") + string(REPLACE "\\" "/" CMKR_DIRECTORY_PREFIX "${CMKR_DIRECTORY_PREFIX}") + if(NOT CMKR_DIRECTORY_PREFIX MATCHES "\\/$") + set(CMKR_DIRECTORY_PREFIX "${CMKR_DIRECTORY_PREFIX}/") + endif() +else() + set(CMKR_DIRECTORY_PREFIX "${CMAKE_CURRENT_BINARY_DIR}/_cmkr_") +endif() +set(CMKR_DIRECTORY "${CMKR_DIRECTORY_PREFIX}${CMKR_TAG}") +set(CMKR_CACHED_EXECUTABLE "${CMKR_DIRECTORY}/bin/${CMKR_EXECUTABLE_NAME}") + +# Handle upgrading logic +if(CMKR_EXECUTABLE AND NOT CMKR_CACHED_EXECUTABLE STREQUAL CMKR_EXECUTABLE) + if(CMKR_EXECUTABLE MATCHES "^${CMAKE_CURRENT_BINARY_DIR}/_cmkr") + if(DEFINED ENV{CMKR_CACHE} AND EXISTS "$ENV{CMKR_CACHE}") + message(AUTHOR_WARNING "[cmkr] Switching to cached cmkr: '${CMKR_CACHED_EXECUTABLE}'") + if(EXISTS "${CMKR_CACHED_EXECUTABLE}") + set(CMKR_EXECUTABLE "${CMKR_CACHED_EXECUTABLE}" CACHE FILEPATH "Full path to cmkr executable" FORCE) + else() + unset(CMKR_EXECUTABLE CACHE) + endif() + else() + message(AUTHOR_WARNING "[cmkr] Upgrading '${CMKR_EXECUTABLE}' to '${CMKR_CACHED_EXECUTABLE}'") + unset(CMKR_EXECUTABLE CACHE) + endif() + elseif(DEFINED ENV{CMKR_CACHE} AND EXISTS "$ENV{CMKR_CACHE}" AND CMKR_EXECUTABLE MATCHES "^${CMKR_DIRECTORY_PREFIX}") + message(AUTHOR_WARNING "[cmkr] Upgrading cached '${CMKR_EXECUTABLE}' to '${CMKR_CACHED_EXECUTABLE}'") + unset(CMKR_EXECUTABLE CACHE) + endif() +endif() + +if(CMKR_EXECUTABLE AND EXISTS "${CMKR_EXECUTABLE}") + message(VERBOSE "[cmkr] Found cmkr: '${CMKR_EXECUTABLE}'") +elseif(CMKR_EXECUTABLE AND NOT CMKR_EXECUTABLE STREQUAL CMKR_CACHED_EXECUTABLE) + message(FATAL_ERROR "[cmkr] '${CMKR_EXECUTABLE}' not found") +elseif(NOT CMKR_EXECUTABLE AND EXISTS "${CMKR_CACHED_EXECUTABLE}") + set(CMKR_EXECUTABLE "${CMKR_CACHED_EXECUTABLE}" CACHE FILEPATH "Full path to cmkr executable" FORCE) + message(STATUS "[cmkr] Found cached cmkr: '${CMKR_EXECUTABLE}'") +else() + set(CMKR_EXECUTABLE "${CMKR_CACHED_EXECUTABLE}" CACHE FILEPATH "Full path to cmkr executable" FORCE) + message(VERBOSE "[cmkr] Bootstrapping '${CMKR_EXECUTABLE}'") + + message(STATUS "[cmkr] Fetching cmkr...") + if(EXISTS "${CMKR_DIRECTORY}") + cmkr_exec("${CMAKE_COMMAND}" -E rm -rf "${CMKR_DIRECTORY}") + endif() + find_package(Git QUIET REQUIRED) + cmkr_exec("${GIT_EXECUTABLE}" + clone + --config advice.detachedHead=false + --branch ${CMKR_TAG} + --depth 1 + ${CMKR_REPO} + "${CMKR_DIRECTORY}" + ) + message(STATUS "[cmkr] Building cmkr (using system compiler)...") + cmkr_exec("${CMAKE_COMMAND}" + --no-warn-unused-cli + "${CMKR_DIRECTORY}" + "-B${CMKR_DIRECTORY}/build" + "-DCMAKE_BUILD_TYPE=${CMKR_BUILD_TYPE}" + "-DCMAKE_UNITY_BUILD=ON" + "-DCMAKE_INSTALL_PREFIX=${CMKR_DIRECTORY}" + "-DCMKR_GENERATE_DOCUMENTATION=OFF" + ) + cmkr_exec("${CMAKE_COMMAND}" + --build "${CMKR_DIRECTORY}/build" + --config "${CMKR_BUILD_TYPE}" + --parallel + ) + cmkr_exec("${CMAKE_COMMAND}" + --install "${CMKR_DIRECTORY}/build" + --config "${CMKR_BUILD_TYPE}" + --prefix "${CMKR_DIRECTORY}" + --component cmkr + ) + if(NOT EXISTS ${CMKR_EXECUTABLE}) + message(FATAL_ERROR "[cmkr] Failed to bootstrap '${CMKR_EXECUTABLE}'") + endif() + cmkr_exec("${CMKR_EXECUTABLE}" version) + message(STATUS "[cmkr] Bootstrapped ${CMKR_EXECUTABLE}") +endif() +execute_process(COMMAND "${CMKR_EXECUTABLE}" version + RESULT_VARIABLE CMKR_EXEC_RESULT + ) +if(NOT CMKR_EXEC_RESULT EQUAL 0) + message(FATAL_ERROR "[cmkr] Failed to get version, try clearing the cache and rebuilding") +endif() + +# Use cmkr.cmake as a script +if(CMAKE_SCRIPT_MODE_FILE) + if(NOT EXISTS "${CMAKE_SOURCE_DIR}/cmake.toml") + execute_process(COMMAND "${CMKR_EXECUTABLE}" init + RESULT_VARIABLE CMKR_EXEC_RESULT + ) + if(NOT CMKR_EXEC_RESULT EQUAL 0) + message(FATAL_ERROR "[cmkr] Failed to bootstrap cmkr project. Please report an issue: https://github.com/build-cpp/cmkr/issues/new") + else() + message(STATUS "[cmkr] Modify cmake.toml and then configure using: cmake -B build") + endif() + else() + execute_process(COMMAND "${CMKR_EXECUTABLE}" gen + RESULT_VARIABLE CMKR_EXEC_RESULT + ) + if(NOT CMKR_EXEC_RESULT EQUAL 0) + message(FATAL_ERROR "[cmkr] Failed to generate project.") + else() + message(STATUS "[cmkr] Configure using: cmake -B build") + endif() + endif() +endif() + +# This is the macro that contains black magic +macro(cmkr) + # When this macro is called from the generated file, fake some internal CMake variables + get_source_file_property(CMKR_CURRENT_LIST_FILE "${CMAKE_CURRENT_LIST_FILE}" CMKR_CURRENT_LIST_FILE) + if(CMKR_CURRENT_LIST_FILE) + set(CMAKE_CURRENT_LIST_FILE "${CMKR_CURRENT_LIST_FILE}") + get_filename_component(CMAKE_CURRENT_LIST_DIR "${CMAKE_CURRENT_LIST_FILE}" DIRECTORY) + endif() + + # File-based include guard (include_guard is not documented to work) + get_source_file_property(CMKR_INCLUDE_GUARD "${CMAKE_CURRENT_LIST_FILE}" CMKR_INCLUDE_GUARD) + if(NOT CMKR_INCLUDE_GUARD) + set_source_files_properties("${CMAKE_CURRENT_LIST_FILE}" PROPERTIES CMKR_INCLUDE_GUARD TRUE) + + file(SHA256 "${CMAKE_CURRENT_LIST_FILE}" CMKR_LIST_FILE_SHA256_PRE) + + # Generate CMakeLists.txt + cmkr_exec("${CMKR_EXECUTABLE}" gen + WORKING_DIRECTORY "${CMAKE_CURRENT_SOURCE_DIR}" + ) + + file(SHA256 "${CMAKE_CURRENT_LIST_FILE}" CMKR_LIST_FILE_SHA256_POST) + + # Delete the temporary file if it was left for some reason + set(CMKR_TEMP_FILE "${CMAKE_CURRENT_SOURCE_DIR}/CMakerLists.txt") + if(EXISTS "${CMKR_TEMP_FILE}") + file(REMOVE "${CMKR_TEMP_FILE}") + endif() + + if(NOT CMKR_LIST_FILE_SHA256_PRE STREQUAL CMKR_LIST_FILE_SHA256_POST) + # Copy the now-generated CMakeLists.txt to CMakerLists.txt + # This is done because you cannot include() a file you are currently in + configure_file(CMakeLists.txt "${CMKR_TEMP_FILE}" COPYONLY) + + # Add the macro required for the hack at the start of the cmkr macro + set_source_files_properties("${CMKR_TEMP_FILE}" PROPERTIES + CMKR_CURRENT_LIST_FILE "${CMAKE_CURRENT_LIST_FILE}" + ) + + # 'Execute' the newly-generated CMakeLists.txt + include("${CMKR_TEMP_FILE}") + + # Delete the generated file + file(REMOVE "${CMKR_TEMP_FILE}") + + # Do not execute the rest of the original CMakeLists.txt + return() + endif() + # Resume executing the unmodified CMakeLists.txt + endif() +endmacro() diff --git a/viv/CMakeLists.txt b/viv/CMakeLists.txt deleted file mode 100644 index 9b5f05c..0000000 --- a/viv/CMakeLists.txt +++ /dev/null @@ -1,52 +0,0 @@ -add_executable(${PROJECT_NAME} - cli.c - dynamic_array.c - gemini.c - flag.c - log.c - ssl.c - ui.c - viv.c -) - -target_include_directories(${PROJECT_NAME} PRIVATE ${PROJECT_SOURCE_DIR}/include) - -set_target_properties(${PROJECT_NAME} PROPERTIES - CMAKE_C_STANDARD_REQUIRED ON - CMAKE_C_STANDARD 99 - CMAKE_C_EXTENSIONS OFF -) - -target_compile_options(${PROJECT_NAME} PUBLIC - -std=c99 - -Wall - -Wextra - -Werror=pedantic - -Wno-unused-function - -Wpedantic - -pedantic-errors - -march=native - # -03 - -D_XOPEN_SOURCE=500 - # -fsanitize=address -) -# target_link_options(${PROJECT_NAME} PUBLIC -fsanitize=address) - -find_package(OpenSSL REQUIRED) -target_link_libraries(${PROJECT_NAME} PRIVATE - OpenSSL::SSL - OpenSSL::Crypto -) - -set(CURSES_NEED_NCURSES ON) -find_package(Curses REQUIRED) -if (CURSES_FOUND AND CURSES_HAVE_NCURSES_H) - target_include_directories(${PROJECT_NAME} PRIVATE - ncurses - menu - ) - target_link_libraries(${PROJECT_NAME} PRIVATE - ncurses - menu - ) -endif () -- cgit v1.2.3