From 251f7473436097d0f142af806477af8510301491 Mon Sep 17 00:00:00 2001 From: Dan Kegel Date: Sun, 4 Jun 2017 15:17:51 -0700 Subject: [PATCH 01/14] First draft of cmake port --- CMakeLists.txt | 61 ++++++++++++++++++++++++++++++++++++ libpkgconf/CMakeLists.txt | 16 ++++++++++ libpkgconf/config.h.cmake.in | 8 +++++ 3 files changed, 85 insertions(+) create mode 100644 CMakeLists.txt create mode 100644 libpkgconf/CMakeLists.txt create mode 100644 libpkgconf/config.h.cmake.in diff --git a/CMakeLists.txt b/CMakeLists.txt new file mode 100644 index 0000000..5193158 --- /dev/null +++ b/CMakeLists.txt @@ -0,0 +1,61 @@ +CMAKE_MINIMUM_REQUIRED(VERSION 3.5.1) +PROJECT(pkgconf C) + +SET(PACKAGE_BUGREPORT http://github.com/pkgconf/pkgconf/issues) +SET(PACKAGE_NAME pkgconf) +SET(PACKAGE_VERSION 1.3.7) + +# Expand config.h +INCLUDE (CheckIncludeFiles) +CHECK_INCLUDE_FILES(sys/stat.h HAVE_SYS_STAT_H) +INCLUDE (CheckFunctionExists) +CHECK_FUNCTION_EXISTS(strlcpy HAVE_STRLCPY) +CHECK_FUNCTION_EXISTS(strlcat HAVE_STRLCAT) +CHECK_FUNCTION_EXISTS(strndup HAVE_STRNDUP) +CHECK_FUNCTION_EXISTS(cygwin_conv_path HAVE_CYGWIN_CONV_PATH) +SET(abs_top_srcdir ${pkgconf_SOURCE_DIR}) +CONFIGURE_FILE(libpkgconf/config.h.cmake.in libpkgconf/config.h @ONLY) +# Expand others +FOREACH(file Kyuafile libpkgconf.pc tests/Kyuafile tests/test_env.sh) + CONFIGURE_FILE(${file}.in ${file} @ONLY) +ENDFOREACH() + +IF (WIN32) + SET(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} /Wx") +ELSE() + SET(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -Wall -Wextra -Wformat=2 -std=gnu99") +ENDIF() + +INCLUDE_DIRECTORIES(${pkgconf_SOURCE_DIR} ${pkgconf_BINARY_DIR}) +ADD_DEFINITIONS(-DPKG_DEFAULT_PATH=\"$(pkg_default_dir)\") +ADD_DEFINITIONS(-DSYSTEM_INCLUDEDIR=\"$(system_includedir)\") +ADD_DEFINITIONS(-DSYSTEM_LIBDIR=\"$(system_libdir)\") + +ADD_SUBDIRECTORY(libpkgconf) + +INCLUDE_DIRECTORIES(${libpkgconf_BINARY_DIR}) +ADD_EXECUTABLE(pkgconf main.c getopt_long.c) +TARGET_LINK_LIBRARIES(pkgconf libpkgconf) + +ENABLE_TESTING() + +SET(test_scripts + tests/basic + tests/builtins + tests/conflicts + tests/framework + tests/parser + tests/provides + tests/regress + tests/requires + tests/sysroot + tests/version + ) +# No accounting for taste +FOREACH(file ${test_scripts}) + CONFIGURE_FILE(${file}.sh ${file} @ONLY) +ENDFOREACH() + +ADD_TEST(kyua + kyua --config=none test --kyuafile=${pkgconf_BINARY_DIR}/Kyuafile --build-root=${pkgconf_BINARY_DIR} + ) diff --git a/libpkgconf/CMakeLists.txt b/libpkgconf/CMakeLists.txt new file mode 100644 index 0000000..fa3066c --- /dev/null +++ b/libpkgconf/CMakeLists.txt @@ -0,0 +1,16 @@ +PROJECT(libpkgconf C) + +ADD_LIBRARY(libpkgconf + argvsplit.c + audit.c + bsdstubs.c + cache.c + client.c + dependency.c + fileio.c + fragment.c + path.c + pkg.c + queue.c + tuple.c +) diff --git a/libpkgconf/config.h.cmake.in b/libpkgconf/config.h.cmake.in new file mode 100644 index 0000000..12fc8d4 --- /dev/null +++ b/libpkgconf/config.h.cmake.in @@ -0,0 +1,8 @@ +#cmakedefine HAVE_CYGWIN_CONV_PATH +#cmakedefine HAVE_STRLCAT +#cmakedefine HAVE_STRLCPY +#cmakedefine HAVE_STRNDUP +#cmakedefine HAVE_SYS_STAT_H +#cmakedefine PACKAGE_BUGREPORT "@PACKAGE_BUGREPORT@" +#cmakedefine PACKAGE_NAME "@PACKAGE_NAME@" +#cmakedefine PACKAGE_VERSION "@PACKAGE_VERSION@" From d4098f95c370541aaff9b23afc07fe0e4502b43b Mon Sep 17 00:00:00 2001 From: Dan Kegel Date: Sun, 4 Jun 2017 17:46:38 -0700 Subject: [PATCH 02/14] Document how to install test dependencies on ubuntu Just a tip to save other devs a few minutes. --- CMakeLists.txt | 2 +- scripts/install_deps.sh | 5 +++++ 2 files changed, 6 insertions(+), 1 deletion(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index 5193158..4111a8e 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -21,7 +21,7 @@ FOREACH(file Kyuafile libpkgconf.pc tests/Kyuafile tests/test_env.sh) ENDFOREACH() IF (WIN32) - SET(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} /Wx") + SET(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} /WX") ELSE() SET(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -Wall -Wextra -Wformat=2 -std=gnu99") ENDIF() diff --git a/scripts/install_deps.sh b/scripts/install_deps.sh index 3538a53..6cf6723 100755 --- a/scripts/install_deps.sh +++ b/scripts/install_deps.sh @@ -27,6 +27,11 @@ # # This script is primarily intended for travis CI to be able to setup the # build environment. +# +# To run on a clean Ubuntu system, try something like this: +# export PKG_CONFIG_PATH=/usr/local/lib/pkgconfig +# sudo apt install liblua5.2-dev libsqlite3-dev +# sh -ex scripts/install_deps.sh install_from_github() { local name="${1}" From 35d0f63dafd21e04033974a140e4f425a67ff98e Mon Sep 17 00:00:00 2001 From: Dan Kegel Date: Sun, 4 Jun 2017 19:19:01 -0700 Subject: [PATCH 03/14] win-dirent.h: MIT-licensed port of dirent to win32 from https://github.com/tronkko/dirent --- libpkgconf/win-dirent.h | 929 ++++++++++++++++++++++++++++++++++++++++ 1 file changed, 929 insertions(+) create mode 100644 libpkgconf/win-dirent.h diff --git a/libpkgconf/win-dirent.h b/libpkgconf/win-dirent.h new file mode 100644 index 0000000..ad9d2b3 --- /dev/null +++ b/libpkgconf/win-dirent.h @@ -0,0 +1,929 @@ +/* + * Dirent interface for Microsoft Visual Studio + * Version 1.21 + * + * Copyright (C) 2006-2012 Toni Ronkko + * This file is part of dirent. Dirent may be freely distributed + * under the MIT license. For all details and documentation, see + * https://github.com/tronkko/dirent + */ +#ifndef DIRENT_H +#define DIRENT_H + +/* + * Include windows.h without Windows Sockets 1.1 to prevent conflicts with + * Windows Sockets 2.0. + */ +#ifndef WIN32_LEAN_AND_MEAN +# define WIN32_LEAN_AND_MEAN +#endif +#include + +#include +#include +#include +#include +#include +#include +#include +#include +#include + +/* Indicates that d_type field is available in dirent structure */ +#define _DIRENT_HAVE_D_TYPE + +/* Indicates that d_namlen field is available in dirent structure */ +#define _DIRENT_HAVE_D_NAMLEN + +/* Entries missing from MSVC 6.0 */ +#if !defined(FILE_ATTRIBUTE_DEVICE) +# define FILE_ATTRIBUTE_DEVICE 0x40 +#endif + +/* File type and permission flags for stat(), general mask */ +#if !defined(S_IFMT) +# define S_IFMT _S_IFMT +#endif + +/* Directory bit */ +#if !defined(S_IFDIR) +# define S_IFDIR _S_IFDIR +#endif + +/* Character device bit */ +#if !defined(S_IFCHR) +# define S_IFCHR _S_IFCHR +#endif + +/* Pipe bit */ +#if !defined(S_IFFIFO) +# define S_IFFIFO _S_IFFIFO +#endif + +/* Regular file bit */ +#if !defined(S_IFREG) +# define S_IFREG _S_IFREG +#endif + +/* Read permission */ +#if !defined(S_IREAD) +# define S_IREAD _S_IREAD +#endif + +/* Write permission */ +#if !defined(S_IWRITE) +# define S_IWRITE _S_IWRITE +#endif + +/* Execute permission */ +#if !defined(S_IEXEC) +# define S_IEXEC _S_IEXEC +#endif + +/* Pipe */ +#if !defined(S_IFIFO) +# define S_IFIFO _S_IFIFO +#endif + +/* Block device */ +#if !defined(S_IFBLK) +# define S_IFBLK 0 +#endif + +/* Link */ +#if !defined(S_IFLNK) +# define S_IFLNK 0 +#endif + +/* Socket */ +#if !defined(S_IFSOCK) +# define S_IFSOCK 0 +#endif + +/* Read user permission */ +#if !defined(S_IRUSR) +# define S_IRUSR S_IREAD +#endif + +/* Write user permission */ +#if !defined(S_IWUSR) +# define S_IWUSR S_IWRITE +#endif + +/* Execute user permission */ +#if !defined(S_IXUSR) +# define S_IXUSR 0 +#endif + +/* Read group permission */ +#if !defined(S_IRGRP) +# define S_IRGRP 0 +#endif + +/* Write group permission */ +#if !defined(S_IWGRP) +# define S_IWGRP 0 +#endif + +/* Execute group permission */ +#if !defined(S_IXGRP) +# define S_IXGRP 0 +#endif + +/* Read others permission */ +#if !defined(S_IROTH) +# define S_IROTH 0 +#endif + +/* Write others permission */ +#if !defined(S_IWOTH) +# define S_IWOTH 0 +#endif + +/* Execute others permission */ +#if !defined(S_IXOTH) +# define S_IXOTH 0 +#endif + +/* Maximum length of file name */ +#if !defined(PATH_MAX) +# define PATH_MAX MAX_PATH +#endif +#if !defined(FILENAME_MAX) +# define FILENAME_MAX MAX_PATH +#endif +#if !defined(NAME_MAX) +# define NAME_MAX FILENAME_MAX +#endif + +/* File type flags for d_type */ +#define DT_UNKNOWN 0 +#define DT_REG S_IFREG +#define DT_DIR S_IFDIR +#define DT_FIFO S_IFIFO +#define DT_SOCK S_IFSOCK +#define DT_CHR S_IFCHR +#define DT_BLK S_IFBLK +#define DT_LNK S_IFLNK + +/* Macros for converting between st_mode and d_type */ +#define IFTODT(mode) ((mode) & S_IFMT) +#define DTTOIF(type) (type) + +/* + * File type macros. Note that block devices, sockets and links cannot be + * distinguished on Windows and the macros S_ISBLK, S_ISSOCK and S_ISLNK are + * only defined for compatibility. These macros should always return false + * on Windows. + */ +#if !defined(S_ISFIFO) +# define S_ISFIFO(mode) (((mode) & S_IFMT) == S_IFIFO) +#endif +#if !defined(S_ISDIR) +# define S_ISDIR(mode) (((mode) & S_IFMT) == S_IFDIR) +#endif +#if !defined(S_ISREG) +# define S_ISREG(mode) (((mode) & S_IFMT) == S_IFREG) +#endif +#if !defined(S_ISLNK) +# define S_ISLNK(mode) (((mode) & S_IFMT) == S_IFLNK) +#endif +#if !defined(S_ISSOCK) +# define S_ISSOCK(mode) (((mode) & S_IFMT) == S_IFSOCK) +#endif +#if !defined(S_ISCHR) +# define S_ISCHR(mode) (((mode) & S_IFMT) == S_IFCHR) +#endif +#if !defined(S_ISBLK) +# define S_ISBLK(mode) (((mode) & S_IFMT) == S_IFBLK) +#endif + +/* Return the exact length of d_namlen without zero terminator */ +#define _D_EXACT_NAMLEN(p) ((p)->d_namlen) + +/* Return number of bytes needed to store d_namlen */ +#define _D_ALLOC_NAMLEN(p) (PATH_MAX) + + +#ifdef __cplusplus +extern "C" { +#endif + + +/* Wide-character version */ +struct _wdirent { + /* Always zero */ + long d_ino; + + /* Structure size */ + unsigned short d_reclen; + + /* Length of name without \0 */ + size_t d_namlen; + + /* File type */ + int d_type; + + /* File name */ + wchar_t d_name[PATH_MAX]; +}; +typedef struct _wdirent _wdirent; + +struct _WDIR { + /* Current directory entry */ + struct _wdirent ent; + + /* Private file data */ + WIN32_FIND_DATAW data; + + /* True if data is valid */ + int cached; + + /* Win32 search handle */ + HANDLE handle; + + /* Initial directory name */ + wchar_t *patt; +}; +typedef struct _WDIR _WDIR; + +static _WDIR *_wopendir (const wchar_t *dirname); +static struct _wdirent *_wreaddir (_WDIR *dirp); +static int _wclosedir (_WDIR *dirp); +static void _wrewinddir (_WDIR* dirp); + + +/* For compatibility with Symbian */ +#define wdirent _wdirent +#define WDIR _WDIR +#define wopendir _wopendir +#define wreaddir _wreaddir +#define wclosedir _wclosedir +#define wrewinddir _wrewinddir + + +/* Multi-byte character versions */ +struct dirent { + /* Always zero */ + long d_ino; + + /* Structure size */ + unsigned short d_reclen; + + /* Length of name without \0 */ + size_t d_namlen; + + /* File type */ + int d_type; + + /* File name */ + char d_name[PATH_MAX]; +}; +typedef struct dirent dirent; + +struct DIR { + struct dirent ent; + struct _WDIR *wdirp; +}; +typedef struct DIR DIR; + +static DIR *opendir (const char *dirname); +static struct dirent *readdir (DIR *dirp); +static int closedir (DIR *dirp); +static void rewinddir (DIR* dirp); + + +/* Internal utility functions */ +static WIN32_FIND_DATAW *dirent_first (_WDIR *dirp); +static WIN32_FIND_DATAW *dirent_next (_WDIR *dirp); + +static int dirent_mbstowcs_s( + size_t *pReturnValue, + wchar_t *wcstr, + size_t sizeInWords, + const char *mbstr, + size_t count); + +static int dirent_wcstombs_s( + size_t *pReturnValue, + char *mbstr, + size_t sizeInBytes, + const wchar_t *wcstr, + size_t count); + +static void dirent_set_errno (int error); + +/* + * Open directory stream DIRNAME for read and return a pointer to the + * internal working area that is used to retrieve individual directory + * entries. + */ +static _WDIR* +_wopendir( + const wchar_t *dirname) +{ + _WDIR *dirp = NULL; + int error; + + /* Must have directory name */ + if (dirname == NULL || dirname[0] == '\0') { + dirent_set_errno (ENOENT); + return NULL; + } + + /* Allocate new _WDIR structure */ + dirp = (_WDIR*) malloc (sizeof (struct _WDIR)); + if (dirp != NULL) { + DWORD n; + + /* Reset _WDIR structure */ + dirp->handle = INVALID_HANDLE_VALUE; + dirp->patt = NULL; + dirp->cached = 0; + + /* Compute the length of full path plus zero terminator + * + * Note that on WinRT there's no way to convert relative paths + * into absolute paths, so just assume its an absolute path. + */ +# if defined(WINAPI_FAMILY) && (WINAPI_FAMILY == WINAPI_FAMILY_PHONE_APP) + n = wcslen(dirname); +# else + n = GetFullPathNameW (dirname, 0, NULL, NULL); +# endif + + /* Allocate room for absolute directory name and search pattern */ + dirp->patt = (wchar_t*) malloc (sizeof (wchar_t) * n + 16); + if (dirp->patt) { + + /* + * Convert relative directory name to an absolute one. This + * allows rewinddir() to function correctly even when current + * working directory is changed between opendir() and rewinddir(). + * + * Note that on WinRT there's no way to convert relative paths + * into absolute paths, so just assume its an absolute path. + */ +# if defined(WINAPI_FAMILY) && (WINAPI_FAMILY == WINAPI_FAMILY_PHONE_APP) + wcsncpy_s(dirp->patt, n+1, dirname, n); +# else + n = GetFullPathNameW (dirname, n, dirp->patt, NULL); +# endif + if (n > 0) { + wchar_t *p; + + /* Append search pattern \* to the directory name */ + p = dirp->patt + n; + if (dirp->patt < p) { + switch (p[-1]) { + case '\\': + case '/': + case ':': + /* Directory ends in path separator, e.g. c:\temp\ */ + /*NOP*/; + break; + + default: + /* Directory name doesn't end in path separator */ + *p++ = '\\'; + } + } + *p++ = '*'; + *p = '\0'; + + /* Open directory stream and retrieve the first entry */ + if (dirent_first (dirp)) { + /* Directory stream opened successfully */ + error = 0; + } else { + /* Cannot retrieve first entry */ + error = 1; + dirent_set_errno (ENOENT); + } + + } else { + /* Cannot retrieve full path name */ + dirent_set_errno (ENOENT); + error = 1; + } + + } else { + /* Cannot allocate memory for search pattern */ + error = 1; + } + + } else { + /* Cannot allocate _WDIR structure */ + error = 1; + } + + /* Clean up in case of error */ + if (error && dirp) { + _wclosedir (dirp); + dirp = NULL; + } + + return dirp; +} + +/* + * Read next directory entry. The directory entry is returned in dirent + * structure in the d_name field. Individual directory entries returned by + * this function include regular files, sub-directories, pseudo-directories + * "." and ".." as well as volume labels, hidden files and system files. + */ +static struct _wdirent* +_wreaddir( + _WDIR *dirp) +{ + WIN32_FIND_DATAW *datap; + struct _wdirent *entp; + + /* Read next directory entry */ + datap = dirent_next (dirp); + if (datap) { + size_t n; + DWORD attr; + + /* Pointer to directory entry to return */ + entp = &dirp->ent; + + /* + * Copy file name as wide-character string. If the file name is too + * long to fit in to the destination buffer, then truncate file name + * to PATH_MAX characters and zero-terminate the buffer. + */ + n = 0; + while (n + 1 < PATH_MAX && datap->cFileName[n] != 0) { + entp->d_name[n] = datap->cFileName[n]; + n++; + } + dirp->ent.d_name[n] = 0; + + /* Length of file name excluding zero terminator */ + entp->d_namlen = n; + + /* File type */ + attr = datap->dwFileAttributes; + if ((attr & FILE_ATTRIBUTE_DEVICE) != 0) { + entp->d_type = DT_CHR; + } else if ((attr & FILE_ATTRIBUTE_DIRECTORY) != 0) { + entp->d_type = DT_DIR; + } else { + entp->d_type = DT_REG; + } + + /* Reset dummy fields */ + entp->d_ino = 0; + entp->d_reclen = sizeof (struct _wdirent); + + } else { + + /* Last directory entry read */ + entp = NULL; + + } + + return entp; +} + +/* + * Close directory stream opened by opendir() function. This invalidates the + * DIR structure as well as any directory entry read previously by + * _wreaddir(). + */ +static int +_wclosedir( + _WDIR *dirp) +{ + int ok; + if (dirp) { + + /* Release search handle */ + if (dirp->handle != INVALID_HANDLE_VALUE) { + FindClose (dirp->handle); + dirp->handle = INVALID_HANDLE_VALUE; + } + + /* Release search pattern */ + if (dirp->patt) { + free (dirp->patt); + dirp->patt = NULL; + } + + /* Release directory structure */ + free (dirp); + ok = /*success*/0; + + } else { + /* Invalid directory stream */ + dirent_set_errno (EBADF); + ok = /*failure*/-1; + } + return ok; +} + +/* + * Rewind directory stream such that _wreaddir() returns the very first + * file name again. + */ +static void +_wrewinddir( + _WDIR* dirp) +{ + if (dirp) { + /* Release existing search handle */ + if (dirp->handle != INVALID_HANDLE_VALUE) { + FindClose (dirp->handle); + } + + /* Open new search handle */ + dirent_first (dirp); + } +} + +/* Get first directory entry (internal) */ +static WIN32_FIND_DATAW* +dirent_first( + _WDIR *dirp) +{ + WIN32_FIND_DATAW *datap; + + /* Open directory and retrieve the first entry */ + dirp->handle = FindFirstFileExW( + dirp->patt, FindExInfoStandard, &dirp->data, + FindExSearchNameMatch, NULL, 0); + if (dirp->handle != INVALID_HANDLE_VALUE) { + + /* a directory entry is now waiting in memory */ + datap = &dirp->data; + dirp->cached = 1; + + } else { + + /* Failed to re-open directory: no directory entry in memory */ + dirp->cached = 0; + datap = NULL; + + } + return datap; +} + +/* Get next directory entry (internal) */ +static WIN32_FIND_DATAW* +dirent_next( + _WDIR *dirp) +{ + WIN32_FIND_DATAW *p; + + /* Get next directory entry */ + if (dirp->cached != 0) { + + /* A valid directory entry already in memory */ + p = &dirp->data; + dirp->cached = 0; + + } else if (dirp->handle != INVALID_HANDLE_VALUE) { + + /* Get the next directory entry from stream */ + if (FindNextFileW (dirp->handle, &dirp->data) != FALSE) { + /* Got a file */ + p = &dirp->data; + } else { + /* The very last entry has been processed or an error occured */ + FindClose (dirp->handle); + dirp->handle = INVALID_HANDLE_VALUE; + p = NULL; + } + + } else { + + /* End of directory stream reached */ + p = NULL; + + } + + return p; +} + +/* + * Open directory stream using plain old C-string. + */ +static DIR* +opendir( + const char *dirname) +{ + struct DIR *dirp; + int error; + + /* Must have directory name */ + if (dirname == NULL || dirname[0] == '\0') { + dirent_set_errno (ENOENT); + return NULL; + } + + /* Allocate memory for DIR structure */ + dirp = (DIR*) malloc (sizeof (struct DIR)); + if (dirp) { + wchar_t wname[PATH_MAX]; + size_t n; + + /* Convert directory name to wide-character string */ + error = dirent_mbstowcs_s (&n, wname, PATH_MAX, dirname, PATH_MAX); + if (!error) { + + /* Open directory stream using wide-character name */ + dirp->wdirp = _wopendir (wname); + if (dirp->wdirp) { + /* Directory stream opened */ + error = 0; + } else { + /* Failed to open directory stream */ + error = 1; + } + + } else { + /* + * Cannot convert file name to wide-character string. This + * occurs if the string contains invalid multi-byte sequences or + * the output buffer is too small to contain the resulting + * string. + */ + error = 1; + } + + } else { + /* Cannot allocate DIR structure */ + error = 1; + } + + /* Clean up in case of error */ + if (error && dirp) { + free (dirp); + dirp = NULL; + } + + return dirp; +} + +/* + * Read next directory entry. + * + * When working with text consoles, please note that file names returned by + * readdir() are represented in the default ANSI code page while any output to + * console is typically formatted on another code page. Thus, non-ASCII + * characters in file names will not usually display correctly on console. The + * problem can be fixed in two ways: (1) change the character set of console + * to 1252 using chcp utility and use Lucida Console font, or (2) use + * _cprintf function when writing to console. The _cprinf() will re-encode + * ANSI strings to the console code page so many non-ASCII characters will + * display correcly. + */ +static struct dirent* +readdir( + DIR *dirp) +{ + WIN32_FIND_DATAW *datap; + struct dirent *entp; + + /* Read next directory entry */ + datap = dirent_next (dirp->wdirp); + if (datap) { + size_t n; + int error; + + /* Attempt to convert file name to multi-byte string */ + error = dirent_wcstombs_s( + &n, dirp->ent.d_name, PATH_MAX, datap->cFileName, PATH_MAX); + + /* + * If the file name cannot be represented by a multi-byte string, + * then attempt to use old 8+3 file name. This allows traditional + * Unix-code to access some file names despite of unicode + * characters, although file names may seem unfamiliar to the user. + * + * Be ware that the code below cannot come up with a short file + * name unless the file system provides one. At least + * VirtualBox shared folders fail to do this. + */ + if (error && datap->cAlternateFileName[0] != '\0') { + error = dirent_wcstombs_s( + &n, dirp->ent.d_name, PATH_MAX, + datap->cAlternateFileName, PATH_MAX); + } + + if (!error) { + DWORD attr; + + /* Initialize directory entry for return */ + entp = &dirp->ent; + + /* Length of file name excluding zero terminator */ + entp->d_namlen = n - 1; + + /* File attributes */ + attr = datap->dwFileAttributes; + if ((attr & FILE_ATTRIBUTE_DEVICE) != 0) { + entp->d_type = DT_CHR; + } else if ((attr & FILE_ATTRIBUTE_DIRECTORY) != 0) { + entp->d_type = DT_DIR; + } else { + entp->d_type = DT_REG; + } + + /* Reset dummy fields */ + entp->d_ino = 0; + entp->d_reclen = sizeof (struct dirent); + + } else { + /* + * Cannot convert file name to multi-byte string so construct + * an errornous directory entry and return that. Note that + * we cannot return NULL as that would stop the processing + * of directory entries completely. + */ + entp = &dirp->ent; + entp->d_name[0] = '?'; + entp->d_name[1] = '\0'; + entp->d_namlen = 1; + entp->d_type = DT_UNKNOWN; + entp->d_ino = 0; + entp->d_reclen = 0; + } + + } else { + /* No more directory entries */ + entp = NULL; + } + + return entp; +} + +/* + * Close directory stream. + */ +static int +closedir( + DIR *dirp) +{ + int ok; + if (dirp) { + + /* Close wide-character directory stream */ + ok = _wclosedir (dirp->wdirp); + dirp->wdirp = NULL; + + /* Release multi-byte character version */ + free (dirp); + + } else { + + /* Invalid directory stream */ + dirent_set_errno (EBADF); + ok = /*failure*/-1; + + } + return ok; +} + +/* + * Rewind directory stream to beginning. + */ +static void +rewinddir( + DIR* dirp) +{ + /* Rewind wide-character string directory stream */ + _wrewinddir (dirp->wdirp); +} + +/* Convert multi-byte string to wide character string */ +static int +dirent_mbstowcs_s( + size_t *pReturnValue, + wchar_t *wcstr, + size_t sizeInWords, + const char *mbstr, + size_t count) +{ + int error; + +#if defined(_MSC_VER) && _MSC_VER >= 1400 + + /* Microsoft Visual Studio 2005 or later */ + error = mbstowcs_s (pReturnValue, wcstr, sizeInWords, mbstr, count); + +#else + + /* Older Visual Studio or non-Microsoft compiler */ + size_t n; + + /* Convert to wide-character string (or count characters) */ + n = mbstowcs (wcstr, mbstr, sizeInWords); + if (!wcstr || n < count) { + + /* Zero-terminate output buffer */ + if (wcstr && sizeInWords) { + if (n >= sizeInWords) { + n = sizeInWords - 1; + } + wcstr[n] = 0; + } + + /* Length of resuting multi-byte string WITH zero terminator */ + if (pReturnValue) { + *pReturnValue = n + 1; + } + + /* Success */ + error = 0; + + } else { + + /* Could not convert string */ + error = 1; + + } + +#endif + + return error; +} + +/* Convert wide-character string to multi-byte string */ +static int +dirent_wcstombs_s( + size_t *pReturnValue, + char *mbstr, + size_t sizeInBytes, /* max size of mbstr */ + const wchar_t *wcstr, + size_t count) +{ + int error; + +#if defined(_MSC_VER) && _MSC_VER >= 1400 + + /* Microsoft Visual Studio 2005 or later */ + error = wcstombs_s (pReturnValue, mbstr, sizeInBytes, wcstr, count); + +#else + + /* Older Visual Studio or non-Microsoft compiler */ + size_t n; + + /* Convert to multi-byte string (or count the number of bytes needed) */ + n = wcstombs (mbstr, wcstr, sizeInBytes); + if (!mbstr || n < count) { + + /* Zero-terminate output buffer */ + if (mbstr && sizeInBytes) { + if (n >= sizeInBytes) { + n = sizeInBytes - 1; + } + mbstr[n] = '\0'; + } + + /* Length of resulting multi-bytes string WITH zero-terminator */ + if (pReturnValue) { + *pReturnValue = n + 1; + } + + /* Success */ + error = 0; + + } else { + + /* Cannot convert string */ + error = 1; + + } + +#endif + + return error; +} + +/* Set errno variable */ +static void +dirent_set_errno( + int error) +{ +#if defined(_MSC_VER) && _MSC_VER >= 1400 + + /* Microsoft Visual Studio 2005 and later */ + _set_errno (error); + +#else + + /* Non-Microsoft compiler or older Microsoft compiler */ + errno = error; + +#endif +} + + +#ifdef __cplusplus +} +#endif +#endif /*DIRENT_H*/ + From 4d7b4d7c8e9966c593f472355607204c6c80fecb Mon Sep 17 00:00:00 2001 From: Dan Kegel Date: Sun, 4 Jun 2017 19:19:55 -0700 Subject: [PATCH 04/14] Minimal tweaks to compile with Visual C 2015 --- getopt_long.c | 2 ++ libpkgconf/bsdstubs.c | 1 + libpkgconf/libpkgconf.h | 2 +- libpkgconf/path.c | 10 +++++----- libpkgconf/pkg.c | 28 +++++++++++++++++++--------- libpkgconf/stdinc.h | 9 +++++++-- 6 files changed, 35 insertions(+), 17 deletions(-) diff --git a/getopt_long.c b/getopt_long.c index afeb68d..5ce9bfd 100644 --- a/getopt_long.c +++ b/getopt_long.c @@ -62,7 +62,9 @@ #include #include #include +#ifndef _WIN32 #include +#endif #define PKGCONF_HACK_LOGICAL_OR_ALL_VALUES diff --git a/libpkgconf/bsdstubs.c b/libpkgconf/bsdstubs.c index 8f70ff3..2c000ac 100644 --- a/libpkgconf/bsdstubs.c +++ b/libpkgconf/bsdstubs.c @@ -17,6 +17,7 @@ * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. */ +#include #include #include diff --git a/libpkgconf/libpkgconf.h b/libpkgconf/libpkgconf.h index 404bf0c..551d85d 100644 --- a/libpkgconf/libpkgconf.h +++ b/libpkgconf/libpkgconf.h @@ -310,7 +310,7 @@ void pkgconf_audit_log_dependency(pkgconf_client_t *client, const pkgconf_pkg_t /* path.c */ void pkgconf_path_add(const char *text, pkgconf_list_t *dirlist, bool filter); size_t pkgconf_path_split(const char *text, pkgconf_list_t *dirlist, bool filter); -size_t pkgconf_path_build_from_environ(const char *environ, const char *fallback, pkgconf_list_t *dirlist, bool filter); +size_t pkgconf_path_build_from_environ(const char *envvarname, const char *fallback, pkgconf_list_t *dirlist, bool filter); bool pkgconf_path_match_list(const char *path, const pkgconf_list_t *dirlist); void pkgconf_path_free(pkgconf_list_t *dirlist); bool pkgconf_path_relocate(char *buf, size_t buflen); diff --git a/libpkgconf/path.c b/libpkgconf/path.c index dddb3bf..59e003e 100644 --- a/libpkgconf/path.c +++ b/libpkgconf/path.c @@ -20,7 +20,7 @@ # include #endif -#ifdef HAVE_SYS_STAT_H +#if defined(HAVE_SYS_STAT_H) && ! defined(_WIN32) # include # define PKGCONF_CACHE_INODES #endif @@ -156,12 +156,12 @@ pkgconf_path_split(const char *text, pkgconf_list_t *dirlist, bool filter) /* * !doc * - * .. c:function:: size_t pkgconf_path_build_from_environ(const char *environ, const char *fallback, pkgconf_list_t *dirlist) + * .. c:function:: size_t pkgconf_path_build_from_environ(const char *envvarname, const char *fallback, pkgconf_list_t *dirlist) * * Adds the paths specified in an environment variable to a path list. If the environment variable is not set, * an optional default set of paths is added. * - * :param char* environ: The environment variable to look up. + * :param char* envvarname: The environment variable to look up. * :param char* fallback: The fallback paths to use if the environment variable is not set. * :param pkgconf_list_t* dirlist: The path list to add the path nodes to. * :param bool filter: Whether to perform duplicate filtering. @@ -169,11 +169,11 @@ pkgconf_path_split(const char *text, pkgconf_list_t *dirlist, bool filter) * :rtype: size_t */ size_t -pkgconf_path_build_from_environ(const char *environ, const char *fallback, pkgconf_list_t *dirlist, bool filter) +pkgconf_path_build_from_environ(const char *envvarname, const char *fallback, pkgconf_list_t *dirlist, bool filter) { const char *data; - data = getenv(environ); + data = getenv(envvarname); if (data != NULL) return pkgconf_path_split(data, dirlist, filter); diff --git a/libpkgconf/pkg.c b/libpkgconf/pkg.c index 7aebd61..5dacae3 100644 --- a/libpkgconf/pkg.c +++ b/libpkgconf/pkg.c @@ -30,6 +30,8 @@ # define PKG_CONFIG_REG_KEY "Software\\pkgconfig\\PKG_CONFIG_PATH" # undef PKG_DEFAULT_PATH # define PKG_DEFAULT_PATH "../lib/pkgconfig;../share/pkgconfig" +#define strncasecmp _strnicmp +#define strcasecmp _stricmp #endif #define PKG_CONFIG_EXT ".pc" @@ -134,21 +136,21 @@ static int pkgconf_pkg_parser_keyword_pair_cmp(const void *key, const void *ptr) static void pkgconf_pkg_parser_tuple_func(const pkgconf_client_t *client, pkgconf_pkg_t *pkg, const ptrdiff_t offset, char *value) { - char **dest = ((void *) pkg + offset); + char **dest = (char **)((char *) pkg + offset); *dest = pkgconf_tuple_parse(client, &pkg->vars, value); } static void pkgconf_pkg_parser_fragment_func(const pkgconf_client_t *client, pkgconf_pkg_t *pkg, const ptrdiff_t offset, char *value) { - pkgconf_list_t *dest = ((void *) pkg + offset); + pkgconf_list_t *dest = (pkgconf_list_t *)((char *) pkg + offset); pkgconf_fragment_parse(client, dest, &pkg->vars, value); } static void pkgconf_pkg_parser_dependency_func(const pkgconf_client_t *client, pkgconf_pkg_t *pkg, const ptrdiff_t offset, char *value) { - pkgconf_list_t *dest = ((void *) pkg + offset); + pkgconf_list_t *dest = (pkgconf_list_t *)((char *) pkg + offset); pkgconf_dependency_parse(client, pkg, dest, value); } @@ -238,7 +240,7 @@ pkgconf_pkg_validate(const pkgconf_client_t *client, const pkgconf_pkg_t *pkg) for (i = 0; i < PKGCONF_ARRAY_SIZE(pkgconf_pkg_validations); i++) { - char **p = ((void *) pkg + pkgconf_pkg_validations[i].offset); + char **p = (char **)((char *) pkg + pkgconf_pkg_validations[i].offset); if (*p != NULL) continue; @@ -587,7 +589,7 @@ pkgconf_scan_all(pkgconf_client_t *client, void *data, pkgconf_pkg_iteration_fun #ifdef _WIN32 static pkgconf_pkg_t * -pkgconf_pkg_find_in_registry_key(const pkgconf_client_t *client, HKEY hkey, const char *name) +pkgconf_pkg_find_in_registry_key(pkgconf_client_t *client, HKEY hkey, const char *name) { pkgconf_pkg_t *pkg = NULL; @@ -1048,8 +1050,12 @@ typedef struct { static const pkgconf_pkg_provides_vermatch_rule_t pkgconf_pkg_provides_vermatch_rules[] = { [PKGCONF_CMP_ANY] = { - .rulecmp = {}, - .depcmp = {}, + .rulecmp = { + [PKGCONF_CMP_ANY] = pkgconf_pkg_comparator_none, + }, + .depcmp = { + [PKGCONF_CMP_ANY] = pkgconf_pkg_comparator_none, + }, }, [PKGCONF_CMP_LESS_THAN] = { .rulecmp = { @@ -1121,7 +1127,9 @@ static const pkgconf_pkg_provides_vermatch_rule_t pkgconf_pkg_provides_vermatch_ [PKGCONF_CMP_EQUAL] = pkgconf_pkg_comparator_eq, [PKGCONF_CMP_NOT_EQUAL] = pkgconf_pkg_comparator_ne }, - .depcmp = {}, + .depcmp = { + [PKGCONF_CMP_ANY] = pkgconf_pkg_comparator_none, + }, }, [PKGCONF_CMP_NOT_EQUAL] = { .rulecmp = { @@ -1133,7 +1141,9 @@ static const pkgconf_pkg_provides_vermatch_rule_t pkgconf_pkg_provides_vermatch_ [PKGCONF_CMP_EQUAL] = pkgconf_pkg_comparator_ne, [PKGCONF_CMP_NOT_EQUAL] = pkgconf_pkg_comparator_eq }, - .depcmp = {}, + .depcmp = { + [PKGCONF_CMP_ANY] = pkgconf_pkg_comparator_none, + }, }, }; diff --git a/libpkgconf/stdinc.h b/libpkgconf/stdinc.h index 58cc6c7..ac7e53c 100644 --- a/libpkgconf/stdinc.h +++ b/libpkgconf/stdinc.h @@ -24,9 +24,7 @@ #include #include #include -#include #include -#include #include #ifdef _WIN32 @@ -34,8 +32,15 @@ # include # include # define PATH_DEV_NULL "nul" +# ifndef ssize_t +# include +# define ssize_t SSIZE_T +# endif +# include "win-dirent.h" #else # define PATH_DEV_NULL "/dev/null" +# include +# include #endif #endif From 8b4a4b831ba7028df3e1e5e98a6f47853e93e027 Mon Sep 17 00:00:00 2001 From: Dan Kegel Date: Sun, 4 Jun 2017 19:32:08 -0700 Subject: [PATCH 05/14] First draft of cmake install rules --- CMakeLists.txt | 1 + libpkgconf/CMakeLists.txt | 7 ++++++- 2 files changed, 7 insertions(+), 1 deletion(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index 4111a8e..742922f 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -36,6 +36,7 @@ ADD_SUBDIRECTORY(libpkgconf) INCLUDE_DIRECTORIES(${libpkgconf_BINARY_DIR}) ADD_EXECUTABLE(pkgconf main.c getopt_long.c) TARGET_LINK_LIBRARIES(pkgconf libpkgconf) +INSTALL(TARGETS pkgconf DESTINATION bin) ENABLE_TESTING() diff --git a/libpkgconf/CMakeLists.txt b/libpkgconf/CMakeLists.txt index fa3066c..7ea083d 100644 --- a/libpkgconf/CMakeLists.txt +++ b/libpkgconf/CMakeLists.txt @@ -1,6 +1,6 @@ PROJECT(libpkgconf C) -ADD_LIBRARY(libpkgconf +ADD_LIBRARY(libpkgconf SHARED argvsplit.c audit.c bsdstubs.c @@ -14,3 +14,8 @@ ADD_LIBRARY(libpkgconf queue.c tuple.c ) +INSTALL(TARGETS libpkgconf + RUNTIME DESTINATION bin + LIBRARY DESTINATION lib + ARCHIVE DESTINATION lib +) From 26d9a81c9c85c24ee2be2dd27b9cdf3a37b68332 Mon Sep 17 00:00:00 2001 From: Dan Kegel Date: Mon, 5 Jun 2017 07:26:00 -0700 Subject: [PATCH 06/14] install_deps.sh: first cut at cygwin support --- scripts/install_deps.sh | 32 +++++++++++++++++++++++++++----- 1 file changed, 27 insertions(+), 5 deletions(-) diff --git a/scripts/install_deps.sh b/scripts/install_deps.sh index 6cf6723..1461838 100755 --- a/scripts/install_deps.sh +++ b/scripts/install_deps.sh @@ -51,20 +51,42 @@ install_from_github() { CPPFLAGS="-I/usr/local/include" \ LDFLAGS="-L/usr/local/lib -Wl,-R/usr/local/lib" \ PKG_CONFIG_PATH="/usr/local/lib/pkgconfig" - make - sudo make install + make -j2 + $SUDO make install cd - rm -rf "${distname}" "${distname}.tar.gz" } -if [ $(uname -s) = "Darwin" ]; then +SUDO=sudo +CFLAGS="-g -O2" +case $(uname -s) in +Darwin) brew update brew install libarchive --with-xz brew install openssl brew install kyua -elif [ $(uname -s) = "Linux" ]; then + ;; +Linux) install_from_github atf 0.21 install_from_github lutok 0.4 install_from_github kyua 0.12 -fi + ;; +CYGWIN*) + SUDO="" + apt-cyg update + apt-cyg install lua-devel libsqlite3-devel + install_from_github lutok 0.4 + + # Work around + # utils/process/system.cpp:59:68: error: invalid conversion from ‘pid_t (*)(pid_t, __wait_status_ptr_t, int) {aka int (*)(int, void*, int)}’ to ‘pid_t (*)(pid_t, int*, int) {aka int (*)(int, int*, int)}’ [-fpermissive] + # pid_t (*detail::syscall_waitpid)(const pid_t, int*, const int) = ::waitpid; + # ^ + # make[1]: *** [Makefile:7014: utils/process/libutils_a-system.o] Error 1 + export CXXFLAGS="-g -O2 -fpermissive" + install_from_github kyua 0.12 + unset CXXFLAGS + + install_from_github atf 0.21 + ;; +esac From 347539ca87c1c009b993fed8c7f072c6ba7f4ce8 Mon Sep 17 00:00:00 2001 From: Dan Kegel Date: Mon, 5 Jun 2017 10:22:38 -0700 Subject: [PATCH 07/14] cmake: ignore more visual C warnings, don't feed DOS line endings to atf --- CMakeLists.txt | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index 742922f..cedd61c 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -17,11 +17,14 @@ SET(abs_top_srcdir ${pkgconf_SOURCE_DIR}) CONFIGURE_FILE(libpkgconf/config.h.cmake.in libpkgconf/config.h @ONLY) # Expand others FOREACH(file Kyuafile libpkgconf.pc tests/Kyuafile tests/test_env.sh) - CONFIGURE_FILE(${file}.in ${file} @ONLY) + CONFIGURE_FILE(${file}.in ${file} @ONLY NEWLINE_STYLE UNIX) ENDFOREACH() IF (WIN32) - SET(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} /WX") + # Make warnings fatal... but ignore C4996: 'strdup' two different ways + SET(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} /WX /wd4996") + # Ignore warning C4996: 'strncpy' + ADD_DEFINITIONS("-D_CRT_SECURE_NO_WARNINGS=1") ELSE() SET(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -Wall -Wextra -Wformat=2 -std=gnu99") ENDIF() From 9131496d645ca3c40acc88515fb8b5c27881e791 Mon Sep 17 00:00:00 2001 From: Dan Kegel Date: Mon, 5 Jun 2017 10:23:30 -0700 Subject: [PATCH 08/14] getopt_long.c: placate visual c by adding a few explicit typecasts --- getopt_long.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/getopt_long.c b/getopt_long.c index 5ce9bfd..c47215f 100644 --- a/getopt_long.c +++ b/getopt_long.c @@ -287,7 +287,7 @@ parse_long_options(char * const *nargv, const char *options, * XXX: GNU sets pkg_optopt to val regardless of flag */ if (long_options[match].flag == NULL) - pkg_optopt = long_options[match].val; + pkg_optopt = (int)long_options[match].val; else pkg_optopt = 0; #ifdef GNU_COMPATIBLE @@ -327,7 +327,7 @@ parse_long_options(char * const *nargv, const char *options, * XXX: GNU sets pkg_optopt to val regardless of flag */ if (long_options[match].flag == NULL) - pkg_optopt = long_options[match].val; + pkg_optopt = (int)long_options[match].val; else pkg_optopt = 0; --pkg_optind; @@ -360,7 +360,7 @@ parse_long_options(char * const *nargv, const char *options, #endif return (0); } else - return (long_options[match].val); + return ((int)long_options[match].val); } /* From 9258874ee1a28d29410bed941283978bfeca7f30 Mon Sep 17 00:00:00 2001 From: Dan Kegel Date: Mon, 5 Jun 2017 10:23:56 -0700 Subject: [PATCH 09/14] cmake: use right soversion for libpkgconf --- libpkgconf/CMakeLists.txt | 1 + 1 file changed, 1 insertion(+) diff --git a/libpkgconf/CMakeLists.txt b/libpkgconf/CMakeLists.txt index 7ea083d..0252e84 100644 --- a/libpkgconf/CMakeLists.txt +++ b/libpkgconf/CMakeLists.txt @@ -19,3 +19,4 @@ INSTALL(TARGETS libpkgconf LIBRARY DESTINATION lib ARCHIVE DESTINATION lib ) +SET_TARGET_PROPERTIES(libpkgconf PROPERTIES VERSION "2.0.0" SOVERSION 2) From 2e80d72a6f6fd3bc633b0a72638fd9d8e94f3f7a Mon Sep 17 00:00:00 2001 From: Dan Kegel Date: Mon, 5 Jun 2017 13:58:03 -0700 Subject: [PATCH 10/14] cmake: remove DOS line endings from tests --- CMakeLists.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index cedd61c..2c5d20f 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -57,7 +57,7 @@ SET(test_scripts ) # No accounting for taste FOREACH(file ${test_scripts}) - CONFIGURE_FILE(${file}.sh ${file} @ONLY) + CONFIGURE_FILE(${file}.sh ${file} @ONLY NEWLINE_STYLE UNIX) ENDFOREACH() ADD_TEST(kyua From 4ba2bac538d4d6788551d942b2e473ab0ee0a3d3 Mon Sep 17 00:00:00 2001 From: Dan Kegel Date: Mon, 5 Jun 2017 14:00:02 -0700 Subject: [PATCH 11/14] Don't depend on libtool magic to control which symbols are exported from shared libraries --- libpkgconf/CMakeLists.txt | 4 + libpkgconf/bsdstubs.h | 8 +- libpkgconf/libpkgconf-api.h | 20 +++++ libpkgconf/libpkgconf.h | 169 ++++++++++++++++++------------------ 4 files changed, 114 insertions(+), 87 deletions(-) create mode 100644 libpkgconf/libpkgconf-api.h diff --git a/libpkgconf/CMakeLists.txt b/libpkgconf/CMakeLists.txt index 0252e84..5305f7b 100644 --- a/libpkgconf/CMakeLists.txt +++ b/libpkgconf/CMakeLists.txt @@ -1,5 +1,9 @@ PROJECT(libpkgconf C) +# Enforce visibiliity restrictions when building shared libraries on Unix. +SET(CMAKE_CXX_VISIBILITY_PRESET hidden) +ADD_DEFINITIONS(-DLIBPKGCONF_EXPORT) + ADD_LIBRARY(libpkgconf SHARED argvsplit.c audit.c diff --git a/libpkgconf/bsdstubs.h b/libpkgconf/bsdstubs.h index fe8c950..2e0fb5c 100644 --- a/libpkgconf/bsdstubs.h +++ b/libpkgconf/bsdstubs.h @@ -16,8 +16,10 @@ #ifndef __BSDSTUBS_H__ #define __BSDSTUBS_H__ -extern size_t pkgconf_strlcpy(char *dst, const char *src, size_t siz); -extern size_t pkgconf_strlcat(char *dst, const char *src, size_t siz); -extern char *pkgconf_strndup(const char *src, size_t len); +#include + +PKGCONF_API extern size_t pkgconf_strlcpy(char *dst, const char *src, size_t siz); +PKGCONF_API extern size_t pkgconf_strlcat(char *dst, const char *src, size_t siz); +PKGCONF_API extern char *pkgconf_strndup(const char *src, size_t len); #endif diff --git a/libpkgconf/libpkgconf-api.h b/libpkgconf/libpkgconf-api.h new file mode 100644 index 0000000..1c4fb73 --- /dev/null +++ b/libpkgconf/libpkgconf-api.h @@ -0,0 +1,20 @@ +#ifndef PKGCONFG_API +#define PKGCONFG_API + +/* Makefile.am specifies visibility using the libtool option -export-symbols-regex '^pkgconf_' + * Unfortunately, that is not available when building with cmake, so use attributes instead, + * in a way that doesn't depend on any cmake magic. + */ +#if defined(PKGCONFIG_IS_STATIC) +# define PKGCONF_API +#elif defined(_WIN32) || defined(_WIN64) +# ifdef LIBPKGCONF_EXPORT +# define PKGCONF_API __declspec(dllexport) +# else +# define PKGCONF_API __declspec(dllimport) +# endif +#else +# define PKGCONF_API __attribute__((visibility("default"))) +#endif + +#endif diff --git a/libpkgconf/libpkgconf.h b/libpkgconf/libpkgconf.h index 551d85d..8a0031e 100644 --- a/libpkgconf/libpkgconf.h +++ b/libpkgconf/libpkgconf.h @@ -19,6 +19,7 @@ #include #include #include +#include /* pkg-config uses ';' on win32 as ':' is part of path */ #ifdef _WIN32 @@ -163,24 +164,24 @@ struct pkgconf_client_ { }; /* client.c */ -void pkgconf_client_init(pkgconf_client_t *client, pkgconf_error_handler_func_t error_handler, void *error_handler_data); -pkgconf_client_t *pkgconf_client_new(pkgconf_error_handler_func_t error_handler, void *error_handler_data); -void pkgconf_client_deinit(pkgconf_client_t *client); -void pkgconf_client_free(pkgconf_client_t *client); -const char *pkgconf_client_get_sysroot_dir(const pkgconf_client_t *client); -void pkgconf_client_set_sysroot_dir(pkgconf_client_t *client, const char *sysroot_dir); -const char *pkgconf_client_get_buildroot_dir(const pkgconf_client_t *client); -void pkgconf_client_set_buildroot_dir(pkgconf_client_t *client, const char *buildroot_dir); -unsigned int pkgconf_client_get_flags(const pkgconf_client_t *client); -void pkgconf_client_set_flags(pkgconf_client_t *client, unsigned int flags); -const char *pkgconf_client_get_prefix_varname(const pkgconf_client_t *client); -void pkgconf_client_set_prefix_varname(pkgconf_client_t *client, const char *prefix_varname); -pkgconf_error_handler_func_t pkgconf_client_get_warn_handler(const pkgconf_client_t *client); -void pkgconf_client_set_warn_handler(pkgconf_client_t *client, pkgconf_error_handler_func_t warn_handler, void *warn_handler_data); -pkgconf_error_handler_func_t pkgconf_client_get_error_handler(const pkgconf_client_t *client); -void pkgconf_client_set_error_handler(pkgconf_client_t *client, pkgconf_error_handler_func_t error_handler, void *error_handler_data); -pkgconf_error_handler_func_t pkgconf_client_get_trace_handler(const pkgconf_client_t *client); -void pkgconf_client_set_trace_handler(pkgconf_client_t *client, pkgconf_error_handler_func_t trace_handler, void *trace_handler_data); +PKGCONF_API void pkgconf_client_init(pkgconf_client_t *client, pkgconf_error_handler_func_t error_handler, void *error_handler_data); +PKGCONF_API pkgconf_client_t * pkgconf_client_new(pkgconf_error_handler_func_t error_handler, void *error_handler_data); +PKGCONF_API void pkgconf_client_deinit(pkgconf_client_t *client); +PKGCONF_API void pkgconf_client_free(pkgconf_client_t *client); +PKGCONF_API const char *pkgconf_client_get_sysroot_dir(const pkgconf_client_t *client); +PKGCONF_API void pkgconf_client_set_sysroot_dir(pkgconf_client_t *client, const char *sysroot_dir); +PKGCONF_API const char *pkgconf_client_get_buildroot_dir(const pkgconf_client_t *client); +PKGCONF_API void pkgconf_client_set_buildroot_dir(pkgconf_client_t *client, const char *buildroot_dir); +PKGCONF_API unsigned int pkgconf_client_get_flags(const pkgconf_client_t *client); +PKGCONF_API void pkgconf_client_set_flags(pkgconf_client_t *client, unsigned int flags); +PKGCONF_API const char *pkgconf_client_get_prefix_varname(const pkgconf_client_t *client); +PKGCONF_API void pkgconf_client_set_prefix_varname(pkgconf_client_t *client, const char *prefix_varname); +PKGCONF_API pkgconf_error_handler_func_t pkgconf_client_get_warn_handler(const pkgconf_client_t *client); +PKGCONF_API void pkgconf_client_set_warn_handler(pkgconf_client_t *client, pkgconf_error_handler_func_t warn_handler, void *warn_handler_data); +PKGCONF_API pkgconf_error_handler_func_t pkgconf_client_get_error_handler(const pkgconf_client_t *client); +PKGCONF_API void pkgconf_client_set_error_handler(pkgconf_client_t *client, pkgconf_error_handler_func_t error_handler, void *error_handler_data); +PKGCONF_API pkgconf_error_handler_func_t pkgconf_client_get_trace_handler(const pkgconf_client_t *client); +PKGCONF_API void pkgconf_client_set_trace_handler(pkgconf_client_t *client, pkgconf_error_handler_func_t trace_handler, void *trace_handler_data); #define PKGCONF_IS_MODULE_SEPARATOR(c) ((c) == ',' || isspace ((unsigned int)(c))) #define PKGCONF_IS_OPERATOR_CHAR(c) ((c) == '<' || (c) == '>' || (c) == '!' || (c) == '=') @@ -217,10 +218,10 @@ void pkgconf_client_set_trace_handler(pkgconf_client_t *client, pkgconf_error_ha #define DEPRECATED #endif /* defined(__INTEL_COMPILER) || defined(__GNUC__) */ -bool pkgconf_error(const pkgconf_client_t *client, const char *format, ...) PRINTFLIKE(2, 3); -bool pkgconf_warn(const pkgconf_client_t *client, const char *format, ...) PRINTFLIKE(2, 3); -bool pkgconf_trace(const pkgconf_client_t *client, const char *filename, size_t lineno, const char *funcname, const char *format, ...) PRINTFLIKE(5, 6); -bool pkgconf_default_error_handler(const char *msg, const pkgconf_client_t *client, const void *data); +PKGCONF_API bool pkgconf_error(const pkgconf_client_t *client, const char *format, ...) PRINTFLIKE(2, 3); +PKGCONF_API bool pkgconf_warn(const pkgconf_client_t *client, const char *format, ...) PRINTFLIKE(2, 3); +PKGCONF_API bool pkgconf_trace(const pkgconf_client_t *client, const char *filename, size_t lineno, const char *funcname, const char *format, ...) PRINTFLIKE(5, 6); +PKGCONF_API bool pkgconf_default_error_handler(const char *msg, const pkgconf_client_t *client, const void *data); #if defined(__GNUC__) || defined(__INTEL_COMPILER) #define PKGCONF_TRACE(client, ...) do { \ @@ -232,87 +233,87 @@ bool pkgconf_default_error_handler(const char *msg, const pkgconf_client_t *clie } while (0); #endif -pkgconf_pkg_t *pkgconf_pkg_ref(const pkgconf_client_t *client, pkgconf_pkg_t *pkg); -void pkgconf_pkg_unref(pkgconf_client_t *client, pkgconf_pkg_t *pkg); -void pkgconf_pkg_free(pkgconf_client_t *client, pkgconf_pkg_t *pkg); -pkgconf_pkg_t *pkgconf_pkg_find(pkgconf_client_t *client, const char *name); -unsigned int pkgconf_pkg_traverse(pkgconf_client_t *client, pkgconf_pkg_t *root, pkgconf_pkg_traverse_func_t func, void *data, int maxdepth); -unsigned int pkgconf_pkg_verify_graph(pkgconf_client_t *client, pkgconf_pkg_t *root, int depth); -pkgconf_pkg_t *pkgconf_pkg_verify_dependency(pkgconf_client_t *client, pkgconf_dependency_t *pkgdep, unsigned int *eflags); -const char *pkgconf_pkg_get_comparator(const pkgconf_dependency_t *pkgdep); -unsigned int pkgconf_pkg_cflags(pkgconf_client_t *client, pkgconf_pkg_t *root, pkgconf_list_t *list, int maxdepth); -unsigned int pkgconf_pkg_libs(pkgconf_client_t *client, pkgconf_pkg_t *root, pkgconf_list_t *list, int maxdepth); -pkgconf_pkg_comparator_t pkgconf_pkg_comparator_lookup_by_name(const char *name); -pkgconf_pkg_t *pkgconf_builtin_pkg_get(const char *name); +PKGCONF_API pkgconf_pkg_t *pkgconf_pkg_ref(const pkgconf_client_t *client, pkgconf_pkg_t *pkg); +PKGCONF_API void pkgconf_pkg_unref(pkgconf_client_t *client, pkgconf_pkg_t *pkg); +PKGCONF_API void pkgconf_pkg_free(pkgconf_client_t *client, pkgconf_pkg_t *pkg); +PKGCONF_API pkgconf_pkg_t *pkgconf_pkg_find(pkgconf_client_t *client, const char *name); +PKGCONF_API unsigned int pkgconf_pkg_traverse(pkgconf_client_t *client, pkgconf_pkg_t *root, pkgconf_pkg_traverse_func_t func, void *data, int maxdepth); +PKGCONF_API unsigned int pkgconf_pkg_verify_graph(pkgconf_client_t *client, pkgconf_pkg_t *root, int depth); +PKGCONF_API pkgconf_pkg_t *pkgconf_pkg_verify_dependency(pkgconf_client_t *client, pkgconf_dependency_t *pkgdep, unsigned int *eflags); +PKGCONF_API const char *pkgconf_pkg_get_comparator(const pkgconf_dependency_t *pkgdep); +PKGCONF_API unsigned int pkgconf_pkg_cflags(pkgconf_client_t *client, pkgconf_pkg_t *root, pkgconf_list_t *list, int maxdepth); +PKGCONF_API unsigned int pkgconf_pkg_libs(pkgconf_client_t *client, pkgconf_pkg_t *root, pkgconf_list_t *list, int maxdepth); +PKGCONF_API pkgconf_pkg_comparator_t pkgconf_pkg_comparator_lookup_by_name(const char *name); +PKGCONF_API pkgconf_pkg_t *pkgconf_builtin_pkg_get(const char *name); -int pkgconf_compare_version(const char *a, const char *b); -pkgconf_pkg_t *pkgconf_scan_all(pkgconf_client_t *client, void *ptr, pkgconf_pkg_iteration_func_t func); -void pkgconf_pkg_dir_list_build(pkgconf_client_t *client); +PKGCONF_API int pkgconf_compare_version(const char *a, const char *b); +PKGCONF_API pkgconf_pkg_t *pkgconf_scan_all(pkgconf_client_t *client, void *ptr, pkgconf_pkg_iteration_func_t func); +PKGCONF_API void pkgconf_pkg_dir_list_build(pkgconf_client_t *client); /* parse.c */ -pkgconf_pkg_t *pkgconf_pkg_new_from_file(pkgconf_client_t *client, const char *path, FILE *f); -void pkgconf_dependency_parse_str(const pkgconf_client_t *client, pkgconf_list_t *deplist_head, const char *depends); -void pkgconf_dependency_parse(const pkgconf_client_t *client, pkgconf_pkg_t *pkg, pkgconf_list_t *deplist_head, const char *depends); -void pkgconf_dependency_append(pkgconf_list_t *list, pkgconf_dependency_t *tail); -void pkgconf_dependency_free(pkgconf_list_t *list); -const char *pkgconf_dependency_to_str(const pkgconf_dependency_t *dep); -pkgconf_dependency_t *pkgconf_dependency_add(const pkgconf_client_t *client, pkgconf_list_t *list, const char *package, const char *version, pkgconf_pkg_comparator_t compare); +PKGCONF_API pkgconf_pkg_t *pkgconf_pkg_new_from_file(pkgconf_client_t *client, const char *path, FILE *f); +PKGCONF_API void pkgconf_dependency_parse_str(const pkgconf_client_t *client, pkgconf_list_t *deplist_head, const char *depends); +PKGCONF_API void pkgconf_dependency_parse(const pkgconf_client_t *client, pkgconf_pkg_t *pkg, pkgconf_list_t *deplist_head, const char *depends); +PKGCONF_API void pkgconf_dependency_append(pkgconf_list_t *list, pkgconf_dependency_t *tail); +PKGCONF_API void pkgconf_dependency_free(pkgconf_list_t *list); +PKGCONF_API const char *pkgconf_dependency_to_str(const pkgconf_dependency_t *dep); +PKGCONF_API pkgconf_dependency_t *pkgconf_dependency_add(const pkgconf_client_t *client, pkgconf_list_t *list, const char *package, const char *version, pkgconf_pkg_comparator_t compare); /* argvsplit.c */ -int pkgconf_argv_split(const char *src, int *argc, char ***argv); -void pkgconf_argv_free(char **argv); +PKGCONF_API int pkgconf_argv_split(const char *src, int *argc, char ***argv); +PKGCONF_API void pkgconf_argv_free(char **argv); /* fragment.c */ typedef bool (*pkgconf_fragment_filter_func_t)(const pkgconf_client_t *client, const pkgconf_fragment_t *frag, void *data); -void pkgconf_fragment_parse(const pkgconf_client_t *client, pkgconf_list_t *list, pkgconf_list_t *vars, const char *value); -void pkgconf_fragment_add(const pkgconf_client_t *client, pkgconf_list_t *list, const char *string); -void pkgconf_fragment_copy(const pkgconf_client_t *client, pkgconf_list_t *list, const pkgconf_fragment_t *base, bool is_private); -void pkgconf_fragment_delete(pkgconf_list_t *list, pkgconf_fragment_t *node); -void pkgconf_fragment_free(pkgconf_list_t *list); -void pkgconf_fragment_filter(const pkgconf_client_t *client, pkgconf_list_t *dest, pkgconf_list_t *src, pkgconf_fragment_filter_func_t filter_func, void *data); -size_t pkgconf_fragment_render_len(const pkgconf_list_t *list, bool escape); -void pkgconf_fragment_render_buf(const pkgconf_list_t *list, char *buf, size_t len, bool escape); -char *pkgconf_fragment_render(const pkgconf_list_t *list, bool escape); -bool pkgconf_fragment_has_system_dir(const pkgconf_client_t *client, const pkgconf_fragment_t *frag); +PKGCONF_API void pkgconf_fragment_parse(const pkgconf_client_t *client, pkgconf_list_t *list, pkgconf_list_t *vars, const char *value); +PKGCONF_API void pkgconf_fragment_add(const pkgconf_client_t *client, pkgconf_list_t *list, const char *string); +PKGCONF_API void pkgconf_fragment_copy(const pkgconf_client_t *client, pkgconf_list_t *list, const pkgconf_fragment_t *base, bool is_private); +PKGCONF_API void pkgconf_fragment_delete(pkgconf_list_t *list, pkgconf_fragment_t *node); +PKGCONF_API void pkgconf_fragment_free(pkgconf_list_t *list); +PKGCONF_API void pkgconf_fragment_filter(const pkgconf_client_t *client, pkgconf_list_t *dest, pkgconf_list_t *src, pkgconf_fragment_filter_func_t filter_func, void *data); +PKGCONF_API size_t pkgconf_fragment_render_len(const pkgconf_list_t *list, bool escape); +PKGCONF_API void pkgconf_fragment_render_buf(const pkgconf_list_t *list, char *buf, size_t len, bool escape); +PKGCONF_API char *pkgconf_fragment_render(const pkgconf_list_t *list, bool escape); +PKGCONF_API bool pkgconf_fragment_has_system_dir(const pkgconf_client_t *client, const pkgconf_fragment_t *frag); /* fileio.c */ -char *pkgconf_fgetline(char *line, size_t size, FILE *stream); +PKGCONF_API char *pkgconf_fgetline(char *line, size_t size, FILE *stream); /* tuple.c */ -pkgconf_tuple_t *pkgconf_tuple_add(const pkgconf_client_t *client, pkgconf_list_t *parent, const char *key, const char *value, bool parse); -char *pkgconf_tuple_find(const pkgconf_client_t *client, pkgconf_list_t *list, const char *key); -char *pkgconf_tuple_parse(const pkgconf_client_t *client, pkgconf_list_t *list, const char *value); -void pkgconf_tuple_free(pkgconf_list_t *list); -void pkgconf_tuple_free_entry(pkgconf_tuple_t *tuple, pkgconf_list_t *list); -void pkgconf_tuple_add_global(pkgconf_client_t *client, const char *key, const char *value); -char *pkgconf_tuple_find_global(const pkgconf_client_t *client, const char *key); -void pkgconf_tuple_free_global(pkgconf_client_t *client); -void pkgconf_tuple_define_global(pkgconf_client_t *client, const char *kv); +PKGCONF_API pkgconf_tuple_t *pkgconf_tuple_add(const pkgconf_client_t *client, pkgconf_list_t *parent, const char *key, const char *value, bool parse); +PKGCONF_API char *pkgconf_tuple_find(const pkgconf_client_t *client, pkgconf_list_t *list, const char *key); +PKGCONF_API char *pkgconf_tuple_parse(const pkgconf_client_t *client, pkgconf_list_t *list, const char *value); +PKGCONF_API void pkgconf_tuple_free(pkgconf_list_t *list); +PKGCONF_API void pkgconf_tuple_free_entry(pkgconf_tuple_t *tuple, pkgconf_list_t *list); +PKGCONF_API void pkgconf_tuple_add_global(pkgconf_client_t *client, const char *key, const char *value); +PKGCONF_API char *pkgconf_tuple_find_global(const pkgconf_client_t *client, const char *key); +PKGCONF_API void pkgconf_tuple_free_global(pkgconf_client_t *client); +PKGCONF_API void pkgconf_tuple_define_global(pkgconf_client_t *client, const char *kv); /* queue.c */ -void pkgconf_queue_push(pkgconf_list_t *list, const char *package); -bool pkgconf_queue_compile(pkgconf_client_t *client, pkgconf_pkg_t *world, pkgconf_list_t *list); -void pkgconf_queue_free(pkgconf_list_t *list); -bool pkgconf_queue_apply(pkgconf_client_t *client, pkgconf_list_t *list, pkgconf_queue_apply_func_t func, int maxdepth, void *data); -bool pkgconf_queue_validate(pkgconf_client_t *client, pkgconf_list_t *list, int maxdepth); +PKGCONF_API void pkgconf_queue_push(pkgconf_list_t *list, const char *package); +PKGCONF_API bool pkgconf_queue_compile(pkgconf_client_t *client, pkgconf_pkg_t *world, pkgconf_list_t *list); +PKGCONF_API void pkgconf_queue_free(pkgconf_list_t *list); +PKGCONF_API bool pkgconf_queue_apply(pkgconf_client_t *client, pkgconf_list_t *list, pkgconf_queue_apply_func_t func, int maxdepth, void *data); +PKGCONF_API bool pkgconf_queue_validate(pkgconf_client_t *client, pkgconf_list_t *list, int maxdepth); /* cache.c */ -pkgconf_pkg_t *pkgconf_cache_lookup(const pkgconf_client_t *client, const char *id); -void pkgconf_cache_add(pkgconf_client_t *client, pkgconf_pkg_t *pkg); -void pkgconf_cache_remove(pkgconf_client_t *client, pkgconf_pkg_t *pkg); -void pkgconf_cache_free(pkgconf_client_t *client); +PKGCONF_API pkgconf_pkg_t *pkgconf_cache_lookup(const pkgconf_client_t *client, const char *id); +PKGCONF_API void pkgconf_cache_add(pkgconf_client_t *client, pkgconf_pkg_t *pkg); +PKGCONF_API void pkgconf_cache_remove(pkgconf_client_t *client, pkgconf_pkg_t *pkg); +PKGCONF_API void pkgconf_cache_free(pkgconf_client_t *client); /* audit.c */ -void pkgconf_audit_set_log(pkgconf_client_t *client, FILE *auditf); -void pkgconf_audit_log(pkgconf_client_t *client, const char *format, ...) PRINTFLIKE(2, 3); -void pkgconf_audit_log_dependency(pkgconf_client_t *client, const pkgconf_pkg_t *dep, const pkgconf_dependency_t *depnode); +PKGCONF_API void pkgconf_audit_set_log(pkgconf_client_t *client, FILE *auditf); +PKGCONF_API void pkgconf_audit_log(pkgconf_client_t *client, const char *format, ...) PRINTFLIKE(2, 3); +PKGCONF_API void pkgconf_audit_log_dependency(pkgconf_client_t *client, const pkgconf_pkg_t *dep, const pkgconf_dependency_t *depnode); /* path.c */ -void pkgconf_path_add(const char *text, pkgconf_list_t *dirlist, bool filter); -size_t pkgconf_path_split(const char *text, pkgconf_list_t *dirlist, bool filter); -size_t pkgconf_path_build_from_environ(const char *envvarname, const char *fallback, pkgconf_list_t *dirlist, bool filter); -bool pkgconf_path_match_list(const char *path, const pkgconf_list_t *dirlist); -void pkgconf_path_free(pkgconf_list_t *dirlist); -bool pkgconf_path_relocate(char *buf, size_t buflen); +PKGCONF_API void pkgconf_path_add(const char *text, pkgconf_list_t *dirlist, bool filter); +PKGCONF_API size_t pkgconf_path_split(const char *text, pkgconf_list_t *dirlist, bool filter); +PKGCONF_API size_t pkgconf_path_build_from_environ(const char *envvarname, const char *fallback, pkgconf_list_t *dirlist, bool filter); +PKGCONF_API bool pkgconf_path_match_list(const char *path, const pkgconf_list_t *dirlist); +PKGCONF_API void pkgconf_path_free(pkgconf_list_t *dirlist); +PKGCONF_API bool pkgconf_path_relocate(char *buf, size_t buflen); #endif From ededaa6415f8db00ac2d2311c010b33d6eb0d375 Mon Sep 17 00:00:00 2001 From: Dan Kegel Date: Mon, 5 Jun 2017 17:40:10 -0700 Subject: [PATCH 12/14] cmake: add missing configure variables, install headers and .pc file, use simpler line to invoke kyua, tweak build location of dll for ease of testing --- CMakeLists.txt | 17 +++++++++++------ libpkgconf/CMakeLists.txt | 10 +++++++++- 2 files changed, 20 insertions(+), 7 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index 2c5d20f..3015c6b 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -14,9 +14,14 @@ CHECK_FUNCTION_EXISTS(strlcat HAVE_STRLCAT) CHECK_FUNCTION_EXISTS(strndup HAVE_STRNDUP) CHECK_FUNCTION_EXISTS(cygwin_conv_path HAVE_CYGWIN_CONV_PATH) SET(abs_top_srcdir ${pkgconf_SOURCE_DIR}) +SET(prefix ${CMAKE_INSTALL_PREFIX}) +SET(exec_prefix ${CMAKE_INSTALL_PREFIX}) +SET(datarootdir ${CMAKE_INSTALL_PREFIX}/share) +SET(libdir ${CMAKE_INSTALL_PREFIX}/lib) +SET(PKGCONFIGDIR "${libdir}/pkgconfig:${datarootdir}/pkgconfig") CONFIGURE_FILE(libpkgconf/config.h.cmake.in libpkgconf/config.h @ONLY) -# Expand others -FOREACH(file Kyuafile libpkgconf.pc tests/Kyuafile tests/test_env.sh) +# Handy that these files need configuring; cygwin atf doesn't like windows line endings, and NEWLINE_STYLE helps. +FOREACH(file Kyuafile tests/Kyuafile tests/test_env.sh) CONFIGURE_FILE(${file}.in ${file} @ONLY NEWLINE_STYLE UNIX) ENDFOREACH() @@ -34,6 +39,8 @@ ADD_DEFINITIONS(-DPKG_DEFAULT_PATH=\"$(pkg_default_dir)\") ADD_DEFINITIONS(-DSYSTEM_INCLUDEDIR=\"$(system_includedir)\") ADD_DEFINITIONS(-DSYSTEM_LIBDIR=\"$(system_libdir)\") +# Place shared libraries in same place as binary, for ease of setting PATH in test_env.sh +set(CMAKE_RUNTIME_OUTPUT_DIRECTORY ${pkgconf_BINARY_DIR}) ADD_SUBDIRECTORY(libpkgconf) INCLUDE_DIRECTORIES(${libpkgconf_BINARY_DIR}) @@ -55,11 +62,9 @@ SET(test_scripts tests/sysroot tests/version ) -# No accounting for taste +# Handy that these files need configuring; cygwin atf doesn't like windows line endings, and NEWLINE_STYLE helps. FOREACH(file ${test_scripts}) CONFIGURE_FILE(${file}.sh ${file} @ONLY NEWLINE_STYLE UNIX) ENDFOREACH() -ADD_TEST(kyua - kyua --config=none test --kyuafile=${pkgconf_BINARY_DIR}/Kyuafile --build-root=${pkgconf_BINARY_DIR} - ) +ADD_TEST(kyua kyua --config=none test) diff --git a/libpkgconf/CMakeLists.txt b/libpkgconf/CMakeLists.txt index 5305f7b..8bbd35a 100644 --- a/libpkgconf/CMakeLists.txt +++ b/libpkgconf/CMakeLists.txt @@ -18,9 +18,17 @@ ADD_LIBRARY(libpkgconf SHARED queue.c tuple.c ) +SET_TARGET_PROPERTIES(libpkgconf PROPERTIES VERSION "2.0.0" SOVERSION 2) INSTALL(TARGETS libpkgconf RUNTIME DESTINATION bin LIBRARY DESTINATION lib ARCHIVE DESTINATION lib ) -SET_TARGET_PROPERTIES(libpkgconf PROPERTIES VERSION "2.0.0" SOVERSION 2) +INSTALL( + FILES bsdstubs.h iter.h libpkgconf.h libpkgconf-api.h stdinc.h + DESTINATION include/libpkgconf +) + +# Hypothesis: .pc files are a Unix thing, should always have unix line endings. +CONFIGURE_FILE(${pkgconf_SOURCE_DIR}/libpkgconf.pc.in libpkgconf.pc @ONLY NEWLINE_STYLE UNIX) +INSTALL(FILES ${libpkgconf_BINARY_DIR}/libpkgconf.pc DESTINATION lib/pkgconfig) From 0ba391bc6f8b84a7b2a252ac8c435b4d5afdda33 Mon Sep 17 00:00:00 2001 From: Dan Kegel Date: Mon, 5 Jun 2017 17:41:13 -0700 Subject: [PATCH 13/14] Miscelaneous tweaks for Visual C in Cygwin compatibility --- main.c | 14 ++++++++++++++ tests/test_env.sh.in | 30 ++++++++++++++++++++++++++---- 2 files changed, 40 insertions(+), 4 deletions(-) diff --git a/main.c b/main.c index 35a4854..d06b471 100644 --- a/main.c +++ b/main.c @@ -17,6 +17,10 @@ #include #include "config.h" #include "getopt_long.h" +#ifdef _WIN32 +#include /* for _setmode() */ +#include +#endif #define PKG_CFLAGS_ONLY_I (((uint64_t) 1) << 2) #define PKG_CFLAGS_ONLY_OTHER (((uint64_t) 1) << 3) @@ -652,6 +656,16 @@ main(int argc, char *argv[]) want_flags = 0; +#ifdef _WIN32 + /* When running regression tests in cygwin, and building native + * executable, tests fail unless native executable outputs unix + * line endings. Come to think of it, this will probably help + * real people who use cygwin build environments but native pkgconf, too. + */ + _setmode(fileno(stdout), O_BINARY); + _setmode(fileno(stderr), O_BINARY); +#endif + struct pkg_option options[] = { { "version", no_argument, &want_flags, PKG_VERSION|PKG_PRINT_ERRORS, }, { "about", no_argument, &want_flags, PKG_ABOUT|PKG_PRINT_ERRORS, }, diff --git a/tests/test_env.sh.in b/tests/test_env.sh.in index cf0cfc4..3120811 100644 --- a/tests/test_env.sh.in +++ b/tests/test_env.sh.in @@ -1,10 +1,32 @@ -export PATH="$(atf_get_srcdir)/../:${PATH}" +srcdir="$(atf_get_srcdir)" +export PATH="$srcdir/..:${PATH}" + +#--- begin windows kludge --- +# When building with Visual Studio, binaries are in a subdirectory named after the configration... +# and the configuration is not known unless you're in the IDE, or something. +# So just guess. This won't work well if you build more than one configuration. +the_configuration="" +for configuration in Debug Release RelWithDebInfo +do + if test -d "$srcdir/../$configuration" + then + if test "$the_configuration" != "" + then + echo "test_env.sh: FAIL: more than one configuration found" + exit 1 + fi + the_configuration=$configuration + export PATH="$srcdir/../${configuration}:${PATH}" + fi +done +#--- end kludge --- + selfdir="@abs_top_srcdir@/tests" PATH_SEP=":" SYSROOT_DIR="${selfdir}/test" -if [ "$(uname -s)" = "Msys" ]; then - PATH_SEP=";" -fi +case "$(uname -s)" in +Msys|CYGWIN*) PATH_SEP=";";; +esac prefix="@prefix@" exec_prefix="@exec_prefix@" From 794aa5016afffd5bb8a98e5ff454ad2a75845836 Mon Sep 17 00:00:00 2001 From: Dan Kegel Date: Mon, 5 Jun 2017 20:54:57 -0700 Subject: [PATCH 14/14] Tidy up a bit. --- CMakeLists.txt | 73 ++++++++++++++++++++++++++++++--------- libpkgconf/CMakeLists.txt | 2 +- libpkgconf/pkg.c | 4 +-- 3 files changed, 60 insertions(+), 19 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index 3015c6b..b9a9bd0 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -1,11 +1,46 @@ -CMAKE_MINIMUM_REQUIRED(VERSION 3.5.1) +# CMake configuration for pkgconf +# +# Caution: this assumes you don't set CMAKE_BUILD_TYPE +# +# FIXME: this isn't a native cmake approach, it's just a straight translation +# of configure.ac + Makefile.am, barely good enough to work on Linux, Mac, and Windows. + +# Require recent cmake, but not so recent that Ubuntu 16.04 users have to upgrade. +CMAKE_MINIMUM_REQUIRED(VERSION 3.5.1 FATAL_ERROR) + PROJECT(pkgconf C) SET(PACKAGE_BUGREPORT http://github.com/pkgconf/pkgconf/issues) SET(PACKAGE_NAME pkgconf) SET(PACKAGE_VERSION 1.3.7) +SET(LIBPKGCONF_VERSION "2.0.0") +SET(LIBPKGCONF_SOVERSION 2) + +#-------- GNU directory variables --------- + +SET(abs_top_srcdir ${pkgconf_SOURCE_DIR}) +SET(prefix ${CMAKE_INSTALL_PREFIX}) +SET(exec_prefix ${prefix}) +SET(datarootdir ${prefix}/share) +SET(datadir ${datarootdir}) +SET(libdir ${prefix}/lib) +SET(includedir ${prefix}/include) + +#-------- User-settable options --------- + +# FIXME: this is overridden in get_default_pkgconfig_path() on windows, but not in test_env.sh.in?! +SET(pkg_config_dir "${libdir}/pkgconfig:${datadir}/pkgconfig" CACHE STRING "specify the places where pc files will be found") +SET(PKGCONFIGDIR "${pkg_config_dir}") +SET(pkg_default_dir "${PKGCONFIGDIR}") # c'mon, make up your mind + +SET(system_libdir "${libdir}" CACHE STRING "specify the system library directory (default LIBDIR)") +SET(SYSTEM_LIBDIR "${system_libdir}") + +SET(system_includedir "${includedir}" CACHE STRING "specify the system include directory (default INCLUDEDIR)") +SET(SYSTEM_INCLUDEDIR "${system_includedir}") + +#-------- Probe system --------- -# Expand config.h INCLUDE (CheckIncludeFiles) CHECK_INCLUDE_FILES(sys/stat.h HAVE_SYS_STAT_H) INCLUDE (CheckFunctionExists) @@ -13,17 +48,12 @@ CHECK_FUNCTION_EXISTS(strlcpy HAVE_STRLCPY) CHECK_FUNCTION_EXISTS(strlcat HAVE_STRLCAT) CHECK_FUNCTION_EXISTS(strndup HAVE_STRNDUP) CHECK_FUNCTION_EXISTS(cygwin_conv_path HAVE_CYGWIN_CONV_PATH) -SET(abs_top_srcdir ${pkgconf_SOURCE_DIR}) -SET(prefix ${CMAKE_INSTALL_PREFIX}) -SET(exec_prefix ${CMAKE_INSTALL_PREFIX}) -SET(datarootdir ${CMAKE_INSTALL_PREFIX}/share) -SET(libdir ${CMAKE_INSTALL_PREFIX}/lib) -SET(PKGCONFIGDIR "${libdir}/pkgconfig:${datarootdir}/pkgconfig") + +#-------- Generate source files --------- + CONFIGURE_FILE(libpkgconf/config.h.cmake.in libpkgconf/config.h @ONLY) -# Handy that these files need configuring; cygwin atf doesn't like windows line endings, and NEWLINE_STYLE helps. -FOREACH(file Kyuafile tests/Kyuafile tests/test_env.sh) - CONFIGURE_FILE(${file}.in ${file} @ONLY NEWLINE_STYLE UNIX) -ENDFOREACH() + +#-------- Configure common compiler options -------- IF (WIN32) # Make warnings fatal... but ignore C4996: 'strdup' two different ways @@ -31,25 +61,36 @@ IF (WIN32) # Ignore warning C4996: 'strncpy' ADD_DEFINITIONS("-D_CRT_SECURE_NO_WARNINGS=1") ELSE() - SET(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -Wall -Wextra -Wformat=2 -std=gnu99") + SET(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -Wall -Wextra -Wformat=2 -std=gnu99 -O2 -g") ENDIF() INCLUDE_DIRECTORIES(${pkgconf_SOURCE_DIR} ${pkgconf_BINARY_DIR}) -ADD_DEFINITIONS(-DPKG_DEFAULT_PATH=\"$(pkg_default_dir)\") -ADD_DEFINITIONS(-DSYSTEM_INCLUDEDIR=\"$(system_includedir)\") -ADD_DEFINITIONS(-DSYSTEM_LIBDIR=\"$(system_libdir)\") +ADD_DEFINITIONS(-DPKG_DEFAULT_PATH=\"${pkg_default_dir}\") +ADD_DEFINITIONS(-DSYSTEM_INCLUDEDIR=\"${system_includedir}\") +ADD_DEFINITIONS(-DSYSTEM_LIBDIR=\"${system_libdir}\") + +#-------- Build and install library -------- # Place shared libraries in same place as binary, for ease of setting PATH in test_env.sh set(CMAKE_RUNTIME_OUTPUT_DIRECTORY ${pkgconf_BINARY_DIR}) ADD_SUBDIRECTORY(libpkgconf) +#-------- Build and install executable -------- + INCLUDE_DIRECTORIES(${libpkgconf_BINARY_DIR}) ADD_EXECUTABLE(pkgconf main.c getopt_long.c) TARGET_LINK_LIBRARIES(pkgconf libpkgconf) INSTALL(TARGETS pkgconf DESTINATION bin) +#-------- Tests --------- + ENABLE_TESTING() +# Handy that these files need configuring; cygwin atf doesn't like windows line endings, and NEWLINE_STYLE helps. +FOREACH(file Kyuafile tests/Kyuafile tests/test_env.sh) + CONFIGURE_FILE(${file}.in ${file} @ONLY NEWLINE_STYLE UNIX) +ENDFOREACH() + SET(test_scripts tests/basic tests/builtins diff --git a/libpkgconf/CMakeLists.txt b/libpkgconf/CMakeLists.txt index 8bbd35a..9617448 100644 --- a/libpkgconf/CMakeLists.txt +++ b/libpkgconf/CMakeLists.txt @@ -18,7 +18,7 @@ ADD_LIBRARY(libpkgconf SHARED queue.c tuple.c ) -SET_TARGET_PROPERTIES(libpkgconf PROPERTIES VERSION "2.0.0" SOVERSION 2) +SET_TARGET_PROPERTIES(libpkgconf PROPERTIES VERSION ${LIBPKGCONF_VERSION} SOVERSION ${LIBPKGCONF_SOVERSION}) INSTALL(TARGETS libpkgconf RUNTIME DESTINATION bin LIBRARY DESTINATION lib diff --git a/libpkgconf/pkg.c b/libpkgconf/pkg.c index 5dacae3..cbc0ac2 100644 --- a/libpkgconf/pkg.c +++ b/libpkgconf/pkg.c @@ -30,8 +30,8 @@ # define PKG_CONFIG_REG_KEY "Software\\pkgconfig\\PKG_CONFIG_PATH" # undef PKG_DEFAULT_PATH # define PKG_DEFAULT_PATH "../lib/pkgconfig;../share/pkgconfig" -#define strncasecmp _strnicmp -#define strcasecmp _stricmp +# define strncasecmp _strnicmp +# define strcasecmp _stricmp #endif #define PKG_CONFIG_EXT ".pc"