Why is clang not using the precompiled header? - clang

// test.hpp
#include <iostream>
// test.cpp
#include "test.hpp"
int main(){std::cout << "hello world" << std::endl;}
Let's precompile header:
clang++ -c test.hpp
Let's use the header
clang++ test.cpp -H
Output shows it is not using the header, as no ! appears before test.hpp (like it does with g++):
. ./test.hpp
.. /usr/bin/../lib/gcc/x86_64-linux-gnu/9/../../../../include/c++/9/iostream
... /usr/bin/../lib/gcc/x86_64-linux-gnu/9/../../../../include/x86_64-linux-gnu/c++/9/bits/c++config.h
.... /usr/bin/../lib/gcc/x86_64-linux-gnu/9/../../../../include/x86_64-linux-gnu/c++/9/bits/os_defines.h
..... /usr/include/features.h
Why is this?

This (seems to) work:
clang++ -x c++-header test.hpp -o test.hpp.pch
clang++ -include test.hpp test.cpp
The option -H appears not to be used in clang++ as adding -H to the second above line displays nothing.

Related

Nix's clang won't build wasm

I'm have a C Wasm module with the following import:
__attribute__((import_module("env"), import_name("runtime_exit"))) void exit(int);
I'm compiling with Clang 12.0.0 on Linux:
clang --target=wasm32 --no-standard-libraries \
-c -Ofast -o out.o in.c
With the package from my package manager (xbps), this works fine. In Nix (see below for the derivation), however (Clang 12.0.1), I get the following warning on nix-build:
tests/test.h:1:16: warning: unknown attribute 'import_module' ignored [-Wunknown-attributes]
__attribute__((import_module("env"), import_name("runtime_exit"))) void exit(int);
^~~~~~~~~~~~~~~~~~~~
tests/test.h:1:38: warning: unknown attribute 'import_name' ignored [-Wunknown-attributes]
__attribute__((import_module("env"), import_name("runtime_exit"))) void exit(int);
This is just a warning, but linking later fails: in fact, clang is attempting to link with ld, not wasm-ld or even lld.
My default.nix specifies:
{ pkgs ? import <nixpkgs> {} }:
let
stdenv = pkgs.llvmPackages_12.stdenv;
src = ./.; # etc, etc
in
stdenv.mkDerivation {
# --- snip ---
buildPhase = ''
clang --target=wasm32 --no-standard-libraries \
-c -Ofast -o $out/out.o in.c
'';
# --- snip ---
buildInputs = [ pkgs.clang_12 pkgs.lld_12 ];
}
I don't see why this shouldn't work, but all the different variations of packages I've tried using seem to suggest that I'm getting at the LLVM toolchain incorrectly.
If this isn't enough information, please let me know. Thanks!
Edit
It looks like Nix isn't respecting the --target argument:
$ nix-shell
[nix-shell:~/...]$ clang -target wasm32 --print-target-triple
x86_64-unknown-linux-gnu
[nix-shell:~/...]$ exit
$ clang --target=wasm32 --print-target-triple
wasm32
Despite the above, clang wasm32 as an available target.
The clang wrapper script given by Nix seems to do something. The compiler should be called with clang-[VERSION] instead of clang, for example as:
clang-12 --target=wasm32 --no-standard-libraries \
-c -std=c99 -Ofast -Wall -Werror -pedantic \
input.c -o output.o

How to tranform clang .ast file to ir or bitcode file?

Apologize for my poor English.
[root#xxxx] ~
❯ clang -emit-ast aa.c
[root#xxxx] ~
❯ xxd aa.ast | head
00000000: 4350 4348 0108 0000 ce0a 0000 07c1 b3d0 CPCH............
00000010: 8cc2 2bb8 022d c8c2 2bb0 c22f 8802 2bbc ..+..-..+../..+.
00000020: c228 acc2 4312 b442 29d0 4228 9042 28d0 .(..C..B).B(.B(.
00000030: 4228 3c30 472b bc02 29d4 022b 94c2 2fb8 B(<0G+..)..+../.
I can get clang ast file with -emit-ast option
and I want to transform it to llvm ir.
But I cannot find any interface to solved it.
Anyone has suggests??
Clang AST files can be used in place of source files, so the following code works:
// main.cpp
#include <iostream>
int main() {
std::cout << "Hello, world!" << std::endl;
return 0;
}
> clang++ -emit-ast main.cpp -o a.ast
> clang++ a.ast -o a.out
> ./a.out
Hello, world!
Answering your question:
> clang -emit-llvm -c aa.ast

ESP8266 NONOS SDK: How to compile C++ code?

ESP8266 NONOS SDK: How to compile C++ code?
I'm somehow not able to compile C++ code using the ESP8266 NONOS SDK.
I use the gen_misc.sh-script to configure and compile the program,
but it outputs the following error:
start...
make[1]: Entering directory '/repos/esp/ESP8266_NONOS_SDK/diplomarbeit-firmware/user'
xtensa-lx106-elf-g++ -Os -g -Wpointer-arith -Wundef -Werror -Wl,-EL -fno-inline-functions -nostdlib -mlongcalls -mtext-section-literals -ffunction-sections -fdata-sections -fno-builtin-printf -DICACHE_FLASH -DSPI_FLASH_SIZE_MAP=3 -I include -I ./ -I ../../include/ets -I ../include -I ../../include -I ../../include/eagle -I ../../driver_lib/include -o .output/eagle/debug/obj/user_main.o -c user_main.cpp
xtensa-lx106-elf-ar ru .output/eagle/debug/lib/libuser.a .output/eagle/debug/obj/user_main.o
make[1]: Leaving directory '/repos/esp/ESP8266_NONOS_SDK/diplomarbeit-firmware/user'
xtensa-lx106-elf-gcc -L../lib -nostdlib -T../ld/eagle.app.v6.ld -Wl,--no-check-sections -Wl,--gc-sections -u call_user_start -Wl,-static -Wl,--start-group -lc -lgcc -lhal -lphy -lpp-lnet80211 -llwip -lwpa -lcrypto -lmain -ldriver user/.output/eagle/debug/lib/libuser.a -Wl,--end-group -o .output/eagle/debug/image/eagle.app.v6.out
../lib/libmain.a(app_main.o): In function `user_uart_wait_tx_fifo_empty':
(.irom0.text+0x6a0): undefined reference to `user_pre_init'
../lib/libmain.a(app_main.o): In function `user_uart_wait_tx_fifo_empty':
(.irom0.text+0x6b8): undefined reference to `user_init'
../lib/libmain.a(app_main.o): In function `flash_data_check':
(.irom0.text+0x718): undefined reference to `user_pre_init'
../lib/libmain.a(app_main.o): In function `flash_data_check':
(.irom0.text+0xac1): undefined reference to `user_init'
collect2: error: ld returned 1 exit status
../Makefile:398: recipe for target '.output/eagle/debug/image/eagle.app.v6.out' failed
make: *** [.output/eagle/debug/image/eagle.app.v6.out] Error 1
My code looks like that:
user_main.cpp
#include "user_interface.h"
#include "osapi.h"
#include "partition.h"
void ICACHE_FLASH_ATTR user_pre_init ()
{
// register partition table here
if (!system_partition_table_regist(partition_table,
sizeof(partition_table) / sizeof(partition_table[0]),
SPI_FLASH_SIZE_MAP))
{
os_printf("FAIL TO REGISTER PARTITION TABLE");
while (1) {}
}
}
class MyClass {
};
void user_init ()
{
os_printf("Hello world!\n");
}
I really don't know how to fix this problem.
The header files you are including are C header files, not C++. The C++ compiler will mangle the function names, leading to the above error you see. You need to wrap them in an extern block like this to tell the compiler not to mangle them:
extern "C" {
#include "user_interface.h"
#include "osapi.h"
#include "partition.h"
}

LLVM/Clang use opt to show linked ll file

I had two c files and want show IR for its linked bit code
link1.c
#include "link2.h"
int main() {
int a;
int b;
foo(a,b);
return 0;
}
link2.h
#include<stdio.h>
link2.c
#include "link2.h"
void foo(int a, int b) {
printf("%d\n", a);
printf("%d\n", b);
}
I did the following command to get bc file.
clang -o0 -emit-llvm file1.c -c -o file1.bc
clang -o0 -emit-llvm file2.c -c -o file2.bc
llvm-link -o link.bc link1.bc link2.bc
When I tried lli link.bc and llvm-dis link.bc it run correctly and showed linked ll file, but when I use opt link.bc -S -o link.ll to get ll file it just reported segmentation error. Can anyone let me know what to do with opt?
It seems like it is because version compatible issue of opt. I should use a 3.5 version but turns out I was using 3.4.2.

Is it possible code coverage of a shared library using gcov?

I try to test an executable which uses OpenCV shared library. When using gcov to know what code lines were covered I only get info about my .cpp files and .hpp of the library. No info is shown about .cpp files of the library.
I compiled and linked with -pg --coverage flags.
Yes, gcov can give coverage information about a shared library. If I remember correctly from the problems I had getting this to work on my project, you're probably not including the --coverage flag on the linking of the dynamic library. Here's the smallest example I could create.
Makefile:
CXXFLAGS += --coverage
LDFLAGS += --coverage
myexec: myexec.cpp libmylib.so
libmylib.so: mylib.o
gcc --coverage -shared -Wl,-soname,libmylib.so -o libmylib.so mylib.o
mylib.o: CXXFLAGS += -fPIC
myexec.cpp:
#include "mylib.h"
int main(int argc, char** argv)
{
return is_even(argc);
}
mylib.h
#ifndef MYLIB_H
#define MYLIB_H
int is_even(int num);
#endif
mylib.cpp
#include "mylib.h"
int is_even(int num)
{
if (num % 2)
return false;
else
return true;
}
Output of make (so you can see exactly what the build was):
g++ --coverage -fPIC -c -o mylib.o mylib.cpp
gcc --coverage -shared -Wl,-soname,libmylib.so -o libmylib.so mylib.o
g++ --coverage --coverage myexec.cpp libmylib.so -o myexec
I ran the executable using LD_LIBRARY_PATH="." ./myexec a, and then ran gcov mylib.cpp. Here's the contents of mylib.cpp.gcov:
-: 0:Source:mylib.cpp
-: 0:Graph:mylib.gcno
-: 0:Data:mylib.gcda
-: 0:Runs:1
-: 0:Programs:1
-: 1:#include "mylib.h"
-: 2:
1: 3:int is_even(int num)
-: 4:{
1: 5: if (num % 2)
#####: 6: return false;
-: 7: else
1: 8: return true;
-: 9:}

Resources