[LINUX] If "can not be used when making a PIE object" appears in make

When I built a user program from a Makefile to replace it with Ubuntu 18.04 on Amazon Lightsail, the linker threw an error.

phenomenon

$ uname -a
Linux example 5.3.0-1023-aws #25~18.04.1-Ubuntu SMP Fri Jun 5 15:18:30 UTC 2020 x86_64 x86_64 x86_64 GNU/Linux

$ make
gcc -g -I../include -c foo.c
gcc -g -o foo foo.o bar.o -L ../lib -lwebsockets -lmysqlclient
/usr/bin/ld: bar.o: relocation R_X86_64_32 against `.rodata' can not be used when making a PIE object。 -Recompile with fPIC.
/usr/bin/ld:Last link failed:There is no section corresponding to the output
collect2: error: ld returned 1 exit status
Makefile:14: recipe for target 'foo' failed
make: *** [foo] Error 1

It seems that it has changed to link as ** PIE ** (Position Independent Executable) by default from version 6 of gcc. ** PIE ** is an executable file consisting only of ** PIC ** (Position Independent Code) object files. So, if there is a code that is not ** PIC **, the link will fail.

Verification

Let's take a look at the configure option when gcc was built.

$ gcc -v
Using built-in specs.
COLLECT_GCC=gcc
COLLECT_LTO_WRAPPER=/usr/lib/gcc/x86_64-linux-gnu/7/lto-wrapper
OFFLOAD_TARGET_NAMES=nvptx-none
OFFLOAD_TARGET_DEFAULT=1
Target: x86_64-linux-gnu
Configured with: ../src/configure -v --with-pkgversion='Ubuntu 7.5.0-3ubuntu1~18.04' --with-bugurl=file:///usr/share/doc/gcc-7/README.Bugs --enable-languages=c,ada,c++,go,brig,d,fortran,objc,obj-c++ --prefix=/usr --with-gcc-major-version-only --program-suffix=-7 --program-prefix=x86_64-linux-gnu- --enable-shared --enable-linker-build-id --libexecdir=/usr/lib --without-included-gettext --enable-threads=posix --libdir=/usr/lib --enable-nls --enable-bootstrap --enable-clocale=gnu --enable-libstdcxx-debug --enable-libstdcxx-time=yes --with-default-libstdcxx-abi=new --enable-gnu-unique-object --disable-vtable-verify --enable-libmpx --enable-plugin --enable-default-pie --with-system-zlib --with-target-system-zlib --enable-objc-gc=auto --enable-multiarch --disable-werror --with-arch-32=i686 --with-abi=m64 --with-multilib-list=m32,m64,mx32 --enable-multilib --with-tune=generic --enable-offload-targets=nvptx-none --without-cuda-driver --enable-checking=release --build=x86_64-linux-gnu --host=x86_64-linux-gnu --target=x86_64-linux-gnu
Thread model: posix
gcc version 7.5.0 (Ubuntu 7.5.0-3ubuntu1~18.04) 

You can see that there is --enable-default-pie. Certainly ** PIE ** is enabled by default. (** PIE ** is disabled on CPU architectures that don't work)

On the other hand, the configure of the machine used for development did not have it, and the version of gcc was quite old as 5 series.

$ gcc -v
Using built-in specs.
COLLECT_GCC=gcc
COLLECT_LTO_WRAPPER=/usr/lib/gcc/x86_64-linux-gnu/5/lto-wrapper
Target: x86_64-linux-gnu
Configured with: ../src/configure -v --with-pkgversion='Ubuntu 5.4.0-6ubuntu1~16.04.12' --with-bugurl=file:///usr/share/doc/gcc-5/README.Bugs --enable-languages=c,ada,c++,java,go,d,fortran,objc,obj-c++ --prefix=/usr --program-suffix=-5 --enable-shared --enable-linker-build-id --libexecdir=/usr/lib --without-included-gettext --enable-threads=posix --libdir=/usr/lib --enable-nls --with-sysroot=/ --enable-clocale=gnu --enable-libstdcxx-debug --enable-libstdcxx-time=yes --with-default-libstdcxx-abi=new --enable-gnu-unique-object --disable-vtable-verify --enable-libmpx --enable-plugin --with-system-zlib --disable-browser-plugin --enable-java-awt=gtk --enable-gtk-cairo --with-java-home=/usr/lib/jvm/java-1.5.0-gcj-5-amd64/jre --enable-java-home --with-jvm-root-dir=/usr/lib/jvm/java-1.5.0-gcj-5-amd64 --with-jvm-jar-dir=/usr/lib/jvm-exports/java-1.5.0-gcj-5-amd64 --with-arch-directory=amd64 --with-ecj-jar=/usr/share/java/eclipse-ecj.jar --enable-objc-gc --enable-multiarch --disable-werror --with-arch-32=i686 --with-abi=m64 --with-multilib-list=m32,m64,mx32 --enable-multilib --with-tune=generic --enable-checking=release --build=x86_64-linux-gnu --host=x86_64-linux-gnu --target=x86_64-linux-gnu
Thread model: posix
gcc version 5.4.0 20160609 (Ubuntu 5.4.0-6ubuntu1~16.04.12)

Coping

You don't have to put it in ** PIE ** format, so just add -no-pie to LDFLAGS in the Makefile.

Recommended Posts

If "can not be used when making a PIE object" appears in make
pd.tseries.offsets.DateOffset can be quite slow if not used with caution
Scripts that can be used when using bottle in Python
Can be used when aws-cli is available but jq is not available jp.py
Make a Spinbox that can be displayed in Binary with Tkinter
A timer (ticker) that can be used in the field (can be used anywhere)
Make a Spinbox that can be displayed in HEX with Tkinter
[Python3] Code that can be used when you want to cut out an image in a specific size
If you want to make a Windows application (exe) that can be actually used now using only Python
A personal memo of Pandas related operations that can be used in practice
I made a familiar function that can be used in statistics with Python
What to do if NotADirectoryError: [Errno 20] Not a directory:'xdg-settings' appears in jupyter notebook
Functions that can be used in for statements
When the selected object in bpy.context.selected_objects is not returned
Basic algorithms that can be used in competition pros
Japanese can be used with Python in Docker environment
ANTs image registration that can be used in 5 minutes
Can be used in competition pros! Python standard library
Can be used with AtCoder! A collection of techniques for drawing short code in Python!
[Python3] Code that can be used when you want to resize images in folder units
[Python] Variadic arguments can be used when unpacking iterable elements
Goroutine (parallel control) that can be used in the field
Goroutine that can be used in the field (errgroup.Group edition)
Let's make a diagram that can be clicked with IPython
About the matter that torch summary can be really used when building a model with Pytorch
Addictive note: max (max (list)) must not be used when maxing the value of a 2D array
If you are a beginner in programming, why not make a "game" for the time being? The story