GCC cross compiler for DOS produces linker errors for simple "Hello world!" in C - gcc

I've tried to configure GCC 9.3.0 to produce executable files for DOS. However, for a simple "Hello world!" program in C, it outputs:
/home/teo.samarzija/djgpp-9.3.0/lib/gcc/djgpp/9.3.0/../../../../djgpp/bin/ld: /home/teo.samarzija/djgpp-9.3.0/lib/gcc/djgpp/9.3.0/../../../../djgpp/lib/libc.a(crt1.o):crt1.c:(.text+0xd6): undefined reference to `_environ'
/home/teo.samarzija/djgpp-9.3.0/lib/gcc/djgpp/9.3.0/../../../../djgpp/bin/ld: /home/teo.samarzija/djgpp-9.3.0/lib/gcc/djgpp/9.3.0/../../../../djgpp/lib/libc.a(crt1.o):crt1.c:(.text+0x10b): undefined reference to `_environ'
/home/teo.samarzija/djgpp-9.3.0/lib/gcc/djgpp/9.3.0/../../../../djgpp/bin/ld: /home/teo.samarzija/djgpp-9.3.0/lib/gcc/djgpp/9.3.0/../../../../djgpp/lib/libc.a(crt1.o):crt1.c:(.text+0x131): undefined reference to `_environ'
/home/teo.samarzija/djgpp-9.3.0/lib/gcc/djgpp/9.3.0/../../../../djgpp/bin/ld: /home/teo.samarzija/djgpp-9.3.0/lib/gcc/djgpp/9.3.0/../../../../djgpp/lib/libc.a(crt1.o):crt1.c:(.text+0x141): undefined reference to `_environ'
/home/teo.samarzija/djgpp-9.3.0/lib/gcc/djgpp/9.3.0/../../../../djgpp/bin/ld: /home/teo.samarzija/djgpp-9.3.0/lib/gcc/djgpp/9.3.0/../../../../djgpp/lib/libc.a(crt1.o):crt1.c:(.text+0x3d4): undefined reference to `_environ'
/home/teo.samarzija/djgpp-9.3.0/lib/gcc/djgpp/9.3.0/../../../../djgpp/bin/ld: /home/teo.samarzija/djgpp-9.3.0/lib/gcc/djgpp/9.3.0/../../../../djgpp/lib/libc.a(getenv.o):getenv.c:(.text+0x4): more undefined references to `_environ' follow
collect2: error: ld returned 1 exit status
djgpp-gcc -v outputs:
Using built-in specs.
COLLECT_GCC=djgpp-gcc
COLLECT_LTO_WRAPPER=/home/teo.samarzija/djgpp-9.3.0/libexec/gcc/djgpp/9.3.0/lto-wrapper
Target: djgpp
Configured with: ../gcc-9.3.0/configure --target=djgpp --prefix=/home/teo.samarzija/djgpp-9.3.0 --enable-languages=c,c++,objc,ada,fortran,go
Thread model: single
gcc version 9.3.0 (GCC)
I've also compiled the newest version of the GNU linker and GNU Assembler, they output as their versions:
GNU ld (GNU Binutils) 2.34
Copyright (C) 2020 Free Software Foundation, Inc.
This program is free software; you may redistribute it under the terms of
the GNU General Public License version 3 or (at your option) a later version.
This program has absolutely no warranty.
and
GNU assembler (GNU Binutils) 2.34
Copyright (C) 2020 Free Software Foundation, Inc.
This program is free software; you may redistribute it under the terms of
the GNU General Public License version 3 or later.
This program has absolutely no warranty.
This assembler was configured for a target of `djgpp'.
Any idea what I am doing wrong? Have GCC or GAS or GLD stopped supporting DOS some time in the past? I suppose not, because they compile for DOS as a target without warning about that.

I only stumbled on this question because of a more recent Stackoverflow question you asked about some code that didn't run properly in 32-bit Windows 10 inside an NTVDM virtual DOS session.
The problem is that you have not properly built a DJGPP cross compiler and all the needed components. You do not show us what commands you use for the build process and which versions of the dependencies were used and where they came from.
1st thing you need to do is build a DJGPP cross compiler. There are some people who maintain scripts to do just that. One build environment/script in particular I have used successfully is from the user Andrew Wu on Github. It is very simple to use. It appears you are using a Unix type environment based on the output you have shown us. Since you managed to build DJGPP (albeit one that doesn't work) I will assume you have all the necessary build tools installed already. First retrieve the scripts with:
git clone https://github.com/andrewwutw/build-djgpp
Change into the project directory with:
cd build-djgpp
Review the README.md file! It tells you what versions are supported by the script, build requirements for the type of OS you are on etc. At present they support versions all the way to 10.1.0. If you have everything needed choose a version to build (I'll use 9.3.0 since it is the version you are using) and then start the build. You will have to build as root or use sudo as it installs to directory /usr/local/djgpp
./build-djgpp.sh 9.3.0
It will take a while but when finished it should be installed and ready to use. The naming convention is a bit different than prefixing the commands with djgpp-. This script builds things with a more complete target prefix i586-pc-msdosdjgpp-
To add it to your path and set up other environment variables use:
. /usr/local/djgpp/setenv
If you wish it to be done each time you are logged in add that line to your shell login script. For BASH that is in the file ~/.bashrc
Create a file called hello.c containing:
#include<stdio.h>
int main()
{
printf("Hello, world!\n");
}
Compile it to a file called hello.exe:
i586-pc-msdosdjgpp-gcc -O3 -Wall -Wextra hello.c -o hello.exe
Assuming you have a DPMI host installed (like CWSDPMI.EXE), hello.exe should run in MS-DOS, FreeDOS, DOSBox, a Windows NTVDM session etc. When run it should display:
Hello, world!
If you don't wish to build from scratch, Andrew Wu has a number of pre-built packages for a number of the latest DJGPP releases. Platforms they are available for are MacOS, Linux 32, Linux 64, MinGW, and a MinGW standalone version that doesn't need the MinGW environment to run.

Related

gcc mismatched-tags option giving `unrecognized command line option`

I was trying to activate the option -Wmismatched-tags on gcc (detect inconsistent class/struct declaration, which might happens when using forward declaration), but on Ubuntu I get
c++: error: unrecognized command line option '-Wmismatched-tags'
My gcc version:
# gcc --version
gcc (Ubuntu 9.3.0-17ubuntu1~20.04) 9.3.0
Copyright (C) 2019 Free Software Foundation, Inc.
Looking here it seems like it was integrated in gcc 4.9.0
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=61339
Am I doing something wrong, or is the option actually not available anymore?
I am aware of Can GCC produce struct/class name mismatches like VS?, however the answer is 10 years old and I was hoping things had improved in the meantime.
Background: I need this in a project where we also build with clang, and where these inconsistencies are treated as error.
Looking here it seems like it was integrated in gcc 4.9.0
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=61339
Actually, it doesn't. It was reported in 2014 but as OP explained in
#5th post:
I can't speak for MS, but the original warning I posted was produced
by clang. It does seem to worry about mismatched tags.
In gcc -Wmismatched-tags was introduced only in December 2019 and
became a part of GCC 10 release:
$ git describe e8f1ade269a39ea86a76a2440818e1512ed480ee
basepoints/gcc-10-5517-ge8f1ade269a
Luckily, these days we have docker and official GCC releases are
officially distributed as docker images:
$ docker search gcc
NAME DESCRIPTION STARS OFFICIAL AUTOMATED
gcc The GNU Compiler Collection is a compiling s… 587 [OK]
(...)
so you can just do:
docker run --rm -it gcc
and either mount your source directory into the docker container or
use TRAMP integration for docker
containers or any other
preferred tool to put your code into the container and use the newest gcc inside it:
root#53d309d5d619:/# g++ --version
g++ (GCC) 10.2.0
Copyright (C) 2020 Free Software Foundation, Inc.
This is free software; see the source for copying conditions. There is NO
warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
root#53d309d5d619:/# g++ hello.cpp -o hello -Wmismatched-tags

GDB Compilation Issue

I have run in an issue with compiling gdb from source. I am downloading version 8.2.1 but when I try to compile it, I get the following error:
configure: error: *** A compiler with support for C++11 language features is required.
make[1]: *** [configure-gdb] Error 1
My operating system is Red Hat 7.6 (Maipo) but i have a compiled from source gcc(that i set as the default one with an alias in bashrc)
gcc --version
gcc (GCC) 8.2.0
Copyright (C) 2018 Free Software Foundation, Inc.
which gcc
alias gcc='/usr/local/gcc8.2/bin/gcc'
/usr/local/gcc8.2/bin/gcc
which g++
alias g++='/usr/local/gcc8.2/bin/g++'
/usr/local/gcc8.2/bin/g++
What i have tried/read so far
Read the gdb manual regarding the configure and instalation part, also various stackoverflow links but nobody seems to have this problem
Read the README file in the gdb folder/subfolders
Tried setting the following env options CXX_FOR_TARGET=/usr/local/gcc8.2/bin/g++ GCC_FOR_TARGET=/usr/local/gcc8.2/bin/gcc (not sure if i should replace target with my actual target architecture)
Looked in the gdb-8.2.1 folder at the file config.log and found these: ac_cv_env_GCC_FOR_TARGET_value=/usr/local/gcc8.2/bin/gcc
ac_cv_prog_CXX_FOR_TARGET=/usr/local/gcc8.2/bin/g++
ac_cv_prog_GCC_FOR_TARGET=/usr/local/gcc8.2/bin/gcc
However in the C compiler section of the same config log I have found the following:
configure:4284: checking for C compiler version
configure:4293: gcc --version >&5
gcc (GCC) 4.8.5 20150623 (Red Hat 4.8.5-36)
Copyright (C) 2015 Free Software Foundation, Inc.
This is free software; see the source for copying conditions. There is NO
warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
I am not sure ifi can use the devtoolset-8 gdb from RedHat because i have compiled gcc with GLIBCXX_USE_CXX11_ABI=1 and on RedHat due to a bug this is disabled by default and i am not sure if gdb will be able to manage the different binary interface.
Short version: What am I doing wrong that is making the GDB configure script not find the correct compiler and how can i fix/workaround this?
Thank you very much for your help!
A C++11-capable compiler for Red Hat Enterprise Linux 7 is provided as part of Red Hat Developer Toolset. It happens to include not just GCC 8, but GDB 8.2 as well, so you may not even have to compile it yourself. The DTS C++ compiler has been built in a special way so that it interoperates with the system C++ runtime. Unless you have replicated those modifications in your GCC build, it will not be compatible with the rest of the system (and you will have to replace the system libstdc++ library).
The system compiler in Red Hat Enterprise Linux 7 is based on GCC 4.8. In that version, C++11 support was still experimental and not enabled by default. You can try to configure GDB with
./configure CXX="g++ -std=gnu+11"
but this is not recommended (only the C++98 mode is supported).
The configure script does not use shell aliases because those are not inherited by shell scripts invoked from a shell. You will have to specify the full path to the C++ compiler explicitly (in the CXX= argument to configure), or adjust the PATH environment variable manually, or use scl enable to do so in a more polished fashion (for software collections such as Developer Toolset).

how does "make" determine which linker to use?

I wanted to upgrade to binutils 2.26 , so i followed the steps here : How to convert default binutils into binutils-2.26? to solve the same "unrecognized relocation" error.
Now my default linker is 2.26
$ ld --version
GNU ld (GNU Binutils for Ubuntu) 2.26.1
Copyright (C) 2015 Free Software Foundation, Inc.
This program is free software; you may redistribute it under the terms of
the GNU General Public License version 3 or (at your option) a later version.
This program has absolutely no warranty.
But "make" still uses the "/usr/bin/x86_64-linux-gnu-ld" (which is 2.24) and still gives the same error.
So how to force "make" to use the default linker ?
It depends upon your Makefile (which you could debug with remake -x). Notice that make has a lot of builtin rules. Use make -p to also print them. Notice the rules mentioning LINK.c or LINK.cc etc, and notice that LD is not much used. Notice also that ld is almost never used directly (most of the time, some other program like gcc or g++ runs it).
And it is also a matter of the PATH variable. So try setting it so that your new ld comes before the old one.
Generally, you link with the gcc or g++ program (so it is GCC which matters, not make; read about Invoking GCC and its -fuse-ld=), and that gcc or g++ will run the linker (you might, but I don't recommend to, change its spec file which governs what actual programs are run by gcc or g++ which are only drivers to other programs such as cc1, as, ld, collect2 etc...). To understand what programs gcc or g++ is running, pass it the -v flag.
But "make" still uses the "/usr/bin/x86_64-linux-gnu-ld" (which is 2.24) and still gives the same error.
On my Debian system /usr/bin/x86_64-linux-gnu-ld (it is generally started by gcc, not directly by make) is a symlink. You might (but I don't recommend that) just change that symlink.
BTW, you are using an ancient Ubuntu 14. You'll better upgrade your entire distribution (e.g. to Ubuntu 18.04.1 LTS at end of 2018), because there is not only ld but many other programs which are really old on your system.
Upgrading your distribution will take less time than upgrading, compiling, installing and configuring each individual tool.

Synology DSM6 - libc.so.6 - File format not recognized

My final goal is to install Nagios on my Synology DiskStation DS1813+ with DSM 6.0.1-7393 Update 1. But I can't even begin compiling the package...
When I try to use gcc on my Synology DiskStation I always get the following error message:
$ gcc hello.c -o hello.o
/lib/libc.so.6: file not recognized: File format not recognized
collect2: ld returned 1 exit status
Here's my shell environment. I have tried it with different LD_LIBRARY_PATH settings, but even omitting it doesn't make a difference.
$ env
TERM=xterm-256color
SHELL=/bin/sh
SSH_CLIENT=192.168.2.110 51079 22
OLDPWD=/var/services/homes/egi
SSH_TTY=/dev/pts/7
LC_ALL=en_US.utf8
USER=egi
LD_LIBRARY_PATH=/opt/lib:
PAGER=more
MAIL=/var/mail/egi
PATH=/opt/sbin:/opt/bin:/sbin:/bin:/usr/sbin:/usr/bin
PWD=/var/services/homes/egi/exer
LANG=en_US.utf8
PS1=[\u#\h \W]$
SHLVL=1
HOME=/var/services/homes/egi
TERMINFO=/usr/share/terminfo
LOGNAME=shunyam
SSH_CONNECTION=xxx.xxx.xxx.xxx 51079 yyy.yyy.yyy.yyy 22
PGDATA=/var/services/pgsql
CC=gcc
_=/opt/bin/env
The compiler has been installed with ipkg and its specs look like this:
$ gcc --verbose
Using built-in specs.
Target: i686-linux-gnu
Configured with: ../gcc-4.2.1/configure --build=i386-pc-linux-gnu --host=i686-linux-gnu --target=i686-linux-gnu --prefix=/opt --disable-nls --disable-static --with-as=/home/slug/optware/syno-i686/toolchain/gcc-4.2.1-glibc-2.3.6/i686-linux-gnu/bin/i686-linux-gnu-as --with-ld=/home/slug/optware/syno-i686/toolchain/gcc-4.2.1-glibc-2.3.6/i686-linux-gnu/bin/i686-linux-gnu-ld --enable-languages=c,c++ --disable-multilib
Thread model: posix
gcc version 4.2.1
The library that causes the problem returns this information:
$ /lib/libc.so.6
GNU C Library (crosstool-NG 1.20.0) stable release version 2.20-2014.11, by Roland McGrath et al.
Copyright (C) 2014 Free Software Foundation, Inc.
This is free software; see the source for copying conditions.
There is NO warranty; not even for MERCHANTABILITY or FITNESS FOR A
PARTICULAR PURPOSE.
Compiled by GNU CC version 4.9.3 20150311 (prerelease).
Available extensions:
crypt add-on version 2.1 by Michael Glad and others
GNU Libidn by Simon Josefsson
Native POSIX Threads Library by Ulrich Drepper et al
BIND-8.2.3-T5B
libc ABIs: UNIQUE IFUNC
For bug reporting instructions, please see:
<http://www.gnu.org/software/libc/bugs.html>.
There is also a linker script at /opt/lib/libc.so:
$ cat /opt/lib/libc.so
/* GNU ld script
Use the shared library, but some functions are only in
the static library, so try that secondarily. */
OUTPUT_FORMAT(elf32-i386)
GROUP ( /lib/libc.so.6 /opt/lib/libc_nonshared.a )
The library can't actually be broken, otherwise nothing would work at all.
Alongside with gcc all other required packages have also been installed with ipkg.
Weirdly enough I seem to be the only person with that issue as I have found no relevant posts on Google. Synology's support told me that they are not supporting installing command command line packages.
When I first installed gcc on this Diskstation about two years ago, everything was working fine. I have noticed this problem a few months ago (probably after a DSM update).
Has anyone also come across this issue or has a clue on how to get it working again? Thanks!
I had this exact same problem. GCC use to work and now with DSM 6.1 it broke. I think it's after they switched to 64-bit with DSM 6.0 I believe. Your question actually gave me the answer so I wanted to share it here. I changed /lib/libc.so.6 to /lib32/libc.so.6 in the file /opt/lib/libc.so.
$ cat /opt/lib/libc.so
/* GNU ld script
Use the shared library, but some functions are only in
the static library, so try that secondarily. */
OUTPUT_FORMAT(elf32-i386)
GROUP ( /lib32/libc.so.6 /opt/lib/libc_nonshared.a )
After making the change above optware GCC compiled my test file without any environment variables set just like you would expect on a normal Linux system.
It looks like I've been using some other g++:
/volume1/homes/user/x86_64-pc-linux-gnu/bin/x86_64-pc-linux-gnu-g++
It came from this file: gcc473_glibc217_x86_64_cedarview-GPL.tgz.
Other people have problems too with DSM 6: https://forum.synology.com/enu/viewtopic.php?t=116803
It's suggested to use the Debian Chroot Package from SynoCommunity instead.
You just have to change lib by lib32 like this :
cat /opt/lib/libc.so
/* GNU ld script
Use the shared library, but some functions are only in
the static library, so try that secondarily. */
OUTPUT_FORMAT(elf32-i386)
GROUP ( /lib32/libc.so.6 /opt/lib/libc_nonshared.a )

How to choose the assembler GCC uses?

Is there an option to GCC that changes the path of the assembler it uses? I'm getting errors from Solaris /usr/ccs/bin/as when using GCC to attempt to compile Haskell, but I've got a copy of GNU as in my path so when I type which as and as --version they use the GNU version, not the Solaris version. Unfortunately it seems GCC ignores the GNU version in the path and goes to the Solaris version. I'm trying to build Haskell on Solaris and I don't think it sits well with the Solaris assembler. I hope I can change this behaviour with a simple wrapper script so I don't have to recompile GCC.
Specifying the assembler to be used is not possible at run time. It has to be done when configuring gcc:
--with-gnu-as
Specify that the compiler should assume that the assembler it finds is the GNU
assembler. However, this does not modify the rules to find an assembler and will
result in confusion if the assembler found is not actually the GNU assembler.
(Confusion may also result if the compiler finds the GNU assembler but has not
been configured with --with-gnu-as.)
Note the part I've put in italics. Of course you could temporarily change /usr/ccs/bin/as to call the gnu assembler (provided you have the necessary permissions), but the above seems to suggest that you'll very likely run into problems. The gcc build process actually checks the features the assembler supports and generates code for exactly that assembler.
I suggest you build a new version of gcc first (configured to use the gnu tools), and then use that to build ghc.

Resources