Makefile and CImg - makefile

I am having trouble developing a makefile for a code using the CImg library. I have 3 files:
mainProgram.cpp
program.cpp
program.h
CImg.h // CImg library
In the mainProgram.cpp
#include "program.h"
In the program.cpp
#include "program.h"
In the program.h
#ifndef PROGRAM_H
#define PROGRAM_H
#include "CImg.h"
#include <vector>
#include <string>
#include <iostream>
#include <sstream>
using namespace std;
using namespace cimg_library;
I am using a MAC and it suggested to compile it using: g++ -o snake mainSnake.cpp -O2 -lm -lpthread -I/usr/X11R6/include -L/usr/X11R6/lib -lm -lpthread -lX11
But, I am having difficulty communicating this to a makefile. Can anyone assist me?

The simplest make file would be
all:mainProgram.cpp program.cpp program.h
g++ -o snake mainSnake.cpp -O2 -lm -lpthread -I/usr/X11R6/include -L/usr/X11R6/lib -lm -lpthread -lX11
If you read some basics of makefile writing then you can first create the object files then create the final snake executable
May be this would help you get started with. The similar example is given but in c.

Related

Building glut with Makefile in mac OSX

completely Makefile newbie here. I was asked by a professor to submit a Makefile along with the actual source code. I'm having a hard time getting the linker to find the Glut files.
My application has the following structure
My main.cpp has the following dependencies:
#include <iostream>
#include <fstream>
#include <vector>
#include <string>
#include "renderer.cpp"
My renderer.cpp has the following dependencies:
#define GL_SILENCE_DEPRECATION
#ifdef __APPLE__
#include <GLUT/glut.h>
#else
#include <GL/glut.h>
#endif
#define _USE_MATH_DEFINES
#include <math.h>
#include <iostream>
#include <vector>
#include "reader.cpp"
#include "../../../Common/Point.h"
My reader.cpp has the following dependencies:
#include <iostream>
#include <fstream>
#include <vector>
#include <string>
#include "../headers/reader.h"
#include "../../../Common/Point.h"
And finally my Point.cpp has the following dependencies:
#include <iostream>
#include <sstream>
#include "Point.h"
I have zero experience with Makefile, and all i know was taken from a youtube video i watch to have a base of what to do. The Makefile goes as follows:
engine: main.o renderer.o reader.o Point.o
g++ main.o renderer.o reader.o Point.o -o engine
main.o: main.cpp
g++ -c main.cpp $ ./renderer.cpp $(-framework GLUT -framework OpenGL -framework Cocoa)
renderer.o: renderer.cpp
g++ -c renderer.cpp $(-framework GLUT -framework OpenGL -framework Cocoa) $ ./reader.cpp $ ../../../Common/Point.h
reader.o: reader.cpp
g++ -c reader.cpp $ ../headers/reader.h $ ../../../Common/Point.h
Point.o: ../../../Common/Point.cpp
g++ -c ../../../Common/Point.cpp $ ../../../Common/Point.h
clean:
rm *.o
rm *.xml
rm *.3d
When i try to run the make, i get the error "Undefined symbols for architecture x86_64:" followed by every glut/Opengl function i call.
I know the makefile is completely bad written but i would really appreciate some help.

How to use precompiled headers with gcc if linking against openmp

Minimal example:
// file: main.cpp
#include "pch.h"
int main()
{
std::cout << "test" << std::endl;
return 0;
}
--
// file: pch.h
#include <iostream>
Works fine and as expected if I compile this with
g++ pch.h
g++ main.cpp -Winvalid-pch
However once I change the last line to:
g++ main.cpp -fopenmp -Winvalid-pch
usage of the precompiled header is disabled:
warning: pch.h.gch: not used because `_REENTRANT' is defined [-Winvalid-pch]
How can I still use precompiled headers while linking to OpenMP? Why does the _REENTRANT define conflict with using a precompiled header at all?
You must generate .pch and compile sources with identical flags. -fopenmp implies #pragma omp and -pthread.
g++ -fopenmp pch.h
g++ main.cpp -fopenmp -Winvalid-pch
Or at least
g++ -pthread pch.h
g++ main.cpp -fopenmp -Winvalid-pch

Make - what files do I need to state as prerequisites for a target with multiple #include statements?

Assuming I have this example.h:
// example.h
#include "a.h"
#include "b.h"
#include "c.h"
#include "d.h"
#include "e.h"
And example.c:
// example.c
#include "example.h"
#include "a.h"
#include "b.h"
#include "c.h"
#include "d.h"
#include "e.h"
Should my Makefile look like this? :
example.o : example.h example.c
gcc -c example.c -o example.o
Or should it look like this? :
example.o : example.h example.c a.h b.h c.h d.h e.h
gcc -c example.c -o example.o
1) It should look like your second version:
example.o : example.h example.c a.h b.h c.h d.h e.h
gcc -c example.c -o example.o
2) There is no reason for the same #include statement to appear in both example.h and example.c, and redundant #include statements are kruft and ought to be removed. For safety, put them in example.h; for efficiency, put them in example.c when you can. (I won't go into the details of when you can here, but the compiler will tell you when you get it wrong.)
3) If you don't want to maintain that list of headers in the makefile, gcc and Make can take care of it for you. Here's an example, but this is an advanced technique, so I advise you not to use it until you understand how it works:
example.o : example.c
gcc -MMD -c example.c -o example.o
-include *.d

linking OpenMP statically with GCC

Given the following file print.cpp
#include <stdio.h>
int main() {
printf("asdf\n");
}
I can link this statically like this
g++ -static print.cpp
or like this
g++ -static-libgcc -Wl,-Bstatic -lc print.cpp -o print
But now let's add a little OpenMP and call the file print_omp.cpp
#include <omp.h>
#include <stdio.h>
int main() {
printf("%d\n", omp_get_num_threads());
}
I can link this statically like this (I checked it with ldd)
g++ -fopenmp -static print_omp.cpp
However, this does not work
g++ -fopenmp -static-libgcc -Wl,-Bstatic -lc print_omp.cpp -o print
I have tried various combinations of -Wl,--whole-archive -lpthread -Wl,--no-whole-archive and -lgomp -lpthread but no luck (I get various problems linking to pthreads). Can someone explain how I can do this without using the -static option?
GCC says
On glibc-based systems, OpenMP enabled applications cannot be statically linked due to limitations of the underlying pthreads-implementation
However, since g++ -fopenmp -static print_omp.cpp works just fine this does not make sense to me.
Edit:
I figured this out. The library GOMP comes with GCC whereas pthreads and libc come from GLIBC. So I can link GOMP statically like this
ln -s `g++ -print-file-name=libgomp.a`
g++ foo.cpp -static-libgcc -static-libstdc++ -L. -o foo -O3 -fopenmp
ldd shows
linux-vdso.so.1 => (0x00007fff71dbe000)
libpthread.so.0 => /lib/x86_64-linux-gnu/libpthread.so.0 (0x00007fc231923000)
libc.so.6 => /lib/x86_64-linux-gnu/libc.so.6 (0x00007fc23155c000)
/lib64/ld-linux-x86-64.so.2 (0x00007fc231b5c000)
However, if I the try this
ln -s `g++ -print-file-name=libpthread.a`
g++ foo.cpp -static-libgcc -static-libstdc++ -L. -o foo -O3 -fopenmp
It won't link. Pthreads and libc must be linked statically together. So once I add
ln -s `g++ -print-file-name=libc.a`
g++ foo.cpp -static-libgcc -static-libstdc++ -L. -o foo -O3 -fopenmp
ldd returns
not a dynamic executable
I really don't get why you may want to link only libgomp statically, but having separate compilation and linking commands may help. For instance assume main.cpp contains:
#include <omp.h>
#include <stdio.h>
int main() {
#pragma omp parallel
{
printf("%d\n", omp_get_thread_num());
}
}
Then:
~/tmp$ ls
main.cpp
~/tmp$ g++ -Wall -Werror -pedantic -fopenmp main.cpp -c
~/tmp$ ls
main.cpp main.o
~/tmp$ locate libgomp.a
${SOME_PATH_TO_LIBGOMP}/libgomp.a
~/tmp$ g++ -Wall -Werror -pedantic main.o -o main.x ${SOME_PATH_TO_LIBGOMP}/libgomp.a -pthread
~/tmp$ ls
main.cpp main.o main.x
~/tmp$ ldd main.x
linux-gate.so.1 => (0xb7747000)
libstdc++.so.6 => /production/install/gnu/compiler/gcc/lib/libstdc++.so.6 (0xb765c000)
libm.so.6 => /lib/i386-linux-gnu/libm.so.6 (0xb75fa000)
libgcc_s.so.1 => /production/install/gnu/compiler/gcc/lib/libgcc_s.so.1 (0xb75de000)
libpthread.so.0 => /lib/i386-linux-gnu/libpthread.so.0 (0xb75c2000)
libc.so.6 => /lib/i386-linux-gnu/libc.so.6 (0xb7413000)
/lib/ld-linux.so.2 (0xb7748000)
The most clean solution I've found for this is by modifying the libgomp.spec. Mine is at /usr/local/lib64/libgomp.spec. Change the content as follow:
*link_gomp: -l:libgomp.a %{static: -ldl }

while build a demo about ffmpeg , it occurs : undefined reference to `av_register_all'

This problem has bothered me for days.
After I compile and install ffmpeg , I try to build a demo using it, but it always fails.
The demo is:
#include "libavcodec/avcodec.h"
#include "libavformat/avformat.h"
int main(int argc,char *argv[]) {
av_register_all();
return 1;
}
With gcc main.c -o main.o, an error occurs: undefined reference to 'av_register_all'
Building with: gcc main.c -o main.o -lm -ld -lz -lavcodec -lavformat -lavutil, another error occurs: /usr/bin/ld: cannot find -ld
How can I resolve this?
Putting includes within extern "C" block may work.
extern "C"{
#include <libavcodec/avcodec.h>
#include <libavformat/avformat.h>
#include <libswscale/swscale.h>
}
As mentioned here
the order of libraries matters
so in your case the following hopefully should work:
gcc main.c -o main.o -lavformat -lavcodec -lavutil -lz -lm -lpthread
gcc filename.c -o outputfilename -lavformat -lavcodec -lavutil -lz -lm -lpthread -I'/usr/local/include' -lswresample
The above command will help to compile properly.
Have a look at how this project builds sample code.
The Makefile is pretty simple to follow.
It's work for me:
gcc <your source code> -o main -lavformat -lavcodec -lavutil -lm -lpthread -I'/usr/local/include' -lswresample

Resources