Compiling issue in C++ using Docker

Hello,

I have been trying to compile FEniCs in C++ in Docker. I am using mac (M2). I pulled the docker image (fenics-gmsh) by running the command:

docker pull ghcr.io/scientificcomputing/fenics-gmsh:2024-02-19

I made a simple cpp code (test.cpp) to see if it works:

#include <dolfin.h>

using namespace dolfin;

int main()
{
    return 0;
}

I tried to comlie the code by runing: make test. Here is the error:

In file included from /usr/local/include/dolfin/mesh/Facet.h:28,
                 from /usr/local/include/dolfin/mesh/dolfin_mesh.h:19,
                 from /usr/local/include/dolfin.h:10,
                 from test.cpp:1:
/usr/local/include/dolfin/mesh/Cell.h:34:10: fatal error: ufc.h: No such file or directory
   34 | #include <ufc.h>
      |          ^~~~~~~
compilation terminated.

I need to mention that I can run FEniCS codes in python without any problem in this docker environment. The issue is just with compiling with C++. I was not even able to find the folder /usr/local/include. It seems like the ufc.h file is not inside the mesh folder in the docker image.
Is there any fix for this issue?

How does your CMakeLists.txt look like?
This is how the demo (Poisson) CMakeLists looks like if you generate the cmake files:

# This file is automatically generated by running
#
#     cmake/scripts/generate-cmakefiles
#
# Require CMake 3.5
cmake_minimum_required(VERSION 3.5)

set(PROJECT_NAME demo_poisson)
project(${PROJECT_NAME})

# Set CMake behavior
cmake_policy(SET CMP0004 NEW)

# Get DOLFIN configuration data (DOLFINConfig.cmake must be in
# DOLFIN_CMAKE_CONFIG_PATH)
find_package(DOLFIN REQUIRED)

include(${DOLFIN_USE_FILE})

# Default build type (can be overridden by user)
if (NOT CMAKE_BUILD_TYPE)
  set(CMAKE_BUILD_TYPE "RelWithDebInfo" CACHE STRING
      "Choose the type of build, options are: Debug MinSizeRel Release RelWithDebInfo." FORCE)
endif()

# Do not throw error for 'multi-line comments' (these are typical in
# rst which includes LaTeX)
include(CheckCXXCompilerFlag)
CHECK_CXX_COMPILER_FLAG("-Wno-comment" HAVE_NO_MULTLINE)
if (HAVE_NO_MULTLINE)
  set(CMAKE_CXX_FLAGS "-Wno-comment ${CMAKE_CXX_FLAGS}")
endif()

# Executable
add_executable(${PROJECT_NAME} main.cpp)

# Target libraries
target_link_libraries(${PROJECT_NAME} dolfin)

# Test targets
set(test_parameters -np 3 ${MPIEXEC_PARAMS} "./${PROJECT_NAME}")
add_test(NAME ${PROJECT_NAME}_mpi COMMAND "mpirun" ${test_parameters})
add_test(NAME ${PROJECT_NAME}_serial COMMAND ${PROJECT_NAME})

Which compiles nicely in the docker image.

Please note that I would strongly advice against starting with legacy DOLFIN C++ interface if you are a new user. I would strongly encourage you to move to DOLFINx.

There is no CMakeLists.txt file in my system. Again, I do not have any problem running a FEniCS code in python indicating the installation should be correct. The issue is only with cpp codes. Unfortunately I am working with a long code written in legacy version and this is really hard to convert everything to dolfinx.
I also installed FEniCS on another computer with ubuntu. I have exactly the same issue there. FEniCS python codes are run without any issue but the same ufc.h issue when compiling C++ codes.
I was just wondering if you have any other suggestion that probably could fix this error.

Just create one based on the code posted by @dokken, make any required change (e.g., if your cpp file is not called main.cpp, change the name) and then run cmake.

For queries like “what if my long code is split in multiple cpp files?” just search the web for cmake examples. Apart form the line find_package(DOLFIN REQUIRED) which is obviously dolfin specific, the rest of CMakeLists.txt is generic and you can find plenty of documentation and good websites on that.

Thanks for clarifying this. I was able to compile with C++ based on your hint. For those who may have a similar issue in the future, following these steps could resolve the issue:

1- Save your C++ code in a folder. Here is a simple example:

#include <dolfin.h>
using namespace dolfin;

using namespace std;

int main() {

    // Define mesh
    auto mesh = std::make_shared<UnitSquareMesh>(10, 10);

    // Save mesh to file
    File file("unit_square_mesh.pvd");
    file << *mesh;

    return 0;
}

2- Create a CMakeLists.txt file in the same folder where your C++ code exists. As what @francesco-ballarin suggested I copied and pasted the same CMakeLists.txt provided by @dokken. The only change I made was in modifying based on the name of my own cpp file (Which is test.cpp):

# Executable
add_executable(${PROJECT_NAME} test.cpp)

3- Create a new directory (build) by running:

mkdir build

4- Navigate to this directory:

cd build

5- Run:

cmake ..

Some files and a folder will be created inside the build folder (Make sure you do not get any error)

6- Run:

cmake --build .

It generates a file (In my case this is called test) in the build folder

7- Finally, Run:

./test

That is it!

Thanks so much Francesco and Jorgen