避免出现此问题的方法之一是制定规则,以确保您正在构建/安装的程序的所有包/库依赖项都是常驻的并且可以立即在您的系统上找到。在 MacOS [可能还有其他基于 UNIX 的系统] 上,它们都应该在/usr/local
, 或带有相关符号链接的目录中。
我在尝试从 MacOS 上的源文件构建和安装 PHP 时遇到了这个问题。
这是我的配置命令:
./configure --prefix=/usr/local/_utils/php/7.3.27 --enable-fpm --with-fpm-user=myusername --with-fpm-group=mygroupname --enable-bcmath --enable-cli --enable-exif --enable-ftp --enable-mbstring --enable-sockets --enable-zip --with-libzip=/usr/local/_utils/libzip --with-libxml-dir=/usr/local/_utils/libxml2 --with-mysqli --with-pdo-mysql=mysqlnd --with-iconv=/usr/local/_utils/iconv --with-iconv-dir=/usr/local/_utils/iconv --with-openssl=/usr/local/_utils/libressl --with-openssl-dir=/usr/local/_utils/libressl --with-zlib-dir=/usr/local/_utils/zlib --with-pcre-dir=/usr/local --with-pcre-regex=/usr/local --with-sodium=/usr/local/_utils/sodium
如果您注意到所有 [除了几个]--with-pkg=
选项直接引用库/包,因为它们都已安装在自定义目录中,并创建了相关的符号链接。
拿一个像 libxml2 这样的包。以下是它的安装方法:
# Create install directory
sudo mkdir -p /usr/local/_utils/libxml2
# Download and install
wget -c ftp://xmlsoft.org/libxml2/libxml2-2.9.10.tar.gz
tar -zxf libxml2-2.9.10.tar.gz
cd libxml2-2.9.10
./configure --prefix=/usr/local/_utils/libxml2
make
sudo make install
# Create symlinks for bin
sudo ln -s /usr/local/_utils/libxml2/bin/xml2-config /usr/local/bin/
sudo ln -s /usr/local/_utils/libxml2/bin/xmlcatalog /usr/local/bin/
sudo ln -s /usr/local/_utils/libxml2/bin/xmllint /usr/local/bin/
# Create symlinks for lib
sudo ln -s /usr/local/_utils/libxml2/lib/libxml2.a /usr/local/lib/
sudo ln -s /usr/local/_utils/libxml2/lib/libxml2.la /usr/local/lib/
sudo ln -s /usr/local/_utils/libxml2/lib/libxml2.dylib /usr/local/lib/
# Create symlinks for lib/pkgconfig
sudo ln -s /usr/local/_utils/libxml2/lib/pkgconfig/libxml-2.0.pc /usr/local/lib/pkgconfig/
# Create symlinks for include
sudo ln -s /usr/local/_utils/libxml2/include/libxml2 /usr/local/include/
注意:您不必使用_utils
; 您可以选择您认为合适的任何目录。此外,为了避免符号链接,您可以./configure --prefix=/usr/local
直接使用并安装到/usr/local
,但使用自定义目录更安全。
安装包/库后,您可以直接引用它,例如./configure --with-libxml-dir=/usr/local/_utils/libxml2
. 此外,由于符号链接,如果您无意中排除了该选项,将很容易找到它。
为什么这是必要的?
我注意到的是,当我还没有安装这个包 [libxml2] 并且我没有指定--with-libxml-dir
时,发生了以下情况:
- 该
configure
操作进行了搜索以找到libxml
,因为libxml
是必需的。
- 它
libxml
在一个位置找到:/Library/Developer/CommandLineTools/SDKs/MacOSX10.14.sdk/usr/lib
- 然后它将此目录添加到特定变量下的 Makefile,特别是
EXTRA_LDFLAGS
和EXTRA_LDFLAGS_PROGRAM
. 然后,我最终得到了一个 Makefile,其相关部分如下所示:
...
EXTRA_LDFLAGS = -L/Library/Developer/CommandLineTools/SDKs/MacOSX10.14.sdk/usr/lib -L/usr/local/_utils/libxml2/lib -L/usr/local/_utils/zlib/lib -L/usr/local/_utils/xz/lib -L/usr/local/_utils/libressl/lib -L/usr/local/lib -L/usr/local/_utils/iconv/lib -L/usr/local/_utils/sodium/lib -L/usr/local/_utils/libzip/lib
EXTRA_LDFLAGS_PROGRAM = -L/Library/Developer/CommandLineTools/SDKs/MacOSX10.14.sdk/usr/lib -L/usr/local/_utils/libxml2/lib -L/usr/local/_utils/zlib/lib -L/usr/local/_utils/xz/lib -L/usr/local/_utils/libressl/lib -L/usr/local/lib -L/usr/local/_utils/iconv/lib -L/usr/local/_utils/sodium/lib -L/usr/local/_utils/libzip/lib
...
make
然后,当您运行命令时,将在构建包的过程中搜索上面列出的目录以查找库。
问题是在这些目录中搜索了所有库。所以,在我的例子中,你可以看到我已经iconv
在 Makefile: 中有一个链接-L/usr/local/_utils/iconv/lib
,但是/Library/Developer/CommandLineTools/SDKs/MacOSX10.14.sdk/usr/lib
首先被搜索[因为它首先出现],并且在其中发现了一个不合适的版本iconv
,然后使用它而不是iconv
I指定的。结果是错误。
Undefined symbols for architecture x86_64:
"_libiconv", referenced from:
"_libiconv_open", referenced from:
"_libiconv_close", referenced from:
这很有趣,因为这个问题甚至不iconv
相关;正是缺少libxml
它导致了搜索并随后将搜索到的目录包含/Library/Developer/CommandLineTools/SDKs/MacOSX10.14.sdk/usr/lib
到 Makefile 中。
在John Q 的回答中,他建议将此引用移至列表末尾。这应该有效。但是,我会考虑编辑 Makefile 不好的做法并建议不要这样做。
要解决此问题:
- 确保在配置期间可以找到您正在构建/安装的实际程序的所有必需的库/包依赖项,即
./configure ...
. 当您执行此操作时,像上面列出的 [/Library/...
等] 搜索的目录将不会包含在 Makefile 中。
- 运行后检查 Makefile
configure
。如果在/usr/local
带有 suffix 的任何变量下除了带有前缀的目录之外还有其他目录LDFLAGS
,那么您必须缺少一些库/包。找出它是什么并安装它。