Rev 2 | Rev 4 | Go to most recent revision | Show entire file | Ignore whitespace | Details | Blame | Last modification | View Log | RSS feed
Rev 2 | Rev 3 | ||
---|---|---|---|
Line 14... | Line 14... | ||
14 | export BINUTILS_VERSION="2.41" # version of GNU binutils that will be built. Should match the Win32 and Linux tools. |
14 | export BINUTILS_VERSION="2.41" # version of GNU binutils that will be built. Should match the Win32 and Linux tools. |
15 | 15 | ||
16 | export BINUTILS_SOURCES_FILE="binutils-${BINUTILS_VERSION}.tar.gz" # name of the file containing GNU binutils version BINUTILS_VERSION sources |
16 | export BINUTILS_SOURCES_FILE="binutils-${BINUTILS_VERSION}.tar.gz" # name of the file containing GNU binutils version BINUTILS_VERSION sources |
17 | export BINUTILS_SOURCES_URL="https://ftp.gnu.org/gnu/binutils/${BINUTILS_SOURCES_FILE}" # download URL of BINUTILS_SOURCES_FILE |
17 | export BINUTILS_SOURCES_URL="https://ftp.gnu.org/gnu/binutils/${BINUTILS_SOURCES_FILE}" # download URL of BINUTILS_SOURCES_FILE |
18 | export BINUTILS_SOURCES_DIR="binutils-${BINUTILS_VERSION}" # name of directory created when extracting BINUTILS_SOURCES_FILE |
18 | export BINUTILS_SOURCES_DIR="binutils-${BINUTILS_VERSION}" # name of directory created when extracting BINUTILS_SOURCES_FILE |
- | 19 | ||
- | 20 | export REQUIRED_TOOLS="wget python3 gcc g++ make m4" # list of build tools required to build all this on the build host |
|
19 | 21 | ||
20 | # see where we are |
22 | # see where we are |
21 | export CURRENT_DIR="$(pwd)" |
23 | export CURRENT_DIR="$(pwd)" |
22 | 24 | ||
23 |
|
25 | print_error_and_die() |
- | 26 | { |
|
24 |
|
27 | # a handy function that does what it says. Args: error strings to print, one line per argument |
- | 28 | test -z "${COLUMNS}" && COLUMNS=80 |
|
25 | echo "" |
29 | echo "" |
- | 30 | while [ -n "${1}" ]; do |
|
26 |
|
31 | echo "${1}"|fold -s -w "${COLUMNS}" |
- | 32 | shift |
|
- | 33 | done |
|
27 | echo "" |
34 | echo "" |
28 | exit 1 |
35 | exit 1 |
- | 36 | } |
|
- | 37 | ||
- | 38 | # verify we're a x86_64 Linux host |
|
- | 39 | if [ ! "$(uname)" = "Linux" ] || [ ! "$(uname -m)" = "x86_64" ]; then |
|
- | 40 | print_error_and_die "Error: this script requires a x86_64 Linux machine (possibly a virtual machine) as the build host." |
|
29 | fi |
41 | fi |
30 | 42 | ||
31 | # verify that we have the QNX platform SDK |
43 | # verify that we have the QNX platform SDK |
32 | if [ ! -d "${QNXSDK_PATH}/${QNXSDK_HOSTPATH}" ] || [ ! -d "${QNXSDK_PATH}/${QNXSDK_TARGETPATH}" ]; then |
44 | if [ ! -d "${QNXSDK_PATH}/${QNXSDK_HOSTPATH}" ] || [ ! -d "${QNXSDK_PATH}/${QNXSDK_TARGETPATH}" ]; then |
33 | echo "" |
- | |
34 |
|
45 | print_error_and_die "Error: the ${QNXSDK_PATH} path doesn't contain a QNX SDK. It must contain the 'host' and 'target' directories of the QNX SDP for the targeted version of QNX and the ${BUILD_TARGET_ARCH} platform. Please deploy these directories and try again." |
35 | echo "" |
- | |
36 | exit 1 |
- | |
37 | fi |
46 | fi |
38 | 47 | ||
39 | # verify that we have |
48 | # verify that we have the required tools |
40 |
|
49 | for REQUIRED_TOOL in ${REQUIRED_TOOLS}; do |
41 | || ! python3 --version > /dev/null 2>&1 \ |
- | |
42 | || ! make --version > /dev/null 2>&1 \ |
- | |
43 | || ! gcc --version > /dev/null 2>&1 \ |
- | |
44 | || ! g++ --version > /dev/null 2>&1 \ |
- | |
45 |
|
50 | "${REQUIRED_TOOL}" --version > /dev/null 2>&1 || print_error_and_die \ |
46 | echo "" |
- | |
47 |
|
51 | "Error: this script requires at the very least the following tools installed:" \ |
48 |
|
52 | " $(echo "${REQUIRED_TOOLS}"|sed 's/ /\n /g')" \ |
49 | echo " python3" |
- | |
50 | echo " make" |
- | |
51 | echo " gcc" |
- | |
52 | echo " g++" |
- | |
53 | echo " m4" |
- | |
54 |
|
53 | "Please install them (possibly as binary packages with apt-get) and try again." \ |
55 |
|
54 | "More specifically, the following tool was not found: '${REQUIRED_TOOL}'" |
56 | exit 1 |
- | |
57 |
|
55 | done |
58 | 56 | ||
59 | # verify that the symlinks are deployed in the SDK -- just test one of them |
57 | # verify that the symlinks are deployed in the SDK -- just test one of them |
60 | if [ ! -e "${QNXSDK_PATH}/${QNXSDK_TARGETPATH}/usr/include/readline.h" ]; then |
58 | if [ ! -e "${QNXSDK_PATH}/${QNXSDK_TARGETPATH}/usr/include/readline.h" ]; then |
61 |
|
59 | print_error_and_die \ |
62 |
|
60 | "Error: the toolchain platform-specific symbolic links have not been deployed in this QNX SDK. Please run" \ |
63 |
|
61 | "(on a POSIX machine:)" \ |
64 |
|
62 | " cd ${QNXSDK_PATH}" \ |
65 |
|
63 | " find . -name symlinks.lst -exec ./symlinks.sh {} create \\; && printf 'present' > .symlinks-state" \ |
66 |
|
64 | "(else on a Windows machine:)" \ |
67 |
|
65 | " cd ${QNXSDK_PATH}" \ |
68 | echo " host\\win64\\x86_64\\usr\\bin\\busybox.exe sh -c \"" \ |
- | |
69 | "find . -name symlinks.lst -exec ./symlinks.sh {} create \\; && printf 'present' > .symlinks-state" \ |
66 | " host\\win64\\x86_64\\usr\\bin\\busybox.exe sh -c \"find . -name symlinks.lst -exec ./symlinks.sh {} create \\; && printf 'present' > .symlinks-state\"" \ |
70 | "\"" | fold -s -w 79 |
- | |
71 |
|
67 | "Note that this step WILL take time on a Win32 machine, but is only done once." |
72 | echo "" |
- | |
73 | exit 1 |
- | |
74 | fi |
68 | fi |
75 | 69 | ||
76 | # create a symlink in /tmp that will lead to the QNX platform SDK so as to avoid spaces in paths if it doesn't exist already |
70 | # create a symlink in /tmp that will lead to the QNX platform SDK so as to avoid spaces in paths if it doesn't exist already |
77 | # (this is totally prohibitive with the official QNX toolchain) |
71 | # (this is totally prohibitive with the official QNX toolchain) |
78 | if [ ! -L /tmp/qnxsdk ] || [ ! "$(readlink /tmp/qnxsdk)" = "$(realpath "${CURRENT_DIR}/${QNXSDK_PATH}")" ]; then |
72 | if [ ! -L /tmp/qnxsdk ] || [ ! "$(readlink /tmp/qnxsdk)" = "$(realpath "${CURRENT_DIR}/${QNXSDK_PATH}")" ]; then |
Line 150... | Line 144... | ||
150 | 144 | ||
151 | backup_and_patch_if_necessary() |
145 | backup_and_patch_if_necessary() |
152 | { |
146 | { |
153 | # handy function that patches a file in the current directory with a given sed replacement regex if necessary, creating backups |
147 | # handy function that patches a file in the current directory with a given sed replacement regex if necessary, creating backups |
154 | # args: <file pathname> <grep_string_to_test_for_presence_of_patch> <sed regex> |
148 | # args: <file pathname> <grep_string_to_test_for_presence_of_patch> <sed regex> |
- | 149 | _PATCHEE_PATHNAME="${1}" |
|
- | 150 | _PATCHED_PATTERN="${2}" |
|
155 | # test if already patched |
151 | # test if already patched |
156 | grep -q "${ |
152 | grep -q "${_PATCHED_PATTERN}" "${_PATCHEE_PATHNAME}" && return |
157 | # tell what we're about to do |
153 | # tell what we're about to do |
158 | echo "Patching ${ |
154 | echo "Patching ${_PATCHEE_PATHNAME}..." |
- | 155 | _DOTTED_NAME="$(echo "${_PATCHEE_PATHNAME}"|tr '/' '.')" |
|
159 | # have a backup first |
156 | # have a backup first |
160 | test -f "${CURRENT_DIR}/ |
157 | test -f "${CURRENT_DIR}/${_DOTTED_NAME} [ORIGINAL]" || cp "${_PATCHEE_PATHNAME}" "${CURRENT_DIR}/${_DOTTED_NAME} [ORIGINAL]" || exit 1 |
161 | # perform the patch |
158 | # perform the patch |
162 |
|
159 | cp -f "${CURRENT_DIR}/${_DOTTED_NAME} [ORIGINAL]" "${CURRENT_DIR}/${_DOTTED_NAME} [PATCHED]" || exit 1 |
- | 160 | while [ -n "${3}" ]; do |
|
- | 161 | sed -E -i "${3}" "${CURRENT_DIR}/${_DOTTED_NAME} [PATCHED]" |
|
- | 162 | shift |
|
- | 163 | done |
|
163 | # verify that we did it successfully |
164 | # verify that we did it successfully |
164 | if ! grep -q "${ |
165 | if ! grep -q "${_PATCHED_PATTERN}" "${CURRENT_DIR}/${_DOTTED_NAME} [PATCHED]"; then |
165 | echo "Error: the file ${ |
166 | echo "Error: the file ${_PATCHEE_PATHNAME} could not be patched. Please investigate and fix manually." | fold -s -w 79; exit 1 |
166 | fi |
167 | fi |
167 | # and put the patched file in place |
168 | # and put the patched file in place |
168 | cp -f "${CURRENT_DIR}/ |
169 | cp -f "${CURRENT_DIR}/${_DOTTED_NAME} [PATCHED]" "${_PATCHEE_PATHNAME}" || exit 1 |
169 | } |
170 | } |
170 | backup_and_replace() |
171 | backup_and_replace() |
171 | { |
172 | { |
172 | # handy function that replaces a file in the current directory with a given replacement, creating backups |
173 | # handy function that replaces a file in the current directory with a given replacement, creating backups |
173 | # args: <file pathname> <replacement pathname> |
174 | # args: <file pathname> <replacement pathname> |
Line 178... | Line 179... | ||
178 | # perform the replacement |
179 | # perform the replacement |
179 | cp -f "${2}" "${1}" || exit 1 |
180 | cp -f "${2}" "${1}" || exit 1 |
180 | } |
181 | } |
181 | 182 | ||
182 | # patch libiberty/pex-unix.c |
183 | # patch libiberty/pex-unix.c |
- | 184 | # replace: |
|
- | 185 | # defined(HAVE_SPAWNVE) |
|
- | 186 | # with: |
|
- | 187 | # !defined(__QNXNTO__) && defined(HAVE_SPAWNVE) |
|
183 | # RATIONALE: QNX exposes the same spawnve() functions which were invented by Microsoft. Autoconf mistakenly believes it's a Cygwin system. |
188 | # RATIONALE: QNX exposes the same spawnve() functions which were invented by Microsoft. Autoconf mistakenly believes it's a Cygwin system. |
184 | # Moreover the flags _P_NOWAIT and _P_NOWAITO don't have the same meaning on QNX: the second one doesn't create zombies waiting for their exit |
189 | # Moreover the flags _P_NOWAIT and _P_NOWAITO don't have the same meaning on QNX: the second one doesn't create zombies waiting for their exit |
185 | # status to be read, whereas on Microsoft they're the same. This prevents process created with this flag (as libiberty does) from being wait()ed. |
190 | # status to be read, whereas on Microsoft they're the same. This prevents process created with this flag (as libiberty does) from being wait()ed. |
186 | # Fix that by declaring that we want to use the traditional POSIX fork/exec |
191 | # Fix that by declaring that we want to use the traditional POSIX fork/exec scheme, which QNX supports as well. |
- | 192 | backup_and_patch_if_necessary "libiberty/pex-unix.c" __QNXNTO__ \ |
|
187 |
|
193 | 's@defined\(HAVE_SPAWNVE\)@\!defined\(__QNXNTO__\) \&\& defined\(HAVE_SPAWNVE\)@g' |
188 | 194 | ||
189 | # patch bfd/config.bfd |
195 | # patch bfd/config.bfd |
190 | # RATIONALE: insert x86_64 and aarch64 QNX definitions for the BFD library |
196 | # RATIONALE: insert x86_64 and aarch64 QNX definitions for the BFD library |
191 | backup_and_replace "bfd/config.bfd" "${CURRENT_DIR}/bfd.config.bfd" |
197 | backup_and_replace "bfd/config.bfd" "${CURRENT_DIR}/bfd.config.bfd" |
192 | 198 | ||
Line 271... | Line 277... | ||
271 | 277 | ||
272 | # return to the sources dir and proceed to the next arch |
278 | # return to the sources dir and proceed to the next arch |
273 | cd ../.. |
279 | cd ../.. |
274 | done |
280 | done |
275 | 281 | ||
276 |
|
282 | /bin/printf "\n\xf0\x9f\x8d\xba\x20\x43\x68\x65\x65\x72\x73\x2e\n" |
277 | exit 0 |
283 | exit 0 |