vitoral vitoral - 3 months ago 14
C Question

Can't get a C source file to compile when including math.h using a makefile in Linux

I am trying to compile a parallel C program with MPI in Linux. I am aware that I have to include -lm in the compiler/linker flags so that math.h is properly included.

However, I am using a makefile and can't get the src file that includes math.h to compile, even if I put the -lm flag in the variables CFLAGS and LFLAGS. It keeps saying that the symbols defined in math.h (M_PI, sin, cos, sqrt, ...) are not declared.

Below is the makefile that I am using.

# ------------------------------------------------
# Generic Makefile
#
# Author: yanick.rochon@gmail.com
# Date : 2011-08-10
#
# Changelog :
# 2010-11-05 - first version
# 2011-08-10 - added structure : sources, objects, binaries
# thanks to http://stackoverflow.com/users/128940/beta
# ------------------------------------------------

# project name (generate executable with this name)
TARGET = vdynamics

CC = mpicc
# compiling flags here
CFLAGS = -std=c99 -Wall -I.

LINKER = mpicc -o
# linking flags here
LFLAGS = -Wall -lm

# change these to set the proper directories where each files should be
INCDIR = includes
SRCDIR = src
OBJDIR = obj
BINDIR = bin

SOURCES := $(wildcard $(SRCDIR)/*.c)
INCLUDES := $(wildcard $(INCDIR)/*.h)
OBJECTS := $(SOURCES:$(SRCDIR)/%.c=$(OBJDIR)/%.o)
rm = rm -f


$(BINDIR)/$(TARGET): $(OBJECTS)
@$(LINKER) $@ $(OBJECTS) $(LFLAGS)
@echo "Linking complete!"

$(OBJECTS): $(OBJDIR)/%.o : $(SRCDIR)/%.c
@$(CC) $(CFLAGS) -c $< -o $@
@echo "Compiled "$<" successfully!"

.PHONEY: clean
clean:
@$(rm) $(OBJECTS)
@echo "Cleanup complete!"

.PHONEY: remove
remove: clean
@$(rm) $(BINDIR)/$(TARGET)
@echo "Executable removed!"


EDIT:

The error message I get:

src/vtx_vtx_force.c: In function 'vdyn_vtx_vtx_force':
src/vtx_vtx_force.c:30:20: error: 'M_PI' undeclared (first use in this function)
double pi_Lx = M_PI/Lx;
^
src/vtx_vtx_force.c:30:20: note: each undeclared identifier is reported only once for each function it appears in
make: *** [obj/vtx_vtx_force.o] Error 1


The source file I am trying to compile: (I was able to compile it in Mac OS, the problem happened when I tried in Linux)

#include <stdlib.h>
#include <math.h>
#include <stdio.h>
#include <assert.h>

#include "vortex_dynamics.h"

void vdyn_vtx_vtx_force(vdyn_force_t F[], const vdyn_vortex_t vtx[], const vdyn_simulation_box_t* box, size_t start, size_t stop)
{
assert(box != NULL);
assert(start >= 0);
assert(stop < box->nVtx);
assert(stop >= start);

double Lx = box->xLength;
double Ly = box->yLength;

// as variaveis comecando com t sao termos
// das equacoes a serem resolvidas.
double tcos = 0;
double tsin = 0;
double tcosh = 0;
double tsinh = 0;
double ttemp = 0;
double rx_Lx = 0;
double ry_Ly = 0;

// os 2 proximos termos não dependem dos
// vortices, apenas da caixa de simulacao.
double pi_Lx = M_PI/Lx;
double twopi_times_Ly_Lx = 2*M_PI*Ly/Lx;

double Fx = 0;
double Fy = 0;
size_t nVtx = box->nVtx;
size_t i = 0;
size_t j = 0;
int k = 0;

// lembrando que f_index = 0 corresponde ao vortice em que
// indice = start no vetor de vortices.
size_t f_index = 0;

for (i = start; i <= stop; ++i)
{
F[f_index].Fx = 0;
F[f_index].Fy = 0;
Fx = 0;
Fy = 0;
for (j = 0; j < nVtx; ++j)
{
if (j != i)
{
// resolvendo as equacoes por partes. Alguns termos
// independem de k. Por isso, podemos calcula-los
// antes de "for (k = ...)".
rx_Lx = (vtx[i].x - vtx[j].x)/Lx;
ry_Ly = (vtx[i].y - vtx[j].y)/Ly;

// calculo dos termos com seno e cosseno (numerador
// de Fx e denominador de Fx/Fy).
ttemp = 2*M_PI*rx_Lx;
tsin = sin(ttemp);
tcos = cos(ttemp);
for (k = -VDYN_NBOXES; k <= VDYN_NBOXES; ++k)
{
ttemp = twopi_times_Ly_Lx*(ry_Ly+(double)k);
tcosh = cosh(ttemp);
tsinh = sinh(ttemp);
ttemp = tcosh - tcos;
Fx += tsin/ttemp;
Fy += tsinh/ttemp;
}
Fy -= 2*ry_Ly;
}
}

// O termo que multiplica o somatorio é comum a todas as
// contribuicoes. Por isso, pi/Lx foi colocado em evidencia.
Fx *= pi_Lx;
Fy *= pi_Lx;

F[f_index].Fx = Fx;
F[f_index].Fy = Fy;
++f_index;
}

assert(f_index == (stop-start+1));
}


Thank you!

Answer

M_PI is not a standard macro, and it looks like it doesn't exist on your implementation. You can just define it yourself, instead.