Repository: ACCESS-NRI/libaccessom2
Pull request #17: Allow libaccessom2 to be used in other CMake projects using find_package
Author: login: dougiesquire
Created: 2025-05-13T12:21:28Z | Merged: 2025-05-15T00:46:07Z

The changes in this PR allow libaccessom2 to be used in other CMake projects using `find_package`:
- CMake targets are exported
- CMake package config file is configured and installed
- CMAKE_INSTALL_INCLUDEDIR is added to accessom2 include directories


Diff:
diff --git a/CMakeLists.txt b/CMakeLists.txt
index 87ef46e..69ab9d5 100644
--- a/CMakeLists.txt
+++ b/CMakeLists.txt
@@ -91,7 +91,10 @@ target_sources(accessom2 PRIVATE
 target_link_libraries(accessom2 PUBLIC
 			util
 			PkgConfig::DATETIME
-			PkgConfig::OASIS3PSMILE)
+			PkgConfig::OASIS3PSMILE
+			PkgConfig::OASIS3MCT
+			PkgConfig::OASIS3MPEU
+			PkgConfig::OASIS3SCRIP)
 
 add_executable(forcing_test.exe libforcing/test/forcing_test.F90)
 target_link_libraries(forcing_test.exe
@@ -159,11 +162,33 @@ cmake_path(APPEND PKGCONFIGFILE
 cmake_path(APPEND INSTALL_PKGCONFIGDIR ${CMAKE_INSTALL_LIBDIR} "pkgconfig")
 configure_file(libaccessom2.pc.in ${PKGCONFIGFILE} @ONLY)
 
-
-install(TARGETS accessom2)
+# See note at the end of: https://cmake.org/cmake/help/latest/command/install.html#targets
+# Object Libraries with no destination install no artifacts but will be included in the EXPORT
+install(TARGETS util
+	EXPORT libaccessom2-targets)
+install(TARGETS accessom2
+	EXPORT libaccessom2-targets)
 install(TARGETS yatm.exe)
 install(TARGETS ice_stub.exe)
 install(TARGETS ocean_stub.exe)
 # Fortran mod files (https://gitlab.kitware.com/cmake/cmake/-/issues/19608)
 install(DIRECTORY ${CMAKE_Fortran_MODULE_DIRECTORY}/ TYPE INCLUDE)
 install(FILES ${PKGCONFIGFILE} DESTINATION ${INSTALL_PKGCONFIGDIR})
+
+target_include_directories(accessom2 PUBLIC "$<INSTALL_INTERFACE:${CMAKE_INSTALL_INCLUDEDIR}>")
+
+install(EXPORT libaccessom2-targets
+	FILE libaccessom2-targets.cmake
+	NAMESPACE libaccessom2::
+	DESTINATION ${CMAKE_INSTALL_LIBDIR}/cmake/libaccessom2
+)
+
+include(CMakePackageConfigHelpers)
+configure_package_config_file(
+	cmake/libaccessom2-config.cmake.in
+	"${CMAKE_CURRENT_BINARY_DIR}/libaccessom2-config.cmake"
+	INSTALL_DESTINATION ${CMAKE_INSTALL_LIBDIR}/cmake/libaccessom2
+)
+install(FILES ${CMAKE_CURRENT_BINARY_DIR}/libaccessom2-config.cmake
+	DESTINATION ${CMAKE_INSTALL_LIBDIR}/cmake/libaccessom2
+)
\ No newline at end of file
diff --git a/cmake/libaccessom2-config.cmake.in b/cmake/libaccessom2-config.cmake.in
new file mode 100644
index 0000000..b9996a8
--- /dev/null
+++ b/cmake/libaccessom2-config.cmake.in
@@ -0,0 +1,33 @@
+# Copyright ACCESS-NRI and contributors. See the top-level LICENSE file for details.
+
+@PACKAGE_INIT@
+
+if(NOT libaccessom2_FIND_QUIETLY)
+  message(STATUS "Found libaccessom2: ${PACKAGE_PREFIX_DIR}")
+endif()
+
+include(CMakeFindDependencyMacro)
+
+# Request components
+set(_required_components ${libaccessom2_FIND_COMPONENTS})
+
+find_package(MPI REQUIRED)
+find_package(PkgConfig REQUIRED)
+pkg_check_modules(NETCDF REQUIRED IMPORTED_TARGET "netcdf-fortran")
+# Back to using the upstream version as the the bug is apparently not
+# reproducible since intel-compiler/2019.5.281 and intel-compiler/2020.0.166:
+# https://github.com/wavebitscientific/datetime-fortran/issues/51
+pkg_check_modules(DATETIME REQUIRED IMPORTED_TARGET "datetime-fortran")
+pkg_check_modules(JSONFORTRAN REQUIRED IMPORTED_TARGET "json-fortran")
+pkg_check_modules(OASIS3MCT REQUIRED IMPORTED_TARGET "oasis3-mct")
+pkg_check_modules(OASIS3MPEU REQUIRED IMPORTED_TARGET "oasis3-mpeu")
+pkg_check_modules(OASIS3PSMILE REQUIRED IMPORTED_TARGET "oasis3-psmile.MPI1")
+pkg_check_modules(OASIS3SCRIP REQUIRED IMPORTED_TARGET "oasis3-scrip")
+
+# Run the normal Targets.cmake
+list(APPEND CMAKE_MODULE_PATH ${CMAKE_CURRENT_LIST_DIR})
+include("${CMAKE_CURRENT_LIST_DIR}/libaccessom2-targets.cmake")
+list(REMOVE_ITEM CMAKE_MODULE_PATH ${CMAKE_CURRENT_LIST_DIR})
+
+# Check the requested components are valid
+check_required_components(_required_components)
\ No newline at end of file


Reviews:
user: login: micaeljtoliveira
body: I can't see any obvious issues in the added code, so will approve.
state: APPROVED
author_association: MEMBER
submitted_at: 2025-05-13T22:05:47Z
user: login: harshula
state: COMMENTED
author_association: NONE
submitted_at: 2025-05-14T02:34:59Z
user: login: dougiesquire
state: COMMENTED
author_association: COLLABORATOR
submitted_at: 2025-05-14T02:57:05Z
user: login: harshula
state: COMMENTED
author_association: NONE
submitted_at: 2025-05-15T00:43:21Z

Review comments:
diff_hunk: @@ -91,7 +91,10 @@ target_sources(accessom2 PRIVATE
 target_link_libraries(accessom2 PUBLIC
 			util
 			PkgConfig::DATETIME
-			PkgConfig::OASIS3PSMILE)
+			PkgConfig::OASIS3PSMILE
+			PkgConfig::OASIS3MCT
+			PkgConfig::OASIS3MPEU
+			PkgConfig::OASIS3SCRIP)
path: CMakeLists.txt
user: login: harshula
body: Does libaccessom2 need these three libraries?
created_at: 2025-05-14T02:34:59Z
author_association: NONE
diff_hunk: @@ -91,7 +91,10 @@ target_sources(accessom2 PRIVATE
 target_link_libraries(accessom2 PUBLIC
 			util
 			PkgConfig::DATETIME
-			PkgConfig::OASIS3PSMILE)
+			PkgConfig::OASIS3PSMILE
+			PkgConfig::OASIS3MCT
+			PkgConfig::OASIS3MPEU
+			PkgConfig::OASIS3SCRIP)
path: CMakeLists.txt
user: login: dougiesquire
body: They are used by `OASIS3PSMILE`. I had to add these to avoid getting errors like:
```
.../psmile/src/mod_oasis_method.F90:735: undefined reference to `m_mctworld_mp_initd__'
```
created_at: 2025-05-14T02:57:05Z
author_association: COLLABORATOR
diff_hunk: @@ -91,7 +91,10 @@ target_sources(accessom2 PRIVATE
 target_link_libraries(accessom2 PUBLIC
 			util
 			PkgConfig::DATETIME
-			PkgConfig::OASIS3PSMILE)
+			PkgConfig::OASIS3PSMILE
+			PkgConfig::OASIS3MCT
+			PkgConfig::OASIS3MPEU
+			PkgConfig::OASIS3SCRIP)
path: CMakeLists.txt
user: login: harshula
body: Looks like I had handled that dependency in the oasis3-mct SPR (not ideal) for other dependents:
```
    @property
    def libs(self):
        # NOTE: The order matters during the linking step of the cice5 build!
        # "-lpsmile.MPI1 -lmct -lmpeu -lscrip"
        libraries = ["libpsmile.MPI1", "libmct", "libmpeu", "libscrip"]
        return find_libraries(
            libraries, root=self.prefix, shared=False, recursive=True
        )
```
created_at: 2025-05-15T00:43:21Z
author_association: NONE

PR comments:
user: login: dougiesquire
created_at: 2025-05-13T23:45:24Z
body: Thanks @micaeljtoliveira. I'll wait for @harshula's nod of approval before merging.
author_association: COLLABORATOR
user: login: harshula
created_at: 2025-05-15T00:44:36Z
body: I'm not familiar enough with the CMake side to review this, so please go ahead and merge since @micaeljtoliveira has reviewed it.
author_association: NONE