Skip to content

Commit 057f88e

Browse files
committed
Improve PEAR installation
This adds a new configuration variable PHP_PEAR_TEMP_DIR to be able to set the temporary directory and prevents PEAR installation step to write to system's temp directory during the installation, which makes the installation one step better to not worry about some files being written outside of the project binary directory. The PEAR installation is now in a separate CMake script to have simpler code syntax. The pear.conf is also patched to not include some binary or DESTDIR locations. Added PHP cli options to configure shared xml extension.
1 parent 5016355 commit 057f88e

File tree

2 files changed

+195
-104
lines changed

2 files changed

+195
-104
lines changed

cmake/pear/CMakeLists.txt

Lines changed: 44 additions & 104 deletions
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,8 @@ if(PHP_PEAR)
1313
set(
1414
PHP_PEAR_DIR "${CMAKE_INSTALL_DATADIR}/pear"
1515
CACHE FILEPATH
16-
"The PEAR installation directory (default: DATADIR/pear)"
16+
"The PEAR installation directory. CMAKE_INSTALL_PREFIX is automatically\
17+
prepended when given as relative path. Default: DATADIR/pear"
1718
)
1819
# Change from INTERNAL type to show variable on consecutive configuration run.
1920
set_property(CACHE PHP_PEAR_DIR PROPERTY TYPE FILEPATH)
@@ -23,6 +24,27 @@ elseif(DEFINED PHP_PEAR_DIR)
2324
endif()
2425
mark_as_advanced(PHP_PEAR_DIR)
2526

27+
if(CMAKE_SYSTEM_NAME STREQUAL "Windows")
28+
set(tmpDir "C:/temp/pear")
29+
else()
30+
set(tmpDir "/tmp/pear")
31+
endif()
32+
if(PHP_PEAR)
33+
set(
34+
PHP_PEAR_TEMP_DIR "${tmpDir}"
35+
CACHE FILEPATH
36+
"The PEAR temporary directory where PEAR writes temporary files, such as\
37+
cache, downloaded packages artefacts and similar. Must be absolute path.\
38+
Default: ${tmpDir}."
39+
)
40+
# Change from INTERNAL type to show variable on consecutive configuration run.
41+
set_property(CACHE PHP_PEAR_TEMP_DIR PROPERTY TYPE FILEPATH)
42+
elseif(DEFINED PHP_PEAR_TEMP_DIR)
43+
# Hide variable.
44+
set_property(CACHE PHP_PEAR_TEMP_DIR PROPERTY TYPE INTERNAL)
45+
endif()
46+
mark_as_advanced(PHP_PEAR_TEMP_DIR)
47+
2648
message(CHECK_START "Checking for PEAR")
2749

2850
if(NOT PHP_PEAR)
@@ -35,7 +57,10 @@ endif()
3557
message(DEPRECATION "The PHP_PEAR option is deprecated.")
3658

3759
if(NOT SAPI_CLI)
38-
message(FATAL_ERROR "The PHP_PEAR option requires CLI SAPI. Set SAPI_CLI='ON'.")
60+
message(
61+
FATAL_ERROR
62+
"The PHP_PEAR option requires CLI SAPI. Please set SAPI_CLI to 'ON'."
63+
)
3964
endif()
4065

4166
# Check PEAR dependencies.
@@ -45,114 +70,29 @@ if(NOT EXT_XML)
4570
"PEAR requires the xml extension to be enabled. Set EXT_XML to 'ON'.")
4671
endif()
4772

73+
set(PHP_EXECUTABLE)
4874
if(NOT CMAKE_CROSSCOMPILING)
4975
set(PHP_EXECUTABLE "$<TARGET_FILE:php_cli>")
5076
elseif(CMAKE_CROSSCOMPILING AND CMAKE_CROSSCOMPILING_EMULATOR)
5177
set(PHP_EXECUTABLE "${CMAKE_CROSSCOMPILING_EMULATOR};$<TARGET_FILE:php_cli>")
5278
endif()
5379

54-
set(_phpPearInstallerUrl "https://pear.php.net/install-pear-nozlib.phar")
55-
5680
php_install(CODE "
57-
set(
58-
pearInstallDir
59-
\"$<PATH:ABSOLUTE_PATH,NORMALIZE,${PHP_PEAR_DIR},\${CMAKE_INSTALL_PREFIX}>\"
60-
)
61-
set(
62-
binDir
63-
\"$<PATH:ABSOLUTE_PATH,NORMALIZE,${CMAKE_INSTALL_BINDIR},\${CMAKE_INSTALL_PREFIX}>\"
64-
)
65-
66-
message(STATUS \"Installing PEAR to \$ENV{DESTDIR}\${pearInstallDir}\")
67-
68-
if(EXISTS \"${CMAKE_CURRENT_SOURCE_DIR}/install-pear-nozlib.phar\"
69-
AND NOT \"${CMAKE_CURRENT_SOURCE_DIR}\" STREQUAL \"${CMAKE_CURRENT_BINARY_DIR}\"
70-
)
71-
file(
72-
COPY_FILE
73-
\"${CMAKE_CURRENT_SOURCE_DIR}/install-pear-nozlib.phar\"
74-
\"${CMAKE_CURRENT_BINARY_DIR}/install-pear-nozlib.phar\"
75-
)
76-
endif()
77-
78-
if(NOT EXISTS \"${CMAKE_CURRENT_BINARY_DIR}/install-pear-nozlib.phar\")
79-
file(
80-
DOWNLOAD
81-
${_phpPearInstallerUrl}
82-
\"${CMAKE_CURRENT_BINARY_DIR}/install-pear-nozlib.phar\"
83-
SHOW_PROGRESS
84-
STATUS downloadStatus
85-
)
86-
87-
if(NOT downloadStatus)
88-
# Download using fetch.php.
89-
execute_process(
90-
COMMAND ${PHP_EXECUTABLE}
91-
-n
92-
${CMAKE_CURRENT_SOURCE_DIR}/fetch.php
93-
${_phpPearInstallerUrl}
94-
${CMAKE_CURRENT_BINARY_DIR}/install-pear-nozlib.phar
95-
OUTPUT_VARIABLE output
96-
ERROR_VARIABLE output
97-
)
98-
if(output)
99-
message(STATUS \"\${output}\")
100-
endif()
101-
endif()
102-
endif()
103-
104-
if(EXISTS ${CMAKE_CURRENT_BINARY_DIR}/install-pear-nozlib.phar)
105-
# PEAR reads the staging INSTALL_ROOT environment variable if set. However,
106-
# there is a bug where .channels, .registry and temporary dot files are
107-
# duplicated outside of the INSTALL_ROOT into the install prefix. No known
108-
# workaround. See: https://pear.php.net/bugs/bug.php?id=20383
109-
if(DEFINED ENV{DESTDIR})
110-
set(ENV{INSTALL_ROOT} \"\$ENV{DESTDIR}\")
111-
endif()
112-
113-
# The PEAR sysconf directory by default matches the PHP SYSCONFDIR and it
114-
# doesn't seem that any configuration option installs the pear.conf into the
115-
# manually specified directory. But the sysconf can be also bypassed with
116-
# the environment variable for the installation time.
117-
set(ENV{PHP_PEAR_SYSCONF_DIR} \${CMAKE_INSTALL_FULL_SYSCONFDIR})
118-
119-
file(
120-
MAKE_DIRECTORY
121-
\$ENV{DESTDIR}\${pearInstallDir}
122-
${CMAKE_CURRENT_BINARY_DIR}/CMakeFiles/pear
123-
)
124-
125-
execute_process(
126-
COMMAND ${PHP_EXECUTABLE}
127-
-n
128-
-dshort_open_tag=0
129-
-dopen_basedir=
130-
-derror_reporting=1803
131-
-dmemory_limit=-1
132-
-ddetect_unicode=0
133-
${CMAKE_CURRENT_BINARY_DIR}/install-pear-nozlib.phar
134-
--dir \"\${pearInstallDir}\"
135-
--bin \"\${binDir}\"
136-
--metadata \"\${pearInstallDir}\"
137-
--data \"\${pearInstallDir}\"
138-
--temp \"${CMAKE_CURRENT_BINARY_DIR}/CMakeFiles/pear\"
139-
--php \${binDir}/$<TARGET_FILE_NAME:php_cli>
140-
-dp a${PHP_PROGRAM_PREFIX}
141-
-ds a${PHP_PROGRAM_SUFFIX}
142-
OUTPUT_VARIABLE output
143-
ERROR_VARIABLE output
144-
)
145-
if(output)
146-
message(STATUS \"\${output}\")
147-
endif()
148-
else()
149-
message(
150-
WARNING
151-
\"The installation process is not complete. The following resources \"
152-
\"were not installed:\\n\"
153-
\" PEAR: PHP Extension and Application Repository\\n\"
154-
\"To install these components, download ${_phpPearInstallerUrl} to \"
155-
\"to php-src/pear/ and repeat the 'cmake --install' command.\"
156-
)
81+
set(phpPearInstallDir \"$<PATH:ABSOLUTE_PATH,NORMALIZE,${PHP_PEAR_DIR},\${CMAKE_INSTALL_PREFIX}>\")
82+
set(phpPearInstallBinDir \"$<PATH:ABSOLUTE_PATH,NORMALIZE,${CMAKE_INSTALL_BINDIR},\${CMAKE_INSTALL_PREFIX}>\")
83+
set(phpPearCurrentSourceDir \"${CMAKE_CURRENT_SOURCE_DIR}\")
84+
set(phpPearCurrentBinaryDir \"${CMAKE_CURRENT_BINARY_DIR}\")
85+
set(phpPearPhpExecutable \"${PHP_EXECUTABLE}\")
86+
set(phpExtensionDir \"$<PATH:ABSOLUTE_PATH,NORMALIZE,${PHP_EXTENSION_DIR},\${CMAKE_INSTALL_PREFIX}>\")
87+
# When the xml extension is shared, it must be loaded for the PHP_EXECUTABLE.
88+
set(EXT_XML_SHARED ${EXT_XML_SHARED})
89+
if(EXT_XML_SHARED)
90+
set(phpPearOptions -d extension_dir=${PHP_BINARY_DIR}/modules -d extension=xml)
15791
endif()
92+
set(phpPearTempDir \"${PHP_PEAR_TEMP_DIR}\")
93+
set(phpPearInstalledPhpBin \"\${phpPearInstallBinDir}/$<TARGET_FILE_NAME:php_cli>\")
94+
set(phpPearPhpProgramPrefix \"${PHP_PROGRAM_PREFIX}\")
95+
set(phpPearPhpProgramSuffix \"${PHP_PROGRAM_SUFFIX}\")
96+
set(phpPearInstallSysconfDir \"\${CMAKE_INSTALL_FULL_SYSCONFDIR}\")
15897
")
98+
install(SCRIPT InstallPear.cmake)

cmake/pear/InstallPear.cmake

Lines changed: 151 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,151 @@
1+
#[=============================================================================[
2+
The PEAR installation script.
3+
4+
It downloads the PEAR installer and installs it using the built PHP CLI
5+
executable to sistem directory structure. Some variables need to be set before
6+
running it via the install(CODE) as done in the PEAR's CMakeLists.txt.
7+
#]=============================================================================]
8+
9+
set(phpPearInstallerUrl "https://pear.php.net/install-pear-nozlib.phar")
10+
11+
message(STATUS "Installing PEAR to $ENV{DESTDIR}${phpPearInstallDir}")
12+
13+
# If PEAR installer is packaged in the PHP release archive.
14+
if(
15+
EXISTS ${phpPearCurrentSourceDir}/install-pear-nozlib.phar
16+
AND NOT "${phpPearCurrentSourceDir}" STREQUAL "${phpPearCurrentBinaryDir}"
17+
)
18+
file(
19+
COPY_FILE
20+
"${phpPearCurrentSourceDir}/install-pear-nozlib.phar"
21+
"${phpPearCurrentBinaryDir}/install-pear-nozlib.phar"
22+
)
23+
endif()
24+
25+
# Download PEAR installer.
26+
if(NOT EXISTS ${phpPearCurrentBinaryDir}/install-pear-nozlib.phar)
27+
file(
28+
DOWNLOAD
29+
${phpPearInstallerUrl}
30+
${phpPearCurrentBinaryDir}/install-pear-nozlib.phar
31+
SHOW_PROGRESS
32+
STATUS downloadStatus
33+
)
34+
35+
if(IS_EXECUTABLE "${phpPearPhpExecutable}" AND NOT downloadStatus)
36+
# Download using fetch.php.
37+
execute_process(
38+
COMMAND ${phpPearPhpExecutable}
39+
-n
40+
${phpPearCurrentSourceDir}/fetch.php
41+
${phpPearInstallerUrl}
42+
${phpPearCurrentBinaryDir}/install-pear-nozlib.phar
43+
OUTPUT_VARIABLE output
44+
ERROR_VARIABLE output
45+
)
46+
if(output)
47+
message(STATUS "${output}")
48+
endif()
49+
endif()
50+
endif()
51+
52+
if(NOT IS_EXECUTABLE "${phpPearPhpExecutable}")
53+
message(
54+
WARNING
55+
"The PEAR installation is not complete.\n"
56+
"To install PEAR, download ${phpPearInstallerUrl}\n"
57+
"and install it manually."
58+
)
59+
return()
60+
endif()
61+
62+
if(NOT EXISTS ${phpPearCurrentBinaryDir}/install-pear-nozlib.phar)
63+
message(
64+
WARNING
65+
"The PEAR installation is not complete.\n"
66+
"To install PEAR, download ${phpPearInstallerUrl}\n"
67+
"to php-src/pear/ and repeat the 'cmake --install' command."
68+
)
69+
return()
70+
endif()
71+
72+
# PEAR reads the staging INSTALL_ROOT environment variable if set. However,
73+
# there is a bug where .channels, .registry and temporary dot files are
74+
# duplicated outside of the INSTALL_ROOT into the install prefix. No known
75+
# workaround. See: https://pear.php.net/bugs/bug.php?id=20383
76+
if(DEFINED ENV{DESTDIR})
77+
set(ENV{INSTALL_ROOT} "$ENV{DESTDIR}")
78+
endif()
79+
80+
# The PEAR sysconf directory by default matches the PHP_SYSCONFDIR and it
81+
# doesn't seem that any configuration option installs the pear.conf into the
82+
# manually specified directory. But the sysconf can be also bypassed with
83+
# the environment variable for the installation time.
84+
set(ENV{PHP_PEAR_SYSCONF_DIR} ${phpPearInstallSysconfDir})
85+
86+
# Set temporary directory for the PEAR installation.
87+
set(localPearTempDir ${phpPearCurrentBinaryDir}/CMakeFiles/pear)
88+
89+
# Set the PHP extensions directory.
90+
set(ENV{PHP_PEAR_EXTENSION_DIR} "${phpExtensionDir}")
91+
92+
file(
93+
MAKE_DIRECTORY
94+
"$ENV{DESTDIR}${phpPearInstallDir}"
95+
${localPearTempDir}
96+
)
97+
98+
# Run the PEAR phar installer.
99+
execute_process(
100+
COMMAND ${phpPearPhpExecutable}
101+
-n
102+
-dshort_open_tag=0
103+
-dopen_basedir=
104+
-derror_reporting=1803
105+
-dmemory_limit=-1
106+
-ddetect_unicode=0
107+
${phpPearOptions}
108+
${phpPearCurrentBinaryDir}/install-pear-nozlib.phar
109+
--dir "${phpPearInstallDir}"
110+
--bin "${phpPearInstallBinDir}"
111+
--metadata "${phpPearInstallDir}"
112+
--data "${phpPearInstallDir}"
113+
--temp "${localPearTempDir}"
114+
--cache "${phpPearTempDir}/cache"
115+
--download "${phpPearTempDir}/download"
116+
--php ${phpPearInstalledPhpBin}
117+
-dp a${phpPearPhpProgramPrefix}
118+
-ds a${phpPearPhpProgramSuffix}
119+
OUTPUT_VARIABLE output
120+
ERROR_VARIABLE output
121+
RESULT_VARIABLE result
122+
)
123+
124+
if(output)
125+
message(STATUS "${output}")
126+
endif()
127+
128+
if(NOT result EQUAL 0)
129+
message(WARNING "Something went wrong with PEAR installation.")
130+
return()
131+
endif()
132+
133+
# Patch the pear.conf file because it contains the temporary CMakeFiles path.
134+
set(pearConf $ENV{DESTDIR}$ENV{PHP_PEAR_SYSCONF_DIR}/pear.conf)
135+
if(NOT EXISTS "${pearConf}")
136+
return()
137+
endif()
138+
139+
message(STATUS "Patching pear.conf")
140+
141+
file(READ "${pearConf}" content)
142+
file(WRITE ${localPearTempDir}/pear.conf "${content}")
143+
string(LENGTH "${phpPearTempDir}/temp" length)
144+
string(
145+
REGEX REPLACE
146+
"s:[0-9]+:\"${localPearTempDir}"
147+
"s:${length}:\"${phpPearTempDir}/temp"
148+
content
149+
"${content}"
150+
)
151+
file(WRITE ${pearConf} "${content}")

0 commit comments

Comments
 (0)