Skip to content

Commit a9ecdfb

Browse files
authored
Build improvements (and fixes) to facilitate downstream packaging (#25)
* Issue #24: Fix SUPERNOVAS_VERSION_STRING macro * Issue #23: Build improvements with easier packaging in mind * cio_file.c: Fix warnings about unchecked return values * version.c: Build utility for printing version string * make to use externally defined LDFLAGS also when generating .so files * Smarter make shared and make static implementations
1 parent af46ba6 commit a9ecdfb

File tree

8 files changed

+221
-46
lines changed

8 files changed

+221
-46
lines changed

.gitignore

+1-1
Original file line numberDiff line numberDiff line change
@@ -16,4 +16,4 @@ site/**
1616
*.swp
1717
README-headless.md
1818
TODO
19-
19+
VERSION

CHANGELOG.md

+31-1
Original file line numberDiff line numberDiff line change
@@ -10,17 +10,47 @@ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.1.0/),
1010

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

13+
14+
### Fixed
15+
16+
- Bungled definition of `SUPERNOVAS_VERSION_STRING` in `novas.h`.
17+
1318
### Added
1419

1520
- `make help` to provide a brief list and explanation of the available build targets. (Thanks to `@teuben` for
16-
suggesting.)
21+
suggesting this.)
22+
23+
- `version.c` utility code for printing version info, e.g. for versioned `SONAME` in shared libraries during the
24+
build.
25+
26+
- `lib/supernovas.so` target for `make`, which generates the same library as `lib/novas.so`, except that the `SONAME`
27+
is also `supernovas.so.$(VERSION)` instead of `novas.so.$(VERSION)`, and might be preferred for packaging with
28+
inconsistent naming.
1729

1830
### Changed
1931

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

36+
- `make` can be configured without editing `config.mk` simply by setting the appropriate shell variables (the same
37+
ones as in `config.mk` prior to invoking `make`. As such standard `CFLAGS` and `LDFLAGS` will be used if defined
38+
externally.
39+
40+
- `make shared` now also builds `lib/solsys1.so` and `lib/solsys2.so` shared libraries that can be used by programs
41+
that need solsys1 (via `eph_manager`) or solsys2 (via `jplint`) functionality.
42+
43+
- `make solsys` now generates only the `solarsystem()` implementation objects that are external (not built in).
44+
45+
- `make` now generates `.so` shared libraries with `SONAME` set to `lib<name>.so.$(VERSION)` where `VERSION` is the
46+
library version as printed by `version.c`. E.g. `novas.so` will have `SONAME` set to `libnovas.so.1.0.2` for
47+
version 1.0.2 of the library.
48+
49+
- `make` now uses `LDFLAGS` (if defined) also when generating `.so` shared libs.
50+
51+
- Eliminate unchecked return value compiler warnings from `cio_file` (used typically at build time only to generate
52+
`cio_ra.bin`).
53+
2454

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

Makefile

+70-11
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@ include config.mk
1010
# Specific build targets and recipes below...
1111
# ===============================================================================
1212

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

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

31+
SOLSYS_TARGETS :=
32+
SHARED_TARGETS := lib/novas.so
33+
34+
ifneq ($(BUILTIN_SOLSYS1),1)
35+
SOLSYS_TARGETS += obj/solsys1.o obj/eph_manager.o
36+
SHARED_TARGETS += lib/solsys1.so
37+
endif
38+
39+
ifneq ($(BUILTIN_SOLSYS2),1)
40+
SOLSYS_TARGETS += obj/solsys2.o obj/jplint.o
41+
SHARED_TARGETS += lib/solsys2.so
42+
endif
43+
44+
ifneq ($(BUILTIN_SOLSYS3),1)
45+
SOLSYS_TARGETS += obj/solsys3.o
46+
SHARED_TARGETS += lib/solsys3.so
47+
endif
48+
49+
ifneq ($(BUILTIN_SOLSYS_EPHEM),1)
50+
SOLSYS_TARGETS += obj/solsys-ephem.o
51+
SHARED_TARGETS += lib/solsys-ephem.so
52+
endif
53+
54+
3055
.PHONY: api
3156
api: $(DEFAULT_TARGETS)
3257

3358
.PHONY: static
34-
static: lib/novas.a
59+
static: lib/novas.a solsys
3560

3661
.PHONY: shared
37-
shared: lib/novas.so
62+
shared: $(SHARED_TARGETS)
3863

3964
.PHONY: solsys
40-
solsys: obj/solsys1.o obj/eph_manager.o obj/solsys2.o obj/jplint.o obj/solsys3.o obj/solsys-ephem.o
65+
solsys: $(SOLSYS_TARGETS)
4166

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

5378
.PHONY: clean
5479
clean:
55-
rm -f object README-headless.md bin/cio_file
80+
rm -f obj VERSION README-headless.md bin/cio_file
5681
make -C test clean
5782

5883
.PHONY: distclean
5984
distclean: clean
6085
rm -f lib cio_ra.bin
6186

62-
6387
# Static library: novas.a
6488
lib/novas.a: $(OBJECTS) | lib
6589
ar -rc $@ $^
6690
ranlib $@
6791

68-
# Shared library: novas.so
69-
lib/novas.so: $(SOURCES) | lib
70-
$(CC) -o $@ $(CFLAGS) $^ -shared -fPIC
92+
# Shared library: novas.so -- same as supernovas.so except the builtin SONAME
93+
lib/novas.so: LIBNAME := novas
94+
lib/novas.so: $(SOURCES)
95+
96+
# Shared library: supernovas.so -- same as novas.so except the builtin SONAME
97+
lib/supernovas.so: LIBNAME := supernovas
98+
lib/supernovas.so: $(SOURCES)
99+
100+
# Shared library: solsys1.so (standalone solsys1.c functionality)
101+
lib/solsys1.so: BUILTIN_SOLSYS1 := 0
102+
lib/solsys1.so: LIBNAME := solsys1
103+
lib/solsys1.so: $(SRC)/solsys1.c $(SRC)/eph_manager.c
104+
105+
# Shared library: solsys2.so (standalone solsys2.c functionality)
106+
lib/solsys2.so: BUILTIN_SOLSYS2 := 0
107+
lib/solsys2.so: LIBNAME := solsys2
108+
lib/solsys2.so: $(SRC)/solsys2.c $(SRC)/jplint.f
109+
110+
# Shared library: solsys1.so (standalone solsys1.c functionality)
111+
lib/solsys3.so: BUILTIN_SOLSYS3 := 0
112+
lib/solsys3.so: LIBNAME := solsys3
113+
lib/solsys3.so: $(SRC)/solsys3.c
114+
115+
# Shared library: solsys2.so (standalone solsys2.c functionality)
116+
lib/solsys-ephem.so: BUILTIN_SOLSYS_EPHEM := 0
117+
lib/solsys-ephem.so: LIBNAME := solsys-ephem
118+
lib/solsys-ephem.so: $(SRC)/solsys-ephem.c
119+
120+
lib/%.so: | lib VERSION
121+
$(CC) -o $@ $(CFLAGS) $^ -shared -fPIC -Wl,-soname,lib$(LIBNAME).so.$(shell cat VERSION) $(LDFLAGS)
122+
123+
# A VERSION string extracted from novas.h version constants
124+
VERSION: bin/version
125+
$< >> $@
126+
127+
.INTERMEDIATE: bin/version
128+
bin/version: $(SRC)/version.c | bin
129+
$(CC) -o $@ -I$(INC) $<
71130

72131
# CIO locator data
73132
.PHONY: cio_ra.bin
@@ -97,12 +156,12 @@ help:
97156
@echo " 'dox' if 'doxygen' is available, or was specified via the"
98157
@echo " DOXYGEN variable (e.g. in 'config.mk')."
99158
@echo " static Builds the static 'lib/novas.a' library."
100-
@echo " shared Builds the shared 'lib/novas.so' library."
159+
@echo " shared Builds the shared 'novas.so', 'solsys1.so', and 'solsys2.so'."
101160
@echo " cio_ra.bin Generates the CIO locator lookup data file 'cio_ra.bin', in the"
102161
@echo " destination specified in 'config.mk'."
103162
@echo " dox Compiles HTML API documentation using 'doxygen'."
104-
@echo " solsys Builds only the objects that may provide 'solarsystem()' call"
105-
@echo " implemtations (e.g. 'solsys1.o', 'eph_manager.o'...)."
163+
@echo " solsys Builds only the objects that may provide external 'solarsystem()'"
164+
@echo " call implentations (e.g. 'solsys1.o', 'eph_manager.o'...)."
106165
@echo " check Performs static analysis with 'cppcheck'."
107166
@echo " test Runs regression tests."
108167
@echo " coverage Runs 'gcov' to analyze regression test coverage."

README.md

+6-4
Original file line numberDiff line numberDiff line change
@@ -164,7 +164,8 @@ The SuperNOVAS distribution contains a GNU `Makefile`, which is suitable for com
164164
documentation, and tests, etc.) on POSIX systems such as Linux, BSD, MacOS X, or Cygwin or WSL. (At this point we do
165165
not provide a similar native build setup for Windows, but speak up if you would like to add it yourself!)
166166

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

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

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

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

193195
Now you are ready to build the library:
194196

config.mk

+45-13
Original file line numberDiff line numberDiff line change
@@ -9,17 +9,25 @@
99
SRC = src
1010
INC = include
1111

12-
# Compiler options
13-
CFLAGS = -Os -Wall -I$(INC)
12+
13+
# Base compiler options (if not defined externally...)
14+
CFLAGS ?= -Os -Wall
15+
16+
# Add include/ directory
17+
CFLAGS += -I$(INC)
18+
1419

1520
# Specific Doxygen to use if not the default one
16-
#DOXYGEN = /opt/bin/doxygen
21+
#DOXYGEN ?= /opt/bin/doxygen
22+
1723

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

27+
2128
# For maximum compatibility with NOVAS C 3.1, uncomment the line below
22-
#CFLAGS += -DCOMPAT=1
29+
#COMPAT ?= 1
30+
2331

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

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

4555
# Whether to build into the library planet_eph_manager() routines provided in
4656
# solsys1.c. Because the default readeph implementation (readeph0.c) does not
4757
# provide useful functionality, we do not include solsys1.c in the build
4858
# by default.
49-
#BUILTIN_SOLSYS1 = 1
59+
#BUILTIN_SOLSYS1 ?= 1
60+
5061

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

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

6376
# Whether to build into the library earth_sun_calc() routines provided in
6477
# solsys3.c
65-
BUILTIN_SOLSYS3 = 1
78+
BUILTIN_SOLSYS3 ?= 1
79+
6680

6781
# Whether to build into the library planet_ephem_reader() routines provided in
6882
# solsys3.c
69-
BUILTIN_SOLSYS_EPHEM = 1
83+
BUILTIN_SOLSYS_EPHEM ?= 1
84+
7085

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

7792

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

97+
8298
# ============================================================================
8399
# END of user config section.
84100
#
85101
# Below are some generated constants based on the one that were set above
86102
# ============================================================================
87103

104+
# If the COMPAT variable is set to one, then force set compatibility mode
105+
ifeq ($(COMPAT),1)
106+
CFLAGS += -DCOMPAT=1
107+
endif
108+
109+
# If the CIO_LOCATOR_FILE variable is defined, the use its definition
110+
ifdef $(CIO_LOCATOR_FILE)
111+
CFLAGS += -DDEFAULT_CIO_LOCATOR_FILE=\"$(CIO_LOCATOR_FILE)\"
112+
endif
113+
114+
# If the THREAD_LOCAL variable was defined externally, use that definition to
115+
# specify the thread local keyword to use.
116+
ifdef $(THREAD_LOCAL)
117+
CFLAGS += -DTHREAD_LOCAL=\"$(THREAD_LOCAL)"
118+
endif
119+
88120
ifeq ($(DEFAULT_SOLSYS), 1)
89121
BUILTIN_SOLSYS1 = 1
90122
CFLAGS += -DDEFAULT_SOLSYS=1

include/novas.h

+30-7
Original file line numberDiff line numberDiff line change
@@ -50,15 +50,38 @@
5050

5151
#include "nutation.h"
5252

53-
#define SUPERNOVAS_MAJOR_VERSION 1 ///< API major version
54-
#define SUPERNOVAS_MINOR_VERSION 0 ///< API minor version
55-
#define SUPERNOVAS_PATCHLEVEL 2 ///< Integer sub version of the release
56-
#define SUPERNOVAS_RELEASE_STRING "-devel" ///< Additional release information in version, e.g. "-1", or "-rc1".
53+
/// API major version
54+
#define SUPERNOVAS_MAJOR_VERSION 1
55+
56+
/// API minor version
57+
#define SUPERNOVAS_MINOR_VERSION 0
58+
59+
/// Integer sub version of the release
60+
#define SUPERNOVAS_PATCHLEVEL 2
61+
62+
/// Additional release information in version, e.g. "-1", or "-rc1".
63+
#define SUPERNOVAS_RELEASE_STRING "-devel"
64+
65+
66+
67+
#ifdef xstr
68+
# undef xstr
69+
#endif
70+
71+
/// Stringify level 2 macro
72+
#define xstr(s) str(s)
73+
74+
#ifdef str
75+
# undef str
76+
#endif
77+
78+
/// Stringify level 1 macro
79+
#define str(s) #s
5780

5881
/// The version string for this library
59-
#define SUPERNOVAS_VERSION_STRING #SUPERNOVAS_MAJOR_VERSION "." #SUPERNOVAS_MINOR_VERSION \
60-
(#SUPERNOVAS_PATCHLEVEL ? "." #SUPERNOVAS_PATCHLEVEL : "") \
61-
SUPERNOVAS_RELEASE_STRING
82+
#define SUPERNOVAS_VERSION_STRING xstr(SUPERNOVAS_MAJOR_VERSION) "." xstr(SUPERNOVAS_MINOR_VERSION) \
83+
"." xstr(SUPERNOVAS_PATCHLEVEL) SUPERNOVAS_RELEASE_STRING
84+
6285

6386
#define NOVAS_MAJOR_VERSION 3 ///< Major version of NOVAS on which this library is based
6487
#define NOVAS_MINOR_VERSION 1 ///< Minor version of NOVAS on which this library is based

0 commit comments

Comments
 (0)