Compare commits

...

3 Commits

Author SHA1 Message Date
Gennaro Prota 92da55a05b Run the examples serially in CI
The example programs write to fixed temp filenames---demo and
demo_exception even share tmpdir()/demofile.txt---so running them under
`b2 -jN` with N > 1 races: concurrent processes clobber each other's
archive files and a reader picks up a half-written one, throwing
`archive_exception`. Therefore, run the examples under `-j1` (the tests
keep running in parallel).
2026-07-17 16:02:20 +02:00
Gennaro Prota f387cb6efc Skip the non-ASCII path round trip only on the wide-text archive
The wide *text* archive transcodes a narrow `std::string` through the
stream locale's `codecvt_null`, which cannot represent bytes outside the
ASCII range; it is the only archive in the test list that fails to
round-trip non-ASCII content. The others preserve it: narrow text and
XML store the bytes verbatim, binary stores them raw, and wide XML
installs a UTF-8 codecvt.

Rather than dropping the non-ASCII path from the test entirely, exercise
it against every archive but the wide-text one.
2026-07-17 12:02:31 +02:00
Gennaro Prota 438fdbeabc Disable std::filesystem serialization on GCC before 9
GCC's initial `<filesystem>` (before version 9) shipped in a separate
libstdc++fs and is unreliable: serializing a `std::filesystem::path`
segfaults at runtime in CI. Exclude those versions from the availability
guard so the feature is inert.

Refs issue #337.
2026-07-17 11:59:44 +02:00
4 changed files with 51 additions and 5 deletions
+18 -2
View File
@@ -243,7 +243,15 @@ jobs:
run: |
cd ../boost-root
export ADDRMD=${{matrix.address-model}}
./b2 -j3 libs/$LIBRARY/test libs/$LIBRARY/example toolset=${{matrix.toolset}} cxxstd=${{matrix.cxxstd}} ${ADDRMD:+address-model=$ADDRMD} variant=debug,release
./b2 -j3 libs/$LIBRARY/test toolset=${{matrix.toolset}} cxxstd=${{matrix.cxxstd}} ${ADDRMD:+address-model=$ADDRMD} variant=debug,release
- name: Run examples
run: |
cd ../boost-root
export ADDRMD=${{matrix.address-model}}
# The demos use fixed temp filenames, so run them serially (-j1)
# to avoid concurrent runs clobbering each other's archive files.
./b2 -j1 libs/$LIBRARY/example toolset=${{matrix.toolset}} cxxstd=${{matrix.cxxstd}} ${ADDRMD:+address-model=$ADDRMD} variant=debug,release
windows:
strategy:
@@ -298,7 +306,15 @@ jobs:
shell: cmd
run: |
cd ../boost-root
b2 -j3 libs/%LIBRARY%/test libs/%LIBRARY%/example toolset=${{matrix.toolset}} cxxstd=${{matrix.cxxstd}} address-model=${{matrix.addrmd}} variant=debug,release embed-manifest-via=linker
b2 -j3 libs/%LIBRARY%/test toolset=${{matrix.toolset}} cxxstd=${{matrix.cxxstd}} address-model=${{matrix.addrmd}} variant=debug,release embed-manifest-via=linker
- name: Run examples
shell: cmd
run: |
cd ../boost-root
rem The demos use fixed temp filenames, so run them serially (-j1)
rem to avoid concurrent runs clobbering each other's archive files.
b2 -j1 libs/%LIBRARY%/example toolset=${{matrix.toolset}} cxxstd=${{matrix.cxxstd}} address-model=${{matrix.addrmd}} variant=debug,release embed-manifest-via=linker
posix-cmake-subdir:
strategy:
+2
View File
@@ -11,6 +11,8 @@ project libs/serialization/example
: requirements <library>../build//boost_serialization
;
import testing ;
import ../util/test :
run-template
run-invoke
+5 -1
View File
@@ -18,8 +18,12 @@
#include <boost/config.hpp>
// GCC's <filesystem> before version 9 is the initial, incomplete
// implementation (shipped in a separate libstdc++fs and buggy at runtime),
// so the feature is disabled there.
#if defined(__has_include)
# if __has_include(<filesystem>) && (BOOST_CXX_VERSION >= 201703L)
# if __has_include(<filesystem>) && (BOOST_CXX_VERSION >= 201703L) \
&& ! (defined(__GNUC__) && ! defined(__clang__) && __GNUC__ < 9)
# define BOOST_SERIALIZATION_HAS_STD_FILESYSTEM
# endif
#endif
+26 -2
View File
@@ -17,8 +17,11 @@
// `std::filesystem::path` is a C++17 feature; when it isn't available, this
// test has nothing to exercise and simply succeeds.
// Note the guard for GCC < 9, which matches the one in
// boost/serialization/filesystem.hpp: see the comment there for the why.
#if defined(__has_include)
# if __has_include(<filesystem>) && (BOOST_CXX_VERSION >= 201703L)
# if __has_include(<filesystem>) && (BOOST_CXX_VERSION >= 201703L) \
&& ! (defined(__GNUC__) && ! defined(__clang__) && __GNUC__ < 9)
# define BOOST_SERIALIZATION_TEST_STD_FILESYSTEM
# endif
#endif
@@ -29,6 +32,11 @@
#include <boost/serialization/filesystem.hpp>
#include <filesystem>
#include <type_traits>
#ifndef BOOST_NO_STD_WSTREAMBUF
#include <boost/archive/text_woarchive.hpp>
#endif
void check_roundtrip(const std::filesystem::path & original){
const char * testfile = boost::archive::tmpnam(NULL);
@@ -57,6 +65,21 @@ std::filesystem::path from_utf8(const std::string & utf8){
#endif
}
// The wide *text* archive is the one archive that cannot round-trip non-ASCII
// content: it transcodes the narrow UTF-8 std::string through the stream
// locale's codecvt (codecvt_null), which mangles bytes outside the ASCII
// range. Every other archive in the test list preserves them -- narrow text
// and XML store the bytes verbatim, binary stores them raw, and wide XML
// installs a UTF-8 codecvt. So the non-ASCII case is exercised everywhere
// except that single archive.
bool archive_round_trips_non_ascii(){
#ifndef BOOST_NO_STD_WSTREAMBUF
return ! std::is_same<test_oarchive, boost::archive::text_woarchive>::value;
#else
return true;
#endif
}
int test_main(int /* argc */, char * /* argv */ []){
check_roundtrip(std::filesystem::path()); // empty
check_roundtrip("foo/bar/baz.txt"); // relative
@@ -66,7 +89,8 @@ int test_main(int /* argc */, char * /* argv */ []){
// The escapes are the UTF-8 encoding of U+00E9, U+00EF and U+00FC
// (e-acute, i-diaeresis, u-diaeresis); written as `\x` so the source
// file stays pure ASCII and encoding-independent.
check_roundtrip(from_utf8("caf\xC3\xA9/na\xC3\xAF" "ve/\xC3\xBC.txt"));
if(archive_round_trips_non_ascii())
check_roundtrip(from_utf8("caf\xC3\xA9/na\xC3\xAF" "ve/\xC3\xBC.txt"));
return EXIT_SUCCESS;
}