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

Why does Intel C compiler link c++ libraries for pure C code?

dpeterc
Beginner
1,465 Views

I am compiling the most basic hello.c on Mac OS X Catalina 10.5.2, Xcode 11.3, ICC 19.0.4.233 20190416

#include <stdio.h>
int main()
{
printf("Hello!\n");
return(0);
}

gcc  hello.c
ls -l a.out
-rwxr-xr-x  1 dusan  staff  12556 Jan 13 17:27 a.out
otool -L a.out
a.out:
    /usr/lib/libSystem.B.dylib (compatibility version 1.0.0, current version 1281.0.0)

Gcc (or actually clang) gives reasonable binary size and does not link to anything extra.

But with icc, it is a different story:

icc hello.c
ls -l aout
-rwxr-xr-x  1 dusan  staff  38856 Jan 13 17:19 a.out
otool -L  a.out
a.out:
    /usr/lib/libc++.1.dylib (compatibility version 1.0.0, current version 800.7.0)
    /usr/lib/libSystem.B.dylib (compatibility version 1.0.0, current version 1281.0.0)

Why does icc link to libc++, if I only use C language?

And why is the resulting binary so big?
Setting setting optimization options does not change the result

Binary contains tons of messages, many of which are not necessary, for example the one about Windows XP:

Fatal Error: This program was not built to run on the processor in your system.
Run-Time Check Failure: The variable '%s' is being used without being initialized
Windows XP 64-bit Edition Version 2003 or newer should be used.
Intel(R) Core(TM) Duo processors and compatible Intel processors with supplemental Streaming SIMD Extensions 3 (SSSE3) instruction support
Intel(R) Pentium(R) 4 and compatible Intel processors with Intel(R) Streaming SIMD Extensions 3 (Intel(R) SSE3) instruction support
Intel(R) Pentium(R) 4 and compatible Intel processors. Enables new optimizations in addition to Intel processor-specific optimizations
Intel(R) processors with SSE4.2 and POPCNT instructions support
Please verify that both the operating system and the processor support Intel(R) AVX.
Please verify that both the operating system and the processor support Intel(R) AVX, F16C and RDRAND instructions.
Please verify that both the operating system and the processor support Intel(R) AVX2, BMI, LZCNT, HLE, RTM and FMA instructions.
Please verify that both the operating system and the processor support Intel(R) %s instructions.
Please verify that your application was built with compatible Intel(R) libirc library
Use of incompatible or internally inconsistent Intel(R) libirc library
Run-Time Check Failure: The variable '%s' is being used in %s without being initialized
Cache size is incorrectly reported as 0. Please engage your hardware and/or OS support to address the problem.
irc_msg.cat
Constant propagation error (%s substitution):
FORMAL
RETURN
GLOBAL
I32 %lx != %lx
SI32 %ld != %ld
F32 %f != %f
I64 %lx:%lx != %lx:%lx
SI64 %ld:%ld != %ld:%ld
F64 %f != %f
Bad second argument
Fatal Error: Can not initiate the Heap
Usage: %s input_file output_file
Usage: %s segment_size input_file [-trace]
Conversion from text file %s to binary %s completed
segment_size = 0x%x = %d
Cannot allocate memory to hold segment (size = 0x%x)
Input file: %s corrupted
routine_name = '%s'
file_name    = '%s'
prof_dir     = '%s'
Dynamic profile created from file %s completed
The allowed processors are: %s.
Error:  Buffer overrun occurred, forced exit
Initialization of symbol handler failed. Error code %d
NTDLL module not found
RtlCaptureContext function not found in ntdll.dll
StackWalk is terminated abnormally. Error code %d
Exception is raised during stack walking
Signal %s is raised
Signal %s is raised at 0x%p
SIGSEGV
SIGILL
SIGBUS
SIGFPE
unknown
No error
You must link with libunwind to use traceback functionality
Intel(R) Pentium(R) M and compatible Intel processors
Intel(R) processors with Swing New Instructions support
Intel(R) processors with MOVBE instructions support
Fatal Error: This program was not built to run in your system.
Boundary Run-Time Check Failure for variable '%s'
Boundary Run-Time Check Failure
Conversion Run-Time Check Failure
 and
LANG
GENERIC_IA32
CMOV
FXSAVE
SSE2
SSE3
SSSE3
SSE4_1
SSE4_2
MOVBE
POPCNT
PCLMULQDQ
F16C
RDRND
LZCNT
AVX2
AVX512DQ
PTWRITE
KNCNI
AVX512F
RDSEED
AVX512IFMA52
AVX512ER
AVX512PF
AVX512CD
AVX512BW
AVX512VL
AVX512VBMI
AVX512_4FMAPS
AVX512_4VNNIW
AVX512_VPOPCNTDQ
AVX512_BITALG
AVX512_VBMI2
GFNI
VAES
VPCLMULQDQ
AVX512_VNNI
CLWB
RDPID
SHSTK
WBNOINVD
PCONFIG
hw.optional.avx512f
hw.optional.avx512cd
hw.optional.avx512dq
hw.optional.avx512bw
hw.optional.avx512vl
hw.optional.avx512ifma
hw.optional.avx512vbmi

0 Kudos
4 Replies
Viet_H_Intel
Moderator
1,466 Views

Seems to me that some of Intel libraries (e.g. libirc.a) has a dependency on libc++.1.dylib.

What system/processor did you build and run your binary on? 

 

0 Kudos
dpeterc
Beginner
1,466 Views

I have compiled it on i9-9900. The linking to libc++ also happens on older processor architectures and compiler versions, like i5-750 (from 2009) or i5-6600 (from 2015).

There is general consensus that in order to call c++ functions from C program, you must make C interface for it. And I don't want to call any of Intel's c++ libraries, I just want "hello world" in plain C.

https://stackoverflow.com/questions/20324863/is-it-possible-to-include-c-libraries-in-c-programs

I want to reduce the number of libraries on which my programs depend, libc++ is relatively big (1.3 MB), especially considering the small footprint of the actual C code.

I have also tested it on Linux (OpenSUSE 15.0), and program compiled with icc uses six libraries

ldd a.out                                                                                                                               
        linux-vdso.so.1 (0x00007fff953fa000)
        libm.so.6 => /lib64/libm.so.6 (0x00007f15684c1000)
        libgcc_s.so.1 => /lib64/libgcc_s.so.1 (0x00007f15682a9000)
        libc.so.6 => /lib64/libc.so.6 (0x00007f1567ee9000)
        libdl.so.2 => /lib64/libdl.so.2 (0x00007f1567ce5000)
        /lib64/ld-linux-x86-64.so.2 (0x00007f1568854000)

wheres the one compiled with gcc or clang needs three libraries less

ldd a.out
        linux-vdso.so.1 (0x00007ffc4f791000)
        libc.so.6 => /lib64/libc.so.6 (0x00007f850f319000)
        /lib64/ld-linux-x86-64.so.2 (0x00007f850f6d9000)

... which results in faster startup times and overall smaller memory footprint.

0 Kudos
Viet_H_Intel
Moderator
1,466 Views

I see your points. 

Did your program run slower than built with GCC?

0 Kudos
dpeterc
Beginner
1,466 Views

For me, speed is not an issue on such a small example program. It might be an issue for somebody who makes software for embedded systems, with tight space and program startup requirements.

I am running in dependency hell on Mac OS X, which is very restrictive regarding shared library naming and locations. Typical system has installed several copies of same library (for example iconv). Many libraries in turn link to other libraries. For example, on Linux, libtiff.so.5 links to liblzma.so.5 libjbig.so.2 libjpeg.so.8 libz.so.1 libm.so.6 libc.so.6 libpthread.so.0. I could have some higher level toolkit which in turn links to libjpeg.so.9, or different version of iconv. What happens, if you link to two different versions of same library, within the same program, in order to satisfy dependencies? Often it is hard to recompile third party library in order to use different version of some other library, so that I would acheive library consistency.

My complete GUI program with medium complexity uses about 40 libraries.

Some are part of the base operating system, some are not. So I need to include them in my application and correct all relative installation and link paths embedded in library binary. On Mac, the library location problem can not be solved simply by adjusting LD_LIBRARY_PATH. So I need to have shared libraries under my control, know for each of them why are they there, and where are they coming from.

And of course, I try to reduce number of shared libraries, if possible.

0 Kudos
Reply