vitoral
vitoral

Reputation: 23

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: [email protected]
# 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!

Upvotes: 2

Views: 406

Answers (1)

Crowman
Crowman

Reputation: 25926

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.

Upvotes: 2

Related Questions