commit 6c8af05fbea510d6c0c96f9fd2f541e5aa97140f Author: Lephenixnoir Date: Thu Jan 28 17:29:39 2021 +0100 base library and build system diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..fa06e14 --- /dev/null +++ b/.gitignore @@ -0,0 +1,3 @@ +# Build files +build-fx +build-cg diff --git a/CMakeLists.txt b/CMakeLists.txt new file mode 100644 index 0000000..3dd0328 --- /dev/null +++ b/CMakeLists.txt @@ -0,0 +1,46 @@ +# libexample: build system + +cmake_minimum_required(VERSION 3.18) +project(libexample VERSION 1.0 LANGUAGES C) + +# Libraries that libexample depends on +find_package(Gint 2.1 REQUIRED) + +# Turn include/example/config.h.in into a proper config.h where the @VAR@ have +# been replaced; this is how version numbers are maintained. libexample_VERSION +# is set to "1.0" by the project() command. +# Note that the input (config.h.in) is relative to the source dir, but the +# output (config.h) is in the build dir, so it doesn't pollute the Git repo. +configure_file(include/example/config.h.in include/example/config.h) + +# Target name is "example", output file is "libexample.a" (by default) +add_library(example STATIC src/add.c src/version.c) + +# Find headers in the following directories: +# -> The include subfolder of the source +# -> The include subfolder of the build files (for config.h) +# PUBLIC means that users of this library will also look here, but there are no +# users in the current project, so it doesn't matter. (The actual flags for +# library users are in FindLibExample.cmake.) +target_include_directories(example PUBLIC + "${CMAKE_CURRENT_SOURCE_DIR}/include" + "${CMAKE_CURRENT_BINARY_DIR}/include") + +# After building, install the target (that is, libexample.a) in the compiler +install(TARGETS example + DESTINATION "${FXSDK_COMPILER_INSTALL}") + +# Also install the headers (our include folder gets merged with the existing +# one in the compiler's install folder). Only install files matching *.h to +# exclude config.h.in. +install(DIRECTORY "${CMAKE_CURRENT_SOURCE_DIR}/include" + DESTINATION "${FXSDK_COMPILER_INSTALL}" + FILES_MATCHING PATTERN "*.h") + +# Install config.h from the build dir +install(FILES "${CMAKE_CURRENT_BINARY_DIR}/include/example/config.h" + DESTINATION "${FXSDK_COMPILER_INSTALL}/include/example") + +# Install FindLibExample.cmake so that users can do find_package(LibExample) +install(FILES cmake/FindLibExample.cmake + DESTINATION "${FXSDK_CMAKE_MODULE_PATH}") diff --git a/cmake/FindLibExample.cmake b/cmake/FindLibExample.cmake new file mode 100644 index 0000000..dd4c4f3 --- /dev/null +++ b/cmake/FindLibExample.cmake @@ -0,0 +1,44 @@ +# Find libexample.a; if we had platform-specific versions we could look for +# libexample-${FXSDK_PLATFORM}.a instead. +execute_process( + COMMAND ${CMAKE_C_COMPILER} -print-file-name=libexample.a + OUTPUT_VARIABLE EX_PATH OUTPUT_STRIP_TRAILING_WHITESPACE) + +# EX_PATH is now the full path if libexample.a exists, "libexample.a" otherwise +if(NOT "${EX_PATH}" STREQUAL "libexample.a") + # Find the version.h header + execute_process( + COMMAND ${CMAKE_C_COMPILER} -print-file-name=include/example/config.h + OUTPUT_VARIABLE EX_CONFIG OUTPUT_STRIP_TRAILING_WHITESPACE) + # Extract version information from the config.h header. This command prints + # the version on the line matching the regex and deletes every other line. + execute_process( + COMMAND sed -E "s/#define.*EX_VERSION\\s+\"(\\S+)\"$/\\1/p; d" ${EX_CONFIG} + OUTPUT_VARIABLE EX_VERSION OUTPUT_STRIP_TRAILING_WHITESPACE) +endif() + +# This CMake utility will handle the version comparisons and other checks. We +# just specify: +# -> Some variables that are defined only if the library is found (so if +# they're undefined, CMake will conclude libexample was not found) +# -> The version, so CMake can compare with the user's requested one +include(FindPackageHandleStandardArgs) + +find_package_handle_standard_args(LibExample + REQUIRED_VARS EX_CONFIG EX_VERSION + VERSION_VAR EX_VERSION) + +# We now have a LibExample_FOUND variable, let's create the target that users +# can link against with target_link_libraries() +if(LibExample_FOUND) + # This is an imported target, we don't build it, we just claim it's here + add_library(LibExample::LibExample UNKNOWN IMPORTED) + # Here's we declare the compiler and linker flags that every user of + # LibExample have to use to work with us + set_target_properties(LibExample::LibExample PROPERTIES + # If we specify where the library comes from, CMake will watch that file + # and relink any user application when the library is updated! + IMPORTED_LOCATION "${EX_PATH}" + # Linking options + INTERFACE_LINK_OPTIONS -lexample) +endif() diff --git a/include/example/add.h b/include/example/add.h new file mode 100644 index 0000000..8edd80f --- /dev/null +++ b/include/example/add.h @@ -0,0 +1,16 @@ +/* libexample: add utilities */ + +#ifndef _EXAMPLE_ADD +#define _EXAMPLE_ADD + +#ifdef __cplusplus +extern "C" { +#endif + +int ex_add(int x, int y); + +#ifdef __cplusplus +} +#endif + +#endif /* _EXAMPLE_ADD */ diff --git a/include/example/config.h.in b/include/example/config.h.in new file mode 100644 index 0000000..4a9ab02 --- /dev/null +++ b/include/example/config.h.in @@ -0,0 +1,9 @@ +/* libexample: compile-time configuration */ + +#ifndef _EXAMPLE_CONFIG +#define _EXAMPLE_CONFIG + +/* The @VAR@ notation is substituted by CMake */ +#define EX_VERSION "@libexample_VERSION@" + +#endif /* _EXAMPLE_CONFIG */ diff --git a/include/example/version.h b/include/example/version.h new file mode 100644 index 0000000..c140ec3 --- /dev/null +++ b/include/example/version.h @@ -0,0 +1,24 @@ +/* libexample: version information */ + +#ifndef _EXAMPLE_VERSION +#define _EXAMPLE_VERSION + +#ifdef __cplusplus +extern "C" { +#endif + +#include + +/* Version of the example library */ +char const *ex_version(void); +uint32_t ex_hash(void); + +/* Version of gint used in this library */ +char const *ex_gint_version(void); +uint32_t ex_gint_hash(void); + +#ifdef __cplusplus +} +#endif + +#endif /* _EXAMPLE_VERSION */ diff --git a/src/add.c b/src/add.c new file mode 100644 index 0000000..aa5cdd6 --- /dev/null +++ b/src/add.c @@ -0,0 +1,6 @@ +#include + +int ex_add(int x, int y) +{ + return x + y; +} diff --git a/src/version.c b/src/version.c new file mode 100644 index 0000000..74f7736 --- /dev/null +++ b/src/version.c @@ -0,0 +1,18 @@ +#include +#include +#include + +char const *ex_version(void) +{ + return EX_VERSION; +} + +char const *ex_gint_version(void) +{ + return GINT_VERSION; +} + +uint32_t ex_gint_hash(void) +{ + return GINT_HASH; +}