CMake issue when developing new module

Dear colleges,
I’m working on developing a new propagation module. The new module needs to use some classes from other modules. I have included the corresponding header file in the source code, but the following problems occur during make file process: “undefined reference to XXX”.I checked the code repeatedly and confirmed that there was a problem with the link library process, not the compilation of the source file.
The new propagation module built on version 1.4.1 is named SustainedPropagationModule. During the running of this module, a subclass(named DepositionGeant4SubModule) with a function similar to the DepositionGeant4Module needs to be constructed. In the DepositionGeant4SubModule.hpp file, some files from Deposition/ folder are included like this:


The CMake error is below:

How can I solve this problem?

Kind regards,
Tong Wei

Hi @WeiTong

In order to compile these methods for your module, you also have to include the source files in your library sources. Check the CMakeList.txt file of your new module for a line like

# Add source files to library
ALLPIX_MODULE_SOURCES(${MODULE_NAME} YourModule.cpp)

There you need to also add the corresponding .cpp files to the methods you are using.

That said, the proper way of doing this very likely would be to inherit from the other module as a base class:

class YourModule : public DepositionGeant4Module {}

However, as a colleague recently pointed out to me this currently isn’t possible and I need to look into a way of telling CMake to link the other module.

Let me know if for now the first approach (doubly compiling the source) works for you, I’ll have a look at the latter option soon. Here is an issue to track the progress: Allow Ineritance Between Modules (#216) · Issues · Allpix Squared / Allpix Squared

Cheers,
Simon

Hi @simonspa
Thanks for your reminding.I checked the CMakeList.txt file and added the corresponding .cpp files like this:
cmakelist

Just as we expected, CMake completed compilation and linking process successfully.Now I can concentrate on verifying the function of this module.However, if the second method(inherit from the other module) can also be implemented, developing new modules may be more convenient and safe.

Best Wishes,
Tong Wei

Hi @WeiTong

great to hear - We’ll definitly look into how to inherit properly in the future.

A small observation from your screenshot: to me it looks like you are compiling two modules (SustainedPropagationModule and DepositionGeant4SubModule) into the same library - is this intended?

/Simon

Hi @simonspa

In fact, this propagation module is designed to simulate the current signal on the detector under sustained irradiation and for long time,kind of like TransientPropagationModule does. The difference is:in each time step, the new module will generate some primary particles through Poisson distribution, then call DepositionGeant4SubModule(with same function to DepositionGeant4Module) to generate carriers that will join the propagation process, and the collected carriers will be removed from the transport process. In this way, I hope to evaluate the influence of polarization effect on the detector response when high intensity rays are injected. In the allpix2 framework, it seems impossible to call between different modules, so I copied DepositionGeant4Module to part of SustainedPropagationModule and rename it.

/Tong Wei

Hi @WeiTong

that sounds like a very interesting simulation, indeed. However, I would probably take a slightly different approach here. I would make the two modules independent treat each Geant4 particle as individual event. In your SustainedPropagationModule you could then buffer incoming messages (events) and add them to your ongoing signal by drawing from the message buffer and assigning a delta t according to a Poisson distribution. I haven’ fully thought this through but it feels like that way could be more sustainable.

The problem with calling other Module’s run() function from a module is that we then can’t guarantee order-of-execution following the configuration file. Also, in a multithreaded environment, we will call the other module’s run() function at random times, making it hard to keep a consistent seed usage and therefore reproducibiliy of the simulation. It’s probably not impossible, but one would have to think about it carefully.

All the best,
Simon

Hi @simonspa

I have thought about and tried your approach days ago, it may involve some more complex problems. However, I am planning to rewrite DepositionGeant4SubModule instead of simply copying from DepositionGeant4Module. In other words, the new module is a combination of the TransientPropagationModule and DepositionGeant4Module,this eliminates the need to call other modules. Multithreading and other issues will also be carefully considered. Thanks for your opinions, that will help.

Best,
Tong Wei

Hi @WeiTong

okay, that sounds good for now! :rocket:

I guess if this is something that comes up as a problem more often, we could think about having something on a framework basis to allow for calling e.g. module A N times and then module B just once, with the combined input? I’ll think about that a bit. :slight_smile:

Simon

Hi @WeiTong

coming back to this - I have actually done something very similar to what you are looking at in the past days, and inheritance works just fine. In my case I have inherited from DepositionGeant4 in order to inject a different GeneratorAction to Geant4. The key for inheritance is to link against the other module library:

source file:

#include "../DepositionGeant4/DepositionGeant4Module.hpp"

class MyModule : public DepositionGeant4Module {}

CMake:

ALLPIX_DETECTOR_MODULE(MODULE_NAME)
ALLPIX_MODULE_SOURCES(${MODULE_NAME} MyModule.cpp)
TARGET_LINK_LIBRARIES(${MODULE_NAME} ${Geant4_LIBRARIES} AllpixModuleDepositionGeant4)
ALLPIX_MODULE_INSTALL(${MODULE_NAME})

For a working example, have a look here: src/modules/DepositionCosmics · cosmics · Allpix Squared / Allpix Squared · GitLab

Cheers,
Simon

Hi @simonspa
the working example shows that inheritance from other module seems not so difficult as we have thought before. Without changing the framework, we just need include path of the parent module and add this line to CMake file:

TARGET_LINK_LIBRARIES(${MODULE_NAME} ${Geant4_LIBRARIES} AllpixModule*ModuleName*)

Am I right? If so, development of new modules with similar functions to existing modules may be more convenient through this feature.

Kind regards,
Tong Wei

Hi @WeiTong

that is exactly right. Of course the Geant4 libraries you only need to link if you’re actually using Geant4 - but I believe that you do from your description above.

I have not tested (yet) if you actually need to link Geant4 directly or if it is enough to link to the other module - feel free to play around and let me know! :slight_smile:

All the best,
Simon