What does the clang++ -c flag do? [closed] - c++

Closed. This question does not meet Stack Overflow guidelines. It is not currently accepting answers.
This question does not appear to be about programming within the scope defined in the help center.
Closed 8 years ago.
Improve this question
What does the -c flag do in the following command?
clang++ -std=c++11 -g -Wall -stdlib=libc++ -isystem testing/gtest-1.7.0/include -Itesting/gtest-1.7.0 -pthread -c testing/gtest-1.7.0/src/gtest-all.cc
I've looked for the flag in the documentation (http://clang.llvm.org/docs/UsersManual.html), as well as in the help message (clang -cc1 --help)...can't seem to find the answer.

The -c flag is used to tell the compiler you don't want to build a program (link together into an executable), just compile this particular file into an object file - typically producing a file called something.o or something.obj - in this case gteger-all.cc
(Note that this flag is common with nearly all compilers available - from Turbo C from 1990's to the latest versions of MS, Gnu and LLVM/Clang)

man clang++
OPTIONS
Stage Selection Options
-E Run the preprocessor stage.
-fsyntax-only
Run the preprocessor, parser and type checking stages.
-S Run the previous stages as well as LLVM generation and optimization stages and target-specific code generation, producing an assembly file.
-c Run all of the above, plus the assembler, generating a target ".o" object file.

man clang is your friend!
OPTIONS
Stage Selection Options
-E Run the preprocessor stage.
-fsyntax-only
Run the preprocessor, parser and type checking stages.
-S Run the previous stages as well as LLVM generation and optimization
stages and target-specific code generation, producing an assembly
file.
-c Run all of the above, plus the assembler, generating a target ".o"
object file.

Related

How to tell clang to put debug symbol into executable binaries? [duplicate]

This question already has an answer here:
Why does a 2-stage command-line build with clang not generate a dSYM directory?
(1 answer)
Closed 5 years ago.
My compile command is in macOS Sierra is
clang -std=c11 -g -Wall -Werror -fsanitize=address -file.c -o file
after it compiles, it also generates an extra file.dSYM file which included all debug symbols. However, when I use WSL or other *nix system it will not generate such file, debug symbols were embedded into executable binaries.
So I just wondering is there a way to do the same in macOS with clang.
When you compile a program in one pass, clang actually runs dsymutil for you, which is responsible for creating the .dSYM file. Thus, the solution to your problem is to compile and link separately, in which case clang won't automatically call dsymutil.
Check this SO question for more details!

Code size is doubled when compiling with GCC ARM Embedded?

I've just ported a STM32 microcontroller project from Keil uVision (using Keil ARM Compiler) to CooCox CoIDE (using GCC ARM Embedded compiler).
Problem is, the code size is the double size when compiled in CoIDE with GCC compared to Keil uVision.
How can this be? What can I do?
Code size in Keil: 54632b (.text)
Code size in CoIDE: 100844b (.text)
GCC compiler flags:
arm-none-eabi-gcc -mcpu=cortex-m3 -mthumb -g2 -Wl,-Map=project.map -Os
-Wl,--gc-sections -Wl,-TC:\arm-gcc-link.ld -g -o project.elf -L -lm
I am suspecting CoIDE and GCC to compile a lot of functions and files, that are present in the project, though aren't used (yet). Is it possible that it compiles whole files even if I only use 1 function out of 20 in there? (even though I have -Os)..
Hard to say which files are really compiled/linked in your final binary from the information you give. I suppose it takes all the C files it finds on your project if you did not explicitly specified which one to compile or if you don't use your own Makefile.
But from the compiler options you give, the linker flag --gc-sections won't do much garbage if you don't have the following compiler flags: -ffunction-sections -fdata-sections. Try to add those options to strip all unused functions and data at link time.
Since the question was tagged with C++, I wonder if you would like to disable exceptions and RTTI. Those take quite a bit of code. Add -fno-exceptions -fno-rtti to linker flags.

Why does a 2-stage command-line build with clang not generate a dSYM directory?

I have a simple project I want to debug want to produce dSYM folder with debugging symbols.
Running:
clang++ -std=c++14 -stdlib=libc++ -g -o Lazy Lazy.cpp
Creates Lazy.dSYM as I expect.
However:
clang++ -std=c++14 -stdlib=libc++ -g -c Lazy.cpp
clang++ -stdlib=libc++ -g -o Lazy Lazy.o
Does not create Lazy.dSYM (It seems that the symbols are embedded in the binary).
Sadly the 2-step build is what my modified makefile does. How can I generate Lazy.dSYM from a 2-stage compile-and-link build?
I don't need a dSYM directory, just debugging symbols, but would like to understand when and why it is created.
The creation of the .dSYM bundle is done by a tool called dsymutil. When Apple added support for DWARF debugging information, they decided to separate "executable linking" from "debug information linking". As such, the debug information linking is not done by the normal linker, it's done by dsymutil.
As a convenience, when you build a program all in one step, the compiler invokes dsymutil on your behalf. That's because it knows it has all of the inputs. If you add the -v (a.k.a. --verbose) option to the compile command, you will see the invocation of dsymutil as the last step it does.
In other cases, though, it doesn't do that. It leaves the debug information linking step for the user to do manually. You can do it by simply issuing the command:
dsymutil <your_program>
Here's an article by an Apple engineer who helped design and implement Apple's support for DWARF explaining their thinking. He also answered a question here on Stack Overflow about this stuff.

Clang's different stages of processing

Similar to GCC, clang supports stopping at different stages when processing C/C++. For example, passing a -E flag causes it to stop after the pre-processor and -c stops before linking.
So far, I am aware of,
-E : pre-processing
-fsyntax-only : syntax checking
-S : assembly
-c : object code
Am I missing any stopping points between those, or is that it?
You can also use -S -emit-llvm to generate LLVM IR assembly files and just -emit-llvm for LLVM bitcode object files. These are the language-independent code representations that clang and other LLVM front-ends generate and pass to LLVM to compile into an executable.

Compiling previously preprocessed file changes output

I have a source file which I preprocess using the options -E and -P (using GCC 4.1.2 for a vxWorks-based embedded platform). All other options are the same as when I compile the file. These options are:
-Wall
-march=pentium
-nostdinc
-O0
-fno-builtin
-fno-defer-pop
-g
-c
-o
as well as all include-paths. Now when I compile this preprocessed file, the resulting object-file is much smaller (about 30%) than when I compile the original directly. And when I then link the program, the linker complains about missing symbols (all in user-code), which again does not happen when using the original source-file. Why is there a difference? Is there any way to make this work?
You're sure you're not missing any -D defines from your command line? Your result would be consistent with parts not being compiled due to conditionals.
Another possibility (since you don't name the compiler specifically) is that you're using a generic gcc -E rather than the arch-specific cross compiler for your vxWorks environment. The cross-gcc will predefine some variables that you'll need for gcc -E.
When compiling the preprocessed output, try passing the -fpreprocessed option to tell GCC not to preprocess again.
The only difference I can think of is macros that result in expanding to an identifier that's a macro name that has already been expanded - the preprocessor stops expansion at that point, but if you ran the preprocessor again, the identifier would be expanded again. I would have expected any instances of this to probably cause a compiler error, but who knows?