Compare commits

...

1 Commits

Author SHA1 Message Date
Lephenixnoir c34bd65859
update tutorial and CMake files for fxSDK 2.9 2022-08-21 10:09:59 +02:00
4 changed files with 61 additions and 60 deletions

1
.gitignore vendored
View File

@ -4,4 +4,3 @@ build-cg
# GiteaPC support
giteapc-config.make
giteapc-config-*.make

View File

@ -13,34 +13,41 @@ find_package(Gint 2.1 REQUIRED)
# 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)
# With the target name "example", the output file will be called "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.)
# This doesn't affect add-ins that *use* the library; flags for these are set
# 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
# After building, install the target (that is, libexample.a) in the fxSDK's
# sysroot which contains libraries for the calculator.
install(TARGETS example
DESTINATION "${FXSDK_COMPILER_INSTALL}")
DESTINATION "${FXSDK_LIB}")
# 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}"
# Install the headers. The contents of our include folder are added to the
# fxSDK's sysroot folder for headers. Since our headers are in an "example"
# subfolder, they will end up in ${FXSDK_INCLUDE}/example and users can include
# them as <example/*.h>.
#
# Note the / at the end of the source DIRECTORY, which indicates to copy the
# *contents* of include/ at the destination, not the folder itself.
#
# We only install files called "*.h" to exclude config.h.in.
install(DIRECTORY "${CMAKE_CURRENT_SOURCE_DIR}/include/"
DESTINATION "${FXSDK_INCLUDE}"
FILES_MATCHING PATTERN "*.h")
# Install config.h from the build dir
# Similarly, install config.h from the build dir.
install(FILES "${CMAKE_CURRENT_BINARY_DIR}/include/example/config.h"
DESTINATION "${FXSDK_COMPILER_INSTALL}/include/example")
DESTINATION "${FXSDK_INCLUDE}/example")
# Install FindLibExample.cmake so that users can do find_package(LibExample)
# Install FindLibExample.cmake so that users can do find_package(LibExample).
install(FILES cmake/FindLibExample.cmake
DESTINATION "${FXSDK_CMAKE_MODULE_PATH}")

View File

@ -7,16 +7,17 @@ Here's how the files are used:
* `src` and `include` are your library's code and headers. Unless you have a single header, you'll want to keep the compiler's include folder clean and have all your headers included as `<example/header.h>`, so `include` has a single subfolder `example`.
* There is a template header at `include/example/config.h.in` that gets transformed by CMake during build to insert the version number without hardcoding it. You can use it for other compile-time options.
* `CMakeLists.txt` is a pretty standard CMake script that builds the library.
* `cmake/FindLibExample.cmake` is a script for add-ins using your library, so that they can `find_package(LibExample)` and get all the compile and link options for free.
* `giteapc.make` makes it possible to build and install your library in a simple command using [GiteaPC](https://gitea.planet-casio.com/Lephenixnoir/GiteaPC). If you don't want that you can delete it (along with the related `.gitignore` entries).
* `cmake/FindLibExample.cmake` is a script for add-ins using your library, so that they can `find_package(LibExample 1.0)` and get all the compile and link options for free.
* `giteapc.make` makes it possible to build and install your library in a simple command using [GiteaPC](/Lephenixnoir/GiteaPC). If you don't want that you can delete it (along with the related `.gitignore` entries).
## The build system
Not a lot to discuss here, this is pretty standard. See the [tutorial on Planète Casio](https://www.planet-casio.com/Fr/forums/topic16647-1-tutoriel-compiler-des-add-ins-avec-cmake-fxsdk.html) (in French) for an introduction to CMake in the context of add-ins. You might be interested in [`configure_file()`](https://cmake.org/cmake/help/latest/command/configure_file.html) and [`install()`](https://cmake.org/cmake/help/latest/command/install.html), which are rarely used in add-ins.
The fxSDK provides two variables to help you install your files:
The fxSDK provides three variables to help you install your files:
* `FXSDK_COMPILER_INSTALL` is the install path for the compiler (`sh-elf-gcc -print-search-dirs`), the libraries go there and the headers in the `include` subfolder.
* `FXSDK_LIB` is the install path for library files (`*.a`).
* `FXSDK_INCLUDE` is the install path for headers (`*.h`); we use a subfolder `example/` to keep things organized.
* `FXSDK_CMAKE_MODULE_PATH` is the path of an fxSDK folder storing built-in and user-provided CMake modules. These are made visible to anyone that configures with `fxsdk build-{fx,cg}`.
## The FindPackage file
@ -27,9 +28,11 @@ The goal of a find module is to determine whether the library is available, its
If the library is found, the find module defines an external target (called "imported") that provides the path to the library and suitable compile and link options. The user can run `target_link_libraries(addin LibExample::LibExample)` and all the flags will be supplied automatically. Whenever you update your library, the library file or the find module will change and all user applications will automatically relink.
The detection step is here automated with the fxSDK's [`FindSimpleLibrary.cmake`](/Lephenixnoir/fxsdk/src/branch/master/fxsdk/cmake/FindSimpleLibrary.cmake) module.
## GiteaPC support
[GiteaPC](https://gitea.planet-casio.com/Lephenixnoir/GiteaPC) is a tool to automate building and installing repositories from the Planète Casio Gitea forge. It was designed to speed up library management in the fxSDK. A repository that has the `giteapc` topic (topics can be added through the "Manage topics" link on the repository's front page) and provides `giteapc.make` can be built, installed, and updated with a simple command.
[GiteaPC](/Lephenixnoir/GiteaPC) is a tool to automate building and installing repositories from the Planète Casio Gitea forge. It was designed to speed up library management in the fxSDK. A repository that has the `giteapc` topic (topics can be added through the "Manage topics" link on the repository's front page) and provides `giteapc.make` can be built, installed, and updated with a simple command.
```
% giteapc install Lephenixnoir/Template-gint-library
@ -39,7 +42,7 @@ The job of `giteapc.make` is simply to provide configure, build, install and uni
`giteapc.make` can also specify basic dependencies in the top comment.
The `giteapc-config.make` file is for the user to customize the build by adding environment variables (such as setting `LIBEXAMPLE_CMAKEOPTS_FX` to change compiler behaviour, or anything they might need). You can provide configurations of your own in `giteapc-config-<name>.cmake` (they can be installed with `giteapc install Lephenixnoir/Template-gint-library:name`), just remember to add the file in `.gitignore` as it will be otherwise ignored. See [sh-elf-gcc](https://gitea.planet-casio.com/Lephenixnoir/sh-elf-gcc) for an example of custom configurations.
The `giteapc-config.make` file is for the user to customize the build by adding environment variables (such as setting `LIBEXAMPLE_CMAKEOPTS_FX` to change compiler behaviour, or anything they might need). You can provide configurations of your own in `giteapc-config-<name>.cmake` (they can be installed with `giteapc install Lephenixnoir/Template-gint-library:name`). See [sh-elf-gcc](/Lephenixnoir/sh-elf-gcc) for an example of custom configurations.
## License

View File

@ -1,46 +1,38 @@
find_package(Gint 2.1 REQUIRED)
# 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()
# The commands above seem common for gint libraries, so the fxSDK provides a
# helper function to get that directly. We simply provide the archive name,
# header file name, macro name, and names for output variables.
# include(FindSimpleLibrary)
# find_simple_library(libexample.a include/example/config.h "EX_VERSION"
# PATH_VAR EX_PATH VERSION_VAR EX_VERSION)
# 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
# Ask the fxSDK to find a library called libexample.a, and find its version in
# the macro EX_VERSION of the header file <example/config.h>.
#
# Store the path to libexample.a in EX_PATH and store the version number in
# EX_VERSION.
include(FindSimpleLibrary)
find_simple_library(libexample.a example/config.h "EX_VERSION"
PATH_VAR EX_PATH
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()
# The fxSDK looks for libexample.a in ${FXSDK_LIB}, then <example/config.h> in
# ${FXSDK_INCLUDE}, and extracts the version number from a macro like
#
# #define EX_VERSION "..."
#
# See the source code for the FindSimpleLibrary module for more detail.
# We then use a CMake function to finish searching the library. We specify:
# * REQUIRED_VARS ... which requires the variables to be non-empty, otherwise
# find_library() says the library was not found.
# * VERSION_VAR ... which provides the version number, so that find_library()
# can compare with the version requested by the user (if any) and fail if
# the version we found isn't compatible.
include(FindPackageHandleStandardArgs)
find_package_handle_standard_args(LibExample
REQUIRED_VARS EX_PATH EX_VERSION
VERSION_VAR EX_VERSION)
# We now have a LibExample_FOUND variable indicating if everything went well.
# If so we can now create an *imported target* that is not built in the project
# but can still be linked against with target_link_libraries().
if(LibExample_FOUND)
# This is an imported target, we don't build it, we just claim it's here
# This is an imported target, we don't build it, we just claim it's here.
add_library(LibExample::LibExample UNKNOWN IMPORTED)
# Here we declare the compiler and linker flags that every user of LibExample
# needs to use.
@ -51,5 +43,5 @@ if(LibExample_FOUND)
# Linking options
INTERFACE_LINK_OPTIONS -lexample
# Dependencies (for order on the command-line)
IMPORTED_LINK_INTERFACE_LIBRARIES Gint::Gint)
INTERFACE_LINK_LIBRARIES Gint::Gint)
endif()