[U-Boot] [PATCH 4/7] Check if compiler-provided <stdint.h> and <inttypes.h> are available if CONFIG_USE_STDINT=y (MAD)
Masahiro Yamada
yamada.m at jp.panasonic.com
Mon Dec 22 11:16:00 CET 2014
CONFIG_USE_STDINT was introduced to use compiler-provided types for
fixed-width variables.
This must be consistent everywhere to avoid warnings/errors
including printf() and friends.
Assume the code below
uint32_t foo;
printf("foo= %x\n", foo);
If <stdint.h> is included, uint32_t is defined by the compiler.
The code above only works on compilers that define "uint32_t"
as "unsigned int". Actually there exist compilers that define
"uint32_t" as "unsigned long".
Going forward, to print out fixed-width variables, we always have
to use PRIxN like this
uint32_t foo;
printf("foo= " PRIx32 "\n", foo);
Notice,
- Typedefs ( uint32_t, int32_t etc.) are provided by <stdint.h>
- Printf formats ( PRIx32, PRId32 etc.) are provided by <inttypes.h>
Also notice, it makes sense only when <stdint.h> and <inttypes.h> are provided by
the same compiler.
^^^^^^^^^^^^^^^^^^
Commit 4166ecb24 (Add some standard headers external code might need) added
hard-coded include/inttypes.h.
It provides hard-coded PRIx32 "x", but it does not make sense.
Some compiler's <stdint.h> define "uint32_t" as "unsigned long"
and expect the format string "lx" to print out "uint32_t" variable.
This commit:
- Adds scripts/gcc-have-stdint.sh to check if the compiler is
providing both <stdint.h> and <inttypes.h>
- Modifies config.mk to error-out if CONFIG_USE_STDINT is enabled,
but <stdint.h> or <inttyps.h> is missing
- Modifies the top Makefile to delete "-nostdinc" option and allow to
include compiler-provided <inttypes.h>
- Remove hard-coded include/inttypes.h
Signed-off-by: Masahiro Yamada <yamada.m at jp.panasonic.com>
Cc: Gabe Black <gabeblack at chromium.org>
Cc: Simon Glass <sjg at chromium.org>
Cc: Bill Richardson <wfrichar at google.com>
Cc: Tom Rini <trini at ti.com>
---
Makefile | 2 +-
config.mk | 12 ++
include/inttypes.h | 287 ---------------------------------------------
scripts/gcc-have-stdint.sh | 21 ++++
4 files changed, 34 insertions(+), 288 deletions(-)
delete mode 100644 include/inttypes.h
create mode 100755 scripts/gcc-have-stdint.sh
diff --git a/Makefile b/Makefile
index 1560bff..b44e504 100644
--- a/Makefile
+++ b/Makefile
@@ -591,7 +591,7 @@ UBOOTINCLUDE := \
-I$(srctree)/arch/$(ARCH)/include \
-include $(srctree)/include/linux/kconfig.h
-NOSTDINC_FLAGS += -nostdinc -isystem $(shell $(CC) -print-file-name=include)
+NOSTDINC_FLAGS += -isystem $(shell $(CC) -print-file-name=include)
CHECKFLAGS += $(NOSTDINC_FLAGS)
# FIX ME
diff --git a/config.mk b/config.mk
index 64c2951..91f60d4 100644
--- a/config.mk
+++ b/config.mk
@@ -64,6 +64,18 @@ ifneq ($(USE_STDINT),)
PLATFORM_CPPFLAGS += -DCONFIG_USE_STDINT
endif
+ifeq ($(CONFIG_USE_STDINT),y)
+HAVE_STDINT := $(shell $(CONFIG_SHELL) scripts/gcc-have-stdint.sh $(CC))
+
+ifeq ($(HAVE_STDINT),)
+$(warning you have enabled CONFIG_USE_STDINT (or given USE_STDINT=1 from the command line))
+$(warning but your compiler is not providing <stdint.h> or <inttypes.h>.)
+$(error check your compiler.)
+
+endif
+
+endif
+
#########################################################################
RELFLAGS := $(PLATFORM_RELFLAGS)
diff --git a/include/inttypes.h b/include/inttypes.h
deleted file mode 100644
index e2e569d..0000000
--- a/include/inttypes.h
+++ /dev/null
@@ -1,287 +0,0 @@
-/*
- * Copyright (C) 1997-2001, 2004, 2007 Free Software Foundation, Inc.
- *
- * This file is taken from the GNU C Library v2.15, with the unimplemented
- * functions removed and a few style fixes.
- *
- * SPDX-License-Identifier: GPL-2.0+
- */
-
-/*
- * ISO C99: 7.8 Format conversion of integer types <inttypes.h>
- */
-
-#ifndef _INTTYPES_H
-#define _INTTYPES_H 1
-
-#include <linux/compiler.h>
-
-/* Get a definition for wchar_t. But we must not define wchar_t itself. */
-#ifndef ____gwchar_t_defined
-# ifdef __cplusplus
-# define __gwchar_t wchar_t
-# elif defined __WCHAR_TYPE__
-typedef __WCHAR_TYPE__ __gwchar_t;
-# else
-# define __need_wchar_t
-# include <stddef.h>
-typedef wchar_t __gwchar_t;
-# endif
-# define ____gwchar_t_defined 1
-#endif
-
-
-/* The ISO C99 standard specifies that these macros must only be
- defined if explicitly requested. */
-#if !defined __cplusplus || defined __STDC_FORMAT_MACROS
-
-#ifdef CONFIG_USE_STDINT
-# if __WORDSIZE == 64
-# define __PRI64_PREFIX "l"
-# define __PRIPTR_PREFIX "l"
-# else
-# define __PRI64_PREFIX "ll"
-# define __PRIPTR_PREFIX
-# endif
-#else
-/* linux/types.h always uses long long for 64-bit and long for uintptr_t */
-# define __PRI64_PREFIX "ll"
-# define __PRIPTR_PREFIX "l"
-#endif
-
-/* Macros for printing format specifiers. */
-
-/* Decimal notation. */
-# define PRId8 "d"
-# define PRId16 "d"
-# define PRId32 "d"
-# define PRId64 __PRI64_PREFIX "d"
-
-# define PRIdLEAST8 "d"
-# define PRIdLEAST16 "d"
-# define PRIdLEAST32 "d"
-# define PRIdLEAST64 __PRI64_PREFIX "d"
-
-# define PRIdFAST8 "d"
-# define PRIdFAST16 __PRIPTR_PREFIX "d"
-# define PRIdFAST32 __PRIPTR_PREFIX "d"
-# define PRIdFAST64 __PRI64_PREFIX "d"
-
-
-# define PRIi8 "i"
-# define PRIi16 "i"
-# define PRIi32 "i"
-# define PRIi64 __PRI64_PREFIX "i"
-
-# define PRIiLEAST8 "i"
-# define PRIiLEAST16 "i"
-# define PRIiLEAST32 "i"
-# define PRIiLEAST64 __PRI64_PREFIX "i"
-
-# define PRIiFAST8 "i"
-# define PRIiFAST16 __PRIPTR_PREFIX "i"
-# define PRIiFAST32 __PRIPTR_PREFIX "i"
-# define PRIiFAST64 __PRI64_PREFIX "i"
-
-/* Octal notation. */
-# define PRIo8 "o"
-# define PRIo16 "o"
-# define PRIo32 "o"
-# define PRIo64 __PRI64_PREFIX "o"
-
-# define PRIoLEAST8 "o"
-# define PRIoLEAST16 "o"
-# define PRIoLEAST32 "o"
-# define PRIoLEAST64 __PRI64_PREFIX "o"
-
-# define PRIoFAST8 "o"
-# define PRIoFAST16 __PRIPTR_PREFIX "o"
-# define PRIoFAST32 __PRIPTR_PREFIX "o"
-# define PRIoFAST64 __PRI64_PREFIX "o"
-
-/* Unsigned integers. */
-# define PRIu8 "u"
-# define PRIu16 "u"
-# define PRIu32 "u"
-# define PRIu64 __PRI64_PREFIX "u"
-
-# define PRIuLEAST8 "u"
-# define PRIuLEAST16 "u"
-# define PRIuLEAST32 "u"
-# define PRIuLEAST64 __PRI64_PREFIX "u"
-
-# define PRIuFAST8 "u"
-# define PRIuFAST16 __PRIPTR_PREFIX "u"
-# define PRIuFAST32 __PRIPTR_PREFIX "u"
-# define PRIuFAST64 __PRI64_PREFIX "u"
-
-/* lowercase hexadecimal notation. */
-# define PRIx8 "x"
-# define PRIx16 "x"
-# define PRIx32 "x"
-# define PRIx64 __PRI64_PREFIX "x"
-
-# define PRIxLEAST8 "x"
-# define PRIxLEAST16 "x"
-# define PRIxLEAST32 "x"
-# define PRIxLEAST64 __PRI64_PREFIX "x"
-
-# define PRIxFAST8 "x"
-# define PRIxFAST16 __PRIPTR_PREFIX "x"
-# define PRIxFAST32 __PRIPTR_PREFIX "x"
-# define PRIxFAST64 __PRI64_PREFIX "x"
-
-/* UPPERCASE hexadecimal notation. */
-# define PRIX8 "X"
-# define PRIX16 "X"
-# define PRIX32 "X"
-# define PRIX64 __PRI64_PREFIX "X"
-
-# define PRIXLEAST8 "X"
-# define PRIXLEAST16 "X"
-# define PRIXLEAST32 "X"
-# define PRIXLEAST64 __PRI64_PREFIX "X"
-
-# define PRIXFAST8 "X"
-# define PRIXFAST16 __PRIPTR_PREFIX "X"
-# define PRIXFAST32 __PRIPTR_PREFIX "X"
-# define PRIXFAST64 __PRI64_PREFIX "X"
-
-
-/* Macros for printing `intmax_t' and `uintmax_t'. */
-# define PRIdMAX __PRI64_PREFIX "d"
-# define PRIiMAX __PRI64_PREFIX "i"
-# define PRIoMAX __PRI64_PREFIX "o"
-# define PRIuMAX __PRI64_PREFIX "u"
-# define PRIxMAX __PRI64_PREFIX "x"
-# define PRIXMAX __PRI64_PREFIX "X"
-
-
-/* Macros for printing `intptr_t' and `uintptr_t'. */
-# define PRIdPTR __PRIPTR_PREFIX "d"
-# define PRIiPTR __PRIPTR_PREFIX "i"
-# define PRIoPTR __PRIPTR_PREFIX "o"
-# define PRIuPTR __PRIPTR_PREFIX "u"
-# define PRIxPTR __PRIPTR_PREFIX "x"
-# define PRIXPTR __PRIPTR_PREFIX "X"
-
-
-/* Macros for scanning format specifiers. */
-
-/* Signed decimal notation. */
-# define SCNd8 "hhd"
-# define SCNd16 "hd"
-# define SCNd32 "d"
-# define SCNd64 __PRI64_PREFIX "d"
-
-# define SCNdLEAST8 "hhd"
-# define SCNdLEAST16 "hd"
-# define SCNdLEAST32 "d"
-# define SCNdLEAST64 __PRI64_PREFIX "d"
-
-# define SCNdFAST8 "hhd"
-# define SCNdFAST16 __PRIPTR_PREFIX "d"
-# define SCNdFAST32 __PRIPTR_PREFIX "d"
-# define SCNdFAST64 __PRI64_PREFIX "d"
-
-/* Signed decimal notation. */
-# define SCNi8 "hhi"
-# define SCNi16 "hi"
-# define SCNi32 "i"
-# define SCNi64 __PRI64_PREFIX "i"
-
-# define SCNiLEAST8 "hhi"
-# define SCNiLEAST16 "hi"
-# define SCNiLEAST32 "i"
-# define SCNiLEAST64 __PRI64_PREFIX "i"
-
-# define SCNiFAST8 "hhi"
-# define SCNiFAST16 __PRIPTR_PREFIX "i"
-# define SCNiFAST32 __PRIPTR_PREFIX "i"
-# define SCNiFAST64 __PRI64_PREFIX "i"
-
-/* Unsigned decimal notation. */
-# define SCNu8 "hhu"
-# define SCNu16 "hu"
-# define SCNu32 "u"
-# define SCNu64 __PRI64_PREFIX "u"
-
-# define SCNuLEAST8 "hhu"
-# define SCNuLEAST16 "hu"
-# define SCNuLEAST32 "u"
-# define SCNuLEAST64 __PRI64_PREFIX "u"
-
-# define SCNuFAST8 "hhu"
-# define SCNuFAST16 __PRIPTR_PREFIX "u"
-# define SCNuFAST32 __PRIPTR_PREFIX "u"
-# define SCNuFAST64 __PRI64_PREFIX "u"
-
-/* Octal notation. */
-# define SCNo8 "hho"
-# define SCNo16 "ho"
-# define SCNo32 "o"
-# define SCNo64 __PRI64_PREFIX "o"
-
-# define SCNoLEAST8 "hho"
-# define SCNoLEAST16 "ho"
-# define SCNoLEAST32 "o"
-# define SCNoLEAST64 __PRI64_PREFIX "o"
-
-# define SCNoFAST8 "hho"
-# define SCNoFAST16 __PRIPTR_PREFIX "o"
-# define SCNoFAST32 __PRIPTR_PREFIX "o"
-# define SCNoFAST64 __PRI64_PREFIX "o"
-
-/* Hexadecimal notation. */
-# define SCNx8 "hhx"
-# define SCNx16 "hx"
-# define SCNx32 "x"
-# define SCNx64 __PRI64_PREFIX "x"
-
-# define SCNxLEAST8 "hhx"
-# define SCNxLEAST16 "hx"
-# define SCNxLEAST32 "x"
-# define SCNxLEAST64 __PRI64_PREFIX "x"
-
-# define SCNxFAST8 "hhx"
-# define SCNxFAST16 __PRIPTR_PREFIX "x"
-# define SCNxFAST32 __PRIPTR_PREFIX "x"
-# define SCNxFAST64 __PRI64_PREFIX "x"
-
-
-/* Macros for scanning `intmax_t' and `uintmax_t'. */
-# define SCNdMAX __PRI64_PREFIX "d"
-# define SCNiMAX __PRI64_PREFIX "i"
-# define SCNoMAX __PRI64_PREFIX "o"
-# define SCNuMAX __PRI64_PREFIX "u"
-# define SCNxMAX __PRI64_PREFIX "x"
-
-/* Macros for scaning `intptr_t' and `uintptr_t'. */
-# define SCNdPTR __PRIPTR_PREFIX "d"
-# define SCNiPTR __PRIPTR_PREFIX "i"
-# define SCNoPTR __PRIPTR_PREFIX "o"
-# define SCNuPTR __PRIPTR_PREFIX "u"
-# define SCNxPTR __PRIPTR_PREFIX "x"
-
-#endif /* C++ && format macros */
-
-
-#if __WORDSIZE == 64
-
-/* We have to define the `uintmax_t' type using `ldiv_t'. */
-typedef struct {
- long int quot; /* Quotient. */
- long int rem; /* Remainder. */
-} imaxdiv_t;
-
-#else
-
-/* We have to define the `uintmax_t' type using `lldiv_t'. */
-typedef struct {
- long long int quot; /* Quotient. */
- long long int rem; /* Remainder. */
-} imaxdiv_t;
-
-#endif
-
-#endif /* inttypes.h */
diff --git a/scripts/gcc-have-stdint.sh b/scripts/gcc-have-stdint.sh
new file mode 100755
index 0000000..555ede6
--- /dev/null
+++ b/scripts/gcc-have-stdint.sh
@@ -0,0 +1,21 @@
+#!/bin/sh
+#
+# Test if the compiler has <stdint.h> and <inttypes.>
+# Kernel.org toolchains do not provide them.
+#
+# CONFIG_USE_STDINT makes sense only when
+# both <stdint.h> and <inttypes.h> are provided by the compiler.
+#
+TMP="$$"
+
+cat <<END | $@ -Werror -x c - -c -o $TMP >/dev/null 2>&1 && echo "y"
+#include <stdint.h>
+#include <inttypes.h>
+
+int main(void)
+{
+ return 0;
+}
+END
+
+rm -f $TMP
--
1.9.1
More information about the U-Boot
mailing list