archlinux 编译 emacs 25.3 和 27 均无法支持imagemagick

configure 只提供了 --without-imagemagick 选项:

⋊> ./configure --help | grep imagemagick
  --without-imagemagick   don't compile with ImageMagick image support

所以 homebrew 的那个 --with-imagemagick@6 只是个安慰选项,默认本来就会检测 imagemagick,除非指定了 --without-imagemagick 参数。

但是 emacs 比较挑剔,不支持 7,也不是所有 6 都支持:

⋊> ag imagemagick_module configure.ac
2547:    IMAGEMAGICK_MODULE="Wand >= 6.3.5 Wand != 6.8.2 Wand < 7"
2548:    EMACS_CHECK_MODULES([IMAGEMAGICK], [$IMAGEMAGICK_MODULE])

不知道 homebrew 用了什么魔法,单看 emacs.rb 文件并没有什么特别设置,而我自行编译把 cflags、libs 参数都设置了还是检测不到 imagemagic:

  Does Emacs use imagemagick (version 6)?                 no

我也发现了 其实emacs本身默认就没有 --with-imagemagick 这个选项,只有 --without-imagemagick .

感谢你贴出emacs要求的imagemagick的版本要求,让我发现emacs对于imagemagickd这么挑剔.

我在想 为什么 emacs对于imagemagick的 支持这么繁琐? 官方有没有解决的办法 ,我google了很多都找不到!:joy:

本人非cs出身 问出什么幼稚的话 还请大佬们海涵.

我知道问题出在哪儿了,参数应该是 wand 而不是 imagemagick:

⋊> cat ./build.sh
#!/usr/bin/env bash
#
# Usage:
#
#       ./build.sh /path/to/emacs-source
#

cd $1

case $(uname -s) in
    Darwin) IMAGEMAGICK_PATH=$(brew --prefix imagemagick@6);;
    *     ) echo "Unknown system: $(uname -s)"; exit 1;;
esac

export PATH=$IMAGEMAGICK_PATH/bin:$PATH
export PKG_CONFIG_PATH=$IMAGEMAGICK_PATH/lib/pkgconfig:$PKG_CONFIG_PATH
export IMAGEMAGICK_LIBS=$(pkg-config --libs wand)
export IMAGEMAGICK_CFLAGS=$(pkg-config --cflags wand)

[[ -f ./configure ]] || ./autogen.sh
./configure --with-imagemagick
make

Linux 下的 ImageMagick 6 路径你补上应该就能检测到:

⋊> ./build.sh emacs-05e8b4392be7fb368dcf4e4a19f75f94b323028d | grep imagemagick
  Does Emacs use imagemagick (version 6)?                 yes
1 个赞

@twlz0ne 新年好

由于之前过年,没有携带自己的个人电脑,所以无法实验你给的解决方案,对于没有及时回复,抱歉。

现在我实验了一下,发现我有以下问题需要你的帮助:

  1. 在LINUX环境下我只是知道 ImageMagick的路径是 /usr/bin/convert 不清楚你在bash脚本中的case中的设定方式(ps:我知道你的case是对于macos的 我已经改为linux了)
  2. 我使用的ImageMagick 版本是直接从gayhub上克隆后切换成6.9.6-0 版本分支,不知道是否符合你之前告诉我的版本条件。
  3. pkg-config --libs wand 之后返回的结果是这样的,我不知道怎样解决:
	[@localhost]$ pkg-config --libs wand
	
	Package wand was not found in the pkg-config search path.
	
	Perhaps you should add the directory containing `wand.pc'
	
	to the PKG_CONFIG_PATH environment variable
	
	Package 'wand', required by 'virtual:world', not found

希望得到你的帮助 :slight_smile:

对 Linux 不了解。

错误信息显示 pkg-config 找不到 imagemagick,有可能:

  1. imagemagick 安装到了 pkg-config 找不到的地方。这就需要像我前面回帖那样设置 PKG_CONFIG_PATH

    通常一个 pkg 安装之后,都会把配置文件拷贝/连接到 pkg-config 搜索目录,例如在我的 macOS 上是 /usr/local/lib/pkgconfig/。为什么 homebrew 不把 imagemagick@6 的配置文件拷贝/连接到 pkg-config 搜索目录?可能是考虑 imagemagick7 才是主流版本。

    如果 linux 不存在这个问题,看下一条。

  2. 需要要安装 imagemagick-devel.XXXX (名字大概是这种形式)。

谢谢你给了我很大的帮助 :slightly_smiling_face:,不过我还是不太明白你所说的,我需要自己从网络中分片搜索你提供的知识点从而学习和了解它们,关于:

  1. 什么是pkg-config;它有什么用;它对于编译源码有什么作用。
  2. cflag设定是什么。

我是否需要学习一下关于编译源码的具体知识才能理解这些?如果方便的化,你可以提供给我一个学习引导以便于让我可以在linux平台中理解和解决这个问题吗?

其实吧,还是用 Gentoo 好。

是指问题解决了还是没解决?


C{XX}FLAGS、LDFLAGS 是 Makefile 环境变量,用来指定依赖的头文件、链接库和编译参数。这些变量的值是什么,就成了一大问题。比如依赖 imagemagick 就得设置:

-L/usr/local/Cellar/imagemagick@6/6.9.9-34/lib -lMagickWand-6.Q16 -lMagickCore-6.Q16
-DMAGICKCORE_HDRI_ENABLE=0 -DMAGICKCORE_QUANTUM_DEPTH=16 -DMAGICKCORE_HDRI_ENABLE=0 -DMAGICKCORE_QUANTUM_DEPTH=16 -I/usr/local/Cellar/imagemagick@6/6.9.9-34/include/ImageMagick-6

WTF!什么鬼!?

所有就有了 pkg-config 这么一个统一的管理工具。源码包通常会提供一份 .pc 文件,告诉使用者,如果依赖了这个包,应如何设置 C{XX}FLAGS/LDFLAGS,毕竟包作者最清楚,例如:

⋊> cat /usr/local/lib/pkgconfig/libzip.pc
prefix=/usr/local/Cellar/libzip/1.3.0
exec_prefix=${prefix}
libdir=${exec_prefix}/lib
includedir=${prefix}/include
libincludedir=${exec_prefix}/lib/libzip/include

zipcmp=/usr/local/Cellar/libzip/1.3.0/bin/zipcmp

Name: libzip
Description: library for handling zip archives
Version: 1.3.0
Libs:  -L${libdir} -lzip -lbz2 -lz
Cflags: -I${includedir} -I${libincludedir}

假如你当前正在编译的源代码依赖 libzip,通过 pkg-config 查询就知道 C{XX}FLAGS/LDFLAGS 该填什么了:

⋊> pkg-config --libs libzip
-L/usr/local/Cellar/libzip/1.3.0/lib -lzip -lbz2 -lz

⋊> pkg-config --cflags libzip
-I/usr/local/Cellar/libzip/1.3.0/include -I/usr/local/Cellar/libzip/1.3.0/lib/libzip/include
1 个赞

我突然想起来一个叫 Linux-Homebrew 的项目,和 macOS 下的 Homebrew 使用体验应该差不多。?这样的话,把 25.3 的 formula 稍微修改一下应该就能编译 27 版的 emacs 了?

冒昧猜测,大概率还是能搞定的。善用一下别人的劳动成果,嘿嘿。


至于 archlinux,我是不碰 Linux 好久,然后趁过年期间尝试了下 manjaro。初步体验是大大超出心理预期的,达到了开箱即用的水平。很想给人安利一下这个发行版 :grin:

Linuxbrew 的 emacs.rb 跟 Homebre 的 emacs.rb 可以说是同步了,就多了两行:

⋊> diff -u0 homebrew-formula-emacs.rb linuxbrew-formula-emacs.rb
--- homebrew-formula-emacs.rb   2018-02-23 13:31:45.000000000 +0800
+++ linuxbrew-formula-emacs.rb  2018-02-23 13:35:27.000000000 +0800
@@ -10,0 +11 @@
+    sha256 "760c34fb38730f2cd9d60fb3e39723c549267d6ad643e952a1fd6e927d8d5a4b" => :x86_64_linux
@@ -43,0 +45 @@
+  depends_on "ncurses" unless OS.mac?

Homebrew 可以判断平台是 macOS 还是 Linux,所以「理论上」两者合二为一,跨平台的包管理器是可能的。实际情况要复杂的多,一想起 Linux 上各种发行版就头大……

还是具体到楼主的问题,看看人家 formula 是怎么处理依赖关系的。修改两三处,编译个支持 imagemagick 的 emacs 27 应该问题不大。

楼主这个问题,从 formula 看不出什么,只有一行 depends_on "imagemagick@6" => :optional,再往上追 [email protected] 也没有什么特别的设置。

Homebrew 安装依赖的时候,把搜索路径都处理好了,所以在 formula 中不体现这些细节,只有一个依赖的名称。

我前面的的 build.sh 实际上是跳过了某些检查步骤,直接设置 IMAGEMAGICK_LIBS & IMAGEMAGICK_CFLAGS,因为我也不知道如何还原 Homebrew 设置的环境变量。

看描述你是计划不安装 Hombrew,继续 wget->config->make->make install 的流程?我的意思是安上 Homebrew,修改一下 emacs formula 的包下载地址和校验值,很有可能就把新版 emacs 编译出来了。

刚才看了下 imagemagick@6 这个 formula,发现里面的版本为 6.9.9-35。也许是 emacs 依赖于这个特定的版本?

又看了下 emacs formula,基本上人家把踩到的坑在注释里都提出来了:

1. 不支持 ImageMagick 7。

# Emacs does not support ImageMagick 7:
# Reported on 2017-03-04: https://debbugs.gnu.org/cgi/bugreport.cgi?bug=25967

2. ImageMagick 有可能找不到路径。但是用 --with-imagemagick 选项却并不会报错,并停止编译。

# Note that if ./configure is passed --with-imagemagick but can't find the
# library it does not fail but imagemagick support will not be available. 
# See: https://debbugs.gnu.org/cgi/bugreport.cgi?bug=24455

3. 在 Vim 和 Emacs 里同时使用 ctags,可能造成冲突。

# Follow MacPorts and don't install ctags from Emacs. This allows Vim
# and Emacs and ctags to play together without violence.

很贴心了,有木有?!

版本坑的问题在前边的回帖都提到了。Homebrew 大家都有去看。

楼主的问题不是选哪个版本,而是自行编译的时候为何检测不到 imagemagick@6,这点从 Homebrew 看不出来。

如果楼主用 Homebrew/Linuxbrew 就不需要开此贴了。

有 Linuxbrew 那就用,为啥非要守着老旧的 wget->config->make->make install 循环呢。纠结为何检测不到 imagemagick@6,还是尽快能使用 emacs 更重要吧?那就安装 Linuxbrew,有空再慢慢研究人家用了什么黑魔法吧。

我刚搜索了一下,AUR 上有编译好的 emacs 27 呀。。。所以楼主纯粹想尝试自己编译一下 emacs?

正在 manjaro 下下载 emacs 27,一会看看支持图片显示不。。。

AUR 上的 emacs 27 支持图片显示,所以楼主别纠结了。真想知道人家是咋编译的话,可以找下 PKGBUILD 看一下,初步了解是文本形态的,和 Homebrew 下的 formula 很相似。我就不再继续折腾了。

补图一张,可怜我 USB2.0 的 U 盘。心疼一秒~

3 个赞

我记得 Linuxbrew 还要重新自举一套工具链,还把 Homebrew 的一整套缺点都继承了(慢,只管杀不管埋,不支持 slot,编译定制选项少),在 Linux 有 portage, nix, pkgsrc 这些成熟的跨平台包管理器的情况下,不觉得需要考虑 Linuxbrew。


@Angelaneia 有运行过 pkg-config --update

出售脚本一枚 ,开箱即食
Note:

  1. 自己安装的ImageMagick路径,可以随便,别放在/tmp就行
  2. CFLAGS和CXXFALGS也可以随便改,这是复制的
  3. emacs的configure 参数也可以随便改,这个还是复制的。 依赖自负
  4. 确定安装了,那就 make install
  5. ImageMagick参数,除了prefix和oldincludedir之外可以改,这个仍然是从别处复制的。依赖自负
  6. /etc/ld.so.conf.d 文件夹下加入刚才新安装的ImageMagick
  7. ldconfig
#!/bin/bash

emacs_src="http://mirrors.ustc.edu.cn/gentoo/distfiles/emacs-25.3.tar.xz"
imagemagick_src="http://mirrors.ustc.edu.cn/gentoo/distfiles/ImageMagick-6.9.9-23.tar.xz"

root_dir="$(mktemp -d)"
cd "$root_dir" || exit -1
fetch

test_file="$root_dir"/test.el

cat > "$test_file" << EOF
(message "%s" "==========================Check emacs support imagemagick==============================")
(message "%s" (image-type-available-p (quote imagemagick)))
EOF

imagemagick_dir="/placeholder"
emacs_dir="/placeholder"

imagemagick_mirror_dir="$HOME"/.config/ImageMagick6                                                  # see note --> 1

export CFLAGS="-O2 -Wno-error -mtune=intel -march=native -pipe -fomit-frame-pointer "                # see note --> 2
export CXXFLAGS="${CFLAGS} -fpermissive "


fetch_src(){
    curl -s "$1" | xz -d | tar xfv -
}

fetch(){
    cd "$root_dir" || exit -1
    fetch_src "$emacs_src"
    fetch_src "$imagemagick_src"
    imagemagick_dir="$(find "${root_dir}" -maxdepth 1 -type d -name 'ImageMagick*')"
    emacs_dir="$(find "${root_dir}" -maxdepth 1 -type d -name 'emacs*')"
}

test_emacs(){
    cd "$emacs_dir" || exit -1
    ./src/emacs -Q --script "$test_file"
}

get_env(){
    PKG_CONFIG_PATH="${imagemagick_mirror_dir}"/lib/pkgconfig pkg-config MagickWand --"$1"
}

configure_emacs(){
    cd "${imagemagick_mirror_dir}/bin/" || exit -1

    IMAGEMAGICK_CFLAGS=$(get_env cflags)
    IMAGEMAGICK_LIBS=$(get_env libs)
    export IMAGEMAGICK_LIBS
    export IMAGEMAGICK_CFLAGS
    cd "$emacs_dir" || exit -1
    ./configure \                                                                                    # see note --> 3
        --prefix=/usr \
        --build=x86_64-pc-linux-gnu \
        --host=x86_64-pc-linux-gnu \
        --mandir=/usr/share/man \
        --infodir=/usr/share/info \
        --datadir=/usr/share \
        --sysconfdir=/etc \
        --localstatedir=/var/lib \
        --disable-dependency-tracking \
        --disable-silent-rules \
        --docdir=/usr/share/doc/emacs-25.3-r2 \
        --htmldir=/usr/share/doc/emacs-25.3-r2/html \
        --libdir=/usr/lib64 \
        --program-suffix=-emacs-25 \
        --infodir=/usr/share/info/emacs-25 \
        --localstatedir=/var \
        --enable-locallisppath=/etc/emacs:/usr/share/emacs/site-lisp \
        --with-gameuser=:gamestat \
        --without-compress-install \
        --with-file-notification=inotify \
        --enable-acl \
        --with-dbus \
        --without-modules \
        --with-gpm \
        --without-hesiod \
        --without-kerberos \
        --without-kerberos5 \
        --with-xml2 \
        --without-selinux \
        --with-gnutls \
        --with-wide-int \
        --with-zlib \
        --with-sound=alsa \
        --with-x \
        --without-ns \
        --with-gconf \
        --with-gsettings \
        --with-toolkit-scroll-bars \
        --with-gif \
        --with-jpeg \
        --with-png \
        --with-rsvg \
        --with-tiff \
        --with-xpm \
        --with-imagemagick \
        --with-xft \
        --without-cairo \
        --with-libotf \
        --with-m17n-flt \
        --with-x-toolkit=gtk3 \
        --without-xwidgets
    make -j9
    echo "Change me: sudo make install"                                       # see note --> 4                      
}

install_imagemagick(){
    cd "$imagemagick_dir" || exit -1
    [ -f ./autogen.sh ] && ./autogen.sh

    ./configure --prefix="$imagemagick_mirror_dir" \                          # see note --> 5
                --oldincludedir="${imagemagick_mirror_dir}/include" \
                --build=x86_64-pc-linux-gnu \
                --host=x86_64-pc-linux-gnu \
                --disable-dependency-tracking \
                --disable-silent-rules \
                --disable-static \
                --enable-shared \
                --disable-hdri \
                --disable-opencl \
                --with-threads \
                --with-modules \
                --with-quantum-depth=16 \
                --with-magick-plus-plus \
                --without-perl \
                --with-bzlib \
                --with-x \
                --with-zlib \
                --without-autotrace \
                --without-dps \
                --without-djvu \
                --without-fftw \
                --without-fpx \
                --without-fontconfig \
                --with-freetype \
                --without-gslib \
                --without-gvc \
                --without-jbig \
                --with-jpeg \
                --without-openjp2 \
                --with-lcms \
                --without-lqr \
                --without-lzma \
                --without-openexr \
                --with-pango \
                --with-png \
                --with-rsvg \
                --with-tiff \
                --without-webp \
                --without-windows-font-dir \
                --without-wmf \
                --with-xml \
                --enable-openmp \
                --with-gcc-arch=no-automagic
    make -j9
    make install
    echo "${imagemagick_mirror_dir}/lib" | sudo tee -a /etc/ld.so.conf.d/999-imagemagick-6.conf      # see note --> 6
    sudo ldconfig                                                                                    # see note --> 7
}

fetch
install_imagemagick
configure_emacs
test_emacs


想安利Gentoo了怎么办
举报BUG:bash脚本中的HERE-DOC体中的 会使下面所有的内容成为字符串,于是不得不使用quote

1 个赞

@Athenacle 很厉害了!可以看下 formula 和 PKGBUILD 的打包规范, 发到 Linuxbrew 和 AUR 上,减少类似楼主这样的问题帖子,帮助大家节省几百至几千小时的折腾时间!:grin:

@LdBeth 我还没有用过 Linuxbrew,不过个人猜测它应该只需要 gcc 和 ruby。你说的 Homebrew 的缺点我没有体会到,“编译选项少”——理论上可以做到和 config 一样多的选项。至于 Gentoo 我没用过不便评论。不过,目前并没有看到吸引我去尝试的点。

Homebrew 好处之一在于把那些可能遇到的坑都替你踩咯,譬如 楼上我提到的,还有 @Athenacle 那一坨脚本,可能节省你数小时至数天的折腾时间。

看看相应的开发用的包有没有安装, debian 上叫 libmagickwand-dev :grinning:

:grinning: