Skip site navigation (1)Skip section navigation (2)

FreeBSD Manual Pages

  
 
  

home | help
ECM-DEVELOPER(7)	       Extra CMake Modules		ECM-DEVELOPER(7)

NAME
     ecm-developer - ECM Developer Reference

WRITING MODULES
     The  CMake 3 documentation (and cmake-developer(7) in particular) has a lot
     of useful information about writing CMake modules, including a  large  sec-
     tion  devoted  to	find modules. This guide will only highlight things that
     are particular to the Extra CMake Modules project.

     Most of these are stylistic points. For example, the license header  for  a
     module in ECM should look like:

	# SPDX-FileCopyrightText: 20XX Your Name <your.email@example.com>
	#
	# SPDX-License-Identifier: BSD-3-Clause

     Documentation  is	written  in  reStructuredText  format  and  put inside a
     bracket comment with a .rst: id after the opening bracket:

	#[=======================================================================[.rst:
	The docs
	#]=======================================================================]

     (docs/sphinx/ext/ecm.py has code to extract the rst  text	from  a  comment
     with such wrapping)

     Functions	should	be  used instead of macros unless there is a good reason
     not to (and that reason should be noted in a comment), and lowercase should
     be used for macros, functions and commands.

     4 spaces is the generally-recommended indent, although  there  are  several
     files  that  use 2 spaces; consistency within a file is more important than
     consistency across files.

     If in doubt, look at how other modules in Extra CMake Modules are	written,
     and follow the same pattern.

   Find Modules
     A good template for find module documentation is:

	#[=======================================================================[.rst:
	FindFoo
	-------

	Finds the Foo library.

	This will define the following variables:

	``Foo_FOUND``
	    True if (the requested version of) Foo is available
	``Foo_VERSION``
	    The version of Foo, if it is found
	``Foo_LIBRARIES``
	    This can be passed to target_link_libraries() instead of the ``Foo::Foo``
	    target
	``Foo_INCLUDE_DIRS``
	    This should be passed to target_include_directories() if the target is not
	    used for linking
	``Foo_DEFINITIONS``
	    This should be passed to target_compile_options() if the target is not
	    used for linking

	If ``Foo_FOUND`` is TRUE, it will also define the following imported target:

	``Foo::Foo``
	    The Foo library

	In general we recommend using the imported target, as it is easier to use.
	Bear in mind, however, that if the target is in the link interface of an
	exported library, it must be made available by the package config file.
	#]=======================================================================]

     Note the use of definition lists for the variables.

     Because  of  the  ECMUseFindModules  module, projects may easily make local
     copies of find modules, and may install those copies with their  own  CMake
     project config files. For this reason, find modules should include the full
     BSD 3-clause license:

	#=============================================================================
	# Copyright 20XX Your Name <your.email@example.com>
	#
	# Redistribution and use in source and binary forms, with or without
	# modification, are permitted provided that the following conditions
	# are met:
	#
	# 1. Redistributions of source code must retain the copyright
	#    notice, this list of conditions and the following disclaimer.
	# 2. Redistributions in binary form must reproduce the copyright
	#    notice, this list of conditions and the following disclaimer in the
	#    documentation and/or other materials provided with the distribution.
	# 3. The name of the author may not be used to endorse or promote products
	#    derived from this software without specific prior written permission.
	#
	# THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
	# IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
	# OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
	# IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
	# INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
	# NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
	# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
	# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
	# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
	# THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
	#=============================================================================

     Find modules should always provide imported targets in addition to the tra-
     ditional variables (like Foo_LIBRARIES, etc).

     Unlike  find  modules shipped with CMake, if the module requires a specific
     CMake version it is not enough to warn when the minimum required version is
     not high enough: you should also produce an error	when  the  actual  CMake
     version being used is not high enough. This can be done with:

	if(CMAKE_VERSION VERSION_LESS 3.16.0)
	    message(FATAL_ERROR "CMake 3.16.0 is required by FindFoo.cmake")
	endif()
	if(CMAKE_MINIMUM_REQUIRED_VERSION VERSION_LESS 3.16.0)
	    message(AUTHOR_WARNING "Your project should require at least CMake 3.16.0 to use FindFoo.cmake")
	endif()

     The  ECMFindModuleHelpers	module	has several useful functions and macros.
     For example, it allows you to replace the above version check with:

	ecm_find_package_version_check(Foo)

   Components
     Using ECMFindModuleHelpers, creating a find module for a library with  sev-
     eral  inter-dependent  components	is reasonably straightforward. After the
     documentation, you need to include the module  and  do  the  usual  version
     check:

	include(ECMFindModuleHelpers)
	ecm_find_package_version_check(Foo)

     The    important	 macros    are	 ecm_find_package_parse_components   and
     ecm_find_package_handle_library_components.  These take a	list  of  compo-
     nents,  and  query  other variables you provide to find out the information
     they require.  The documentation for ECMFindModuleHelpers provides more in-
     formation, but a simple setup might look like:

	set(Foo_known_components Bar Baz)
	set(Foo_Bar_pkg_config "foo-bar")
	set(Foo_Bar_lib "bar")
	set(Foo_Bar_header "foo/bar.h")
	set(Foo_Bar_pkg_config "foo-baz")
	set(Foo_Baz_lib "baz")
	set(Foo_Baz_header "foo/baz.h")

     If Baz depends on Bar, for example, you can specify this with

	set(Foo_Baz_component_deps "Bar")

     Then call the macros:

	ecm_find_package_parse_components(Foo
	    RESULT_VAR Foo_components
	    KNOWN_COMPONENTS ${Foo_known_components}
	)
	ecm_find_package_handle_library_components(Foo
	    COMPONENTS ${Foo_components}
	)

     Of course, if your components need unusual handling, you may  want  to  re-
     place ecm_find_package_handle_library_components with, for example, a fore-
     ach  loop	over  the components (the body of which should implement most of
     what a normal find module does, including setting Foo_<component>_FOUND).

     At this point, you should set Foo_VERSION using  whatever	information  you
     have   available	(such	as   from  parsing  header  files).   Note  that
     ecm_find_package_handle_library_components will set it to the  version  re-
     ported  by pkg-config of the first component found, but this depends on the
     presence of pkg-config files, and the version of a component may not be the
     same as the version of the whole package.	After that, finish off with

	include(FindPackageHandleStandardArgs)
	find_package_handle_standard_args(Foo
	    FOUND_VAR
		Foo_FOUND
	    REQUIRED_VARS
		Foo_LIBRARIES
	    VERSION_VAR
		Foo_VERSION
	    HANDLE_COMPONENTS
	)

	include(FeatureSummary)
	set_package_properties(Foo PROPERTIES
	    URL "https://www.foo.example.com/"
	    DESCRIPTION "A library for doing useful things")

SUBMITTING MODULES
     Proposed new modules should be submitted using the  KDE  Review  Board  in-
     stance,  and  be  assigned to the buildsystem and extracmakemodules groups.
     You should be able to point to two separate projects that will make use  of
     the module.

     The       mailing	     list	can	  be	   found       at      -
     https://mail.kde.org/mailman/listinfo/kde-buildsystem.

COPYRIGHT
     KDE Developers

6.28				  Jul 31, 2026			ECM-DEVELOPER(7)

Want to link to this manual page? Use this URL:
<https://man.freebsd.org/cgi/man.cgi?query=ecm-developer&sektion=7&manpath=FreeBSD+Ports+15.1.quarterly>

home | help