1 方法1(不推荐)
我们可以用 conda 安装一些包来满足编译 C 或 C++ 项目的需求,这样既方便,又可以做到环境隔离。但 pkg-config
找不到我们装好的包,编译的时候还是会报错。
(py38) root@56901b14da37:~ # pkg-config --modversion glib-2.0
Package glib-2.0 was not found in the pkg-config search path.
Perhaps you should add the directory containing `glib-2.0.pc'
to the PKG_CONFIG_PATH environment variable
Package 'glib-2.0', required by 'virtual:world', not found
首先,找到安装的位置
(py38) root@56901b14da37:~/Atlas/build # find / -name glib-2.0.pc
find: ‘/proc/1077275’: 没有那个文件或目录
find: ‘/proc/1077278’: 没有那个文件或目录
/opt/miniconda3/envs/py38/lib/pkgconfig/glib-2.0.pc
/opt/miniconda3/pkgs/libglib-2.78.4-hdc74915_0/lib/pkgconfig/glib-2.0.pc
当然,如果你清楚 conda 环境所在的目录,也可以执行以下命令,节省时间
find /opt/miniconda3/envs -name glib-2.0.pc
/opt/miniconda3/envs/py38/lib/pkgconfig
就是我们需要的路径了,将它加到 PKG_CONFIG_PATH
中,当然可以将下面这一行写入 .bashrc
文件中,以后就不用再输入了
export PKG_CONFIG_PATH=/opt/miniconda3/envs/py38/lib/pkgconfig:$PKG_CONFIG_PATH
再次执行pkg-config --modversion glib-2.0
,发现已经可以找到了!
(py38) root@56901b14da37:~ # pkg-config --modversion glib-2.0
2.78.4
2 方法2(推荐)
2.1 借助$CONDA_PREFIX
递归添加
找到了更好的解决方案:通过$CONDA_PREFIX
指向当前 Conda 环境的根目录,使用冒号(:
)分隔路径,新路径添加到原变量值的前面(优先级更高)。
export PKG_CONFIG_PATH=$CONDA_PREFIX/lib/pkgconfig:$PKG_CONFIG_PATH
export C_INCLUDE_PATH=$CONDA_PREFIX/include:$C_INCLUDE_PATH
export CPLUS_INCLUDE_PATH=$CONDA_PREFIX/include:$CPLUS_INCLUDE_PATH
export LIBRARY_PATH=$CONDA_PREFIX/lib:$LIBRARY_PATH
export LD_LIBRARY_PATH=$CONDA_PREFIX/lib:$LD_LIBRARY_PATH
PKG_CONFIG_PATH
- 该变量用于指定 pkg-config 工具查找
.pc
文件的路径。.pc
文件包含库的元数据(如头文件路径、库文件路径等)。 - 命令
export PKG_CONFIG_PATH=$CONDA_PREFIX/lib/pkgconfig:$PKG_CONFIG_PATH
将 Conda 环境的lib/pkgconfig
目录添加到搜索路径中,确保编译时能正确找到 Conda 安装的库信息。
- 该变量用于指定 pkg-config 工具查找
CPLUS_INCLUDE_PATH
- 该变量指定 C++ 编译器查找头文件的路径。
- 命令
export CPLUS_INCLUDE_PATH=$CONDA_PREFIX/include:$CPLUS_INCLUDE_PATH
将 Conda 环境的include
目录加入搜索路径,使编译器能定位 Conda 安装的 C++ 头文件。
LIBRARY_PATH
- 该变量用于链接阶段(编译时)指定库文件的搜索路径。
- 命令
export LIBRARY_PATH=$CONDA_PREFIX/lib:$LIBRARY_PATH
将 Conda 环境的lib
目录加入链接器搜索路径,确保编译时能找到所需的静态库(.a
)或动态库(.so
)。
LD_LIBRARY_PATH
- 该变量用于运行时指定动态链接库(
.so
)的搜索路径。 - 命令
export LD_LIBRARY_PATH=$CONDA_PREFIX/lib:$LD_LIBRARY_PATH
将 Conda 环境的lib
目录加入运行时库搜索路径,确保程序运行时能加载 Conda 安装的动态库。
- 该变量用于运行时指定动态链接库(
这些命令的作用是确保在 Conda 环境中编译和运行程序时,能够正确找到相关的头文件、库文件及元数据。$CONDA_PREFIX
会随着被激活环境的变化而变化,因此这种写法更加合理。
2.2 非常重要的注意事项
先把 2.1 的五个环境变量的原始值列出来,发现其中不少结尾有冒号!
(py38) root@6ef2ac490ee6:~ # echo $PKG_CONFIG_PATH
/lib/pkgconfig:
(py38) root@6ef2ac490ee6:~ # echo $C_INCLUDE_PATH
(py38) root@6ef2ac490ee6:~ # echo $CPLUS_INCLUDE_PATH
/include:
(py38) root@6ef2ac490ee6:~ # echo $LIBRARY_PATH
/lib:
(py38) root@6ef2ac490ee6:~ # echo $LD_LIBRARY_PATH
/root/SVF/Release-build/svf:/root/SVF/Release-build/svf-llvm:/opt/llvm-14.0.0.obj/lib:/opt/z3.obj/bin:/lib:/root/SVF/Release-build/svf:/root/SVF/Release-build/svf-llvm:/opt/llvm-14.0.0.obj/lib:/opt/z3.obj/bin:
冒号后面的值如果为空,那么会被当作当前目录,而这显然不是我们想要的结果。因此,建议如下:
- 把这些环境变量打印出来,用去掉结尾冒号的值赋值一遍,再递归赋值,以免出现预料之外的错误。
- 某些值如果一开始为空,那么就不可以递归赋值,否则会变成
/opt/miniconda3/envs/py38/:
,还是会把当前目录加到环境变量中。 - 如果原来指向的目录不存在,那么也直接覆盖赋值。
我的配置如下,仅供参考,最后还需要把每个环境变量打印出来,确认无误!
export PKG_CONFIG_PATH=/lib/pkgconfig
export PKG_CONFIG_PATH="${CONDA_PREFIX}/lib/pkgconfig:${PKG_CONFIG_PATH}"
# export C_INCLUDE_PATH="${CONDA_PREFIX}/include"
# export CPLUS_INCLUDE_PATH="${CONDA_PREFIX}/include"
# export LIBRARY_PATH="${CONDA_PREFIX}/lib:${LIBRARY_PATH}" # 有点问题
export LD_LIBRARY_PATH="${LD_LIBRARY_PATH}${CONDA_PREFIX}/lib"
3 补充
如果还找不到库(例如 libboost),可以尝试在 cmake 的时候手动指定路径
-DBOOST_ROOT=$CONDA_PREFIX