various: add -Dbuild-static and alternatives to libc functions
When we try to build with -static, the linker refuses dlopen and various functions related to nss. This commit adds the basic support to compile with -static and allow the link to pass.
This commit is contained in:
@@ -80,6 +80,8 @@ conf.set10('SD_BOOT', false)
|
||||
|
||||
conf.set10('SYSTEMD_MULTICALL_BINARY', get_option('systemd-multicall-binary'))
|
||||
|
||||
conf.set10('BUILD_STATIC', get_option('build-static'))
|
||||
|
||||
# Create a title-less summary section early, so it ends up first in the output.
|
||||
# More items are added later after they have been detected.
|
||||
summary({
|
||||
|
||||
@@ -42,6 +42,8 @@ option('static-libudev', type : 'combo',
|
||||
description : 'install a static library for libudev')
|
||||
option('standalone-binaries', type : 'boolean', value : false,
|
||||
description : 'also build standalone versions of supported binaries')
|
||||
option('build-static', type : 'boolean', value : false,
|
||||
description : 'build static versions of supported binaries')
|
||||
|
||||
option('sysvinit-path', type : 'string', value : '/etc/init.d', deprecated : true,
|
||||
description : 'This option is deprecated and will be removed in a future release')
|
||||
|
||||
@@ -101,6 +101,10 @@ void block_dlopen(void) {
|
||||
}
|
||||
|
||||
int dlopen_safe(const char *filename, void **ret, const char **reterr_dlerror) {
|
||||
#if BUILD_STATIC
|
||||
return log_debug_errno(SYNTHETIC_ERRNO(EOPNOTSUPP),
|
||||
"dlopen is not supported in static builds, cannot load %s.", filename);
|
||||
#else
|
||||
_cleanup_(dlclosep) void *dl = NULL;
|
||||
int r;
|
||||
|
||||
@@ -142,4 +146,5 @@ int dlopen_safe(const char *filename, void **ret, const char **reterr_dlerror) {
|
||||
*ret = TAKE_PTR(dl);
|
||||
|
||||
return 0;
|
||||
#endif
|
||||
}
|
||||
|
||||
+43
-13
@@ -1171,6 +1171,9 @@ int lookup_pwent_in_files(
|
||||
|
||||
return -ESRCH;
|
||||
}
|
||||
|
||||
#if !BUILD_STATIC
|
||||
|
||||
static size_t getpw_buffer_size(void) {
|
||||
long bufsize = sysconf(_SC_GETPW_R_SIZE_MAX);
|
||||
return bufsize <= 0 ? 4096U : (size_t) bufsize;
|
||||
@@ -1182,15 +1185,25 @@ static bool errno_is_user_doesnt_exist(int error) {
|
||||
return IN_SET(abs(error), ENOENT, ESRCH, EBADF, EPERM);
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
int getpwnam_malloc(const char *name, struct passwd **ret) {
|
||||
/* For static builds use a very simplistic implementation that looks at 'passwd' in /etc/
|
||||
* and /usr/lib/, and for non-static builds use NSS. The first matching entry wins. The
|
||||
* same logic is implemented in getpwnam_malloc, getpwuid_malloc, getgrnam_malloc, and
|
||||
* getgrgid_malloc. */
|
||||
|
||||
if (isempty(name))
|
||||
return -EINVAL;
|
||||
|
||||
#if BUILD_STATIC
|
||||
return lookup_pwent_in_files(PASSWD_FILES, name, UID_INVALID, ret);
|
||||
#else
|
||||
size_t bufsize = getpw_buffer_size();
|
||||
int r;
|
||||
|
||||
/* A wrapper around getpwnam_r() that allocates the necessary buffer on the heap. The caller must
|
||||
* free() the returned structures! */
|
||||
|
||||
if (isempty(name))
|
||||
return -EINVAL;
|
||||
* free() the returned structure! */
|
||||
|
||||
for (;;) {
|
||||
_cleanup_free_ void *buf = NULL;
|
||||
@@ -1226,15 +1239,19 @@ int getpwnam_malloc(const char *name, struct passwd **ret) {
|
||||
return -ENOMEM;
|
||||
bufsize *= 2;
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
int getpwuid_malloc(uid_t uid, struct passwd **ret) {
|
||||
size_t bufsize = getpw_buffer_size();
|
||||
int r;
|
||||
|
||||
if (!uid_is_valid(uid))
|
||||
return -EINVAL;
|
||||
|
||||
#if BUILD_STATIC
|
||||
return lookup_pwent_in_files(PASSWD_FILES, /* name= */ NULL, uid, ret);
|
||||
#else
|
||||
size_t bufsize = getpw_buffer_size();
|
||||
int r;
|
||||
|
||||
for (;;) {
|
||||
_cleanup_free_ void *buf = NULL;
|
||||
|
||||
@@ -1267,6 +1284,7 @@ int getpwuid_malloc(uid_t uid, struct passwd **ret) {
|
||||
return -ENOMEM;
|
||||
bufsize *= 2;
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
static int copy_struct_group(const struct group *gr, struct group **ret) {
|
||||
@@ -1427,18 +1445,25 @@ ssize_t lookup_groups_in_files(
|
||||
return n_arr;
|
||||
}
|
||||
|
||||
#if !BUILD_STATIC
|
||||
|
||||
static size_t getgr_buffer_size(void) {
|
||||
long bufsize = sysconf(_SC_GETGR_R_SIZE_MAX);
|
||||
return bufsize <= 0 ? 4096U : (size_t) bufsize;
|
||||
}
|
||||
|
||||
int getgrnam_malloc(const char *name, struct group **ret) {
|
||||
size_t bufsize = getgr_buffer_size();
|
||||
int r;
|
||||
#endif
|
||||
|
||||
int getgrnam_malloc(const char *name, struct group **ret) {
|
||||
if (isempty(name))
|
||||
return -EINVAL;
|
||||
|
||||
#if BUILD_STATIC
|
||||
return lookup_grent_in_files(GROUP_FILES, name, GID_INVALID, ret);
|
||||
#else
|
||||
size_t bufsize = getgr_buffer_size();
|
||||
int r;
|
||||
|
||||
for (;;) {
|
||||
_cleanup_free_ void *buf = NULL;
|
||||
|
||||
@@ -1471,15 +1496,19 @@ int getgrnam_malloc(const char *name, struct group **ret) {
|
||||
return -ENOMEM;
|
||||
bufsize *= 2;
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
int getgrgid_malloc(gid_t gid, struct group **ret) {
|
||||
size_t bufsize = getgr_buffer_size();
|
||||
int r;
|
||||
|
||||
if (!gid_is_valid(gid))
|
||||
return -EINVAL;
|
||||
|
||||
#if BUILD_STATIC
|
||||
return lookup_grent_in_files(GROUP_FILES, /* name= */ NULL, gid, ret);
|
||||
#else
|
||||
size_t bufsize = getgr_buffer_size();
|
||||
int r;
|
||||
|
||||
for (;;) {
|
||||
_cleanup_free_ void *buf = NULL;
|
||||
|
||||
@@ -1512,4 +1541,5 @@ int getgrgid_malloc(gid_t gid, struct group **ret) {
|
||||
return -ENOMEM;
|
||||
bufsize *= 2;
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
@@ -159,6 +159,10 @@ static inline bool hashed_password_is_locked_or_invalid(const char *password) {
|
||||
return password && password[0] != '$';
|
||||
}
|
||||
|
||||
/* Places where we will try to load account data from */
|
||||
#define PASSWD_FILES STRV_MAKE("/etc/passwd", "/usr/lib/passwd")
|
||||
#define GROUP_FILES STRV_MAKE("/etc/group", "/usr/lib/group")
|
||||
|
||||
/* A locked *and* invalid password for "struct spwd"'s .sp_pwdp and "struct passwd"'s .pw_passwd field */
|
||||
#define PASSWORD_LOCKED_AND_INVALID "!*"
|
||||
|
||||
|
||||
@@ -827,6 +827,10 @@ static int parse_unix_address(sd_bus *b, const char **p, char **guid) {
|
||||
}
|
||||
|
||||
static int parse_tcp_address(sd_bus *b, const char **p, char **guid) {
|
||||
#if BUILD_STATIC
|
||||
return log_debug_errno(SYNTHETIC_ERRNO(EOPNOTSUPP),
|
||||
"tcp:// connections are not supported in static builds");
|
||||
#else
|
||||
_cleanup_free_ char *host = NULL, *port = NULL, *family = NULL;
|
||||
int r;
|
||||
struct addrinfo *result, hints = {
|
||||
@@ -889,6 +893,7 @@ static int parse_tcp_address(sd_bus *b, const char **p, char **guid) {
|
||||
b->is_local = false;
|
||||
|
||||
return 0;
|
||||
#endif
|
||||
}
|
||||
|
||||
static int parse_exec_address(sd_bus *b, const char **p, char **guid) {
|
||||
|
||||
@@ -53,10 +53,10 @@ static int populate_uid_cache(const char *root, Hashmap **ret) {
|
||||
/* The directory list is hardcoded here: /etc is the standard, and rpm-ostree uses /usr/lib. This
|
||||
* could be made configurable, but I don't see the point right now. */
|
||||
|
||||
FOREACH_STRING(fname, "/etc/passwd", "/usr/lib/passwd") {
|
||||
STRV_FOREACH(fname, PASSWD_FILES) {
|
||||
_cleanup_fclose_ FILE *f = NULL;
|
||||
|
||||
r = open_passwd_file(root, fname, &f);
|
||||
r = open_passwd_file(root, *fname, &f);
|
||||
if (r == -ENOENT)
|
||||
continue;
|
||||
if (r < 0)
|
||||
@@ -93,10 +93,10 @@ static int populate_gid_cache(const char *root, Hashmap **ret) {
|
||||
if (!cache)
|
||||
return -ENOMEM;
|
||||
|
||||
FOREACH_STRING(fname, "/etc/group", "/usr/lib/group") {
|
||||
STRV_FOREACH(fname, GROUP_FILES) {
|
||||
_cleanup_fclose_ FILE *f = NULL;
|
||||
|
||||
r = open_passwd_file(root, fname, &f);
|
||||
r = open_passwd_file(root, *fname, &f);
|
||||
if (r == -ENOENT)
|
||||
continue;
|
||||
if (r < 0)
|
||||
|
||||
Reference in New Issue
Block a user