Skip to content

Add an optional CMake build - #149

Open
MagnaibayarMN wants to merge 3 commits into
objectcomputing:masterfrom
MagnaibayarMN:cmake-support
Open

Add an optional CMake build#149
MagnaibayarMN wants to merge 3 commits into
objectcomputing:masterfrom
MagnaibayarMN:cmake-support

Conversation

@MagnaibayarMN

@MagnaibayarMN MagnaibayarMN commented Sep 12, 2026

Copy link
Copy Markdown

Adds a CMake build alongside the MPC one. Nothing about the MPC build changes: no .mpc, .mpb, .mwc, .features or setup script is touched, and both builds work from the same working copy.

Stacked on #148. This branch carries that commit as its base, plus a one-line fix to testPresenceMap (arrays of uchar initialized from char literals, which C++11 rejects as narrowing wherever char is signed). Merging #148 first reduces this to those two commits.

Why

Building QuickFAST today means installing MPC and hand-editing setup.sh or setup.cmd to point at a Boost and a Xerces-C tree. With CMake, find_package locates both, and QuickFAST becomes consumable by the many projects that expect a CMake package.

cmake -S . -B build -DQUICKFAST_BUILD_TESTS=ON -DQUICKFAST_BUILD_EXAMPLES=ON
cmake --build build
ctest --test-dir build --output-on-failure

Tests and examples are off by default. Installing exports a target, so a downstream project needs only:

find_package(QuickFAST REQUIRED)
target_link_libraries(app PRIVATE QuickFAST::QuickFAST)

Notes on the design

  • The library target collects the same five directories the MPC project does, and globs them for the same reason MPC lists directories rather than files: so the two builds do not drift apart as sources are added.
  • The definitions Common/QuickFAST_Export.h expects are supplied for both shared and static builds, and the MPC build's precompiled header is kept.
  • Headers install under include/QuickFAST so that the #include <Codecs/Decoder.h> style used throughout the sources keeps working without putting directories named Common or Messages on a consumer's include path.
  • The unit tests find their XML templates through $QUICKFAST_ROOT, so ctest sets it for them.
  • BOOST_TEST_DYN_LINK is defined only when Boost.Test is a shared library; defining it against a static Boost.Test fails to link.

Verification

Environment Result
Ubuntu 24.04, gcc 13, Boost 1.83, Xerces-C 3.2 static and shared, 112 test cases pass, 6 examples
Ubuntu 25.10, gcc 15, Boost 1.88 static and shared, 112 test cases pass, 6 examples

A separate consuming project was configured and built against the installed package in both.

🤖 Generated with Claude Code

https://claude.ai/code/session_017BnyHwonMsq7k6uQxWpVGF

Boost 1.66 reorganized Asio and Boost 1.87 removed what it had deprecated,
so QuickFAST has not compiled against a current Boost for some years.  These
are the changes needed to build with Boost 1.66 through at least 1.91, with
every replacement selected on BOOST_VERSION so that older Boost releases
build exactly as they did before.

The library:

* AsioService_fwd.h forward declared boost::asio::io_service as a class.
  From Boost 1.66 on it is a typedef for io_context, so that declaration
  conflicts with Asio's own and every use of the type fails.  The name is
  now taken from Asio itself; Boost 1.87 and later, which dropped the name
  entirely, get a typedef for io_context.

* The Asio I/O objects replaced their io_service& constructors with a
  template that asks its argument for an executor, so the implicit cast on
  AsioService is no longer enough to construct a socket or a resolver from
  one.  AsioService now forwards get_executor() to the io_service it wraps.

* A new header, Communication/AsioCompatibility.h, spells the four remaining
  interfaces the way the Boost release being compiled against expects:
  ip::address::from_string is now make_address, io_service::post is now the
  free function post, io_service::reset is now restart, and io_service::work
  is now executor_work_guard.  The call sites ask it rather than repeating a
  version test each time.

* The iterator-returning resolver::resolve(query) in TCPReceiver became
  resolve(host, service) returning a results range.

The examples:

* boost::asio::strand became a template, so the two burst senders name the
  class they want, io_service::strand, and reach it through dispatch and
  bind_executor rather than the strand's own wrap and dispatch.

* Asio's date_time based timers are opt-in in recent releases, so those two
  examples use steady_timer and a chrono duration instead of
  deadline_timer and a posix_time duration.

* basic_socket became a private base of the socket stream buffer, so
  FileToTCP moves an accepted socket into its stream instead of accepting
  into the stream's buffer.

* Compare the FILE* returned by std::fopen against 0 rather than ordering it
  against 0, which gcc rejects.

Verified on Ubuntu 24.04 (gcc 13, Boost 1.83), Ubuntu 25.10 (gcc 15, Boost
1.88) and against Boost 1.91 built by vcpkg: the library, all six example
programs and all 112 unit test cases build and pass in each.  No MPC file,
setup script or build flag is changed.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_017BnyHwonMsq7k6uQxWpVGF
magnaimn and others added 2 commits September 11, 2026 21:49
testPresenceMap initializes arrays of uchar from char literals.  Where char
is signed -- x86 and x86_64, as opposed to ARM -- '\xFF' is -1, and C++11
made that a narrowing conversion inside a braced initializer, so gcc and
clang reject it.  Writing the bytes as integer literals says what was meant
and is correct on either sign of char.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_017BnyHwonMsq7k6uQxWpVGF
QuickFAST is built with MPC, which asks the user to install MPC itself and
to point setup.sh or setup.cmd at a Boost and a Xerces-C tree by hand.  This
adds a CMake build alongside it for people who would rather let find_package
locate the dependencies, and so that QuickFAST can be consumed by the many
projects that expect a CMake package.

Nothing about the MPC build changes: no .mpc, .mpb, .mwc, .features or setup
script is touched, and both builds work from the same working copy.

The library target collects the same five directories the MPC project does
(Application, Codecs, Common, Communication, Messages) and globs them for
the same reason MPC lists directories rather than files, so that the two
builds do not drift apart as sources are added.  The definitions that
src/Common/QuickFAST_Export.h expects are supplied for shared and for static
builds, and the precompiled header the MPC build uses is kept.

Tests and examples are off by default:

  cmake -S . -B build -DQUICKFAST_BUILD_TESTS=ON -DQUICKFAST_BUILD_EXAMPLES=ON
  cmake --build build
  ctest --test-dir build --output-on-failure

The unit tests find their XML templates through $QUICKFAST_ROOT, so ctest
sets it for them.

Installing exports a QuickFAST::QuickFAST target, letting a downstream
project build against QuickFAST with nothing more than:

  find_package(QuickFAST REQUIRED)
  target_link_libraries(app PRIVATE QuickFAST::QuickFAST)

Headers install under include/QuickFAST so that the include style used
throughout the sources -- #include <Codecs/Decoder.h> -- keeps working
without putting directories named Common or Messages on a consumer's
include path.

Verified on Ubuntu 24.04 (gcc 13, Boost 1.83, Xerces-C 3.2) and Ubuntu 25.10
(gcc 15, Boost 1.88): static and shared builds, all 112 unit test cases, all
six examples, and a separate consumer project built against the installed
package.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_017BnyHwonMsq7k6uQxWpVGF
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants