Skip to content

Commit 0b95cd6

Browse files
committed
Add env support to Sphinx docs target
1 parent 6c5c251 commit 0b95cd6

File tree

16 files changed

+406
-21
lines changed

16 files changed

+406
-21
lines changed

cmake/FindSphinx.cmake

Lines changed: 86 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -50,12 +50,39 @@ if (Sphinx_FOUND AND NOT TARGET Sphinx::Build)
5050
PROPERTIES
5151
IMPORTED_LOCATION "${SPHINX_EXECUTABLE}")
5252

53+
# Helper function to register a Sphinx documentation target.
5354
function(sphinx_add_docs NAME)
55+
set(_BOOL_ARGS
56+
ALL
57+
SHOW_TRACEBACK
58+
WRITE_ALL
59+
FRESH_ENV
60+
ISOLATED
61+
)
62+
63+
set(_SINGLE_VALUE_ARGS
64+
COMMENT
65+
BUILDER
66+
CONFIG_DIRECTORY
67+
SOURCE_DIRECTORY
68+
OUTPUT_DIRECTORY
69+
WORKING_DIRECTORY
70+
)
71+
72+
set(_MULTI_VALUE_ARGS
73+
DEFINE
74+
DEPENDS
75+
LIBRARY_PATH_PREPEND
76+
PYTHON_PATH_PREPEND
77+
ENVIRONMENT
78+
)
79+
5480
cmake_parse_arguments(
5581
PARSE_ARGV 1 ""
56-
"ALL;SHOW_TRACEBACK;WRITE_ALL;FRESH_ENV;ISOLATED"
57-
"COMMENT;BUILDER;CONFIG_DIRECTORY;SOURCE_DIRECTORY;OUTPUT_DIRECTORY"
58-
"DEFINE;DEPENDS")
82+
"${_BOOL_ARGS}"
83+
"${_SINGLE_VALUE_ARGS}"
84+
"${_MULTI_VALUE_ARGS}"
85+
)
5986

6087
# Ensure that target should be added to the default build target,
6188
# if required.
@@ -65,6 +92,61 @@ if (Sphinx_FOUND AND NOT TARGET Sphinx::Build)
6592
set(_ALL "")
6693
endif()
6794

95+
# Set platform-specific library path environment variable.
96+
if (CMAKE_SYSTEM_NAME STREQUAL Windows)
97+
set(LIBRARY_ENV_NAME PATH)
98+
elseif (CMAKE_SYSTEM_NAME STREQUAL Darwin)
99+
set(LIBRARY_ENV_NAME DYLD_LIBRARY_PATH)
100+
else()
101+
set(LIBRARY_ENV_NAME LD_LIBRARY_PATH)
102+
endif()
103+
104+
# Convert paths to CMake-friendly format.
105+
if(DEFINED ENV{${LIBRARY_ENV_NAME}})
106+
cmake_path(CONVERT "$ENV{${LIBRARY_ENV_NAME}}" TO_CMAKE_PATH_LIST LIBRARY_PATH)
107+
else()
108+
set(LIBRARY_PATH "")
109+
endif()
110+
if(DEFINED ENV{PYTHONPATH})
111+
cmake_path(CONVERT "$ENV{PYTHONPATH}" TO_CMAKE_PATH_LIST PYTHON_PATH)
112+
else()
113+
set(PYTHON_PATH "")
114+
endif()
115+
116+
# Prepend specified paths to the library and Python paths.
117+
if (_LIBRARY_PATH_PREPEND)
118+
list(PREPEND LIBRARY_PATH ${_LIBRARY_PATH_PREPEND})
119+
endif()
120+
121+
if (_PYTHON_PATH_PREPEND)
122+
list(PREPEND PYTHON_PATH ${_PYTHON_PATH_PREPEND})
123+
endif()
124+
125+
# Build environment arguments for cmake -E env.
126+
set(_env_args "")
127+
128+
if (LIBRARY_PATH)
129+
if (CMAKE_SYSTEM_NAME STREQUAL Windows)
130+
list(JOIN LIBRARY_PATH "\\;" _LIBRARY_PATH_STRING)
131+
else()
132+
list(JOIN LIBRARY_PATH ":" _LIBRARY_PATH_STRING)
133+
endif()
134+
list(APPEND _env_args "${LIBRARY_ENV_NAME}=${_LIBRARY_PATH_STRING}")
135+
endif()
136+
137+
if (PYTHON_PATH)
138+
if (CMAKE_SYSTEM_NAME STREQUAL Windows)
139+
list(JOIN PYTHON_PATH "\\;" _PYTHON_PATH_STRING)
140+
else()
141+
list(JOIN PYTHON_PATH ":" _PYTHON_PATH_STRING)
142+
endif()
143+
list(APPEND _env_args "PYTHONPATH=${_PYTHON_PATH_STRING}")
144+
endif()
145+
146+
foreach(_env ${_ENVIRONMENT})
147+
list(APPEND _env_args "${_env}")
148+
endforeach()
149+
68150
# Default working directory to current source path if none is provided.
69151
if (NOT _WORKING_DIRECTORY)
70152
set(_WORKING_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR})
@@ -128,7 +210,6 @@ if (Sphinx_FOUND AND NOT TARGET Sphinx::Build)
128210
COMMENT ${_COMMENT}
129211
DEPENDS ${_DEPENDS}
130212
COMMAND ${CMAKE_COMMAND} -E make_directory ${_OUTPUT_DIRECTORY}
131-
COMMAND Sphinx::Build ${_args}
132-
COMMAND_EXPAND_LISTS)
213+
COMMAND ${CMAKE_COMMAND} -E env ${_env_args} "${SPHINX_EXECUTABLE}" ${_args})
133214
endfunction()
134215
endif()

doc/api_reference.rst

Lines changed: 47 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,9 @@ API Reference
2121
[OUTPUT_DIRECTORY dir]
2222
[DEFINE setting1=value1 setting2=value2...]
2323
[DEPENDS target1 target2...]
24+
[LIBRARY_PATH_PREPEND path1 path2...]
25+
[PYTHON_PATH_PREPEND path1 path2...]
26+
[ENVIRONMENT env1 env2...]
2427
[SHOW_TRACEBACK]
2528
[WRITE_ALL]
2629
[FRESH_ENV]
@@ -120,6 +123,50 @@ API Reference
120123
DEPENDS lib1 lib2
121124
)
122125

126+
* ``LIBRARY_PATH_PREPEND``
127+
128+
List of library paths to prepend to the corresponding environment
129+
variable (:envvar:`LD_LIBRARY_PATH` on Linux,
130+
:envvar:`DYLD_LIBRARY_PATH` on macOS, and :envvar:`PATH` on Windows)
131+
when building the documentation. Each path can be defined literally or
132+
as a CMake expression generator for convenience::
133+
134+
sphinx_add_docs(
135+
...
136+
LIBRARY_PATH_PREPEND
137+
$<TARGET_FILE_DIR:lib1>
138+
$<TARGET_FILE_DIR:lib2>
139+
/path/to/libs/
140+
)
141+
142+
* ``PYTHON_PATH_PREPEND``
143+
144+
List of Python paths to prepend to the :envvar:`PYTHONPATH` environment
145+
variable when building the documentation. Each path can be defined
146+
literally or as a CMake expression generator for convenience::
147+
148+
sphinx_add_docs(
149+
...
150+
PYTHON_PATH_PREPEND
151+
$<TARGET_FILE_DIR:lib1>
152+
$<TARGET_FILE_DIR:lib2>
153+
/path/to/python/
154+
)
155+
156+
* ``ENVIRONMENT``
157+
158+
List of custom environment variables with associated values to set when
159+
building the documentation::
160+
161+
sphinx_add_docs(
162+
...
163+
ENVIRONMENT
164+
"ENV_VAR1=VALUE1"
165+
"ENV_VAR2=VALUE2"
166+
"ENV_VAR3=VALUE3"
167+
)
168+
169+
123170
* ``SHOW_TRACEBACK``
124171

125172
Display the full traceback when an unhandled exception occurs.

doc/environment_variables.rst

Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,28 @@
1+
.. _environment_variables:
2+
3+
*********************
4+
Environment variables
5+
*********************
6+
7+
Environment variables directly defined or referenced by this package.
8+
9+
.. envvar:: CMAKE_PREFIX_PATH
10+
11+
Environment variable (or :term:`CMake` option) used to locate directory
12+
to look for configurations.
13+
14+
.. seealso:: https://cmake.org/cmake/help/latest/envvar/CMAKE_PREFIX_PATH.html
15+
16+
.. envvar:: LD_LIBRARY_PATH
17+
18+
Environment variable used on Linux/UNIX System to locate shared libraries.
19+
20+
.. envvar:: DYLD_LIBRARY_PATH
21+
22+
Environment variable used on macOS System to locate shared libraries.
23+
24+
.. envvar:: PATH
25+
26+
Environment variable used to specifies the directories to be searched to
27+
find a command. On Windows system, this environment variable is also used
28+
to locate shared libraries.

doc/index.rst

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,7 @@ Generate documentation for :term:`Sphinx` with :term:`CMake`.
1414
integration
1515
tutorial
1616
api_reference
17+
environment_variables
1718
release/index
1819
Source Code @ GitHub <https://github.com/python-cmake/sphinx-cmake>
1920
glossary

doc/release/release_notes.rst

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,13 @@
44
Release Notes
55
*************
66

7+
.. release:: Upcoming
8+
9+
.. change:: new
10+
11+
Added support for prepending library and Python paths, and for passing
12+
arbitrary environment variables to Sphinx builds.
13+
714
.. release:: 1.0.1
815
:date: 2025-08-14
916

doc/tutorial.rst

Lines changed: 87 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -4,8 +4,8 @@
44
Tutorial
55
********
66

7-
Once :ref:`integrated in your project <integration>`, the ``Sphinx::Build``
8-
target and the :func:`sphinx_add_docs` function are available for using.
7+
Once :ref:`integrated into your project <integration>`, the ``Sphinx::Build``
8+
target and the :func:`sphinx_add_docs` function are available for use.
99

1010
.. _tutorial/target:
1111

@@ -14,8 +14,9 @@ Using the target
1414

1515
Let's consider a project that includes a :file:`doc` folder containing
1616
:term:`Sphinx` documentation. We need to add a :file:`CMakeLists.txt`
17-
configuration file to add Python tests within the same directory. The
18-
"sphinx-build" command can be easily implemented using a custom target:
17+
configuration file to build the documentation as part of the project.
18+
19+
The ``sphinx-build`` command can be implemented directly using a custom target:
1920

2021
.. code-block:: cmake
2122
@@ -26,29 +27,61 @@ configuration file to add Python tests within the same directory. The
2627
)
2728
2829
Building the project will generate an HTML version of the documentation within
29-
the build folder, making it ready for installation.
30+
the build directory, making it ready for installation or deployment.
31+
32+
In some cases, the documentation build may depend on Python modules or shared
33+
libraries produced by the project itself. These must be made available through
34+
the build environment.
35+
36+
This can be achieved by explicitly defining environment variables on the target,
37+
for example:
38+
39+
.. code-block:: cmake
40+
41+
set_target_properties(doc PROPERTIES
42+
ENVIRONMENT
43+
PYTHONPATH=$<TARGET_FILE_DIR:MyLibrary>:$ENV{PYTHONPATH}
44+
)
45+
46+
Similarly, shared libraries required at runtime must be discoverable through the
47+
platform-specific library search path.
48+
49+
.. code-block:: cmake
50+
51+
set_target_properties(doc PROPERTIES
52+
APPEND ENVIRONMENT
53+
LD_LIBRARY_PATH=$<TARGET_FILE_DIR:MyLibrary>:$ENV{LD_LIBRARY_PATH}
54+
)
55+
56+
.. warning::
57+
58+
The environment variable used to locate shared libraries depends on the
59+
platform. :envvar:`LD_LIBRARY_PATH` is used on Linux,
60+
:envvar:`DYLD_LIBRARY_PATH` on macOS, and :envvar:`PATH` on Windows.
3061

3162
.. _tutorial/function:
3263

3364
Using the function
3465
==================
3566

36-
A :func:`sphinx_add_docs` function is provided to create a target which will
37-
generate the documentation. Therefore, the custom target added in the previous
38-
section could be replaced by the following:
67+
A :func:`sphinx_add_docs` function is provided to simplify the creation of a
68+
documentation target. The configuration above can therefore be replaced by the
69+
following:
3970

4071
.. code-block:: cmake
4172
4273
sphinx_add_docs(doc ALL)
4374
44-
By default, the :term:`builder` used is "html". Another builder can be defined
75+
By default, the :term:`builder` used is ``html``. Another builder can be selected
4576
as follows:
4677

4778
.. code-block:: cmake
4879
49-
sphinx_add_docs(doc ALL BUILDER latex)
80+
sphinx_add_docs(doc ALL
81+
BUILDER latex
82+
)
5083
51-
You can define different source and output directories as follows:
84+
Different source and output directories can be specified:
5285

5386
.. code-block:: cmake
5487
@@ -57,26 +90,64 @@ You can define different source and output directories as follows:
5790
OUTPUT_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR}/sphinx-doc
5891
)
5992
60-
You can also define a separate directory to fetch the :file:`conf.py` file:
93+
A separate directory can also be used to locate the :file:`conf.py` file:
6194

6295
.. code-block:: cmake
6396
6497
sphinx_add_docs(doc ALL
6598
CONFIG_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR}/config
6699
)
67100
68-
Defining configuration setting directly within the :term:`CMake` configuration
69-
file to override the :file:`conf.py` file can be done as follows:
101+
Configuration values can be overridden directly from the :term:`CMake`
102+
configuration using the ``DEFINE`` option:
70103

71104
.. code-block:: cmake
72105
73106
sphinx_add_docs(doc ALL
74107
DEFINE
75-
version=${MAKE_PROJECT_VERSION}
108+
version=${PROJECT_VERSION}
76109
)
77110
78-
If necessary, you can also ignore the :file:`conf.py` file:
111+
The :file:`conf.py` file can be ignored entirely if required:
79112

80113
.. code-block:: cmake
81114
82115
sphinx_add_docs(doc ALL ISOLATED)
116+
117+
When the documentation depends on project-built libraries or Python modules,
118+
the build environment can be configured declaratively using dedicated options.
119+
120+
The ``LIBRARY_PATH_PREPEND`` option prepends directories to the platform-specific
121+
library search path, selecting the appropriate environment variable
122+
automatically:
123+
124+
.. code-block:: cmake
125+
126+
sphinx_add_docs(doc ALL
127+
LIBRARY_PATH_PREPEND
128+
$<TARGET_FILE_DIR:MyLibrary>
129+
)
130+
131+
Python modules can similarly be made available by prepending directories to the
132+
Python module search path:
133+
134+
.. code-block:: cmake
135+
136+
sphinx_add_docs(doc ALL
137+
PYTHON_PATH_PREPEND
138+
${CMAKE_CURRENT_SOURCE_DIR}/python
139+
)
140+
141+
Custom environment variables can also be defined explicitly:
142+
143+
.. code-block:: cmake
144+
145+
sphinx_add_docs(doc ALL
146+
ENVIRONMENT
147+
"MY_PROJECT_DOCS_MODE=1"
148+
"CUSTOM_FLAG=enabled"
149+
)
150+
151+
These options allow the documentation build environment to be described
152+
declaratively and consistently across platforms, without manually handling
153+
platform-specific environment variables.

0 commit comments

Comments
 (0)