Compiling on RaspberryPi by using make - c

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).

Related

compile multiple cuda files (that have dynamic parallelism) and MPI code

I have a bunch of .cu files that use dynamic parallelism (a.cu, b.cu, c.cu.., e.cu, f.cu), and a main.c file that uses MPI to call functions from a.cu on multiple nodes. I'm trying to write a make file to compile the executable, but I keep facing the following errors:
cudafiles.o: In function `__cudaRegisterLinkedBinary_66_tmpxft_00001a84_00000000_17_cuda_device_runtime_compute_61_cpp1_ii_8b1a5d37':
link.stub:(.text+0x1fb): undefined reference to `__fatbinwrap_66_tmpxft_00001a84_00000000_17_cuda_device_runtime_compute_61_cpp1_ii_8b1a5d37'
Here is my makefile:
INCFILES=-I/usr/local/cuda-8.0/include -I/opt/mpi/mvapich2-gnu/2.2/include -I./
LIBFILES=-L/usr/local/cuda-8.0/lib64 -L/opt/mpi/mvapich2-gnu/2.2/lib
LIBS=-lcudart -lcudadevrt -lcublas_device -lmpi
ARCH=-gencode arch=compute_60,code=sm_60
NVCC=nvcc -ccbin g++
default: all
all: clean final.o
io.o: io.cpp
g++ -c -std=c++11 io.cpp
final.o: io.o a.cu b.cu c.cu d.cu e.cu f.cu main.cpp
$(NVCC) -std=c++11 $(INCFILES) $(LIBFILES) $(LIBS) -g -G -Xptxas -v -dc $(ARCH) a.cu b.cu c.cu d.cu e.cu f.cu
$(NVCC) -std=c++11 $(ARCH) $(INCFILES) $(LIBFILES) $(LIBS) -rdc=true -dlink a.o b.o c.o d.o e.o f.o io.o -o cudafiles.o
mpicxx -O3 $(INCFILES) $(LIBFILES) -c main.cpp -o main.o
mpicxx $(INCFILES) $(LIBFILES) $(LIBS) cudafiles.o a.o b.o c.o d.o e.o f.o io.o main.o -o exec
clean:
rm -rf *.o exec
The original problem reported was an undefined reference to main. This was arising from this line in the Makefile:
$(NVCC) -std=c++11 $(ARCH) $(INCFILES) $(LIBFILES) $(LIBS) -rdc=true a.o b.o c.o d.o e.o f.o io.o -o cudafiles.o
As constructed, this actually instructs nvcc to perform full/final linking. However the intent of this line was to perform the device-link step only, required when compiling with -rdc=true or -dc, and when not performing the final link with nvcc. In this case, the final link was being performed by mpicc/mpicxx. To perform the device-link step only, we need to specify -dlink. Without that switch, nvcc expects to do final linking, but fails because none of the supplied objects contain a main function. The correct solution, since we have no intent to do final link at this point, is to use the -dlink switch.
I also suggested converting everything to C++ style linking, since nvcc links that way. It might be possible to sort out a C-style link with a C++-style link, but this just seems troublesome to me. Therefore I suggested converting the only .c file (main.c) to a .cpp file, and convert from mpicc to mpicxx
The next problem that arose was undefined references to e.g. cudaSetDevice() and cudaFree(). These are part of the CUDA runtime API library ("libcudart"). When performing final link with nvcc, these are linked automatically. But since final link is being performed by mpicxx (basically a wrapper on g++), it's necessary to call out the link against that library specifically with -lcudart.
Finally, the remaining problem was a link-order problem. In a nutshell, link dependencies need to be satisfied from left to right in the linker command line. Different compilers are more or less picky about this. The final reordering changes were to specify the libraries to link against in the correct order, and also to specify these libraries at the end of the link command line, so that any dependencies on these libraries, to their left in the link command line, are satisfied.

How can I compile a header file and a C file together?

I created a file.h and a file.c how can I compile them on Ubuntu?
You only need to compile your .c file(s), not your .h file(s).
To compile file.c on Ubuntu, you can use GCC:
gcc file.c -o my_program
...or Clang:
clang file.c -o my_program
It is possible to precompile your header files, but you only need precompiled headers in particular cases. More information here.
If file.h is not in the same folder as file.c, you can use GCC or Clang's -I option.
Example if file.h is in the include/ folder:
gcc -I include/ file.c -o my_program
In file.c you still have this instruction, with only the filename:
#include "file.h"
You can also use a more generic approach by the usage of a makefile.
Here is a short example of such a file:
# Declaration of variables
CC = gcc
CC_FLAGS = -w -Werror -Wall
# File names
# "prgoram" will be the name of the output produced from the make process
EXEC = program
#Incorporates all the files with .c extension
SOURCES = $(wildcard *.c)
OBJECTS = $(SOURCES:.c=.o)
# Main target
$(EXEC): $(OBJECTS)
$(CC) $(OBJECTS) -o $(EXEC)
# To obtain object files
%.o: %.c
$(CC) -c $(CC_FLAGS) $< -o $#
# To remove generated files
clean:
rm -f $(EXEC) $(OBJECTS)
To use this utility just make sure that the file itself is within the directory containing your source files and its name is either "makefile" or "Makefile".
To compile the code simply run the following command from your working directory:
make program
This command will automatically link all the source files within your working directory into one executable file with the name of "program". To run the program itself just use the command:
./program
To clean your project and the created executable you can run the command:
make clean
The makefile is very powerful when dealing with larger projects that contain a larger number of source files. Here you can check for more guidance on how to use makefiles. This is also a very detailed tutorial on the topic.
Use following command to compile your program(For GCC Compiler):
gcc file.c -o file
No need to compile file.h file.

GNU g++ -G option to create a shared library available on Solaris not on Linux

I am using GNU g++ 4.9.2 compiler both on Solaris and Linux.
On Solaris platform, to create a shared library from a source file (a.c), I use the following command:
g++ -G a.c -o a
a becomes a shared library
a.c contains the following code:
void libfn1()
{
}
If I try not to use -G option i.e. compile as:
g++ a.c -o a
It gets a linker error: Undefined Symbol main
But, on Linux, if I do the same thing: it says:
g++: error: unrecognized command line option -G
How to create a shared library on Linux? What is the g++ option for that?
The g++ documentation says this:
These additional options are available on System V Release 4 for
compatibility with other compilers on those systems:
-G Create a shared object. It is recommended that -symbolic or -shared be
used instead.
Normally you want to generate position independent code too, for a shared library, with the -fPIC flag.
So you'd want to run:
g++ -fPIC -shared a.c -o liba.so
The process to create a shared library on a Linux system is a bit different.
Shared libraries on Linux are .so (for "shared object") files, not .g.
You do it like this:
First, you need to generate position-independent code from your C++ source. That is so your library works from wherever it is called. To do that, you should use g++'s -fPIC flag.
So, for each source file you want to be included in your library, you should only compile it to position-independent code. We'll handle linking later.
For each source file:
g++ -c -fPIC file.cpp
(The -c flag tells g++ "compile, don't link").
for each file.cpp, g++ will generate file.o, an object file containing position-independent code.
To then build the object files into a shared library, you should use
g++ -o -shared myLibrary.so {all_object_files}
So if you have file1.o, file2.o and file3.o, the command would be:
g++ -shared -o myLibrary.so file1.o file2.o file3.o
Of course, if you have a lot of files this can get pretty tedious, so you should write a Makefile to automate this process for you! Here's an example:
myLibrary.so: file1.o file2.o file3.o
$(CXX) -shared $^ -o $#
file1.o file2.o file3.o : CXXFLAGS+=-fPIC

Linking static library with -l flag

How can I have my makefile compile with the -l flag?
I have a makefile that looks like
myLibrary:
gcc -c myLibrary.c -o myLibrary.o
ar cr libmyLibrary.a myLibrary.o
and then I compile my main program with
main:
gcc -g -c -o main.o main.c
gcc main.o -o main libmyLibrary.a
The above makefile works, but if I want to replace
libmyLibrary.a
with -lmyLibrary I get an error. Shouldn't both be working the same?
Here is a rudimentary, unrealistic makefile that will make the static library libmyLibary
before it makes the program main, which it will link with the static library
using the -L (library search-path) and -l (library) options.
Makefile
.PHONY: all clean
all: libmyLibrary.a main
main: main.o | libmyLibrary.a
$(CC) -o main main.o -L. -lmyLibrary
libmyLibrary.a: myLibrary.o
$(AR) rcs libmyLibrary.a myLibrary.o
clean:
rm -f *.o libmyLibrary.a main
which runs like:
$ make
cc -c -o myLibrary.o myLibrary.c
ar rcs libmyLibrary.a myLibrary.o
cc -c -o main.o main.c
cc -o main main.o -L. -lmyLibrary
As I think you know, it's unrealistic to make both a library and a program
that links with it in the same makefile, since the point of a library is
that you don't need to keep remaking it to link it with many programs. You'd really have
a makefile for libmyLibrary.a and other makefiles for programs that
use it.
This is how the gcc linkage options -L and -l work:
-L/path/to/search
tells the linker to look for any libraries that you specify with the -l option in /path/to/search,
before it looks for them in its default search directories. The current directory, .,
isn't one of the linker's default search directories. So if you want it to
find a library specified with the -l option in the current directory, then you need to
specify -L.
-lfoo
tells the linker to search for either a dynamic library, libfoo.so, or a static
library, libfoo.a, first in your -L directories, if any, in the order you've
specified them, and then in its default search directories. It stops searching
as soon as if finds either libfoo.so or libfoo.a in one of the search directories.
If it finds both of them in the same directory, then by default it will link libfoo.so with
your program and not link libfoo.a.
To link purely statically library, use -static, Like
gcc -static main.c libmyLibrary.a
And run executable file ./a.out GCC Linux.

How do I use CMake to build an ispc file?

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.

Resources