Of the paths you listed, if the path has the name of the <package>, then it
very likely means that the port uses something called a "config-file
package" [1]. This is something that is often related to us as software
packagers, and is made up of "package configuration files" and "package
version files". For a package named 'Foo', these files will have names that
look something like 'FooConfig.cmake' and 'FooConfigVersion.cmake'. If you
look at the documentation that I linked to, you will see that these files
are usually placed in ${prefix}/lib/cmake/Foo. The config-file package
files may be provided as an alternative to a CMake find module file (or
sometimes provided in addition to a find module file).

Here are some general guidelines that I've found when dealing with
packaging open source projects that use CMake, which seems to be the
majority, these days. (None of this is documented anywhere, of course. It's
just my personal experience, and my personal interpretation of the CMake
documentation.)

* In general, you should never place any find module files inside
${prefix}/share/cmake-<cmakeVersion>/Modules. These are the default find
modules that are provided by the CMake package itself.
* You CAN (and probably should) place your package's find module file
inside ${prefix}/share/cmake/Modules.
* You can also place your package's find module file inside one of the
package-specific paths you listed (e.g. ${prefix}/lib/cmake/Foo/modules),
and then create a symlink from ${prefix}/share/cmake/Modules to the actual
file. I've found that sometimes CMake is unable to resolve the symlink when
compiling a port that depends on the port with my custom find module,
regardless of what file permissions I put on both the symlink and the
actual file. YMMV.

If you are going to be creating a find module file from scratch, you should
try to follow the sample that is given in the CMake documentation that
discusses CMake find modules [2]. This isn't always possible, because what
the find module file looks like is highly dependent on how the source code
is getting compiled. Still, you should use the sample as your starting
point, and then modify accordingly.

Note that there are two strategies for getting the find module file into
the final products of the package. The first is a MacPorts-specific
solution:

post-destroot {
    ...
    # Install the CMake find module
    set cmake_modules_dir ${prefix}/share/cmake/Modules
    xinstall -d ${destroot}$cmake_modules_dir
    copy ${filespath}/Find${github.author}.cmake.in \
         ${destroot}$cmake_modules_dir/Find${github.author}.cmake
    ...
}

The second strategy is to create a patch that modifies 'CMakeLists.txt' to
install your find module file for you during the compilation process.

If your find module file ends up working well, you may also want to
consider submitting it upstream so that it gets included in the original
project. This is where the second strategy pays off, since it's not
MacPorts-specific.

[1]
https://cmake.org/cmake/help/latest/manual/cmake-packages.7.html#package-layout
[2]
https://cmake.org/cmake/help/latest/manual/cmake-developer.7.html#find-modules

P.S.: If you want to be super fancy, you may also want to consider creating
a pkg-config file (Foo.pc) for your package. This will allow any downstream
projects that are dependent on your package to find your package using
either pkg-config OR CMake, and it also allows your CMake find module to
utilize pkg-config to find your package (as discussed in the sample given
in [2]). I have occasionally run into a situation where a library uses
CMake to get compiled, but then the downstream application that depends on
the library still uses autotools for its build. Obviously autotools can't
use CMake's find_package(), but pkg-config is designed to be highly
compatible with the autotools toolchain. So having both a CMake find module
file and a pkg-config file allows the library to be used by a wider range
of downstream projects. And again, if your pkg-config file works well, you
should also submit it upstream to your package's source code.

-- 
Jason Liu


On Thu, Apr 24, 2025 at 10:56 PM Dave Allured - NOAA Affiliate via
macports-dev <macports-dev@lists.macports.org> wrote:

> I am working on a port that tries to install its own Find<package>.cmake
> file.  Is there a standard install directory, or "best" directory, to
> install such .cmake files?
>
> A search of my current MacPorts installs finds multiple choices within
> $prefix; such as lib/cmake/<package>, lib/cmake/<package>/modules,
> libexec/<package>/lib/cmake, share/<package>/src, share/cmake/Modules, and
> share/<package>/cmake.  There is also an include/<package> example that I
> don't trust because it is on the broken port that I am trying to fix.
>
> I did not find guidance in MacPorts docs or Trac tickets.  I hope someone
> on the dev list has experience in this.  Any advice?
>

Reply via email to