How do I use CMake to build an ispc file? - c

I have a simple project. It contains two files:
main.c
kernel.ispc
(ispc files are source for https://ispc.github.io/)
To manually compile the file I would just use:
ispc --target=sse2 kernel.ispc -o kernel.o
gcc -c main.c -o main.o
gcc main.o kernel.o -o my_program
So for my cmake file it would look intially look like
project(my_program)
add_executable(my_program main.c)
but of course it wont link as it's missing symbols that are in kernel.o
So the question is:
How do I get cmake to compile kernel.ispc using the ispc compiler, and how do I get cmake to then link it into my_program?

How do I get cmake to compile kernel.ispc using the ispc compiler?
Just use add_custom_command:
add_custom_command(OUTPUT kernel.o
COMMAND ispc --target=sse2 ${CMAKE_SOURCE_DIR}/kernel.ispc -o kernel.o
DEPENDS kernel.ispc)
How do I get cmake to then link it into my_program?
From CMake view, .o files are just another sources for executable:
add_executable(my_program main.c kernel.o)

I know this is an old question, but CMAKE 3.19 now has built in support for ISPC.

Related

CMake compile NASM and C and link everything together

I'm trying to compile assembly files with NASM and C files with GCC and link all object files together. Moreover, I'd like the C preprocessor to process the assembly files as well. This is normally no problem from the command line or a simple makefile, but I've had some trouble in replicating this functionality in CMake.
The exact process, assuming three files (boot.S, kernel.c, link.ld) would look something like this:
gcc -E -P boot.S -D <...> -o boot.s
nasm -f elf32 boot.s -o boot.o
gcc -c kernel.c -o kernel.o -ffreestanding -O2 -Wall -Wextra
Now its time to link. I want to do this like this (maybe with a few extra flags):
gcc -T link.ld -o out.bin -ffreestanding -O2 -nostdlib boot.o kernel.o -lgcc
The problems with CMake are the following:
Cmake support for NASM is weird at best. When adding .S files as sources to targets they don't get recognized as assembly files and I get hit with 'cannot determine linker language for target'. I have tried adding 's S' to CMAKE_ASM_NASM_SOURCE_FILE_EXTENSIONS but it still doesn't work unless I manually set the languages with set_source_files_properties(). Moreover, as is pointed out here, CMAKE_ASM_NASM_LINK_EXECUTABLE is broken.
As far as I understand, after compiling source files to objects, CMake attempts to link them automatically. Which linker will it use to link all .o files? Will it use the linker for C? Will it use the linker for NASM? The answer is relevant, because I need to configure it with the flags I mentioned above.
What would an example CMakeLists.txt would look like that replicates the previously mentioned process? Also do I need a create_custom_command() in order to invoke just the preprocessor? Thank you.

Compiling on RaspberryPi by using make

When I use make to compile the RaspberryPi's source code, the error happens like this:
"bmp180.c:(.text+0xe8): undefined reference to `bcm2835_i2c_write'"
However, I have used the "-l bcm2835", the makefile as follow:
#makefile
bmp: main.o bmp180.o
gcc -o bmp main.o bmp180.o
main.o: main.c bmp180.h
gcc -c main.c -l bcm2835.h
bmp180.o: bmp180.c bmp180.h
gcc -c bmp180.c -l bcm2835.h
clear:
rm -f main.o bmp180.o
You have -l bcm2835.h in your Makefile. The name of the library is simply bcm2835. Files ending with .h are files meant to be #include'd in your C source; they are not dynamic shared libraries.
Additionally, shared libraries are required at the link stage, not the compile stage; you will need to add -l bcm2835 to the linking step:
bmp: main.o bmp180.o
gcc -o bmp main.o bmp180.o -l bcm2835
The -l arguments in your compile steps are effectively no-ops (but they won't hurt anything).

Error compiling C code using MinGW-w64 in Windows 7

I'm trying to compile code from a backtrace project https://code.google.com/p/backtrace-mingw/ which is written for MinGW, but using MinGW-w64.
My old install and fresh install of MinGW-w64 produce the same problem. Path is set in path variables, and also in command prompt:
C:\mingw-w64\i686-4.9.2-win32-sjlj-rt_v3-rev1\mingw32\bin
and C:\mingw-w64\i686-4.9.2-win32-sjlj-rt_v3-rev1\mingw32 although this one isn't needed.
This is the makefile of that project:
.PHONY: all clean
all : backtrace.dll test.exe
backtrace.dll : backtrace.c
gcc -O2 -shared -Wall -o $# $^ -lbfd -lintl -liberty -limagehlp
test.exe : test.c
gcc -g -Wall -o $# $^
clean :
-del -f backtrace.dll test.exe
When compiling I get the warning:
backtrace.c:23:17: fatal error: bfd.h: No such file or directory #include < bfd.h>`
Which is weird because that file exists in ../mingw32/include folder.
If I add this when compilind the dll: -IC:\mingw-w64\i686-4.9.2-win32-sjlj-rt_v3-rev1\mingw32\include it continues but stops at the directive: #error config.h must be included before this header and config.h is missing in MinGW-w64
Any ideas?
That path is definetely missing from gcc include paths in mingw. I don't know why. You have to add it yourself in any way you like: cmake recipe, autoconf recipe, CFLAGS, CPATH, gcc specs.
And, as far as I remember, it uses only HAVE_STRINGIZE macro from config.h and it is used only to define CONCAT4 macro, that's not used anywhere in bfd.h. So, it's safe to cheat a little and put
#define PACKAGE package
before including bfd.h
add this to the end of the compile statement:
-I./mingw32/include
so the whole compile statement would be:
gcc -g -Wall -o $# $^ -I./mingw32/include
so the compiler knows where to find the include files

Is it possible to link bitcode with llvm-ar archieve into a single bitcode file?

I have read this thread on llvm-dev and is faced with the same problem: I cannot link the llvm-ar archieve library with other bitcode files into another single bitcode file with the help of llvm-link.
clang -emit-llvm -g -c -o main.bc main.c
clang -emit-llvm -g -c -o calc.bc calc.c
llvm-ar rcs libcalc.la calc.bc
llvm-link libcalc.la main.bc -o test
the problem is the same: llvm-link complains
llvm-link: libcalc.la:1:2: error: expected integer
!<arch>
^
And after reading How to link object to libraries with LLVM >= 3.1 ? ( no GNU ld ), I also tried a llvm2.9 version of llvm-ld.
llvm-ld --disable-opt libcalc.la main.bc -o test
however libcalc.la is not linked into the module correctly and lli reports:
LLVM ERROR: Program used external function 'Square' which could not be resolved!
So what should i do?
UPDATE
I then read Can't link against static library when compiling objects from LLVM bitcode. and find that llvm-ld WORKS when changing the order:
llvm-ld --disable-opt main.bc libcalc.la -o test
But llvm-link still fails.
llvm-link does not support bitcode archives, AFAIK. It simply goes over the input files it was provided, and tries to parse each one as a bitcode file (either binary or textual LLVM IR).
llvm-ld doesn't exist in the newer LLVMs, so I would suggest to stay away from it completely.
Just link the separate .bc files together with llvm-link. The archiving of bitcode files doesn't have the same benefits for the linker as in native linking anyway.
You don't need archivers to link your bitcode files:
clang -emit-llvm -g -c -o main.bc main.c
clang -emit-llvm -g -c -o calc.bc calc.c
clang main.bc calc.bc -o test

Can't load dll in linux gcc

I'm trying to compile my code with a DLL i made and I get the error below when i write ./prog
./prog: error while loading shared libraries: libctest.so.1: cannot open shared object file: No such file or directory
I followed the tutorial here and my mono app has no problem loading the dll and calling the functions. The key parts of the tutorial were
gcc -Wall -fPIC -c *.c
gcc -shared -Wl,-soname,libctest.so.1 -o libctest.so.1.0 *.o
mv libctest.so.1.0 /opt/lib
ln -sf /opt/lib/libctest.so.1.0 /opt/lib/libctest.so.1
ln -sf /opt/lib/libctest.so.1.0 /opt/lib/libctest.so
My C# code does
[DllImport("path/to/CDLL", CallingConvention = CallingConvention.Cdecl)]
public static extern void test();
I built with
gcc -Wall -L/opt/lib main.c -lctest -o prog
This is the first thing i changed. prog.c to main.c. From there I simply run with ./prog to get the error at the top of this question. I do this as root so there shouldn't be permission issues. I also chmod 755 the so's. What am I doing wrong? This is opensuse. I had to create the /opt/lib so I am thinking this path isn't registered where it should be
The dynamic linker ld.so will not look in /opt/lib by default when attempting to resolve library dependencies. You have to tell the linker about the non-standard library directories or add the /opt/lib path to your prog binary.
eg
LD_LIBRARY_PATH=/opt/lib ./prog
or, link prog with the -rpath linker option. This provides an additional path for the linker to search when resolving locations of shared objects.
gcc -Wall -L/opt/lib -Wl,-rpath,/opt/lib main.c -lctest -o prog
You can use the ldd command on a binary to show the locations of shared libraries.
ldd prog
This will currently show that libctest.so cannot be found. With an additional search path, the following command should show that all libraries are resolved:
LD_LIBRARY_PATH=/opt/lib ldd prog

Resources