Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Build improvements (and fixes) to facilitate downstream packaging #25

Merged
merged 9 commits into from
May 22, 2024
2 changes: 1 addition & 1 deletion .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -16,4 +16,4 @@ site/**
*.swp
README-headless.md
TODO

VERSION
32 changes: 31 additions & 1 deletion CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -10,17 +10,47 @@ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.1.0/),

Changes coming to the next quarterly release. Some or all of these may be readily available on the `main` branch.


### Fixed

- Bungled definition of `SUPERNOVAS_VERSION_STRING` in `novas.h`.

### Added

- `make help` to provide a brief list and explanation of the available build targets. (Thanks to `@teuben` for
suggesting.)
suggesting this.)

- `version.c` utility code for printing version info, e.g. for versioned `SONAME` in shared libraries during the
build.

- `lib/supernovas.so` target for `make`, which generates the same library as `lib/novas.so`, except that the `SONAME`
is also `supernovas.so.$(VERSION)` instead of `novas.so.$(VERSION)`, and might be preferred for packaging with
inconsistent naming.

### Changed

- Default `make` to skip `dox` target unless `doxygen` is available (either in the default `PATH` or else specified
via the `DOXYGEN` variable, e.g. in `config.mk`). This way the default build does not have unexpected dependencies.
(see Issue #22, thanks to `@teuben`).

- `make` can be configured without editing `config.mk` simply by setting the appropriate shell variables (the same
ones as in `config.mk` prior to invoking `make`. As such standard `CFLAGS` and `LDFLAGS` will be used if defined
externally.

- `make shared` now also builds `lib/solsys1.so` and `lib/solsys2.so` shared libraries that can be used by programs
that need solsys1 (via `eph_manager`) or solsys2 (via `jplint`) functionality.

- `make solsys` now generates only the `solarsystem()` implementation objects that are external (not built in).

- `make` now generates `.so` shared libraries with `SONAME` set to `lib<name>.so.$(VERSION)` where `VERSION` is the
library version as printed by `version.c`. E.g. `novas.so` will have `SONAME` set to `libnovas.so.1.0.2` for
version 1.0.2 of the library.

- `make` now uses `LDFLAGS` (if defined) also when generating `.so` shared libs.

- Eliminate unchecked return value compiler warnings from `cio_file` (used typically at build time only to generate
`cio_ra.bin`).


## [1.0.1] -- 2024-05-13

Expand Down
81 changes: 70 additions & 11 deletions Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ include config.mk
# Specific build targets and recipes below...
# ===============================================================================


# The targets to build by default if not otherwise specified to 'make'
DEFAULT_TARGETS := static shared cio_ra.bin

Expand All @@ -27,17 +28,41 @@ else
$(info WARNING! Doxygen is not available. Will skip 'dox' target)
endif

SOLSYS_TARGETS :=
SHARED_TARGETS := lib/novas.so

ifneq ($(BUILTIN_SOLSYS1),1)
SOLSYS_TARGETS += obj/solsys1.o obj/eph_manager.o
SHARED_TARGETS += lib/solsys1.so
endif

ifneq ($(BUILTIN_SOLSYS2),1)
SOLSYS_TARGETS += obj/solsys2.o obj/jplint.o
SHARED_TARGETS += lib/solsys2.so
endif

ifneq ($(BUILTIN_SOLSYS3),1)
SOLSYS_TARGETS += obj/solsys3.o
SHARED_TARGETS += lib/solsys3.so
endif

ifneq ($(BUILTIN_SOLSYS_EPHEM),1)
SOLSYS_TARGETS += obj/solsys-ephem.o
SHARED_TARGETS += lib/solsys-ephem.so
endif


.PHONY: api
api: $(DEFAULT_TARGETS)

.PHONY: static
static: lib/novas.a
static: lib/novas.a solsys

.PHONY: shared
shared: lib/novas.so
shared: $(SHARED_TARGETS)

.PHONY: solsys
solsys: obj/solsys1.o obj/eph_manager.o obj/solsys2.o obj/jplint.o obj/solsys3.o obj/solsys-ephem.o
solsys: $(SOLSYS_TARGETS)

.PHONY: test
test:
Expand All @@ -52,22 +77,56 @@ all: api solsys obj/novascon.o test coverage check

.PHONY: clean
clean:
rm -f object README-headless.md bin/cio_file
rm -f obj VERSION README-headless.md bin/cio_file
make -C test clean

.PHONY: distclean
distclean: clean
rm -f lib cio_ra.bin


# Static library: novas.a
lib/novas.a: $(OBJECTS) | lib
ar -rc $@ $^
ranlib $@

# Shared library: novas.so
lib/novas.so: $(SOURCES) | lib
$(CC) -o $@ $(CFLAGS) $^ -shared -fPIC
# Shared library: novas.so -- same as supernovas.so except the builtin SONAME
lib/novas.so: LIBNAME := novas
lib/novas.so: $(SOURCES)

# Shared library: supernovas.so -- same as novas.so except the builtin SONAME
lib/supernovas.so: LIBNAME := supernovas
lib/supernovas.so: $(SOURCES)

# Shared library: solsys1.so (standalone solsys1.c functionality)
lib/solsys1.so: BUILTIN_SOLSYS1 := 0
lib/solsys1.so: LIBNAME := solsys1
lib/solsys1.so: $(SRC)/solsys1.c $(SRC)/eph_manager.c

# Shared library: solsys2.so (standalone solsys2.c functionality)
lib/solsys2.so: BUILTIN_SOLSYS2 := 0
lib/solsys2.so: LIBNAME := solsys2
lib/solsys2.so: $(SRC)/solsys2.c $(SRC)/jplint.f

# Shared library: solsys1.so (standalone solsys1.c functionality)
lib/solsys3.so: BUILTIN_SOLSYS3 := 0
lib/solsys3.so: LIBNAME := solsys3
lib/solsys3.so: $(SRC)/solsys3.c

# Shared library: solsys2.so (standalone solsys2.c functionality)
lib/solsys-ephem.so: BUILTIN_SOLSYS_EPHEM := 0
lib/solsys-ephem.so: LIBNAME := solsys-ephem
lib/solsys-ephem.so: $(SRC)/solsys-ephem.c

lib/%.so: | lib VERSION
$(CC) -o $@ $(CFLAGS) $^ -shared -fPIC -Wl,-soname,lib$(LIBNAME).so.$(shell cat VERSION) $(LDFLAGS)

# A VERSION string extracted from novas.h version constants
VERSION: bin/version
$< >> $@

.INTERMEDIATE: bin/version
bin/version: $(SRC)/version.c | bin
$(CC) -o $@ -I$(INC) $<

# CIO locator data
.PHONY: cio_ra.bin
Expand Down Expand Up @@ -97,12 +156,12 @@ help:
@echo " 'dox' if 'doxygen' is available, or was specified via the"
@echo " DOXYGEN variable (e.g. in 'config.mk')."
@echo " static Builds the static 'lib/novas.a' library."
@echo " shared Builds the shared 'lib/novas.so' library."
@echo " shared Builds the shared 'novas.so', 'solsys1.so', and 'solsys2.so'."
@echo " cio_ra.bin Generates the CIO locator lookup data file 'cio_ra.bin', in the"
@echo " destination specified in 'config.mk'."
@echo " dox Compiles HTML API documentation using 'doxygen'."
@echo " solsys Builds only the objects that may provide 'solarsystem()' call"
@echo " implemtations (e.g. 'solsys1.o', 'eph_manager.o'...)."
@echo " solsys Builds only the objects that may provide external 'solarsystem()'"
@echo " call implentations (e.g. 'solsys1.o', 'eph_manager.o'...)."
@echo " check Performs static analysis with 'cppcheck'."
@echo " test Runs regression tests."
@echo " coverage Runs 'gcov' to analyze regression test coverage."
Expand Down
10 changes: 6 additions & 4 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -164,7 +164,8 @@ The SuperNOVAS distribution contains a GNU `Makefile`, which is suitable for com
documentation, and tests, etc.) on POSIX systems such as Linux, BSD, MacOS X, or Cygwin or WSL. (At this point we do
not provide a similar native build setup for Windows, but speak up if you would like to add it yourself!)

Before compiling the library take a look a `config.mk` and edit it as necessary for your needs, such as:
Before compiling the library take a look a `config.mk` and edit it as necessary for your needs, or else define
the necessary variables in the shell prior to invoking `make`. For example:

- Choose which planet calculator function routines are built into the library (for example to provide
`earth_sun_calc()` set `BUILTIN_SOLSYS3 = 1` and/or for `planet_ephem_provider()` set `BUILTIN_SOLSYS_EPHEM = 1`.
Expand All @@ -182,13 +183,14 @@ Before compiling the library take a look a `config.mk` and edit it as necessary
and you can provide a superior ephemeris reader implementation at runtime via the `set_ephem_provider()` call.

- If you want to use the CIO locator binary file for `cio_location()`, you can specify the path to the binary file
(e.g. `/usr/local/share/novas/cio_ra.bin`) on your system. (The CIO locator file is not at all necessary for the
functioning of the library, unless you specifically require CIO positions relative to GCRS.)
(e.g. `/usr/local/share/novas/cio_ra.bin`) on your system e.g. by setting the `CIO_LOCATOR_FILE` shell variable
prior to calling `make`. (The CIO locator file is not at all necessary for the functioning of the library, unless
you specifically require CIO positions relative to GCRS.)

- If your compiler does not support the C11 standard and it is not GCC &gt;=3.3, but provides some non-standard
support for declaring thread-local variables, you may want to pass the keyword to use to declare variables as
thread local via `-DTHREAD_LOCAL=...` added to `CFLAGS`. (Don't forget to enclose the string value in escaped
quotes.)
quotes in `config.mk`, or unescaped if defining the `THREAD_LOCAL` shell variable prior to invoking `make`.)

Now you are ready to build the library:

Expand Down
58 changes: 45 additions & 13 deletions config.mk
Original file line number Diff line number Diff line change
Expand Up @@ -9,17 +9,25 @@
SRC = src
INC = include

# Compiler options
CFLAGS = -Os -Wall -I$(INC)

# Base compiler options (if not defined externally...)
CFLAGS ?= -Os -Wall

# Add include/ directory
CFLAGS += -I$(INC)


# Specific Doxygen to use if not the default one
#DOXYGEN = /opt/bin/doxygen
#DOXYGEN ?= /opt/bin/doxygen


# Extra warnings (not supported on all compilers)
#CFLAGS += -Wextra


# For maximum compatibility with NOVAS C 3.1, uncomment the line below
#CFLAGS += -DCOMPAT=1
#COMPAT ?= 1


# To make SuperNOVAS thread-safe, we use thread-local storage modifier
# keywords. These were not standardized prior to C11. So while we automatically
Expand All @@ -28,9 +36,10 @@ CFLAGS = -Os -Wall -I$(INC)
# explicitly here by passing the keyword via the THREAD_LOCAL definition
#
# E.g.
#CFLAGS += -DTHREAD_LOCAL=\"__thread\"
#THREAD_LOCAL ?= __thread
#or
#CFLAGS += -DTHREAD_LOCAL=\"__declspec(thread)\"
#THREAD_LOCAL ?= __declspec(thread)


# You can set the default CIO locator file to use depending on where you
# installed it. By default, the library will assume
Expand All @@ -40,51 +49,74 @@ CFLAGS = -Os -Wall -I$(INC)
# availability, or in '$(HOME)/.local/share/novas' for user-specific
# installation.
#
#CFLAGS += -DDEFAULT_CIO_LOCATOR_FILE=\"/user/share/novas/cio_ra.bin\"
#CIO_LOCATOR_FILE ?= /usr/share/novas/cio_ra.bin


# Whether to build into the library planet_eph_manager() routines provided in
# solsys1.c. Because the default readeph implementation (readeph0.c) does not
# provide useful functionality, we do not include solsys1.c in the build
# by default.
#BUILTIN_SOLSYS1 = 1
#BUILTIN_SOLSYS1 ?= 1


# Compile library with a default readeph() implementation for solsys1.c, which
# will be used only if the application does not define another implementation
# via calls to the to set_ephem_reader() function.
DEFAULT_READEPH = $(SRC)/readeph0.c
DEFAULT_READEPH ?= $(SRC)/readeph0.c


# Whether to build into the library planet_jplint() routines provided in
# solsys2.c. Note, that if you choose to build in the functionality of
# solsys2.c you will need to provide a jplint_() implementation and its
# dependencies such as pleph_() as well when linking your application.
# Therefore, we do not include solsys2.c by default...
#BUILTIN_SOLSYS2 = 1
#BUILTIN_SOLSYS2 ?= 1


# Whether to build into the library earth_sun_calc() routines provided in
# solsys3.c
BUILTIN_SOLSYS3 = 1
BUILTIN_SOLSYS3 ?= 1


# Whether to build into the library planet_ephem_reader() routines provided in
# solsys3.c
BUILTIN_SOLSYS_EPHEM = 1
BUILTIN_SOLSYS_EPHEM ?= 1


# Compile library with a default solarsystem() implementation. If you want to
# use your library with your own solarsystem() implementation, you should
# not set this option. In that case you must always provide a solarsystem()
# implementation when linking your application against this library.
DEFAULT_SOLSYS = 3
DEFAULT_SOLSYS ?= 3


# cppcheck options for 'check' target
CHECKOPTS ?= --enable=performance,warning,portability,style --language=c \
--error-exitcode=1


# ============================================================================
# END of user config section.
#
# Below are some generated constants based on the one that were set above
# ============================================================================

# If the COMPAT variable is set to one, then force set compatibility mode
ifeq ($(COMPAT),1)
CFLAGS += -DCOMPAT=1
endif

# If the CIO_LOCATOR_FILE variable is defined, the use its definition
ifdef $(CIO_LOCATOR_FILE)
CFLAGS += -DDEFAULT_CIO_LOCATOR_FILE=\"$(CIO_LOCATOR_FILE)\"
endif

# If the THREAD_LOCAL variable was defined externally, use that definition to
# specify the thread local keyword to use.
ifdef $(THREAD_LOCAL)
CFLAGS += -DTHREAD_LOCAL=\"$(THREAD_LOCAL)"
endif

ifeq ($(DEFAULT_SOLSYS), 1)
BUILTIN_SOLSYS1 = 1
CFLAGS += -DDEFAULT_SOLSYS=1
Expand Down
37 changes: 30 additions & 7 deletions include/novas.h
Original file line number Diff line number Diff line change
Expand Up @@ -50,15 +50,38 @@

#include "nutation.h"

#define SUPERNOVAS_MAJOR_VERSION 1 ///< API major version
#define SUPERNOVAS_MINOR_VERSION 0 ///< API minor version
#define SUPERNOVAS_PATCHLEVEL 2 ///< Integer sub version of the release
#define SUPERNOVAS_RELEASE_STRING "-devel" ///< Additional release information in version, e.g. "-1", or "-rc1".
/// API major version
#define SUPERNOVAS_MAJOR_VERSION 1

/// API minor version
#define SUPERNOVAS_MINOR_VERSION 0

/// Integer sub version of the release
#define SUPERNOVAS_PATCHLEVEL 2

/// Additional release information in version, e.g. "-1", or "-rc1".
#define SUPERNOVAS_RELEASE_STRING "-devel"



#ifdef xstr
# undef xstr
#endif

/// Stringify level 2 macro
#define xstr(s) str(s)

#ifdef str
# undef str
#endif

/// Stringify level 1 macro
#define str(s) #s

/// The version string for this library
#define SUPERNOVAS_VERSION_STRING #SUPERNOVAS_MAJOR_VERSION "." #SUPERNOVAS_MINOR_VERSION \
(#SUPERNOVAS_PATCHLEVEL ? "." #SUPERNOVAS_PATCHLEVEL : "") \
SUPERNOVAS_RELEASE_STRING
#define SUPERNOVAS_VERSION_STRING xstr(SUPERNOVAS_MAJOR_VERSION) "." xstr(SUPERNOVAS_MINOR_VERSION) \
"." xstr(SUPERNOVAS_PATCHLEVEL) SUPERNOVAS_RELEASE_STRING


#define NOVAS_MAJOR_VERSION 3 ///< Major version of NOVAS on which this library is based
#define NOVAS_MINOR_VERSION 1 ///< Minor version of NOVAS on which this library is based
Expand Down
Loading
Loading