【问题标题】:Errors when linking a custom Apache 2.4 modules statically with httpd/apr libraries on Linux将自定义 Apache 2.4 模块与 Linux 上的 httpd/apr 库静态链接时出错
【发布时间】:2012-05-04 18:36:31
【问题描述】:

我正在尝试将我的模块移动到 Linux Apache 2.4,但我遇到了链接问题。在 Windows 上,一个 libhttpd.lib 可用于链接以及 apr/apr-util 库。 lib* httpd apr 和 aprutil 在我的 Windows 安装中都是静态链接的。我想为 Linux 安装做同样的事情。

根据可用的有限文档,我无法使用 APXS,因为我的模块是用 C++ 编写的。

我很难在 Linux 上找到服务器的存档文件。我需要链接什么才能让我的模块工作?

源可以在 Windows 主机上链接和执行。

示例错误:

    /home/ec2-user/httpd-2.4.2/srclib/apr/locks/unix/proc_mutex.c:367: undefined reference to `pthread_mutexattr_init'
    /home/ec2-user/httpd-2.4.2/srclib/apr/locks/unix/proc_mutex.c:374: undefined reference to `pthread_mutexattr_setpshared'
    /home/ec2-user/httpd-2.4.2/srclib/apr/locks/unix/proc_mutex.c:384: undefined reference to `pthread_mutexattr_setrobust_np'
    /home/ec2-user/httpd-2.4.2/srclib/apr/locks/unix/proc_mutex.c:393: undefined reference to `pthread_mutexattr_setprotocol'
    /home/ec2-user/httpd-2.4.2/srclib/apr/locks/unix/proc_mutex.c:414: undefined reference to `pthread_mutexattr_destroy'
    /home/ec2-user/httpd-2.4.2/srclib/apr/locks/unix/proc_mutex.c:408: undefined reference to `pthread_mutexattr_destroy'

谢谢

【问题讨论】:

    标签: c++ linux apache2 g++ apache-modules


    【解决方案1】:

    这些错误意味着您没有将 -pthread 添加到编译命令行中,因此您没有获得链接到的 pthread 库。

    (注意:它是-pthread,而不是-lpthread - 它不仅仅是一个链接器选项。)

    【讨论】:

    • 我只包含了其中一个 unixDL 问题,但您知道我将使用哪个库来修复这些错误吗? /usr/lib/gcc/i686-amazon-linux/4.4.6/../../../crt1.o: In function '_start': (.text+0x18): undefined reference to 'main' /home/ec2-user/mod_infx_tools.cpp:236: undefined reference to 'ap_log_error_' /home/ec2-user/lib/libsqlite3.a(sqlite3.o): In function 'unixDlOpen': /home/ec2-user/sqlite-autoconf-3071100/sqlite3.c:30412: undefined reference to 'dlopen'
    • 对于dlopen-ldl。另一个不知道,可能是-lapr-lapr-util
    【解决方案2】:

    对于那些用 C++ 构建 Apache 模块并想要动态链接的人,这里是我用来成功构建模块的 g++ 命令行;在 Apache 2.2.22/CentOS 6.2 上进行了简要测试。

    g++ [my files].cpp  -I/httpd/include/ -I/httpd/srclib/apr/include/ 
        -I/httpd/srclib/apr-util/include/ -I/usr/include/ -I/usr/include/apr-1/ 
        -I/httpd/os/unix/ -shared -fPIC -o mod_mymodule.so
    

    我是 Apache/linux 编程菜鸟,无法在其他任何地方找到此信息;感谢 OP 的解决方案,经过几天的挫折,我得以完成这项工作。

    这里还有一个链接,它帮助解释了当找不到 httpd 服务器核心代码(Windows 上的 libhttpd.lib)中包含的 apache 函数时如何解决“未解决的引用”链接器问题——这不是存在于 *nix 中,除非您像 OP 那样手动制作。基本上,答案是使用 -shared 标志,以便在运行时自动解析这些引用。 http://www.yolinux.com/TUTORIALS/LibraryArchives-StaticAndDynamic.html

    不要忘记模块代码中的“extern C”,并在构建 HTTPD 时内置 DSO 支持。

    希望这对其他人有帮助!

    【讨论】:

    • 不错!我会推荐一个 Makefile 来帮助再生。我在 Amazon AWS Linux 平台上进行编译,虽然有限,但绝对有 shell 脚本和 Makefile 的帮助。
    • @AlexErwin - 好电话。我还在学习makefile的东西。顺便说一句,希望你不介意我半劫持你的问题,那里缺乏关于 c++ apache 模块的信息。感谢您发布您的解决方案!
    • 非常欢迎。我花了无数个小时搜索每一个信息,然后仍然需要进行反复试验。
    【解决方案3】:

    所以任何搜索这个的人都可能得到答案。

    1. 从 apache httpd 站点下载任何 Apache 版本(高于 2.2)源到主目录
    2. 解压
    3. 配置所有内容或只是不指定选项(您可以 稍后重新配置以进行实际构建)
    4. 在源代码上执行 make(暂时不要执行 make 安装!只需要目标文件)
    5. 创建一个目录,用于存放您的库和源代码 自己的模块。在您的主目录(或任何您 愿望)
    6. 假设主目录:execute (find ~/httpdX.X -name '*.o' -exec cp {} ~/foo \;) 命令在括号中。这会将所有已编译的对象复制到 foo。
    7. 执行 (find ~/foo -name '*.o' -exec ar r libhttpd.a {} \;) 其中 将为您创建代码存档。
    8. 然后在 gcc 的编译定义中包含这些开关 或 g++ (-Wl,-Bstatic -lhttpd -lpcre -lpcreposix -lapr-1 -laprutil-1 -Wl,-Bdynamic -pthread -ldl -lcrypt)
    9. 如果您愿意,可以通过在 *.o 上运行 rm 来清理您的 foo 目录 文件

    您不需要像我需要的那样进行静态编译,但我希望能够将我的模块移动到任何 Linux 主机上,而不用担心必要的组件。 Apache 需要 pcre(正则表达式)、apr(所有库)、线程(proc/thread mutex)、dl(动态加载)和 crypt(apr 密码)才能工作。由于 thread、dl 和 crypt 很可能已经在机器上,所以我选择不静态编译它们。

    狩猎愉快。我希望我在 3 天内永无止境的故事对其他人有所帮助!

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2011-08-01
      • 1970-01-01
      • 2018-12-27
      • 1970-01-01
      相关资源
      最近更新 更多