Istnieją dwa bardzo ważne punkty warte dokonywania związanych tutaj wzdłuż „nie rób tego w ten sposób” linii:
- Nie używają
atoi
ponieważ it's not safe.
- Nie używaj
atoi
, ponieważ nie jest to funkcja standardowa i istnieją dobre standardowe funkcje (takie jak snprintf
), które można wykonywać w dowolny sposób.
Ale, odkładając to na chwilę, chcę przedstawić Wam autoconf, part of the GNU build system. autoconf jest częścią bardzo wszechstronnego, bardzo przenośnego zestawu narzędzi, które mają na celu ułatwienie pisania kodu, który można z powodzeniem zbudować na szerokiej gamie systemów docelowych. Niektórzy twierdzą, że autoconf jest zbyt skomplikowanym systemem, który rozwiązuje tylko jeden problem, który stwarzasz za pomocą tylko jednej funkcji bibliotecznej, ale jak każdy program rośnie, najprawdopodobniej będzie musiał stawić czoła kolejnym przeszkodom podobnym do tego, a ustawienie autoconfu dla twojego programu będzie teraz jesteś w znacznie silniejszej pozycji na przyszłość.
start z pliku o nazwie Makefile.in
który zawiera:
CFLAGS=--ansi --pedantic -Wall -W
program: program.o
program.o: program.c
clean:
rm -f program.o program
i plik o nazwie configure.ac
który zawiera:
AC_PREREQ([2.69])
AC_INIT(program, 1.0)
AC_CONFIG_SRCDIR([program.c])
AC_CONFIG_HEADERS([config.h])
# Checks for programs.
AC_PROG_CC
# Checks for library functions.
AH_TEMPLATE([HAVE_ITOA], [Set to 1 if function atoi() is available.])
AC_CHECK_FUNC([itoa],
[AC_DEFINE([HAVE_ITOA], [1])]
)
AC_CONFIG_FILES([Makefile])
AC_OUTPUT
i plik o nazwie program.c
który zawiera:
#include <stdio.h>
#include "config.h"
#ifndef HAVE_ITOA
/*
* WARNING: This code is for demonstration purposes only. Your
* implementation must have a way of ensuring that the size of the string
* produced does not overflow the buffer provided.
*/
void itoa(int n, char* p) {
sprintf(p, "%d", n);
}
#endif
int main(void) {
char buffer[100];
itoa(10, buffer);
printf("Result: %s\n", buffer);
return 0;
}
Teraz uruchom kolejno następujące polecenia:
autoheader
: To generuje nowy plik o nazwie config.h.in
których będziemy potrzebować później.
autoconf
: To generuje skrypt konfiguracyjny o nazwie configure
./configure
: To działa kilka testów, w tym kontroli, które masz pracy kompilatora C i, ponieważ prosiliśmy go, czy dana funkcja jest dostępna itoa
. Zapisuje wyniki w pliku config.h
na później.
make
: To kompiluje i łączy program.
./program
: To w końcu uruchamia program.
Podczas etapu ./configure
zobaczysz sporo produkcji, w tym coś takiego:
checking for itoa... no
W tym przypadku, zobaczysz, że config.h
znalezisko zawiera następujące wiersze:
/* Set to 1 if function atoi() is available. */
/* #undef HAVE_ITOA */
Ewentualnie, jeśli zrobić mieć atoi
dostępne, zobaczysz:
checking for itoa... yes
i to w config.h
:
/* Set to 1 if function atoi() is available. */
#define HAVE_ITOA 1
Zobaczysz, że program może teraz odczytać nagłówek config.h
i wybierz zdefiniować itoa
jeśli nie jest obecny.
Tak, daleko jest do rozwiązania problemu, ale teraz zaczęto używać bardzo potężnego narzędzia, które może pomóc na wiele sposobów.
Powodzenia!
Istnieje system 'autoconf' - zaprojektowany do radzenia sobie z takimi złożonościami. Nie ma wielu prostszych systemów, które działają niezawodnie; Nie jestem pewien, czy znam jednego. Istnieją również 'automake' i' libtool', które działają w połączeniu z 'autoconf', ale najczęściej używasz' autoconf'. Można zbadać inne systemy kompilacji, takie jak 'cmake'. –
Inną trudną częścią dotyczącą funkcji, która jest dostępna tylko w systemach _some_ jest to, że są one zbyt często _funkcjonalnie różne_ w różnych systemach. Proponuję funkcję otoki. – chux
Funkcja @chux * wrapper * objaśnienie? –