Lukas Bystricky
Lukas Bystricky

Reputation: 1272

Compiling a Fortran mex file with CMake

I have a Fortran project that I've compiled into mex. It has a bunch of Fortran files that have to be linked together, and some mex libraries. Using a Makefile like the one below, I was able to get this to work:

MEX=/opt/matlab/r2018a/bin/mex

FORTRAN = gfortran
FFLAGS = -c -fpic -fopenmp -Wall -O3 -fdefault-real-8 -fdefault-double-8
MEXLIBDIR = /opt/matlab/r2018a/sys/os/glnxa64
MEXLIB = -lgfortran -liomp5 -lirc -lsvml -limf 

OBJS=\
file_a.o\
file_b.o\

all: file_a file_b mex

mex: mex_executable.F $(OBJS) 
    $(MEX) -v -O mex_exectuable.F $(OBJS) -L$(MEXLIBDIR) $(MEXLIB)

file_a: file_a.f
    $(FORTRAN) $(FFLAGS) file_a.f

file_b: file_b.f
    $(FORTRAN) $(FFLAGS) file_b.f

Since I'll have several projects like this, I'd like to put everything into a single CMake file.

So far, I have a CMakeLists.txt that looks something like this, inside a build directory:

cmake_minimum_required(VERSION 2.8)
project(MEX)

enable_language(Fortran)

find_package(Matlab REQUIRED MAIN_PROGRAM MX_LIBRARY)    
set(CMAKE_LIBRARY_OUTPUT_DIRECTORY "${PROJECT_SOURCE_DIR}/bin/")

# Assuming gfortran
set(CMAKE_Fortran_FLAGS "-c -fpic -Wall -O3  -fopenmp -fdefault-real-8 -fdefault-double-8")

include_directories(
  ${Matlab_INCLUDE_DIRS}
)

# Add modules with MEX to be built
add_subdirectory("${PROJECT_SOURCE_DIR}/Project1")

And inside the Project1 directory I have, another CMakeLists.txt:

include_directories(
  ${CMAKE_CURRENT_SOURCE_DIR}
)

## MEX functions
matlab_add_mex(
    NAME mex_executable
    SRC mex_executable.F *.f
)
target_link_libraries(mex_executable lgfortran liomp5 lirc lsvml limf )

When I run the CMake I get the error:

Cannot find source file:

    *.f

  Tried extensions .c .C .c++ .cc .cpp .cxx .m .M .mm .h .hh .h++ .hm .hpp
  .hxx .in .txx

What is the correct way to tell CMake to compile the Fortran files and link the correct mex libraries?

Upvotes: 1

Views: 264

Answers (1)

Kevin
Kevin

Reputation: 18243

This error likely results from the arguments provided to the matlab_add_mex() command here:

matlab_add_mex(
    NAME mex_executable
    SRC mex_executable.F *.f
)

The SRC argument accepts a list of source files, and likely cannot resolve the *.f provided. It would be best to list each file individually:

matlab_add_mex(
    NAME mex_executable
    SRC mex_executable.F file_a.f file_b.f
)

Or, you can use CMake's GLOB to create a list of .f source files, and use that list instead:

file(GLOB FORTRAN_SRCS_LIST *.f)
matlab_add_mex(
    NAME mex_executable
    SRC mex_executable.F ${FORTRAN_SRCS_LIST}
)

Upvotes: 1

Related Questions