Autobook Chinese Version (iv)

Source: Internet
Author: User
6. Preparation of ' configure.in ' documents

Writing a portable ' configure.in ' file is a tricky job. You can write arbitrary shell code into the ' configure.in ' file and choose a lot. The first time you use autoconf you can encounter the following questions: What is portable and what is not portable. Should be tested (test the system for a function or what conditions are met) what? What should not be detected? How to better use the autoconf function? What should not be written in ' configure.in '? What is the order of detection? What is the only thing that detects a system's name and does not have to detect it?
6.1 What is portability.

Before discussing what to test and how to detect it, let's ask ourselves a simple question: What is portability? Portability is code that has the qualities that can be built and run on different platforms. In a autoconf environment, portability usually refers to the ability to run on a unix-like system, sometimes including Windows.

The first time I used autoconf, I had a lot of effort to decide what to test in the ' configure.in ' file. At the time, I maintained a program that could only run under SunOS 4. However, I would like to transplant it to SOLARIS,OSF/1, perhaps including Irix.

I spent a lot of time doing this: I wrote a very small ' configure.in ', trying to get my program running under Solaris. Whenever I encounter a problem, improve the ' configure.in ' and the program code. When it can be built, I start to test whether it will run correctly after porting.

Because I didn't start thinking about portability and didn't realize that I should put autoconf in the package (see section 24), I had more difficulty than I thought. If you start thinking about porting problems, you'll be better off.

There are many unix-like systems, and many of the systems that are still in use are obsolete. Attempts to migrate applications to systems like this are often ineffective. Porting All programs is a difficult process, especially when it's not always possible to detect all the systems, because there are a lot of new systems that are created, these systems are often problematic, and there are some weird behaviors.

We provide a portable method available: We write the program with a large number of highly advanced unix-like systems in mind. Ability to improve ' configure.in ' and source code to solve problems with porting. In practical, this is an effective method. 6.2 Introduction to Portable SH

If you read some ' configure.in ', you'll notice that they tend to be in unusual style. For example, it is hard to see the use of ' [' instead of calling ' test '. Here we'll drill down to the details of writing a portable script, which is explained in the 22nd chapter.

Like other portability issues, write ' configure.in ' and ' makefile.am ' purposefully. Some systems do not comply with the standard SH rules. For example, the Ultrix system does not support unset commands. The GNU Autotool can write code that is portable on most systems, and it does not restrict portability.

The portable SH code is not entirely feasible. SH can do very little, most of the work is done by a separate program with a potential transplant problem. For example, some of the options are not supported on all systems, and some of the programs that are clearly supposed to exist are not on some systems. So you need to know not only what SH commands are not portable, but also what you can (and cannot) use and what is portable.

It's frustrating, but actually writing portable shell scripts is not as difficult as it looks. Once you use it, you will master its rules. Unfortunately, it's going to take a lot of time. Think of other portable code, and you'll find the "experiment-validation" approach works. Once again, you'll find out what style you want--writing programs that run only on mainstream Linux are very different from programs that are very portable, like Emacs and GCC. It is easy to write a ' configure.in ' that is not portable. It is often easy to overwrite a program segment that is not portable. 6.3 Sorting detection order

Another problem in writing a portable SH code is determining the order of the various detections. , here will be a description autoconf indirect (through the AutoScan program, 24.) The recommended standard order.

The standard order is:

1. Template. The standard template code should be included, such as calling Ac_init (must be in front), Am_init_automake, Ac_config_header, or ac_revision.

2. Options. You should include configure command-line options and macros, such as ac_arg_enable. The option code is generally included, as in the following LIBGCJ example:

Ac_arg_enable (Getenv-properties,
      [  --disable-getenv-properties
                                don ' t set system Properties from Gcj_ PROPERTIES])

      dnl Whether gcj_properties is used depends on the target.
      If Test-n "$enable _getenv_properties"; Then
         Enable_getenv_properties=${enable_getenv_properties_default-yes}
      fi
      if test "$enable _getenv_ Properties "= no; Then
         ac_define (disable_getenv_properties)
      fi

3. Program Files. When the Configure is executed, the program file is instrumented when it is built, or when the program file is built. Typically, macros such as Ac_check_prog and Ac_path_tool are executed.

4. library files. Library files in C (or C + +, or other) are detected first than others. This is necessary because you may try to connect the program when other tests are in place, and the detection library file is guaranteed to connect correctly.

5. header file. Detects if the header file exists.

6. Type and structure definition. Detecting the type and structure after the header file is detected because they appear in the header file. Make sure that it is available before you use it.

7. function. The final detection is because the function relies on the previous file.

8. Output file. Completed by Ac_output.

This order can be used as a simple guideline, it is not strict. Sometimes in order to make the ground ' configure.in ' easier to maintain, you have to stagger the test, or the detection itself must be in a different order. For example, if the project uses both C and C + +, to make ' configure.in ' more readable, you can first detect all C and then detect C + +. 6.4 What to test

Decide what is the main problem to detect as ' configure.in '. Once you've read the autoconf reference manual, you'll know how to write a separate detection code. "When" is still mysterious-testing a lot of things is as simple as detecting very few things.

It should be noted in the Unix-like system that not all systems have the same program. Even if there is, it is not necessarily the same behavior. For these issues, we recommend that you try to comply with the GNU code standard: Use the most common options for relatively limited programs. If that doesn't work, try using the POSIX option, or check the problem with the platform you care about.

Detection tools and their differences are often a small part of the ' Configure ' script, and generally detect functions, library files, and so on.

In addition to some core library files, such as ' libc ', some library files that are not considered core libraries such as ' LIBM ' and ' libx11′ ' may have different names and content in different Unix systems. Even so, the library file is still well handled because the library file only affects ' Makefile '. This means that detecting another library file does not require large (or sometimes, almost no) changes to the source code. Adding a library file's detection has little impact on the development cycle, just rerun the ' Configure ' reconnect, and the detection of the library files can be used in a very loose way. For example, you can make a library file work only on a few systems that you care about, and then improve it as needed.

What to do with connection problems. The first thing to do is to use NM to detect if there is a function to find in the library file. If it exists and can be used, the problem becomes simple-just add a Ac_check_lib macro. Note It is not enough to find this function only in the library file, because some of the "standard" libraries in some systems do not work, ' LIBUCB ' is an example of a library that should be avoided.

If a function is not found in the library file, it means that it is not a portable function. There are basically three reasons why the function cannot be found. Here's a discussion of functions that can be used in a TypeDef, a struct, and a global variable.

The first method is to write an alternate function, use conditional compilation, or put it in a properly named file and use it with Ac_replace_funcs macros. For example, TCL uses Ac_replace_funcs (STRSTR) to process systems that do not have strstr functions.

The second approach is to use a different function that is similar in function. Use different functions depending on your system selection. It is customary to use break as the second parameter of Ac_check_funcs, which avoids unnecessary detection and reader-related testing. For example, the following example is the LIBGCJ detection Inet_aton or INET_ADDR function, which uses only the first one it finds:

Ac_check_funcs (Inet_aton inet_addr, break)

The code for using these instrumentation results is as follows:

#if Have_inet_aton ... use
  Inet_aton here
#else
#if have_inet_addr ... use
  inet_addr here
#else
#error Function missing!
#endif
#endif

Notice how a compile-time error occurs when a function does not exist. It is usually better to discover errors earlier in the build process.

The third method is to write an optional function. For example, you can use the MMAP function to map files to memory when you write an editor. But Mmap is not portable and a portable function is written.

Handling a function that is not portable is only part of the detection process. The practical approach is effective, but it is inefficient in modern systems such as Gnu/linux, which are fully functional. So you may not be concerned about the non portable structure until the project is almost complete.

Unfortunately, there is no better way to solve the problem. You need to have hands-on experience with Unix. The knowledge of POSIX and XPG standards is helpful. But standards are not a panacea, and not all systems are compliant. And some systems have bugs in their functions.

The last type of problem you may encounter is too much detection. It will increase your maintenance burden. For example, you will sometimes see the instrumented code, which is not necessary because it is portable. Again, this can only be done through your understanding of the practical knowledge of the target system. 6.5 application Configuration name

When the best method is used to detect functionality, ' Configure ' occasionally makes a decision on the configuration name. This practice may be necessary when standard autoconf function testing does not detect something. For example, you need information about the system's ' TTY ' implementation and do not detect configuration names that are not known.

It is generally better to detect specific features than to detect specific system types, as Unix and other systems evolve, and different systems replicate certain functions from another system.

When you cannot detect a configuration name in the ' Configure ' script, it is better to define a macro that describes the function than a macro that describes the system type. This allows the macro to be used for other systems that detect this functionality (check section 23).

In the autoconf ' configure.in ' file, a case statement is generally used to detect the detection system. The case statement might look for something like the following to determine if ' host ' is a variable of a specified system shell. Here the case statement uses ' ac_canonical_host ' or ' ac_canonical_system ' macros.

Case "${host}" in
i[[3456]]86-*-linux-gnu*) do something;;
Sparc*-sun-solaris2. [[56789]]*) do something;;
sparc*-sun-solaris*) do something;;
mips*-*-elf*) do something;;
Esac

Notice the two sets of brackets in this code. It is ubiquitous in autoconf implementations. It uses the M4 engine. If it is not two sets of parentheses, M4 does not parse it and will not appear in ' Configure '. See Chapter 24 for details.

It is important to use ' * ' behind the system fields to match the system version produced by ' Config.guess '. Most cases should be carefully matched to the processor type. Most of the processor family, with a ' * ' can be, like the above ' mips* '. For the i386 family, using ' i[34567]86′ ' is OK. For the m68k processor family, fields such as ' m68* ' may be used. Of course, if you don't emphasize the processor, you can replace the entire field with ' * ', such as ' *-*-irix* '.

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.