Skip to content

Commit da5589a

Browse files
garyoclaude
andcommitted
Restructure Conan package to standard CCI layout (#238)
Reorganize the Conan package directory layout to follow the Conan Center Index / aswf-docker conventions, as suggested in #238, and fix several latent bugs in the recipe along the way. Layout changes (package()): - Headers now all live under include/: the OFX C API at the root, with host- and plugin-support headers in include/HostSupport and include/Support (and include/Support/Plugins for the .H helpers). - The CMake build module moves to lib/cmake/OpenFX.cmake, with Info.plist.in co-located so add_ofx_plugin resolves it relative to the module (CMAKE_CURRENT_LIST_DIR) rather than the consumer's CMAKE_SOURCE_DIR, which only worked inside this repo. - LICENSE goes to licenses/openfx/ (a per-package subdir avoids clashes when many packages share an install prefix); README/install docs to res/openfx/. package_info() updated to match the new include/lib/cmake paths. Latent recipe bugs fixed in passing: - "LICENSE, README.md, INSTALL.md" was a single invalid copy pattern, so no docs were ever packaged; LICENSE/install.md case also didn't match. - Support headers were copied from the wrong path (Support/*.h is empty; they live in Support/include) so they were missing from the package. - Support/Plugins helper headers use a .H extension that the *.h pattern missed on case-sensitive filesystems. - cimg and spdlog are direct requirements but were not referenced by any component, which makes package_info() error out under modern Conan (and thus fails for consumers); they are now claimed by the components whose example code uses them. Validated end to end with `conan create` (Ninja, Release): the package builds, lays out as above, and test_package consumes it — building the Invert example plugin via add_ofx_plugin (exercising the relocated Info.plist.in) and passing the property-set compliance checks. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com> Signed-off-by: Gary Oberbrunner <garyo@darkstarsystems.com>
1 parent 5ff71cf commit da5589a

2 files changed

Lines changed: 63 additions & 19 deletions

File tree

cmake/OpenFX.cmake

Lines changed: 17 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -46,7 +46,23 @@ function(add_ofx_plugin TARGET)
4646
set(BUNDLE_SIGNATURE "????") # any value is OK here, ignored by modern MacOS
4747
set(PLUGIN_VERSION "1.0.0")
4848

49-
configure_file(${CMAKE_SOURCE_DIR}/Examples/Info.plist.in
49+
# Locate the Info.plist template. In the OpenFX source tree it lives in
50+
# Examples/; in an installed/Conan package it sits next to this module
51+
# (lib/cmake/). CMAKE_CURRENT_LIST_DIR is the directory of this module file,
52+
# so this resolves correctly regardless of the consumer's CMAKE_SOURCE_DIR.
53+
set(_ofx_info_plist "")
54+
foreach(_dir "${CMAKE_CURRENT_LIST_DIR}"
55+
"${CMAKE_CURRENT_LIST_DIR}/../Examples"
56+
"${CMAKE_SOURCE_DIR}/Examples")
57+
if(EXISTS "${_dir}/Info.plist.in")
58+
set(_ofx_info_plist "${_dir}/Info.plist.in")
59+
break()
60+
endif()
61+
endforeach()
62+
if(NOT _ofx_info_plist)
63+
message(FATAL_ERROR "add_ofx_plugin: could not find Info.plist.in")
64+
endif()
65+
configure_file("${_ofx_info_plist}"
5066
"${PLUGIN_INSTALLDIR}/${TARGET}.ofx.bundle/Contents/Info.plist")
5167

5268
# Set symbol visibility hidden. Individual symbols are exposed via

conanfile.py

Lines changed: 46 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -20,9 +20,9 @@ class openfx(ConanFile):
2020
"scripts/*",
2121
"Support/*",
2222
"CMakeLists.txt",
23-
"LICENSE",
23+
"LICENSE*",
2424
"README.md",
25-
"INSTALL.md"
25+
"install.md"
2626
)
2727

2828
settings = "os", "arch", "compiler", "build_type"
@@ -59,26 +59,54 @@ def build(self):
5959
cmake.build()
6060

6161
def package(self):
62-
copy(self, "cmake/*", src=self.source_folder, dst=self.package_folder)
63-
copy(self, "LICENSE, README.md, INSTALL.md", src=self.source_folder, dst=self.package_folder)
64-
copy(self, "include/*.h", src=self.source_folder, dst=self.package_folder)
65-
copy(self,"HostSupport/include/*.h", src=self.source_folder, dst=self.package_folder)
66-
copy(self,"Support/*.h", src=self.source_folder, dst=self.package_folder)
67-
copy(self,"Support/Plugins/include/*.h", src=self.source_folder, dst=self.package_folder)
68-
copy(self,"*.a", src=self.build_folder, dst=os.path.join(self.package_folder, "lib"), keep_path=False)
69-
copy(self,"*.lib", src=self.build_folder, dst=os.path.join(self.package_folder, "lib"), keep_path=False)
70-
copy(self,"*.ofx", src=self.build_folder, dst=os.path.join(self.package_folder, "bin"), keep_path=False)
71-
copy(self,"*.dll", src=self.build_folder, dst=os.path.join(self.package_folder, "bin"), keep_path=False)
72-
copy(self,"*.so", src=self.build_folder, dst=os.path.join(self.package_folder, "bin"), keep_path=False)
62+
src = self.source_folder
63+
pkg = self.package_folder
64+
inc = os.path.join(pkg, "include")
65+
66+
# Headers, all under include/ following the standard layout. The OFX C
67+
# API headers sit at the root; the host- and plugin-support headers go
68+
# into namespaced subdirectories.
69+
copy(self, "*.h", src=os.path.join(src, "include"), dst=inc)
70+
copy(self, "*.h", src=os.path.join(src, "HostSupport", "include"),
71+
dst=os.path.join(inc, "HostSupport"))
72+
copy(self, "*.h", src=os.path.join(src, "Support", "include"),
73+
dst=os.path.join(inc, "Support"))
74+
# Plugin support helper headers use a .H extension; match both cases.
75+
copy(self, "*.[hH]", src=os.path.join(src, "Support", "Plugins", "include"),
76+
dst=os.path.join(inc, "Support", "Plugins"))
77+
78+
# The CMake build module (add_ofx_plugin) goes in lib/cmake, alongside
79+
# the Info.plist template it needs, so it resolves relative to itself
80+
# when consumed from the package (see cmake/OpenFX.cmake).
81+
cmake_dst = os.path.join(pkg, "lib", "cmake")
82+
copy(self, "OpenFX.cmake", src=os.path.join(src, "cmake"), dst=cmake_dst)
83+
copy(self, "Info.plist.in", src=os.path.join(src, "Examples"), dst=cmake_dst)
84+
85+
# License in a per-package subdir so installing many packages into one
86+
# prefix (as aswf-docker does) doesn't clash; other docs under res/.
87+
copy(self, "LICENSE*", src=src, dst=os.path.join(pkg, "licenses", "openfx"))
88+
copy(self, "README.md", src=src, dst=os.path.join(pkg, "res", "openfx"))
89+
copy(self, "install.md", src=src, dst=os.path.join(pkg, "res", "openfx"))
90+
91+
# Static libraries, then any built example plugins.
92+
lib = os.path.join(pkg, "lib")
93+
bin = os.path.join(pkg, "bin")
94+
copy(self, "*.a", src=self.build_folder, dst=lib, keep_path=False)
95+
copy(self, "*.lib", src=self.build_folder, dst=lib, keep_path=False)
96+
copy(self, "*.ofx", src=self.build_folder, dst=bin, keep_path=False)
97+
copy(self, "*.dll", src=self.build_folder, dst=bin, keep_path=False)
98+
copy(self, "*.so", src=self.build_folder, dst=bin, keep_path=False)
7399

74100
def package_info(self):
75101
libs = collect_libs(self)
76102

77-
self.cpp_info.set_property("cmake_build_modules", [os.path.join("cmake", "OpenFX.cmake")])
103+
self.cpp_info.set_property("cmake_build_modules", [os.path.join("lib", "cmake", "OpenFX.cmake")])
78104
self.cpp_info.components["Api"].includedirs = ["include"]
79105
self.cpp_info.components["HostSupport"].libs = [i for i in libs if "OfxHost" in i]
80-
self.cpp_info.components["HostSupport"].includedirs = ["HostSupport/include"]
81-
self.cpp_info.components["HostSupport"].requires = ["expat::expat"]
106+
self.cpp_info.components["HostSupport"].includedirs = ["include/HostSupport"]
107+
# spdlog is used by the example/host logging helpers (header-only here).
108+
self.cpp_info.components["HostSupport"].requires = ["expat::expat", "spdlog::spdlog"]
82109
self.cpp_info.components["Support"].libs = [i for i in libs if "OfxSupport" in i]
83-
self.cpp_info.components["Support"].includedirs = ["Support/include"]
84-
self.cpp_info.components["Support"].requires = ["opengl::opengl"]
110+
self.cpp_info.components["Support"].includedirs = ["include/Support", "include/Support/Plugins"]
111+
# cimg is used by the support example plugins to draw text (header-only).
112+
self.cpp_info.components["Support"].requires = ["opengl::opengl", "cimg::cimg"]

0 commit comments

Comments
 (0)