Thread: BUG #15190: Build configure should have option to disableclock_gettime on MacOS 10.12 and up.
BUG #15190: Build configure should have option to disableclock_gettime on MacOS 10.12 and up.
From
PG Bug reporting form
Date:
The following bug has been logged on the website: Bug reference: 15190 Logged by: Marc Van Olmen Email address: marcvanolmen@gmail.com PostgreSQL version: 10.3 Operating system: MacOS 10.13 Description: Steps to reproduce issue. 1. Use MacOS 10.12 or higher. I tested MacOS 10.13 because for latest Xcode 9.3 this is the minimal system. 2. Run the standard configure command and make and make install. 3. It will produce an executable for example ./lib/postgress that use the function clock_gettime. 4. Trying to run this produced executable on macOS 10.10 or lower will produce the following error dyld: Symbol not found: _clock_gettime Referenced from: /Volumes/Checkout/Checkout.app/Contents/Resources/postgres_10/bin/postgres Expected in: /usr/lib/libSystem.B.dylib Proposed solution: We should have an option that disable to the automatic search for using the clock_gettime on MacOS 10.12 or higher Other open source projects have also introduced similar options: ./configure --disable-clock-gettime https://github.com/libevent/libevent/issues/399 https://github.com/libevent/libevent/pull/400/files thanks, Marc Van Olmen
Re: BUG #15190: Build configure should have option to disable clock_gettime on MacOS 10.12 and up.
From
Tom Lane
Date:
=?utf-8?q?PG_Bug_reporting_form?= <noreply@postgresql.org> writes: > 1. Use MacOS 10.12 or higher. I tested MacOS 10.13 because for latest Xcode > 9.3 this is the minimal system. > 2. Run the standard configure command and make and make install. > 3. It will produce an executable for example ./lib/postgress that use the > function clock_gettime. > 4. Trying to run this produced executable on macOS 10.10 or lower will > produce the following error > dyld: Symbol not found: _clock_gettime This does not seem like a bug, but user error; or at least, you're thinking about the problem in the wrong way. In general, an executable built on version N of an operating system is not guaranteed to run on versions before N, because of missing features. clock_gettime is just one example of such a feature. We surely aren't going to introduce configure options to override every test it makes; but that would be the logical end result if we proceed as you suggest. That would be unmaintainable, and not very usable either --- how would you know which things have to be disabled to get an executable that works on a desired old OS version? The right way to proceed is to build in an environment that mimics your oldest target OS version. Apple does provide facilities for doing that. I haven't done it, but IIUC the idea is to install the SDK version corresponding to your target OS version and then point at that while building. See https://developer.apple.com/library/content/documentation/DeveloperTools/Conceptual/cross_development/Configuring/configuring.html particularly this bit: Configuring a Makefile-Based Project If you have a makefile-based project, you can also take advantage of SDK-based development, by adding the appropriate options to your compile and link commands. Using SDKs in makefile-based projects requires GCC 4.0 or later. To choose an SDK, you use the -isysroot option with the compiler and the -syslibroot option with the linker. Both options require that you specify the full path to the desired SDK directory. Now, if you've tried that and it doesn't work, we could look into why not. But I don't think that expecting executables built in a default environment to be back-portable is going to get anywhere. regards, tom lane
Re: BUG #15190: Build configure should have option to disableclock_gettime on MacOS 10.12 and up.
From
Marc Van Olmen
Date:
Tom
__CLOCK_AVAILABILITY
int clock_gettime(clockid_t __clock_id, struct timespec *__tp);
much appreciated for quick response and detailed answer!
I found a solution based on this, so I’m adding that to this thread so anyone in the future can be helped by this.
Because I’m using "configure make" system to build and I’m using a recent released mac I can only run MacOS 10.13, I had to use some XCode legacy information to get this to work.
Because Apple has a different philosophy for their own products they want you always to build with the latests SDK (more later) but set a in minimum Deployment target.
1. From this source https://github.com/devernay/xcodelegacy I found the right technique on how to change the build options for a configure approach.
2. From this source https://github.com/phracker/MacOSX-SDKs/releases I was able to find a macos 10.9 SDK and install that on my current XCode setup.
3. Then the following configuration allowed me to compile the postgres code on MacOS 10.13 and have it run also on macOS 10.9.
MACOSX_DEPLOYMENT_TARGET=10.9
SDK_ROOT=/Applications/Xcode.app/Contents/Developer/Platforms/MacOSX.platform/Developer/SDKs/MacOSX10.9.sdk
CPU_ARCH=x86_64
./configure PYTHON=${PYTHON_BIN} \
--with-python \
--prefix="${POSTGRES_DEST_BUILD_DIR}" \
--enable-thread-safety \
--with-includes="${CHECKOUT_PROJECT_DIR}/build_openssl/include" \
--with-libraries="${CHECKOUT_PROJECT_DIR}/build_openssl/lib" \
--with-bonjour \
--with-pgport=5507 \
--with-openssl \
CFLAGS="-arch ${CPU_ARCH} -mmacosx-version-min=${MACOSX_DEPLOYMENT_TARGET} -isysroot ${SDK_ROOT}" \
CXXFLAGS="-arch ${CPU_ARCH} -mmacosx-version-min=${MACOSX_DEPLOYMENT_TARGET} -isysroot ${SDK_ROOT}" \
LDFLAGS="-arch ${CPU_ARCH}" \
LD="-arch ${CPU_ARCH} -mmacosx-version-min=${MACOSX_DEPLOYMENT_TARGET} -isysroot ${SDK_ROOT}"
This fixes the issues I was having and now it won’t use the clock_gettime function, because in that SDK it isn’t in the headers file.
Regarding Apple SDK based development:
I know it is different then other platforms and I understand it is not adopted by other platforms and I understand other building systems don’t take the same approach or don’t want to add extra specific platform build systems.
But it is explained here: https://developer.apple.com/library/content/documentation/DeveloperTools/Conceptual/cross_development/Overview/overview.html
1. You basically only need the SDK for the platform you are running on,
2. You can specify the oldest OS you will deploy too.
3. but there is a catch: the behavior of your app can change depending which SDK you link to also.
So their headers are annotated then with minimum OS requirements for newly introduced functions.
Regarding clock_gettime
/Applications/Xcode.app/Contents/Developer/Platforms/MacOSX.platform/Developer/SDKs/MacOSX.sdk/usr/include/time.h
#if !defined(_DARWIN_FEATURE_CLOCK_GETTIME) || _DARWIN_FEATURE_CLOCK_GETTIME != 0
#if __DARWIN_C_LEVEL >= 199309L
#if __has_feature(enumerator_attributes)
#define __CLOCK_AVAILABILITY __OSX_AVAILABLE(10.12) __IOS_AVAILABLE(10.0) __TVOS_AVAILABLE(10.0) __WATCHOS_AVAILABLE(3.0)
#else
#define __CLOCK_AVAILABILITY
#endif
typedef enum {
_CLOCK_REALTIME __CLOCK_AVAILABILITY = 0,
#define CLOCK_REALTIME _CLOCK_REALTIME
_CLOCK_MONOTONIC __CLOCK_AVAILABILITY = 6,
#define CLOCK_MONOTONIC _CLOCK_MONOTONIC
#if !defined(_POSIX_C_SOURCE) || defined(_DARWIN_C_SOURCE)
_CLOCK_MONOTONIC_RAW __CLOCK_AVAILABILITY = 4,
#define CLOCK_MONOTONIC_RAW _CLOCK_MONOTONIC_RAW
_CLOCK_MONOTONIC_RAW_APPROX __CLOCK_AVAILABILITY = 5,
#define CLOCK_MONOTONIC_RAW_APPROX _CLOCK_MONOTONIC_RAW_APPROX
_CLOCK_UPTIME_RAW __CLOCK_AVAILABILITY = 8,
#define CLOCK_UPTIME_RAW _CLOCK_UPTIME_RAW
_CLOCK_UPTIME_RAW_APPROX __CLOCK_AVAILABILITY = 9,
#define CLOCK_UPTIME_RAW_APPROX _CLOCK_UPTIME_RAW_APPROX
#endif
_CLOCK_PROCESS_CPUTIME_ID __CLOCK_AVAILABILITY = 12,
#define CLOCK_PROCESS_CPUTIME_ID _CLOCK_PROCESS_CPUTIME_ID
_CLOCK_THREAD_CPUTIME_ID __CLOCK_AVAILABILITY = 16
#define CLOCK_THREAD_CPUTIME_ID _CLOCK_THREAD_CPUTIME_ID
} clockid_t;
__CLOCK_AVAILABILITY
int clock_getres(clockid_t __clock_id, struct timespec *__res);
__CLOCK_AVAILABILITY
int clock_gettime(clockid_t __clock_id, struct timespec *__tp);
And the compiler can then throw an error/warning if you are trying to use a function that is above your minimum deployment.
But you can also decide at runtime what functions to use, by wrapping your function calls into blocks that check for the OS version you are running on.
regards and thanks for your support again.
Marc
On May 8, 2018, at 3:10 PM, Tom Lane <tgl@sss.pgh.pa.us> wrote:PG Bug reporting form <noreply@postgresql.org> writes:1. Use MacOS 10.12 or higher. I tested MacOS 10.13 because for latest Xcode
9.3 this is the minimal system.
2. Run the standard configure command and make and make install.
3. It will produce an executable for example ./lib/postgress that use the
function clock_gettime.
4. Trying to run this produced executable on macOS 10.10 or lower will
produce the following error
dyld: Symbol not found: _clock_gettime
This does not seem like a bug, but user error; or at least, you're
thinking about the problem in the wrong way. In general, an executable
built on version N of an operating system is not guaranteed to run on
versions before N, because of missing features. clock_gettime is just one
example of such a feature. We surely aren't going to introduce configure
options to override every test it makes; but that would be the logical
end result if we proceed as you suggest. That would be unmaintainable,
and not very usable either --- how would you know which things have to
be disabled to get an executable that works on a desired old OS version?
The right way to proceed is to build in an environment that mimics your
oldest target OS version. Apple does provide facilities for doing that.
I haven't done it, but IIUC the idea is to install the SDK version
corresponding to your target OS version and then point at that while
building. See
https://developer.apple.com/library/content/documentation/DeveloperTools/Conceptual/cross_development/Configuring/configuring.html
particularly this bit:
Configuring a Makefile-Based Project
If you have a makefile-based project, you can also take advantage of
SDK-based development, by adding the appropriate options to your
compile and link commands. Using SDKs in makefile-based projects
requires GCC 4.0 or later. To choose an SDK, you use the -isysroot
option with the compiler and the -syslibroot option with the
linker. Both options require that you specify the full path to the
desired SDK directory.
Now, if you've tried that and it doesn't work, we could look into
why not. But I don't think that expecting executables built in a
default environment to be back-portable is going to get anywhere.
regards, tom lane