Autoconf 教程 Part-3 [翻译]

  |   0 评论   |   1,123 浏览

Autoconf 教程第3部分

这是整个教程的第三篇, 原文链接: http://www.idryman.org/blog/2016/03/15/autoconf-tutorial-part-3/

在这篇文章中,我将展示一个如何编写跨平台 OpenGL 程序的例子。我们将探索更多 autoconf 特性,包括 config.h、第三方库等等。

跨平台 OpenGL

尽管 OpenGLAPI 在所有平台上基本上都是相同的,但是在不同的平台上它们的头和链接选项是非常不同的!要在 OSX 上使用 OpenGL,必须包含 < OpenGL/GL.h > ,但是在其他平台上必须使用 < GL/GL.h > 。有时,您可能在同一个平台上有多个可能的 OpenGL 实现。如果搜索 OpenGL 教程,大多数都只能在一个平台上构建。

而这正是 autoconf 发挥作用的地方。我最近提交了一个新版本的 AX_CHECK_GL,它可以解决这些复杂的可移植性问题。
查看 autoconf 归档中的三个 OpenGL 检查宏: AX_CHECK_GL, AX_CHECK_GLU, and AX_CHECK_GLUT 。他们的语法非常的简单

  • AX_CHECK_GL([ACTION-IF-FOUND],[ACTION-IF-NOT-FOUND])
  • AX_CHECK_GLU([ACTION-IF-FOUND],[ACTION-IF-NOT-FOUND])
  • AX_CHECK_GLUT([ACTION-IF-FOUND],[ACTION-IF-NOT-FOUND])

但是,它不在默认的 autoconf 包里面,您需要在构建脚本中包含第三方 autoconf archive 归档文件。下面会介绍如何做到这点的。

添加额外的宏

首先,通过 git 子模块安装第三方宏。或者,您可以只复制所需的宏,但一定要包含它所使用的所有依赖宏。

git submodule add git@github.com:peti/autoconf-archive.git

接下来,在 configure.ac 中添加以下代码行:

# before invoking AM_INIT_AUTOMAKE
AC_CONFIG_MACRO_DIR([autoconf-archive/m4])

完成这两个步骤之后,您就可以自由地调用归档(archive)包中的500多个宏了。

C预处理宏

Just adding the macro is not enough. You also have to pass the C preprocessor macros to your C program. To do so, add another line to your configure.ac.

仅仅添加宏是不够的。您还必须将 C 预处理器宏传递给 C 程序。为此,在 configure.ac 中添加另一行。

AC_CONFIG_HEADERS([config.h])

And now in your C program you can write the following to make it portable on all systems. The listing is availabe in the AX_CHECK_GL document.

现在在您的 C 程序中,您可以编写以下代码,使其在所有系统上都可以移植。该清单可以在 AX_CHECK_GL document 文档中找到。

# include "config.h"

#if defined(HAVE_WINDOWS_H) && defined(_WIN32)
# include <windows.h>
#endif
#ifdef HAVE_GL_GL_H
# include <GL/gl.h>
#elif defined(HAVE_OPENGL_GL_H)
# include <OpenGL/gl.h>
#else
# error no gl.h
#endif

Wrapping it up

The full working example can be downloaded from here. Here is the listing of each code:

完整的工作示例可以从这里下载,下面是每个代码的清单:

configure.ac|

AC_INIT([gl-example], [1.0])

AC_CONFIG_SRCDIR([gl-example.c])
AC_CONFIG_AUX_DIR([build-aux])
AC_CONFIG_MACRO_DIR([autoconf-archive/m4])
AM_INIT_AUTOMAKE([-Wall -Werror foreign])

AC_PROG_CC

AX_CHECK_GL
AX_CHECK_GLUT

# For glew you can simply use
# AC_CHECK_LIB([GLEW], [glewInit])

AC_CONFIG_HEADERS([config.h])
AC_CONFIG_FILES([Makefile])

AC_OUTPUT

The default rule for gl_example_SOURCES is to look at the c program with the same name, thus can be omitted.

gl_example_SOURCES 的默认规则是查看具有相同名称的 c 程序,因此可以省略。

Makefile.am|

bin_PROGRAMS = gl-example

gl-example.c 例子|

#include "config.h"
#include <stdlib.h>
# if HAVE_WINDOWS_H && defined(_WIN32)
  #include <windows.h>
# endif

#ifdef HAVE_GL_GL_H
# include <GL/gl.h>
#elif defined(HAVE_OPENGL_GL_H)
# include <OpenGL/gl.h>
#else
# error no gl.h
#endif

# if defined(HAVE_GL_GLUT_H)
#  include <GL/glut.h>
# elif defined(HAVE_GLUT_GLUT_H)
#  include <GLUT/glut.h>
# else
#  error no glut.h
# endif

static void render(void);

int main(int argc, char** argv) {
  glutInit(&argc, argv);
  glutInitDisplayMode(GLUT_RGB | GLUT_DOUBLE);
  glutInitWindowSize(640, 640);
  glutInitWindowPosition(100, 100);
  glutCreateWindow("Hello World!");
  glutDisplayFunc(&render);
  glClearColor(0.0f, 0.0f, 0.0f, 0.0f);

  glutMainLoop();
  return 0;
}

void render(void) {
  glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
  glMatrixMode(GL_MODELVIEW);
  glLoadIdentity();
  glBegin(GL_TRIANGLES);
  glVertex3f( 0.0f, 0.0f, 0.0f);
  glVertex3f( 0.5f, 1.0f, 0.0f);
  glVertex3f( 1.0f, 0.0f, 0.0f);
  glEnd();
  glutSwapBuffers();
}

Try out the configure options by invoking ./configure --help. You’ll find it provides rich options that is familiar to power users.

通过调用。 ./configure --help。您会发现它提供了高级用户所熟悉的丰富选项。

./configure --help
`configure' configures gl-example 1.0 to adapt to many kinds of systems.

Usage: ./configure [OPTION]... [VAR=VALUE]...
...
Optional Packages:
  --with-PACKAGE[=ARG]    use PACKAGE [ARG=yes]
  --without-PACKAGE       do not use PACKAGE (same as --with-PACKAGE=no)
  --with-xquartz-gl[=DIR] On Mac OSX, use opengl provided by X11/XQuartz
                          instead of the built-in framework. If enabled, the
                          default location is [DIR=/opt/X11]. This option is
                          default to false.
...
  PKG_CONFIG  path to pkg-config utility
  PKG_CONFIG_PATH
              directories to add to pkg-config's search path
  PKG_CONFIG_LIBDIR
              path overriding pkg-config's built-in search path
  GL_CFLAGS   C compiler flags for GL, overriding configure script defaults
  GL_LIBS     Linker flags for GL, overriding configure script defaults
  CPP         C preprocessor
  GLUT_CFLAGS C compiler flags for GLUT, overriding configure script defaults
  GLUT_LIBS   Linker flags for GLUT, overriding configure script defaults

So far I haven’t seen other build system that can do OpenGL cross platform setup. (I only searched for CMake and Scons). Though autoconf is said to be harder to learn, but by learning through these three articles, now the syntax shouldn’t be that alien anymore, right?

到目前为止,我还没有看到其他可以进行 OpenGL 跨平台设置的构建系统。(我只搜索了 CMake 和 Sons)。虽然 autoconf 据说更难学,但通过这三篇文章的学习,现在语法应该不再是那么陌生了,对吧?

In the next post, I’ll give another example of how to build a library, with unit tests and debugger setup.

在下一篇文章中,我将给出另一个如何构建库的例子,包括单元测试和调试器设置。

评论

发表评论


取消