acbecker / hotpants

hotpants
MIT License
43 stars 23 forks source link

GCC10.3 installation bug with its default -fno-common #5

Open chaorun opened 3 years ago

chaorun commented 3 years ago

I saw lots of thing like:

gcc  main.o vargs.o alard.o functions.o  -o hotpants -L. -lm -lcfitsio -funroll-loops -O3 -ansi -std=c99 -pedantic-errors -Wall -I. -D_GNU_SOURCE
/usr/bin/ld: vargs.o:(.bss+0x678): multiple definition of `image'; main.o:(.bss+0x678): first defined here
/usr/bin/ld: vargs.o:(.bss+0x680): multiple definition of `template'; main.o:(.bss+0x680): first defined here
/usr/bin/ld: vargs.o:(.bss+0x670): multiple definition of `outim'; main.o:(.bss+0x670): first defined here
/usr/bin/ld: vargs.o:(.bss+0x640): multiple definition of `tNoiseIm'; main.o:(.bss+0x640): first defined here
/usr/bin/ld: vargs.o:(.bss+0x638): multiple definition of `iNoiseIm'; main.o:(.bss+0x638): first defined here
/usr/bin/ld: vargs.o:(.bss+0x630): multiple definition of `tMaskIm'; main.o:(.bss+0x630): first defined here
/usr/bin/ld: vargs.o:(.bss+0x628): multiple definition of `iMaskIm'; main.o:(.bss+0x628): first defined here
/usr/bin/ld: vargs.o:(.bss+0x620): multiple definition of `kernelImIn'; main.o:(.bss+0x620): first defined here

And I found a solution in https://github.com/kr-colab/discoal/issues/21 which shows:

gcc 10 use -fno-common by defaualt. Adding -fcommon flag makes it work again.

This modify in makefile helps a lot. I wish somebody who uses the gcc-10 would see this issue.

kslong commented 1 year ago

I also see this error, and I understand the cause.

In the latest versions of gcc, this error is caused because variables are being defined in multiple places as the errors state. This is because variables are being initialized in the .h files, and these .h files are being included in multiple routines. The "modern" solution, is to define the various variables in the .h files as extern, but not to intialize them there. Instead one intializes them in a single .c routine.

the -fcommon switch sorts this out. See the explanation here, which notes among other things that this, but with a possible performance penalty.

upl1nk-v01d commented 1 year ago

In linux adding -fcommon to CFLAGS in makefile doesn't help: CFLAGS=-m32 -msse2 -mfpmath=sse -Wall -fno-omit-frame-pointer -fmax-errors=15 -fcommon

This still throws 'multiple definition' issue and compiler doesn't produce 'cod4x18_dedrun' file. How to solve this?

dugzzuli commented 4 months ago

To modify your Makefile to add the -fcommon flag and potentially address multiple definition issues when compiling your project with GCC version 10 or later, follow these steps:

Open the Makefile: Use a text editor of your choice to open the Makefile. You mentioned earlier that you use nano, so you can open it with:

bash 复制代码 nano Makefile Locate the COPTS Variable: This variable holds the compilation options for your project. It is already set up with several flags.

Add -fcommon to COPTS: Append the -fcommon flag to the existing flags in the COPTS variable. It should look like this:

makefile 复制代码 COPTS = -funroll-loops -O3 -ansi -std=c99 -pedantic-errors -Wall -I$(CFITSIOINCDIR) -D_GNU_SOURCE -fcommon Adding -fcommon will instruct the compiler to place uninitialized global variables in a common block, which can be shared between different compiled source files. This approach can solve the multiple definition linker errors but may result in slightly less efficient code. This change is recommended if the codebase relies on older C standards or practices where multiple definitions are expected.

Save and Close: After adding the flag, save the file and exit the text editor. If you’re using nano, you can do this by pressing Ctrl+X to close, then Y to save the changes, followed by Enter to confirm.

Recompile Your Project: Go back to your terminal and run the make command to rebuild your project with the new compiler settings:

bash 复制代码 make clean make The make clean command is used to clean out all objects and binaries from the previous build, ensuring that the next build is completely fresh.

Check for Errors: Verify if the compilation completes without the multiple definition errors. If the errors persist, there may be other issues in the code or build system settings that need attention.

This process should help in resolving build issues related to the stricter linking behavior of newer GCC versions. If the problem continues, reviewing the source code for incorrect global variable usage or further adjusting the build settings might be necessary.