-
Notifications
You must be signed in to change notification settings - Fork 243
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Feature-test macros + config header!
We're getting bug reports (e.g. #732) for situations where people have a libpqxx compiled as C++17 but an application compiled as C++20, or _vice versa._ Generally it's probably not wise to link C++17-compiled code to code compiled as C++20. But two things I did exacerbate the problem: 1. I moved a bunch of C++ feature checks to compile time, using C++20's feature test macros. It looked like a much cleaner, easier way forward with reduced maintenance overhead. 2. Usage of C++20's `std::source_location` _when present_ affects the ABI. So effectively there's one ABI with, and one without. I see that mostly as the price of doing libraries in C++ — it's generally dangerous to package library binaries, unless they've been designed to be compatible, or they come as a range of binaries for various compilers, versions, and configurations. And the real problem is that _these two changes interacted._ The detection of support for `std::source_location` happened at compile time. And so if you compile libpqxx in C++17 (without this feature) and the application in C++20 (with this feature), the two will not be link-compatible! In this first commit I'm prototyping a new approach that I hope will combine the ease of maintenance of feature test macros with the ABI stability of a configuration header. Configuration speed should lie somewhere inbetween: no more compiling separate little checks for every individual C++ feature. But it's not easy. There are 2 orthogonal binary choices, leaving me with 4 scenarios to support: * Autoconf vs. CMake * Cross-compiled vs. native. How does cross compilation factor into it? It works like this: I need to check C++ feature test macros. I check them in C++. But I don't want to keep editing that C++ code for every feature — there's a repetitive preprocessor dance that I don't think I could simplify to one simple line of code, because I'd need to pass macro names as parameters to macros. So, I write a minimal config file and run it through a Python script that generates the C++ code for me. Then I have the build configuration machinery compile _and run_ that C++ code, and generate the configuration header. Yes, alright, but how does cross compilation factor into it? First, if you're cross-compiling, it's not a given that you can _run_ the binary you produce on the same system! The whole point is that the two systems are different. And two, you'll have a native compilation environment but there's no guarantee that it will resemble the cross compilation environment at all. So if you compile a binary to run locally, you may get very different results. So for cross-compilation, the Python script just generates a minimal configuration header that just has all features disabled. And in this first commit I've got that working for autoconf. But I'm still struggling with CMake (thanks @KayEss for helping with this). If it gets too difficult, I may go a different route: generate C++ code from Python, but only run it through the preprocessor. (I believe autoconf has a standard, portable way of running the preprocessor; let's hope CMake has one as well.) The output will still C++ code, but now it's been preprocessed, so hopefully it'll be possible to tell portably which features are present. And ironically, I think I'd then have to have another Python script to _postprocess_ the preprocessed code and turn it into a ready-to-use config header.
- Loading branch information
Showing
5 changed files
with
406 additions
and
4 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -20,6 +20,65 @@ You have another version of autoconf. It may work, but is not guaranteed to. | |
If you have problems, you may need to regenerate the build system entirely. | ||
To do so, use the procedure documented by the package, typically 'autoreconf'.])]) | ||
|
||
# =========================================================================== | ||
# https://www.gnu.org/software/autoconf-archive/ax_file_escapes.html | ||
# =========================================================================== | ||
# | ||
# SYNOPSIS | ||
# | ||
# AX_FILE_ESCAPES | ||
# | ||
# DESCRIPTION | ||
# | ||
# Writes the specified data to the specified file. | ||
# | ||
# LICENSE | ||
# | ||
# Copyright (c) 2008 Tom Howard <[email protected]> | ||
# | ||
# Copying and distribution of this file, with or without modification, are | ||
# permitted in any medium without royalty provided the copyright notice | ||
# and this notice are preserved. This file is offered as-is, without any | ||
# warranty. | ||
|
||
#serial 8 | ||
|
||
AC_DEFUN([AX_FILE_ESCAPES],[ | ||
AX_DOLLAR="\$" | ||
AX_SRB="\\135" | ||
AX_SLB="\\133" | ||
AX_BS="\\\\" | ||
AX_DQ="\"" | ||
]) | ||
|
||
# =========================================================================== | ||
# https://www.gnu.org/software/autoconf-archive/ax_print_to_file.html | ||
# =========================================================================== | ||
# | ||
# SYNOPSIS | ||
# | ||
# AX_PRINT_TO_FILE([FILE],[DATA]) | ||
# | ||
# DESCRIPTION | ||
# | ||
# Writes the specified data to the specified file. | ||
# | ||
# LICENSE | ||
# | ||
# Copyright (c) 2008 Tom Howard <[email protected]> | ||
# | ||
# Copying and distribution of this file, with or without modification, are | ||
# permitted in any medium without royalty provided the copyright notice | ||
# and this notice are preserved. This file is offered as-is, without any | ||
# warranty. | ||
|
||
#serial 8 | ||
|
||
AC_DEFUN([AX_PRINT_TO_FILE],[ | ||
AC_REQUIRE([AX_FILE_ESCAPES]) | ||
printf "$2" > "$1" | ||
]) | ||
|
||
# Copyright (C) 2002-2021 Free Software Foundation, Inc. | ||
# | ||
# This file is free software; the Free Software Foundation | ||
|
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,6 @@ | ||
__cpp_concepts pqxx_have_concepts | ||
__cpp_multidimensional_subscript pqxx_have_multidim | ||
__cpp_lib_source_location pqxx_have_source_location | ||
__cpp_lib_span pqxx_have_span | ||
__cpp_lib_ssize pqxx_have_ssize | ||
__cpp_lib_unreachable pqxx_have_unreachable |
Oops, something went wrong.