GCC Default Link -l - gcc

When I need to use, for example, the gnu function gsl_sf_bessel_J0 in a program, I simply compile it with gcc -lgsl -o gsl_test.c gsl_test. Why do I have to include -lgsl for it to work? Is there any way I can set it as a default so I don't have to type it out everytime?

If you compile with the -v flag, you'll see the command the GCC front-end invokes to link your final executable*. If your program uses a function like gsl_sf_bessel_J0 that isn't in one of the default libraries (possibly limited to libc and maybe also libm), you need to explicitly link it.
If you don't like typing it all the time, make a simple Makefile. Your case is simple enough that you can handle it with just environment variables, actually:
$ export CC=gcc
$ export LDLIBS=-lgsl
$ make gsl_test
gcc gsl_test.c -lgsl -o gsl_test
$
make's default built-in rules will do the rest.
*: for reference, my compiler links your example as:
"/Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/bin/ld"
-demangle
-dynamic
-arch x86_64
-macosx_version_min 10.12.0
-o gsl_test
/var/folders/cp/wvm69p1n7_bbjpxxqmttwn700000gn/T/gsl_test-0afe3a.o
-lgsl
-lSystem
/Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/bin/../lib/clang/8.0.0/lib/darwin/libclang_rt.osx.a

Related

Which gcc version introduced `-fstack-protector-strong`?

In my build script, I want to conditionally add -fstack-protector-strong to my CFLAGS if the gcc supports it (my project builds using multiple versions of gcc).
I want my build script (written in bash) to parse the output of gcc --version and automatically add this flag if the gcc supports it.
Which version of gcc is the earliest to include the -fstack-protector-strong flag?
I want my build script (written in bash) to parse the output of gcc --version and automatically add this flag if the gcc supports it.
Instead of doing that, just call gcc -fstack-protector-strong with a valid source file and see if it compiles. Such method works universally for any compile option, which will save you time for searching which version has which options. You may take inspiration from CMake check_c_compile_flag function.
Taking inspiration from #KamilCuk's answer but bashifying it:
add_supported_cc_flag() {
CC=$1
CFLAG_TO_CHECK=$2
C_FILE=/tmp/test.$$.c
O_FILE=${C_FILE/.c/.o}
rm -f ${C_FILE}
cat > ${C_FILE} <<EOF
int main() { return 0; }
EOF
if $CC ${CFLAG_TO_CHECK} -c ${C_FILE} -o ${O_FILE} >/dev/null 2>&1
then
echo ${CFLAG_TO_CHECK}
fi
rm -f ${C_FILE} ${O_FILE}
}
CFLAGS="${CFLAGS} $(add_supported_cc_flag gcc -fstack-protector-strong)"
It appears that -fstack-protector-strong was first available in gcc 4.9.0.
The option doesn't show up in https://gcc.gnu.org/onlinedocs/gcc-4.8.5/gcc/Optimize-Options.html (4.8.5 was the last 4.8.x gcc version), but the option does show up in https://gcc.gnu.org/onlinedocs/gcc-4.9.0/gcc/Optimize-Options.html.
Note that -fstack-protector-all and -fstack-protector are available prior to gcc 4.9.0.

g++ linker options changes target file name

I need help it is bug or I don't understand how compilation options are working ?
I have sample main.c file and try to compile it as:
$ g++ -nostdlib -g -fno-rtti -fno-exceptions -ffreestanding -nostdinc -nostdinc++ -Wl,--build-id=none,-g,-nostdlib,-nostartfiles,-zmax-page-size=0x1000 main.c -o main
and as output I have this:
$ ls
main.c startfiles
I am trying to understand why g++ created file named "startfiles" not "main" ?
If you read the GNU ld official documentation you will see that there is no option named -nostartfiles. What you do pass for arguments to the linker with that is the options -n and -ostartfiles.
If I were you, I would check those other options you try to pass to the linker as well.
-nostartfiles is a compiler flag as far as I know, not a linker flag.
For the linker, it's the same as -n -o startfiles, which is why you're getting that output file name.

Both -fPIC and -s used - possibly contradictory?

In a particular project, I saw the following compiler options used all at once:
gcc foo.c -o foo.o -Icomponent1/subcomponent1 -Icomponent2/subcomponent1 -Wall -fPIC -s
Are the -fPIC and -s used together contradictory here? If not, why?
-s and -fPIC are two flags used for different purposes. They are not contradictory.
From the gcc manual
-s
Remove all symbol table and relocation information from the executable.
-fPIC
If supported for the target machine, emit position-independent code, suitable for dynamic linking and avoiding any limit on the size of the global offset table. This option makes a difference on the m68k, PowerPC and SPARC.

How to specify RPATH in a makefile?

I'm trying to specify rpath in my binary.
My makefile looks like this-
CC=gcc
CFLAGS=-Wall
LDFLAGS= -rpath='../libs/'
main: main.c
gcc -o main main.c
clean:
rm -f main main.o
But when I query rpath using command readelf -a ./main | grep rpath I get nothing
I've tried specifying rpath as LDFLAGS= "-rpath=../libs/" but even that doesn't seem to work.
Can someone please post an example on how should I specify rpath in a makefile?
GCC and ld versions are-
gcc (Ubuntu/Linaro 4.5.2-8ubuntu4) 4.5.2
GNU ld (GNU Binutils for Ubuntu) 2.21.0.20110327
If you set the variables, you should probably use them. It's silly not to, especially when make won't magically set those variables for you! :)
main: main.c
$(CC) $(CFLAGS) $(LDFLAGS) -o main main.c
Another problem is LDFLAGS, it should be
LDFLAGS="-Wl,-rpath,../libs/"
The usual gcc switch for passing options to linker is -Wl,, and it is needed because gcc itself may not understand the bare -rpath linker option. While some builds of various versions of gcc accept -rpath, I have never seen it documented in gcc man pages or info pages. For better portability, -Wl,-rpath should be preferred.

gcc link error occurred

I compiled with gcc
gcc -l. 'net-snmp-config --cflags'
-fPlC -shared -c -o matsu_object.o tsu_object.c
but this error occurred
gcc: -lcrypto: Because a link was
not completed, the input file of the
linker was not used
What's wrong?
Did you mistype the question? There's no way for that to output the message you write, and I would expect that the proper command is something more like
gcc -L. `net-snmp-config --cflags` -fPIC -shared -c -o matsu_object.o tsu_object.c
Notice the -L uppercase, backticks instead of single quotes, and upper-case I in PIC.
Also, you don't say what you're trying to do, but net-snmp-config should also take at least one of --libs or --agent-libs as well.
Ah, I didn't read closely enough...
-c means "compile", that is: generate from tsu_object.c, a compiled matsu_object.o.
Without -c, the compiler actually links, that is: generate from *.o, a.out or other specified file.
-shared (and linker flags like -l and -L) are only meaningful when linking. They're meaningless when compiling, as you are doing here because of -c.
Please correct the command-line in the question to accurately reflect what you're running, and give some more explanation as to what you're trying to do.
I think you are using ticks ' instead of back ticks `. Does --cflags really give linker options? I think you are at the link step here. Also what is the effect of -c at a link. I thought -c was compile only and not attempt to link.
You used single quotes instead of backquotes.
Instead of this:
gcc -l. 'net-snmp-config --cflags' -fPlC -shared -c -o matsu_object.o tsu_object.c
You should type:
gcc -l. `net-snmp-config --cflags`-fPlC -shared -c -o matsu_object.o tsu_object.c
net-snmp-config is a program. When you run it with --cflags, it evaluates to the correct cflags that you should be using to compile your program.
But you know what? You should be using autoconf. Even for something this small, it usually makes sense to do the work. Most people I know need to compile on more than one platform...

Resources