Logo AND Algorithmique Numérique Distribuée

Public GIT Repository
Ease the usage of cmake for SMPI programs
[simgrid.git] / docs / source / Start_your_own_project.rst
1 .. _setup_your_own:
2
3 Start your Own Project
4 ======================
5
6 It is not advised to modify the SimGrid source code directly, as it
7 will make it difficult to upgrade to the next version of SimGrid.
8 Instead, you should create your own working directory somewhere on
9 your disk (say ``/home/joe/MyFirstSimulator/``), and write your code
10 in there.
11
12 Cloning a Template Project for S4U
13 ----------------------------------
14
15 If you plan to use the modern S4U interface of SimGrid, the easiest way is
16 to clone the `Template Project
17 <https://framagit.org/simgrid/simgrid-template-s4u>`_ directly. It
18 contains the necessary configuration to use cmake and S4U together.
19
20 Once you forked the project on FramaGit, do not forget to remove the
21 fork relationship, as you won't need it unless you plan to contribute
22 to the template itself.
23
24 Building your project with CMake
25 --------------------------------
26
27 Here is a `CMakeLists.txt` that you can use as a starting point for your S4U
28 project (see below for MPI projects). It builds two simulators from a given set
29 of source files.
30
31 .. code-block:: cmake
32
33    cmake_minimum_required(VERSION 2.8.12)
34    project(MyFirstSimulator)
35
36    set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -std=c++17")
37
38    set(CMAKE_MODULE_PATH ${CMAKE_MODULE_PATH} "${CMAKE_SOURCE_DIR}/cmake/Modules/")
39    find_package(SimGrid REQUIRED)
40    include_directories(${SimGrid_INCLUDE_DIR})
41
42    set(SIMULATOR_SOURCES main.c other.c util.c)
43    add_executable(my_simulator ${SIMULATOR_SOURCES})
44    target_link_libraries(my_simulator ${SimGrid_LIBRARY})
45
46    set(OTHER_SOURCES blah.c bar.c foo.h)
47    add_executable(other_xp ${OTHER_SOURCES})
48    target_link_libraries(other_xp ${SimGrid_LIBRARY})
49
50
51 For that, you need `FindSimGrid.cmake
52 <https://framagit.org/simgrid/simgrid/raw/master/FindSimGrid.cmake>`_,
53 which is located at the root of the SimGrid tree. You can either copy
54 this file into the `cmake/Modules` directory of your project, or use
55 the version installed on the disk. Both solutions present advantages
56 and drawbacks: if you copy the file, you have to keep it in sync
57 manually but your project will produce relevant error messages when
58 trying to compile on a machine where SimGrid is not installed. Please
59 also refer to the file header for more information.
60
61 MPI projects should NOT search for MPI as usual in cmake, but instead use the ``smpi_c_target()`` macro
62 to declare that a given target is meant to be executed in ``smpirun`` (which path is set in ``${SMPIRUN}``).
63 This macro should work for C and C++ programs. Here is a small example:
64
65 .. code-block:: cmake
66
67    # Search FindSimgrid in my sources
68    set(CMAKE_MODULE_PATH ${CMAKE_MODULE_PATH} "${CMAKE_SOURCE_DIR}")
69    find_package(SimGrid)
70
71    # Declare an executable, and specify that it's meant to run within smpirun
72    add_executable(roundtrip roundtrip.c)
73    smpi_c_target(roundtrip)
74
75    # Declare a test running our executable in ${SMPIRUN}
76    enable_testing()
77    add_test(NAME RoundTrip
78             COMMAND ${SMPIRUN} -platform ${CMAKE_SOURCE_DIR}/../cluster_backbone.xml -np 2 ./roundtrip)
79
80 To compile Fortran code with cmake, you must override the ``MPI_Fortran_COMPILER`` variable as follows, but it will probably
81 break some configuration checks, so you should export ``SMPI_PRETEND_CC=1`` during the configuration (not during the compilation
82 nor the execution).
83
84 .. code-block:: console
85
86    $ SMPI_PRETEND_CC=1 cmake -DMPI_C_COMPILER=/opt/simgrid/bin/smpicc -DMPI_CXX_COMPILER=/opt/simgrid/bin/smpicxx -DMPI_Fortran_COMPILER=/opt/simgrid/bin/smpiff .
87    $ make
88
89 Building your project with Makefile
90 -----------------------------------
91
92 Here is a Makefile that will work if your project is composed of three
93 C files named ``util.h``, ``util.c`` and ``mysimulator.c``. You should
94 take it as a starting point, and adapt it to your code. There is
95 plenty of documentation and tutorials on Makefile if the file's
96 comments are not enough for you.
97
98 .. code-block:: makefile
99
100    # The first rule of a Makefile is the default target. It will be built when make is called with no parameter
101    # Here, we want to build the binary 'mysimulator'
102    all: mysimulator
103
104    # This second rule lists the dependencies of the mysimulator binary
105    # How this dependencies are linked is described in an implicit rule below
106    mysimulator: mysimulator.o util.o
107
108    # These third give the dependencies of the each source file
109    mysimulator.o: mysimulator.c util.h # list every .h that you use
110    util.o: util.c util.h
111
112    # Some configuration
113    SIMGRID_INSTALL_PATH = /opt/simgrid # Where you installed simgrid
114    CC = gcc                            # Your compiler
115    WARNING = -Wshadow -Wcast-align -Waggregate-return -Wmissing-prototypes \
116              -Wmissing-declarations -Wstrict-prototypes -Wmissing-prototypes \
117              -Wmissing-declarations -Wmissing-noreturn -Wredundant-decls \
118              -Wnested-externs -Wpointer-arith -Wwrite-strings -finline-functions
119
120    # CFLAGS = -g -O0 $(WARNINGS) # Use this line to make debugging easier
121    CFLAGS = -g -O2 $(WARNINGS) # Use this line to get better performance
122
123    # No change should be mandated past that line
124    #############################################
125    # The following are implicit rules, used by default to actually build
126    # the targets for which you listed the dependencies above.
127
128    # The blanks before the $(CC) must be a Tab char, not spaces
129    %: %.o
130         $(CC) -L$(SIMGRID_INSTALL_PATH)/lib/    $(CFLAGS) $^ -lsimgrid -o $@
131    %.o: %.c
132         $(CC) -I$(SIMGRID_INSTALL_PATH)/include $(CFLAGS) -c -o $@ $<
133
134    clean:
135         rm -f *.o *~
136    .PHONY: clean
137
138 Develop in C++ with Eclipse
139 ----------------------------------------
140
141 If you wish to develop your plugin or modify SimGrid using
142 Eclipse. You have to run cmake and import it as a Makefile project.
143
144 Next, you have to activate C++17 in your build settings, add -std=c++17
145 in the CDT GCC Built-in compiler settings.
146
147 .. image:: /img/eclipseScreenShot.png
148    :align: center
149
150 .. _install_yours_troubleshooting:
151
152 Troubleshooting your Project Setup
153 ----------------------------------
154
155 Library not found
156 ^^^^^^^^^^^^^^^^^
157
158 When the library cannot be found, you will get such an error message similar to:
159
160 .. code-block:: console
161
162   $ ./masterworker1: error while loading shared libraries: libsimgrid.so: cannot open shared object file: No such file or directory
163
164 To fix this, add the path to where you installed the library to the
165 ``LD_LIBRARY_PATH`` variable. You can add the following line to your
166 ``~/.bashrc`` so that it gets executed each time you log into your
167 computer.
168
169 .. code-block:: shell
170
171   export LD_LIBRARY_PATH=/opt/simgrid/lib
172
173
174 Many undefined references
175 ^^^^^^^^^^^^^^^^^^^^^^^^^
176
177 .. code-block:: console
178
179   masterworker.c:209: undefined reference to `sg_version_check'
180   (and many other undefined references)
181
182 This happens when the linker tries to use the wrong library. Use
183 ``LD_LIBRARY_PATH`` as in the previous item to provide the path to the
184 right library.
185
186 Only a few undefined references
187 ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
188
189 Sometimes, the compilation only spits very few "undefined reference"
190 errors. A possible cause is that the system selected an old version of
191 the SimGrid library somewhere on your disk.
192
193 Discover which version is used with ``ldd name-of-yoursimulator``.
194 Once you've found the obsolete copy of SimGrid, just erase it, and
195 recompile and relaunch your program.