Intel® C++ Compiler
Community support and assistance for creating C++ code that runs on platforms based on Intel® processors.

Is libm.so always linked by default?

Alexey_S_Intel2
Employee
2,614 Views

Hi, guys!

$ cat test.cpp

int main() {

   return 0;

}

$ icpc test.cpp -o test.exe

$ lddtree test.exe

test.exe => ./test.exe (interpreter => /lib64/ld-linux-x86-64.so.2)
    libstdc++.so.6 => /usr/lib/x86_64-linux-gnu/libstdc++.so.6
        ld-linux-x86-64.so.2 => /lib64/ld-linux-x86-64.so.2
    libm.so.6 => /lib/x86_64-linux-gnu/libm.so.6
    libgcc_s.so.1 => /lib/x86_64-linux-gnu/libgcc_s.so.1
    libc.so.6 => /lib/x86_64-linux-gnu/libc.so.6
    libdl.so.2 => /lib/x86_64-linux-gnu/libdl.so.2

test.cpp doesn't use any math, but libm.so still participates in the linking. Why?

By the way, when test.cpp is built with g++, then there's no dependency on the libm library.

What is the standard way to remove this redundant dependency?

I would also like to know why this dependency isn't being dropped during the linking stage by the linker itself?

 

 

0 Kudos
5 Replies
Viet_H_Intel
Moderator
2,614 Views

 

The C++ runtime library (libstdc++) requires libm. So, if you compile a C++ program then you see libm gets linked in automatically. 

I am not sure why you didn't see it with g++ though.

Thanks,

Viet

0 Kudos
Alexey_S_Intel2
Employee
2,614 Views

Hi, Viet!

 

Thank you for your answer. I'm agree that libstdc++ may depend on libm.so, but that isn't what I've asked about.

libm.so is listed by lddtree as a direct dependency, i.e. as if test.exe has undefined symbol linked in from libm.so. But test.exe doesn't use any math function by itself, so there must be no direct dependency on libm.so. That is the question.

0 Kudos
TimP
Honored Contributor III
2,614 Views

Linking by icpc -# would be one way to see whether icpc builds the ld command string with -lm inserted to force link libm (and whether libstdc++ is force linked).  Your example should work with icc, so you could make that comparison.

0 Kudos
Alexey_S_Intel2
Employee
2,614 Views

Tim, thank you very much for this option - it proved to be very useful.

Linking with -# I've got the following output:

ld  \
    /usr/lib/gcc/x86_64-linux-gnu/5/../../../../lib64/crt1.o \
    /usr/lib/gcc/x86_64-linux-gnu/5/../../../../lib64/crti.o \
    /usr/lib/gcc/x86_64-linux-gnu/5/crtbegin.o \
    --eh-frame-hdr \
    --build-id \
    -dynamic-linker \
    /lib64/ld-linux-x86-64.so.2 \
    -m \
    elf_x86_64 \
    -o \
    test.exe \
    -L/nfs/inn/disks/sstd/tools/icl/19.0.0_20180804/compiler/lib/intel64_lin \
    -L/usr/lib/gcc/x86_64-linux-gnu/5/ \
    -L/usr/lib/gcc/x86_64-linux-gnu/5/../../../x86_64-linux-gnu/ \
    -L/usr/lib/gcc/x86_64-linux-gnu/5/../../../../lib64 \
    -L/usr/lib/gcc/x86_64-linux-gnu/5/../../../../lib/ \
    -L/lib/x86_64-linux-gnu/ \
    -L/lib/../lib64 \
    -L/lib/../lib/ \
    -L/usr/lib/x86_64-linux-gnu/ \
    -L/usr/lib/../lib64 \
    -L/usr/lib/../lib/ \
    -L/usr/lib/gcc/x86_64-linux-gnu/5/../../../ \
    -L/lib64 \
    -L/lib/ \
    -L/usr/lib64 \
    -L/usr/lib \
    -L/usr/lib/i386-linux-gnu \
    /tmp/icpcpKdpTH.o \
    -Bdynamic \
    -Bstatic \
    -limf \
    -lsvml \
    -lirng \
    -Bdynamic \
    -lstdc++ \
    -lm \
    -Bstatic \
    -lipgo \
    -ldecimal \
    --as-needed \
    -Bdynamic \
    -lcilkrts \
    --no-as-needed \
    -lstdc++ \
    -lgcc \
    -lgcc_s \
    -Bstatic \
    -lirc \
    -lsvml \
    -Bdynamic \
    -lc \
    -lgcc \
    -lgcc_s \
    -Bstatic \
    -lirc_s \
    -Bdynamic \
    -ldl \
    -lc \
    /usr/lib/gcc/x86_64-linux-gnu/5/crtend.o \
    /usr/lib/gcc/x86_64-linux-gnu/5/../../../../lib64/crtn.o

libm is explicitly linked in. Why doesn't the linker drop this dependency?

On the other hand the libimf lib is explicitly provided as input, but the linker rejects dependency on this lib. Why rejection doesn't happen to libm?

 

0 Kudos
Alexey_S_Intel2
Employee
2,614 Views

I've found out that building with the option -Wl,-as-needed removes the dependency on the libm library (as well as on any other unused lib).

 icpc -Wl,-as-needed test.cpp -o test.exe

Why icpc doesn't use this option by default? Why keep redundant dependencies?

 

0 Kudos
Reply