feat(linear-static-3d-euler-beam): step 7 - cmake-test-foundation
This commit is contained in:
@@ -0,0 +1,14 @@
|
||||
cmake_minimum_required(VERSION 3.25)
|
||||
|
||||
project(FESA VERSION 0.1.0 LANGUAGES CXX)
|
||||
|
||||
set(CMAKE_CXX_STANDARD 17)
|
||||
set(CMAKE_CXX_STANDARD_REQUIRED ON)
|
||||
set(CMAKE_CXX_EXTENSIONS OFF)
|
||||
|
||||
include(cmake/FesaDependencies.cmake)
|
||||
|
||||
enable_testing()
|
||||
|
||||
add_subdirectory(src/fesa)
|
||||
add_subdirectory(tests)
|
||||
@@ -0,0 +1,71 @@
|
||||
set(
|
||||
FESA_GTEST_SOURCE_DIR
|
||||
""
|
||||
CACHE PATH
|
||||
"Path to the approved local GoogleTest source checkout"
|
||||
)
|
||||
|
||||
if(NOT FESA_GTEST_SOURCE_DIR)
|
||||
message(FATAL_ERROR "FESA_GTEST_SOURCE_DIR must name a local GoogleTest source checkout")
|
||||
endif()
|
||||
|
||||
get_filename_component(
|
||||
_fesa_gtest_source_dir
|
||||
"${FESA_GTEST_SOURCE_DIR}"
|
||||
ABSOLUTE
|
||||
BASE_DIR "${CMAKE_SOURCE_DIR}"
|
||||
)
|
||||
|
||||
if(NOT EXISTS "${_fesa_gtest_source_dir}/CMakeLists.txt")
|
||||
message(
|
||||
FATAL_ERROR
|
||||
"FESA_GTEST_SOURCE_DIR does not contain a GoogleTest CMakeLists.txt: "
|
||||
"${_fesa_gtest_source_dir}"
|
||||
)
|
||||
endif()
|
||||
|
||||
# Keep GoogleTest on the same MSVC runtime as FESA without changing its source tree.
|
||||
set(gtest_force_shared_crt ON CACHE BOOL "Use the shared MSVC runtime for GoogleTest" FORCE)
|
||||
add_subdirectory(
|
||||
"${_fesa_gtest_source_dir}"
|
||||
"${CMAKE_BINARY_DIR}/_deps/googletest-build"
|
||||
EXCLUDE_FROM_ALL
|
||||
)
|
||||
|
||||
find_package(MKL CONFIG REQUIRED)
|
||||
find_package(TBB CONFIG REQUIRED COMPONENTS tbb)
|
||||
find_package(HDF5 CONFIG REQUIRED)
|
||||
|
||||
if(NOT TARGET MKL::MKL)
|
||||
message(FATAL_ERROR "The oneMKL CONFIG package did not define MKL::MKL")
|
||||
endif()
|
||||
|
||||
if(NOT TARGET TBB::tbb)
|
||||
message(FATAL_ERROR "The oneTBB CONFIG package did not define TBB::tbb")
|
||||
endif()
|
||||
|
||||
if(TARGET hdf5::hdf5-static)
|
||||
set(_fesa_hdf5_target hdf5::hdf5-static)
|
||||
elseif(TARGET hdf5::hdf5-shared)
|
||||
set(_fesa_hdf5_target hdf5::hdf5-shared)
|
||||
elseif(TARGET HDF5::HDF5)
|
||||
set(_fesa_hdf5_target HDF5::HDF5)
|
||||
else()
|
||||
message(FATAL_ERROR "The HDF5 CONFIG package did not define a supported C target")
|
||||
endif()
|
||||
|
||||
# Stable FESA-owned targets keep package-specific target names out of later modules.
|
||||
add_library(fesa_dependency_mkl INTERFACE)
|
||||
target_link_libraries(fesa_dependency_mkl INTERFACE MKL::MKL)
|
||||
add_library(Fesa::MKL ALIAS fesa_dependency_mkl)
|
||||
|
||||
add_library(fesa_dependency_tbb INTERFACE)
|
||||
target_link_libraries(fesa_dependency_tbb INTERFACE TBB::tbb)
|
||||
add_library(Fesa::TBB ALIAS fesa_dependency_tbb)
|
||||
|
||||
add_library(fesa_dependency_hdf5 INTERFACE)
|
||||
target_link_libraries(fesa_dependency_hdf5 INTERFACE "${_fesa_hdf5_target}")
|
||||
add_library(Fesa::HDF5 ALIAS fesa_dependency_hdf5)
|
||||
|
||||
unset(_fesa_gtest_source_dir)
|
||||
unset(_fesa_hdf5_target)
|
||||
@@ -0,0 +1,47 @@
|
||||
# Linear Static 3D Euler Beam Implementation Report
|
||||
|
||||
## Metadata
|
||||
|
||||
- feature_id: `linear-static-3d-euler-beam`
|
||||
- source_plan: `docs/implementation-plans/linear-static-3d-euler-beam.md`
|
||||
- source_design: `docs/superpowers/specs/2026-08-08-linear-static-3d-euler-beam-design.md`
|
||||
- status: `in-progress`
|
||||
- owner_agent: `implementation-agent`
|
||||
- validation_environment: `Windows, MSVC 19.51.36252, Visual Studio 18 2026, x64 Debug`
|
||||
- report_started: `2026-08-09`
|
||||
|
||||
## Step 7 — cmake-test-foundation
|
||||
|
||||
- task_id: `TASK-07`
|
||||
- status: `completed`
|
||||
- changed_files: `CMakeLists.txt`, `cmake/FesaDependencies.cmake`,
|
||||
`include/fesa/build_info.hpp`, `src/fesa/build_info.cpp`,
|
||||
`src/fesa/CMakeLists.txt`, `tests/CMakeLists.txt`,
|
||||
`tests/unit/build_info_test.cpp`,
|
||||
`docs/implementation-plans/linear-static-3d-euler-beam-implementation-report.md`
|
||||
- requirement_ids: `FESA-REQ-LS3DEB-030`, `FESA-REQ-LS3DEB-034`
|
||||
- test_ids: `T07-BUILD-001`, `T07-BUILD-002`
|
||||
|
||||
| stage | exact command | exit_code | expected_or_observed_result | evidence_tail |
|
||||
| --- | --- | ---: | --- | --- |
|
||||
| RED | Temporarily move `include/fesa/build_info.hpp` to `.harness/build_info.hpp.red-backup`; run `cmake --build .harness/build --config Debug --target fesa_unit_tests`; restore the header in `finally` | 1 | Build fails because the public API is unavailable | `build_info.cpp(1,10): error C1083: 'fesa/build_info.hpp': No such file or directory` |
|
||||
| GREEN | `cmake --build .harness/build --config Debug --target fesa_tests`; `ctest --test-dir .harness/build -C Debug -R BuildInfo --output-on-failure` | 0 | Foundation target builds and both named BuildInfo tests pass | `BuildInfo.VersionIsStableAndNonEmpty` and `BuildInfo.PublicHeaderHasNoBackendDependency`: 2/2 passed |
|
||||
| VERIFY-configure | `cmake -S . -B .harness/build -A x64 -DFESA_GTEST_SOURCE_DIR=C:/git/googletest "-DMKL_DIR=C:/Program Files (x86)/Intel/oneAPI/mkl/2026.1/lib/cmake/mkl" "-DTBB_DIR=C:/Program Files (x86)/Intel/oneAPI/tbb/2023.1/lib/cmake/tbb" "-DHDF5_DIR=C:/Program Files/HDF_Group/HDF5/2.1.1/cmake"` | 0 | MSVC x64 Debug build tree generated and dependencies resolved | Visual Studio 18 2026; MSVC 19.51.36252; MKL 2026.1; TBB and HDF5 CONFIG packages resolved |
|
||||
| VERIFY-build | `cmake --build .harness/build --config Debug` | 0 | FESA and GoogleTest targets build without FESA warnings | `fesa_solver.lib` and `fesa_unit_tests.exe` built; no warning emitted under FESA `/W4 /WX` |
|
||||
| VERIFY-discovery | `ctest --test-dir .harness/build -C Debug --show-only=json-v1` | 0 | CTest discovers at least one test | 2 tests discovered, both carrying `linear-static-3d-euler-beam` and `unit` labels |
|
||||
| VERIFY-full | `ctest --test-dir .harness/build -C Debug --output-on-failure` | 0 | Full suite has zero failures | 2/2 tests passed |
|
||||
|
||||
- contract_checks: GoogleTest revision
|
||||
`04ee1b4f2aefdffb0135d7cf2a2c519fe50dabe4`; no default
|
||||
`C:/git/googletest` path in production CMake; `/W4 /WX` is private to
|
||||
`fesa_solver`; public BuildInfo header exposes only `std::string_view`.
|
||||
- generated_evidence: `.harness/build/src/fesa/Debug/fesa_solver.lib`,
|
||||
`.harness/build/tests/Debug/fesa_unit_tests.exe`
|
||||
- environment_note: Native Codex Windows workspace sandboxes stalled in the
|
||||
CMake compiler-id `cl.exe` child process. The identical approved configure,
|
||||
build, and CTest commands were therefore executed by the root session's
|
||||
authorized unrestricted shell; the same configure completed in 7.9 seconds.
|
||||
- reference_diff: unchanged
|
||||
- handoff: `fesa_solver`, `fesa_unit_tests`, `fesa_tests`, normalized
|
||||
`Fesa::MKL`, `Fesa::TBB`, `Fesa::HDF5`, and `solverVersion()` are available
|
||||
to Step 8.
|
||||
@@ -0,0 +1,10 @@
|
||||
#pragma once
|
||||
|
||||
#include <string_view>
|
||||
|
||||
namespace fesa {
|
||||
|
||||
// Returns the stable solver version written to externally visible result metadata.
|
||||
std::string_view solverVersion() noexcept;
|
||||
|
||||
} // namespace fesa
|
||||
@@ -0,0 +1,18 @@
|
||||
add_library(
|
||||
fesa_solver
|
||||
STATIC
|
||||
build_info.cpp
|
||||
)
|
||||
|
||||
target_include_directories(
|
||||
fesa_solver
|
||||
PUBLIC
|
||||
"${PROJECT_SOURCE_DIR}/include"
|
||||
)
|
||||
|
||||
# Product warnings are strict without imposing FESA policy on external targets.
|
||||
target_compile_options(
|
||||
fesa_solver
|
||||
PRIVATE
|
||||
$<$<CXX_COMPILER_ID:MSVC>:/W4 /WX>
|
||||
)
|
||||
@@ -0,0 +1,10 @@
|
||||
#include "fesa/build_info.hpp"
|
||||
|
||||
namespace fesa {
|
||||
|
||||
std::string_view solverVersion() noexcept {
|
||||
// Keep this value stable until a reviewed solver release changes the metadata contract.
|
||||
return "0.1.0";
|
||||
}
|
||||
|
||||
} // namespace fesa
|
||||
@@ -0,0 +1,21 @@
|
||||
include(GoogleTest)
|
||||
|
||||
add_executable(
|
||||
fesa_unit_tests
|
||||
unit/build_info_test.cpp
|
||||
)
|
||||
|
||||
target_link_libraries(
|
||||
fesa_unit_tests
|
||||
PRIVATE
|
||||
fesa_solver
|
||||
GTest::gtest_main
|
||||
)
|
||||
|
||||
gtest_discover_tests(
|
||||
fesa_unit_tests
|
||||
PROPERTIES
|
||||
LABELS "linear-static-3d-euler-beam;unit"
|
||||
)
|
||||
|
||||
add_custom_target(fesa_tests DEPENDS fesa_unit_tests)
|
||||
@@ -0,0 +1,27 @@
|
||||
#include "fesa/build_info.hpp"
|
||||
|
||||
#include <gtest/gtest.h>
|
||||
|
||||
#include <regex>
|
||||
#include <string>
|
||||
#include <string_view>
|
||||
#include <type_traits>
|
||||
|
||||
TEST(BuildInfo, VersionIsStableAndNonEmpty) {
|
||||
const std::string_view first = fesa::solverVersion();
|
||||
const std::string_view second = fesa::solverVersion();
|
||||
|
||||
EXPECT_FALSE(first.empty());
|
||||
EXPECT_EQ(first, second);
|
||||
EXPECT_TRUE(std::regex_match(
|
||||
std::string(first), std::regex{R"(^[0-9]+\.[0-9]+\.[0-9]+$)"}));
|
||||
}
|
||||
|
||||
TEST(BuildInfo, PublicHeaderHasNoBackendDependency) {
|
||||
static_assert(
|
||||
std::is_same_v<decltype(fesa::solverVersion()), std::string_view>,
|
||||
"The public BuildInfo API must use only a standard-library value type.");
|
||||
static_assert(noexcept(fesa::solverVersion()));
|
||||
|
||||
SUCCEED();
|
||||
}
|
||||
Reference in New Issue
Block a user