GithubHelp home page GithubHelp logo

kristapsdz / oconfigure Goto Github PK

View Code? Open in Web Editor NEW
46.0 6.0 6.0 837 KB

configuration script for portable, OpenBSD-oriented systems

License: ISC License

C 91.68% Makefile 0.63% Shell 7.69%
bsdlv configuration c compatibility portable

oconfigure's Introduction

Introduction

This is a straightforward configuration system for writing portable C systems with OpenBSD-compatible features and functions.

To use:

  1. copy configure, compats.c, and tests.c into your source tree
  2. have include Makefile.configure at the top of your Makefile
  3. have #include "config.h" as the first inclusion in your sources
  4. read over the documentation below in case you need to guard header inclusion
  5. compile compats.o with your sources and link with it

It allows easy porting to Linux (glibc and musl), FreeBSD, NetBSD, Mac OS X, SunOS (Solaris 11), and OmniOS (illumos). Other systems may also be supported: please let us know if they are.

See versions.md for version information.

This framework was inspired by mandoc's configure script written by Ingo Schwarze.

Users and maintainers

Run ./configure prior to running make. The configure script will check for common features as noted in the test files, e.g., pledge(2), and also provide compatibility for other functions, e.g., strlcpy(3).

The ./configure script may be executed in a cross-compiling environment with the compiler and linker set appropriately.

If you have Makefile flags you'd like to set, set them when you invoke configure as key-value pairs on the command-line, e.g.,

./configure PREFIX=/opt

These are set in the generated Makefile.configure, which should be included by the source's Makefile. The following are recognised:

  • LDADD: -l libraries and flags usually used for linking binaries
  • LDLIBS: -l libraries and flags usually used for linking shared libraries (LIBADD is sometimes used for this)
  • LDFLAGS: -L linker flags used for linking
  • CPPFLAGS: C preprocessor flags used for compiling objects
  • DESTDIR: prefixed to all install directories during installation, but not otherwise affecting install directories
  • PREFIX: directory for default install directories (defaults to /usr/local)
  • MANDIR: install directory for manpages (defaults to PREFIX/man)
  • LIBDIR: install directory for libraries (defaults to PREFIX/lib)
  • BINDIR: install directory for binaries (defaults to PREFIX/bin)
  • SHAREDIR: install directory for shared files (defaults to PREFIX/share)
  • SBINDIR: install directory for system binaries (defaults to PREFIX/sbin)
  • INCLUDEDIR: install directory for header files (defaults to PREFIX/include)
  • LINKER_SONAME: linker command used to create shared libraries (defaults to -soname or -install_name)

Anything else is discarded and warned about.

If you want to use override the default AR, CC, or CFLAGS variables, specify them as environmental variables. (The results will be set either way in Makefile.configure.) For example:

CC=musl-gcc ./configure

The CC, LDFLAGS, CPPFLAGS, and CFLAGS are used when running the configuration tests themselves. If a default cc compiler is not found, oconfigure will test for clang and gcc before giving up.

For Linux users with libbsd installed, oconfigure can be instructed to use libbsd exclusively as follows:

CFLAGS=$(pkg-config --cflags libbsd-overlay) \
  ./configure LDFLAGS=$(pkg-config --libs libbsd-overlay)

For new versions of libbsd, this will pull in the library for all compatibility replacements instead of those within compats.c.

For shared library generation, a LINKER_SONAME variable (which may be overridden) is set in the generated Makefile.configure to assist in Mac OS X portability. Generating a shared library lib.so.0 from lib.c might look like:

cc -fPIC -o lib.o -c lib.c
cc -shared -o lib.so.0 -Wl,${LINKER_SONAME},lib.so.0 lib.o

The choice of -fPIC or -fpic is left for the user.

Developers

Using oconfigure requires some work within your sources to node compatibility areas, then some in your build environment:

#include "config.h" /* required inclusion */

#if HAVE_ERR /* sometimes err.h exists, sometimes not */
# include <err.h>
#endif
#include <stdio.h>
#include <unistd.h>

int main(void) {
#if HAVE_PLEDGE /* do we have pledge? */
	if (pledge("stdio", NULL) == -1)
		err(1, NULL);
#endif
	warnx("hello, world!"); /* compat provides this */
	return 0;
}

And then...

./configure
cc -o compats.o -c compats.c
cc -o main.o -c main.c
cc compats.o main.o

It's better to build this into your Makefile, as the output Makefile.configure will set compiler, compiler flags, installation utilities, and so on.

The following example also includes portable idioms for a depending library. It uses BSD make style. The compats.c is as given in oconfigure, and Makefile.configure and config.h are generated when running configure.

include Makefile.configure

LDADD_PKG != pkg-config --libs zlib || echo "-lz"
CFLAGS_PKG != pkg-config --cflags zlib || echo ""
LDADD += $(LDADD_PKG)
CFLAGS += $(CFLAGS_PKG)

main: main.o compats.o
	$(CC) -o $@ main.o compats.o $(LDFLAGS) $(LDADD)

install:
	mkdir -p $(DESTDIR)$(BINDIR)
	$(INSTALL_PROGRAM) main $(DESTDIR)$(BINDIR)

main.o compats.o: config.h

clean:
	rm -f main main.o compats.o

Features

What follows is a description of the features and facilities provided by the package when included into your sources.

arc4random(3)

Tests for the arc4random(3) functions in stdlib.h, defining HAVE_ARC4RANDOM with the result.

#if HAVE_ARC4RANDOM
# include <stdlib.h> /* arc4random, arc4random_buf... */
#endif

If not found, provides compatibility functions. The compatibility functions provide the same quality (via the same source) as OpenBSD, using the host's getentropy function for seed.

blowfish(3)

Tests for the original blf_enc(3) cipher functions including the raw block functions (not documented on OpenBSD, but still in the public API.

#if HAVE_BLOWFISH
# include <blf.h> /* blf_enc ... */
#endif

If not found, provides compatibility functions.

b64_ntop

This and its partner b64_pton are sometimes declared but not defined. The following will guard against that in your sources.

#if HAVE_B64_NTOP
# include <netinet/in.h>
# include <resolv.h>
#endif

Some systems (Linux in particular) with HAVE_B64_NTOP need -lresolv during linking. If so, set LDADD_B64_NTOP in Makefile.configure to -lresolv. Otherwise it is empty.

If the functions are not found, provides compatibility functions b64_ntop and b64_pton.

Since these functions are always poorly documented, the following demonstrates usage for b64_ntop, which translates src into an encoded NUL-terminated string dst and returns the string length or -1. The dstsz is the maximum size required for encoding.

srcsz = strlen(src);
dstsz = ((srcsz + 2) / 3 * 4) + 1;
dst = malloc(dstsz);
if (b64_ntop(src, srcsz, dst, dstsz) == -1)
	goto bad_size;

b64_pton reverses this situation from an encoded NUL-terminated string src into the decoded and NUL-terminated string dst (it's common not to need the NUL-terminator for the decoded string, which is meant to be binary). The dstsz is the maximum size required for decoding.

srcsz = strlen(src);
dstsz = srscsz / 4 * 3;
dst = malloc(dstsz + 1); /* NUL terminator */
if ((c = b64_pton(src, dst, dstsz)) == -1)
	goto bad_data;
dst[c] = '\0'; /* NUL termination */

Capsicum

Tests for FreeBSD's Capsicum subsystem, defining the HAVE_CAPSICUM variable with the result. Does not provide any compatibility.

#if HAVE_CAPSICUM
# include <sys/resource.h>
# include <sys/capsicum.h>
#endif

The guard is required for systems without these headers.

crypt(3)

On OpenBSD, passwords are managed primarily through crypt_newhash(3) and friends. However, the old crypt(3) function is still used in portable applications. Even though it's not very portable.

This tests for crypt(3), defining HAVE_CRYPT with the result.

On many systems with HAVE_CRYPT, you'll also need to add -lcrypt when you compile your system, else it will fail with undefined references.

The LDADD_CRYPT value provided in Makefile.configure will be set to -lcrypt if it's required. Otherwise it is empty.

crypt_newhash(3)

This tests for the crypt(3)-replacing functions crypt_newhash(3) and crypt_checkpass(3) functions, defining HAVE_CRYPT_NEWHASH with the result. Provides compatibility functions if not found.

Just as document, the portability functions only provide bcrypt functionality.

endian.h

On most operating systems (Linux, OpenBSD), endian.h provides the POSIX.1 endian functions, e.g., htole32(3), be32toh(3), etc. On FreeBSD, however, these are in sys/endian.h. Mac OS X and SunOS have their own functions in their own places.

The required invocation to use the endian functions is:

#if HAVE_ENDIAN_H
# include <endian.h>
#elif HAVE_SYS_ENDIAN_H
# include <sys/endian.h>
#elif HAVE_OSBYTEORDER_H
# include <libkern/OSByteOrder.h>
#elif HAVE_SYS_BYTEORDER_H
# include <sys/byteorder.h>
#endif

Compatibility for the Mac OS X and SunOS functions to the usual htole32 style is provided.

To make this easier, the COMPAT_ENDIAN_H is also defined:

#include COMPAT_ENDIAN_H

This will paste the appropriate location.

err.h

Tests for the err(3) functions, defining HAVE_ERR variable with the result. If not found, provides compatibility functions err, errx, errc, warn, warnx, warnc, and the variable-argument versions of each.

#if HAVE_ERR
# include <err.h>
#endif

The err.h header needs to be guarded to prevent systems using the compatibility functions for failing, as the header does not exist.

It's worth noting that glibc defines many of these functions, but misses the errc and warnc variations. oconfigure considers it all or nothing, so will not define HAVE_ERR in this case.

explicit_bzero(3)

Tests for explicit_bzero(3) in string.h, defining HAVE_EXPLICIT_BZERO with the result.

#include <string.h> /* explicit_bzero */

If not found, provides a compatibility function. The compatibility layer will use memset_s, if found. HAVE_EXPLICIT_BZERO shouldn't be directly used in most circumstances.

fts(3)

Tests for the fts_open(3) family of functions in fts.h, defining HAVE_FTS with the result. If not found, provides compatibility functions.

#if HAVE_FTS
# include <sys/types.h>
# include <fts.h> /* fts_open(3) et al. */
#endif

The fts.h header needs to be guarded to prevent systems using the compatibility functions for failing, as the header does not exist.

getprogname(3)

Tests for getprogname(3) in stdlib.h, defining HAVE_GETPROGNAME with the result. Provides a compatibility function if not found.

#include <stdlib.h> /* getprogname */

The compatibility function tries to use __progname, program_invocation_short_name, or getexecname(). If none of these interfaces may be found, it will emit a compile-time error. HAVE_GETPROGNAME shouldn't be directly used in most circumstances.

INFTIM

Tests for INFTIM in poll(2), defining HAVE_INFTIM with the result. Provides a compatibility value if not found.

#include <poll.h> /* INFTIM */

Since a compatibility function is provided, HAVE_INFTIM shouldn't be directly used in most circumstances.

landlock

Tests for Linux's landlock) LSM. Defines HAVE_LANDLOCK if found. Does not provide any compatibility.

This test does not mean that the module is enabled. You'll need to perform a run-time check for landlock_restrict_self's return value in your sources.

To actually use Landlock, you'll need to modify your system's LSM at boot time.

libsocket

On IllumOS-based distributions, all socket functions (bind(2), listen(2), socketpair(2), etc.) require linking to the -lsocket and -lnsl libraries.

If this is required, the LDADD_LIB_SOCKET variable in Makefile.configure will be set to the required libraries.

md5.h

Tests for the standalone md5(3) functions, defining HAVE_MD5 with the result.

If not found, provides a full complement of standalone (i.e., not needing any crypto libraries) MD5 hashing functions. These are MD5Init, MD5Update, MD5Pad, MD5Transform, MD5End, and MD5Final. The preprocessor macros MD5_BLOCK_LENGTH, MD5_DIGEST_LENGTH, and MD5_DIGEST_STRING_LENGTH are also defined.

These differ ever-so-slightly from the OpenBSD versions in that they use C99 types for greater portability, e.g., uint8_t instead of u_int8_t.

If using these functions, you'll want to guard an inclusion of the system-default. Otherwise a partial md5.h may conflict with results, or a missing md5.h may terminate compilation.

#if HAVE_MD5
# include <sys/types.h>
# include <md5.h>
#endif

On some systems (FreeBSD or those with Guillem Jover's libmd) with HAVE_MD5, you'll also need to add -lmd when you compile your system, else it will fail with undefined references.

The LDADD_MD5 value provided in Makefile.configure will be set to -lmd if it's required. Otherwise it is empty.

memmem(3)

Tests for memmem(3) in string.h, defining HAVE_MEMMEM with the result. Provides a compatibility function if not found.

#include <string.h> /* memmem */

Since a compatibility function is provided, HAVE_MEMMEM shouldn't be directly used in most circumstances.

memrchr(3)

Tests for memrchr(3) in string.h, defining HAVE_MEMRCHR with the result. Provides a compatibility function if not found.

#include <string.h> /* memrchr */

Since a compatibility function is provided, HAVE_MEMRCHR shouldn't be directly used in most circumstances.

minor(2)

major(2), minor(2), and makedev(2) all live in different places on different systems.

#if HAVE_SYS_MKDEV_H
# include <sys/types.h> /* dev_t */
# include <sys/mkdev.h> /* minor/major/makedev */
#elif HAVE_SYS_SYSMACROS_H
# include <sys/sysmacros.h> /* minor/major/makedev */
#else
# include <sys/types.h> /* minor/major/makedev */
#endif

This can be made much easier as follows, where COMPAT_MAJOR_MINOR_H is set to one of the above. sys/types.h may be included twice.

#include <sys/types.h>
#include COMPAT_MAJOR_MINOR_H

mkfifoat(2)

Tests for the mkfifoat(3) function, defining HAVE_MKFIFOAT with the result. Provides a compatibility function if not found.

This is not a direct replacement, as the function is not atomic: it internally gets a reference to the current directory, changes into the "at" directory, runs the function, then returns to the prior current.

Upon errors, it makes a best effort to restore the current working directory to what it was.

mknodat(2)

Tests for the mknodat(3) function, defining HAVE_MKNODAT with the result. Provides a compatibility function if not found.

This is not a direct replacement, as the function is not atomic: it internally gets a reference to the current directory, changes into the "at" directory, runs the function, then returns to the prior current.

Upon errors, it makes a best effort to restore the current working directory to what it was.

PATH_MAX

Tests for the PATH_MAX variable in limits.h, defining HAVE_PATH_MAX with the result. If not found, defines the PATH_MAX macro to be 4096.

#include <limits.h> /* PATH_MAX */

Since a compatibility value is provided, HAVE_PATH_MAX shouldn't be directly used in most circumstances.

pledge(2)

Test for pledge(2), defining HAVE_PLEDGE with the result. Does not provide any compatibility.

#include <unistd.h> /* pledge */

The HAVE_PLEDGE guard is not required except around the function invocation.

readpassphrase(3)

Tests for the readpassphrase(3) function, defining HAVE_READPASSPHRASE with the result. Provides a compatibility function if not found. The <readpassphrase.h> header inclusion needs to be guarded for systems that include it by default; otherwise, the definitions are provided in the generated config.h:

#if HAVE_READPASSPHRASE
# include <readpassphrase.h>
#endif

If using this function, makes sure you explicitly zero the passphrase buffer as described in readpassphrase(3).

reallocarray(3)

Tests for reallocarray(3) in stdlib.h, defining HAVE_REALLOCARRAY with the result. Provides a compatibility function if not found.

#include <stdlib.h> /* reallocarray */

Since a compatibility function is provided, HAVE_REALLOCARRAY shouldn't be directly used in most circumstances.

recallocarray(3)

Tests for recallocarray(3) in stdlib.h, defining HAVE_RECALLOCARRAY with the result. Provides a compatibility function if not found.

#include <stdlib.h> /* recallocarray */

Since a compatibility function is provided, HAVE_RECALLOCARRAY shouldn't be directly used in most circumstances.

sandbox_init(3)

Tests for sandbox_init(3), defining HAVE_SANDBOX_INIT with the result. Does not provide any compatibility.

scan_scaled(3), fmt_scaled(3)

Tests for OpenBSD's scan_scaled(3), defining HAVE_SCAN_SCALED if it was found. Provides a compatibility function if not found. If the function is not found, fmt_scaled(3) is also part of the compatibility package.

#if HAVE_SCAN_SCALED
# include <util.h>
#endif

If this is required, the LDADD_SCAN_SCALED variable in Makefile.configure will be set to the required library (-lutil).

seccomp-filter(3)

Tests for Linux's prctl(2) function, which is the gateway for seccomp(2). This defines several variables:

  • HAVE_SECCOMP_HEADER: Compile-time support exists for seccomp.
  • SECCOMP_AUDIT_ARCH: If HAVE_SECCOMP_HEADER is set, this is set to the architecture used for seccomp operations (e.g., AUDIT_ARCH_ARM). If this is not set and HAVE_SECCOMP_HEADER is set, seccomp is enabled in the kernel but the hardware architecture is not known by oconfigure. Please create an issue or pull request with your uname -m and hardware profile.
  • HAVE_SECCOMP_FILTER: Set if both HAVE_SECCOMP_HEADER and SECCOMP_AUDIT_ARCH are set.

Does not provide any compatibility.

This test does not mean that the sandboxing is enabled. You'll need to perform a run-time check for prctl's return value in your sources.

sha2.h

Tests for the standalone sha2(3) functions, defining HAVE_SHA2 with the result. This was previously provided as HAVE_SHA2_H, which still works as an alias for HAVE_SHA2.

If not found, provides a full complement of standalone SHA2 hashing functions. These are SHA256Init, SHA256Transform, SHA256Update, SHA256Pad, SHA256Final, SHA256End, SHA256File, SHA256FileChunk, and SHA256Data. The preprocessor macros SHA256_BLOCK_LENGTH, SHA256_DIGEST_LENGTH, and SHA256_DIGEST_STRING_LENGTH are also defined.

The SHA2 functions and macros are provided for SHA256, SHA384, and SHA512. So for example the SHA512Final function is also provided.

If using these functions, you'll want to guard an inclusion of the system-default. Otherwise a partial sha2.h may conflict with results, or a missing sha2.h may terminate compilation.

#if HAVE_SHA2
# include <sys/types.h>
# include <sha2.h>
#endif

On some systems (such as those with Guillem Jover's libmd) with HAVE_SHA2, you'll also need to add -lmd when you compile your system, else it will fail with undefined references.

The LDADD_SHA2 value provided in Makefile.configure will be set to -lmd if it's required. Otherwise it is empty.

SOCK_NONBLOCK

Tests for socketpair(2) in sys/socket.h supporting the SOCK_NONBLOCK mask as found on OpenBSD. Defines the HAVE_SOCK_NONBLOCK variable.

#if HAVE_SOCK_NONBLOCK
	socketpair(AF_UNIX, flags|SOCK_NONBLOCK, 0, fd);
#else
	socketpair(AF_UNIX, flags, 0, fd);
	fcntl(fd[0], F_SETFL, 
	      fcntl(fd[0], F_GETFL, 0)|O_NONBLOCK);
	fcntl(fd[1], F_SETFL, 
	      fcntl(fd[1], F_GETFL, 0)|O_NONBLOCK);
#endif

The guard is not required only around the variable usage, not header inclusion. However, the above example could have the fcntl.h header guarded by !HAVE_SOCK_NONBLOCK.

strlcat(3)

Tests for strlcat(3) in string.h, defining HAVE_STRLCAT with the result. Provides a compatibility function if not found.

#include <string.h> /* strlcat */

Since a compatibility function is provided, HAVE_STRLCAT shouldn't be directly used in most circumstances.

strlcpy(3)

Tests for strlcpy(3) in string.h, defining HAVE_STRLCPY with the result. Provides a compatibility function if not found.

#include <string.h> /* strlcpy */

Since a compatibility function is provided, HAVE_STRLCPY shouldn't be directly used in most circumstances.

strndup(3)

Tests for strndup(3) in string.h, defining HAVE_STRNDUP with the result. Provides a compatibility function if not found.

#include <string.h> /* strndup */

Since a compatibility function is provided, HAVE_STRNDUP shouldn't be directly used in most circumstances.

strnlen(3)

Tests for strnlen(3) in string.h, defining HAVE_STRNLEN with the result. Provides a compatibility function if not found.

#include <string.h> /* strnlen */

Since a compatibility function is provided, HAVE_STRNLEN shouldn't be directly used in most circumstances.

strtonum(3)

Tests for strtonum(3) in stdlib.h, defining HAVE_STRTONUM with the result. Provides a compatibility function if not found.

#include <stdlib.h> /* strtonum */

Since a compatibility value is provided, HAVE_STRTONUM shouldn't be directly used in most circumstances.

sys/queue.h

Tests for the queue(3) header, sys/queue.h. Defines HAVE_SYS_QUEUE if found and provides all of the queue macros if not. To use these macros, make sure to guard inclusion:

#if HAVE_SYS_QUEUE
# include <sys/queue.h>
#endif

This uses TAILQ_FOREACH_SAFE as a basis for determining whether the header exists and is well-formed. This is because glibc provides a skeleton sys/queue.h without this critical macro.

sys/tree.h

Tests for the tree(3) header, sys/tree.h. Defines HAVE_SYS_TREE if found and provides all of the tree macros if not. To use these macros, make sure to guard inclusion:

#if HAVE_SYS_TREE
# include <sys/tree.h>
#endif

systrace(4)

Tests for the deprecated systrace(4) interface. Defines HAVE_SYSTRACE if found. Does not provide any compatibility.

This function is never "found".

termios(4)

Tests for whether termios(4) exists, defining HAVE_TERMIOS with the result, specifically with the use case of testing terminal widths via ioctl(2) and TIOCGWINSZ (which must also exist). Does not provide any compaibility.

timingsafe_bcmp(3)

Tests for the timingsafe_bcmp(3) functions in string.h, defining HAVE_TIMINGSAFE_BCMP with the result.

#if HAVE_TIMINGSAFE_BCMP
# include <string.h> /* timingsafe_bcmp... */
#endif

If not found, provides compatibility functions.

unveil(2)

Test for unveil(2), defining HAVE_UNVEIL with the result. Does not provide any compatibility.

#include <unistd.h> /* unveil */

The HAVE_UNVEIL guard is not required except around the function invocation.

WAIT_ANY

Tests for WAIT_ANY in waitpid(2), defining HAVE_WAIT_ANY with the result. Provides a compatibility value for both WAIT_ANY and WAIT_MYPGRP if not found.

#include <sys/wait.h> /* WAIT_ANY, WAIT_MYPGRP */

Since a compatibility function is provided, HAVE_WAIT_ANY shouldn't be directly used in most circumstances.

oconfigure's People

Contributors

kristapsdz avatar paravoid avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar

oconfigure's Issues

Replace which by test builtin

Hi there Kristaps,

I would like to ask you what do you think about replacing which by test builtin in oconfigure ? test -x is supported by almost all shells. I would say it's a major benefit. Testing an executable in all directories in PATH could be portable. I am thinking about something like this (I wrote this function for one of my project) :

chk_path() {
	# Return binaries ONLY. POSIX 'command' builtin returns functions.
	# local isn't specified by POSIX!
	local IFS
	local p

	IFS=':'
	for p in $PATH; do
		if [ ! -d "$p" ]; then
			continue
		fi
		if [ -x "${p}/${1}" ]; then
			printf "%s\n" "${p}/${1}"
			return 0
		fi
	done
}

What's your opinion about it ?

Cheers

Support separate builds

$ mkdir build && cd build
$ ../configure && make

If all build output could optionally be confined to an arbitrary directory, blowing it away would leave me with a pristine source tree (very helpful in the ports tree where “make clean” doesn’t get passed through to the software’s makefile). This feature shows up in a lot of newer build systems like cmake and meson and I find myself using it quite a lot.

CC/CFLAGS are misdefined when ./configure is run in a sub-make

This is perhaps easier to explain with a test case than with words: in a GNU+Linux system, add a Makefile.test in the root directory of oconfigure, with those contents:

all:
	./configure

Then, run make -f Makefile.test -w.

configure has a couple of make -sf invocations, which are considered submakes by GNU Make, and thus Entering directory and Leaving directory messages are emitted by it. This makes the CC and CFLAGS outputs of Makefile.configure contain garbage, and in fact the file being syntactically invalid as well.

There is a relatively easy fix:

-CC=`printf "all:\\n\\t@echo \\\$(CC)\\n" | make -sf -`
-CFLAGS=`printf "all:\\n\\t@echo \\\$(CFLAGS)\\n" | make -sf -`
+CC=`printf "all:\\n\\t@echo \\\$(CC)\\n" | make --no-print-directory -sf -`
+CFLAGS=`printf "all:\\n\\t@echo \\\$(CFLAGS)\\n" | make --no-print-directory -sf -`

…but I doubt this would work under BSD Make. I don't have a BSD system to experiment on, but hoping you'd have a better idea on how to address this use case.

(The above test case is a simplified one, of a more complex sequence that happens when building Debian packages, so it's not just a theoretical problem)

sha2 sha224 etc.

Hi
please add some other functions SHA224Init etc., SHA512_256Init etc., SHA1Init etc., and RMD160Init etc.
Many thanks.

SHA2 docs are referring to MD5

In the README.md, the text currently reads:

Tests for the standalone sha2(3) functions, defining HAVE_MD5 with the result.
If not found, provides a full complement of standalone (i.e., not needing any crypto libraries) MD5 hashing functions.
[… more MD5 function references …]
(emphasis mine)

It looks like this was just copy/pasted from the MD5 section but never updated. I'm not submitting a PR because I'm actually unsure about some of the nuances there with regards to C99 types etc.

Also see #15 for the libmd bit.

Use libbsd in part or in whole for the compat layer?

(I realize this may sound provocative but it's with the best of intentions :))

It looks like this project is providing two pieces of functionality: 1) configuration & feature testing, with HAVE_ definitions that projects can use to conditionally enable some functionality (e.g. pledge), 2) compatibility code to implement certain OpenBSD libc/stdlib functions.

There is another project that tries to do (2), libbsd. It's a library, so that one can dynamically link to it and avoid vendoring all of those functions into target binaries themselves, and even provides a "libbsd-overlay" pkg-config that transparently handles the inclusion by downstream projects.

Compared to this project, it seems to have quite a few more BSD APIs implemented and has better coverage in general (e.g. manpages, unit tests etc.). From a quick look, it looks like it's only missing the following compat interfaces that oconfigure ships with:

  • SHA2 functions. These are, however, part of libmd (by the same author, @guillemj), a dependency of oconfigure already
  • recallocarray(), for which I submitted a PR against libbsd just now.
  • (possibly) a sys/types.h implementation to define major/minor/makedev (e.g. by including sysmacros.h on glibc/musl systems)

I wonder whether it would make sense perhaps to consolidate efforts here, contribute anything that's missing there, and convert oconfigure to focus on the feature detection part/autotools replacement part and rely on libbsd for the implementation?

Alternatively, perhaps oconfigure could test pkg-config --exists libbsd-overlay and, if successful, add the relevant CFLAGS/LDFLAGS to use it?

get/setprogname issues

Currently, the presence of getprogname(), program_invocation_short_name and __progname are checked before erroring at the pre-processor level. This means we can't compile on systems that don't have any of these (e.g. Solaris 10, yeah I know) where it would be better to work around it.

Another annoyance is that, on systems where getprogname fails but the others succeed, HAVE_GETPROGNAME is not true, leading to checks like this:

#if !(HAVE_GETPROGNAME || HAVE_PROGRAM_INVOCATION_SHORT_NAME || HAVE__PROGNAME)
	const char *progname;
	if ((progname = strrchr(argv[0], '/')) == NULL)
		progname = argv[0];
	else
		progname++;
	setprogname(progname);
#endif

This is from me patching out the cpp error I mentioned above. I think it would be better to provide an implementation of getprogname if all else fails. Currently, mandoc has the folllowing (compat_progname.c):

#include "config.h"

#if HAVE_PROGNAME
int dummy;
#else
static const char *progname;

void
setprogname(const char *name)
{

	progname = name;
}

const char *
getprogname(void)
{

	return progname;
}

#endif

Where main would set progname as so:

#if HAVE_PROGNAME
	progname = getprogname();
#else
	if ((progname = strrchr(argv[0], '/')) == NULL)
		progname = argv[0];
	else
		++progname;
	setprogname(progname);
#endif

MANDIR on macOS

Hi, I'm not sure if this is a concern or not, but on macOS oconfigure sets MANDIR to ${PREFIX}/man which is usually /usr/local/man. However, on macOS this directory is not in the default MANPATH with man pages usually installed to /usr/local/share/man.

It is of course very easy to call # make MANDIR=/usr/local/share/man install but I just thought I'd flag it for you :)

sys/queue.h test fails

sys_queue: testing...
cc  -g -W -Wall -Wextra -Wmissing-prototypes -Wstrict-prototypes -Wwrite-strings -Wno-unused-parameter  -Wno-unused -Werror -DTEST_SYS_QUEUE  -o test-sys_queue tests.c
In file included from tests.c:366:
tests.c: In function 'main':
tests.c:380:2: error: 'NULL' undeclared (first use in this function)
  TAILQ_INIT(&foo_q);
  ^~~~~~~~~~
tests.c:380:2: note: 'NULL' is defined in header '<stddef.h>'; did you forget to '#include <stddef.h>'?
tests.c:367:1:
+#include <stddef.h>

tests.c:380:2:
  TAILQ_INIT(&foo_q);
  ^~~~~~~~~~
tests.c:380:2: note: each undeclared identifier is reported only once for each function it appears in
sys_queue: cc failed with 1

edit: fails with both glibc and musl, glibc with their sys/queue.h and musl with the openbsd sys/queue.h for compatibility. Alpine ships this as bsd-compat-headers.

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.