ext-tool.mk 8.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232
  1. #
  2. # This file implements the support for external toolchains, i.e
  3. # toolchains that have not been produced by Buildroot itself and that
  4. # are already available on the system on which Buildroot runs.
  5. #
  6. # The basic principle is the following
  7. #
  8. # 1. Perform some checks on the conformity between the toolchain
  9. # configuration described in the Buildroot menuconfig system, and the
  10. # real configuration of the external toolchain. This is for example
  11. # important to make sure that the Buildroot configuration system
  12. # knows whether the toolchain supports RPC, IPv6, locales, large
  13. # files, etc. Unfortunately, these things cannot be detected
  14. # automatically, since the value of these options (such as
  15. # BR2_INET_RPC) are needed at configuration time because these
  16. # options are used as dependencies for other options. And at
  17. # configuration time, we are not able to retrieve the external
  18. # toolchain configuration.
  19. #
  20. # 2. Copy the libraries needed at runtime to the target directory,
  21. # $(TARGET_DIR). Obviously, things such as the C library, the dynamic
  22. # loader and a few other utility libraries are needed if dynamic
  23. # applications are to be executed on the target system.
  24. #
  25. # 3. Copy the libraries and headers to the staging directory. This
  26. # will allow all further calls to gcc to be made using --sysroot
  27. # $(STAGING_DIR), which greatly simplifies the compilation of the
  28. # packages when using external toolchains. So in the end, only the
  29. # cross-compiler binaries remains external, all libraries and headers
  30. # are imported into the Buildroot tree.
  31. #
  32. # Copy a toolchain library and its symbolic links from the sysroot
  33. # directory to the target directory. Also optionaly strips the
  34. # library.
  35. #
  36. # $1: sysroot directory
  37. # $2: library name
  38. # $3: destination directory
  39. # $4: strip (y|n), default is to strip
  40. #
  41. copy_toolchain_lib_root = \
  42. SYSROOT_DIR="$(strip $1)"; \
  43. LIB="$(strip $2)"; \
  44. DST="$(strip $3)"; \
  45. STRIP="$(strip $4)"; \
  46. \
  47. LIB_DIR="$${SYSROOT_DIR}/lib" ; \
  48. for FILE in `find $${LIB_DIR} -maxdepth 1 -name "$${LIB}.*"`; do \
  49. LIB=`basename $${FILE}`; \
  50. while test \! -z "$${LIB}"; do \
  51. rm -fr $(TARGET_DIR)$${DST}/$${LIB}; \
  52. mkdir -p $(TARGET_DIR)$${DST}; \
  53. if test -h $${LIB_DIR}/$${LIB}; then \
  54. cp -d $${LIB_DIR}/$${LIB} $(TARGET_DIR)$${DST}/; \
  55. elif test -f $${LIB_DIR}/$${LIB}; then \
  56. $(INSTALL) -D -m0755 $${LIB_DIR}/$${LIB} $(TARGET_DIR)$${DST}/$${LIB}; \
  57. case "$${STRIP}" in \
  58. (0 | n | no) \
  59. ;; \
  60. (*) \
  61. $(TARGET_CROSS)strip "$(TARGET_DIR)$${DST}/$${LIB}"; \
  62. ;; \
  63. esac; \
  64. else \
  65. exit -1; \
  66. fi; \
  67. LIB="`readlink $${LIB_DIR}/$${LIB}`"; \
  68. done; \
  69. done; \
  70. \
  71. echo -n
  72. #
  73. # Copy the full external toolchain sysroot directory to the staging
  74. # dir
  75. #
  76. # $1: sysroot directory
  77. #
  78. copy_toolchain_sysroot = \
  79. SYSROOT_DIR="$(strip $1)"; \
  80. cp -a $${SYSROOT_DIR}/* $(STAGING_DIR)/ ; \
  81. find $(STAGING_DIR) -type d | xargs chmod 755
  82. #
  83. # Check the availability of a particular glibc feature. We assume that
  84. # all Buildroot toolchain options are supported by glibc, so we just
  85. # check that they are enabled.
  86. #
  87. # $1: Buildroot option name
  88. # $2: feature description
  89. #
  90. check_glibc_feature = \
  91. if [ x$($(1)) != x"y" ] ; then \
  92. echo "$(2) available in C library, please enable $(1)" ; \
  93. exit 1 ; \
  94. fi
  95. #
  96. # Check the correctness of a glibc external toolchain configuration.
  97. # 1. Check that the C library selected in Buildroot matches the one
  98. # of the external toolchain
  99. # 2. Check that all the C library-related features are enabled in the
  100. # config, since glibc always supports all of them
  101. #
  102. # $1: sysroot directory
  103. #
  104. check_glibc = \
  105. SYSROOT_DIR="$(strip $1)"; \
  106. if ! test -f $${SYSROOT_DIR}/lib/ld-linux.so.* ; then \
  107. echo "Incorrect selection of the C library"; \
  108. exit -1; \
  109. fi; \
  110. $(call check_glibc_feature,BR2_LARGEFILE,Large file support) ;\
  111. $(call check_glibc_feature,BR2_INET_IPV6,IPv6 support) ;\
  112. $(call check_glibc_feature,BR2_INET_RPC,RPC support) ;\
  113. $(call check_glibc_feature,BR2_ENABLE_LOCALE,Locale support) ;\
  114. $(call check_glibc_feature,BR2_USE_WCHAR,Wide char support) ;\
  115. $(call check_glibc_feature,BR2_PROGRAM_INVOCATION,Program invocation support)
  116. #
  117. # Check the conformity of Buildroot configuration with regard to the
  118. # uClibc configuration of the external toolchain, for a particular
  119. # feature.
  120. #
  121. # $1: uClibc macro name
  122. # $2: Buildroot option name
  123. # $3: uClibc config file
  124. # $4: feature description
  125. #
  126. check_uclibc_feature = \
  127. IS_IN_LIBC=`grep -q "\#define $(1) 1" $(3) && echo y` ; \
  128. if [ x$($(2)) != x"y" -a x$${IS_IN_LIBC} == x"y" ] ; then \
  129. echo "$(4) available in C library, please enable $(2)" ; \
  130. exit 1 ; \
  131. fi ; \
  132. if [ x$($(2)) == x"y" -a x$${IS_IN_LIBC} != x"y" ] ; then \
  133. echo "$(4) not available in C library, please disable $(2)" ; \
  134. exit 1 ; \
  135. fi
  136. #
  137. # Check the correctness of a uclibc external toolchain configuration
  138. # 1. Check that the C library selected in Buildroot matches the one
  139. # of the external toolchain
  140. # 2. Check that the features enabled in the Buildroot configuration
  141. # match the features available in the uClibc of the external
  142. # toolchain
  143. #
  144. # $1: sysroot directory
  145. #
  146. check_uclibc = \
  147. SYSROOT_DIR="$(strip $1)"; \
  148. if ! test -f $${SYSROOT_DIR}/lib/ld-uClibc.so.* ; then \
  149. echo "Incorrect selection of the C library"; \
  150. exit -1; \
  151. fi; \
  152. UCLIBC_CONFIG_FILE=$${SYSROOT_DIR}/usr/include/bits/uClibc_config.h ; \
  153. $(call check_uclibc_feature,__UCLIBC_HAS_LFS__,BR2_LARGEFILE,$${UCLIBC_CONFIG_FILE},Large file support) ;\
  154. $(call check_uclibc_feature,__UCLIBC_HAS_IPV6__,BR2_INET_IPV6,$${UCLIBC_CONFIG_FILE},IPv6 support) ;\
  155. $(call check_uclibc_feature,__UCLIBC_HAS_RPC__,BR2_INET_RPC,$${UCLIBC_CONFIG_FILE},RPC support) ;\
  156. $(call check_uclibc_feature,__UCLIBC_HAS_LOCALE__,BR2_ENABLE_LOCALE,$${UCLIBC_CONFIG_FILE},Locale support) ;\
  157. $(call check_uclibc_feature,__UCLIBC_HAS_WCHAR__,BR2_USE_WCHAR,$${UCLIBC_CONFIG_FILE},Wide char support) ;\
  158. $(call check_uclibc_feature,__UCLIBC_HAS_PROGRAM_INVOCATION_NAME__,BR2_PROGRAM_INVOCATION,$${UCLIBC_CONFIG_FILE},Program invocation support) ;\
  159. #
  160. # Check that the Buildroot configuration of the ABI matches the
  161. # configuration of the external toolchain.
  162. #
  163. check_arm_abi = \
  164. EXT_TOOLCHAIN_TARGET=$(shell LANG=C $(TARGET_CC) -v 2>&1 | grep ^Target | cut -f2 -d ' ') ; \
  165. if echo $${EXT_TOOLCHAIN_TARGET} | grep -q 'eabi$$' ; then \
  166. EXT_TOOLCHAIN_ABI="eabi" ; \
  167. else \
  168. EXT_TOOLCHAIN_ABI="oabi" ; \
  169. fi ; \
  170. if [ x$(BR2_ARM_OABI) == x"y" -a $${EXT_TOOLCHAIN_ABI} == "eabi" ] ; then \
  171. echo "Incorrect ABI setting" ; \
  172. exit 1 ; \
  173. fi ; \
  174. if [ x$(BR2_ARM_EABI) == x"y" -a $${EXT_TOOLCHAIN_ABI} == "oabi" ] ; then \
  175. echo "Incorrect ABI setting" ; \
  176. exit 1 ; \
  177. fi ; \
  178. #
  179. # Check that the cross-compiler given in the configuration exists
  180. #
  181. check_cross_compiler_exists = \
  182. if ! test -x $(TARGET_CC) ; then \
  183. echo "Cannot find cross-compiler $(TARGET_CC)" ; \
  184. exit 1 ; \
  185. fi ; \
  186. uclibc: dependencies $(STAMP_DIR)/ext-toolchain-installed
  187. EXTERNAL_LIBS=libc.so libcrypt.so libdl.so libgcc_s.so libm.so libnsl.so libpthread.so libresolv.so librt.so libutil.so
  188. ifeq ($(BR2_TOOLCHAIN_EXTERNAL_UCLIBC),y)
  189. EXTERNAL_LIBS+=ld-uClibc.so
  190. else
  191. EXTERNAL_LIBS+=ld-linux.so libnss_files.so libnss_dns.so
  192. endif
  193. ifeq ($(BR2_INSTALL_LIBSTDCPP),y)
  194. EXTERNAL_LIBS+=libstdc++.so
  195. endif
  196. SYSROOT_DIR=$(shell readlink -f $$(LANG=C $(TARGET_CC) -print-file-name=libc.a |sed -r -e 's:usr/lib/libc\.a::;'))
  197. $(STAMP_DIR)/ext-toolchain-installed:
  198. @echo "Checking external toolchain settings"
  199. $(Q)$(call check_cross_compiler_exists)
  200. ifeq ($(strip $(SYSROOT_DIR)),)
  201. @echo "External toolchain doesn't support --sysroot. Cannot use."
  202. exit 1
  203. endif
  204. ifeq ($(BR2_arm),y)
  205. $(Q)$(call check_arm_abi)
  206. endif
  207. ifeq ($(BR2_TOOLCHAIN_EXTERNAL_UCLIBC),y)
  208. $(Q)$(call check_uclibc,$(SYSROOT_DIR))
  209. else
  210. $(Q)$(call check_glibc,$(SYSROOT_DIR))
  211. endif
  212. mkdir -p $(TARGET_DIR)/lib
  213. @echo "Copy external toolchain libraries to target..."
  214. $(Q)for libs in $(EXTERNAL_LIBS); do \
  215. $(call copy_toolchain_lib_root,$(SYSROOT_DIR),$$libs,/lib,$(BR2_TOOLCHAIN_EXTERNAL_STRIP)); \
  216. done
  217. @echo "Copy external toolchain sysroot to staging..."
  218. $(Q)$(call copy_toolchain_sysroot,$(SYSROOT_DIR))
  219. @touch $@