I am currently working on a project which will consist of multiple sub-modules. Each sub-module is developed and unit-tested in its own repository. All sub-modules have to be integrated in one main-project repository.
Furthermore I have some "support-functions" modules which are implementing for example a logging tool and a tool for connecting to a database. The support-function modules are used by most of the sub-modules. As the sub-modules are not necessaryly developed with the same life-cycle, it might be that not every sub-module uses the same version of the support-function modules. The support-function modules are also developed and unit-tested in it's own repository.
This means that I in total have a project structure like this :
- The MainProject consists for example of three submodules (SubmoduleA, SubmoduleB, SubmoduleC)
- SubmoduleA uses the support-function module "Logging-Tool" with version 4.0
- SubmoduleB and SubmoduleC are using the support-function module "Logging-Tool" with version 5.0
In the past I would have created one main-project-repository and copied all header and source-files and testing-source-files of all submodules and of the support-functions module into this repo and compile it all together. If I would have wanted to support the different versions of the Logging-Tool I maybe would have renamed it to be able to compile both versions.
Now my question is : How do I do this with the state of the art-integration techniques of 2019? Do I have to compile each sub-module and support-function-tool to a library and do a binary-integration. Or can I do a source-code integration which allows me to easily debug the project with all it's sub-modules. But if I do a source-code integration how can I handle the duplicate support-functions modules with different versions?
Are there some cool techniques / best-practices or tools to use? I already know of the great possibilities of the "google repo" command. This would maybe be a nice help for the Main-Project repository.
I hope someone can help me, or can maybe give me a hint where to continue reading?
Best Regards, anon1234
P.S. : To show a very simple code-example : There is a Logger-class:
which looks in version 4.0 like this
#ifndef LOGGER_H
#define LOGGER_H
#include <iostream>
using namespace std;
class Logger {
public:
Logger() {}
void log(string val_) {
cout << "DEBUG: " << val_ << endl;
}
};
#endif // LOGGER_H
and in version 5.0 like this
#ifndef LOGGER_H
#define LOGGER_H
#include <iostream>
using namespace std;
class Logger {
public:
Logger() {}
void log(string val_) {
cout << val_ << endl;
}
};
#endif // LOGGER_H
A SubmoduleA could look like :
#ifndef ModuleA_H
#define ModuleA_H
#include "Logger.h"
class ModuleA {
public:
ModuleA() {}
void doSmth() {
Logger l;
l.log("ModuleA is doing smth");
}
};
#endif // ModuleA_H
A SubmoduleB could look like:
#ifndef ModuleB_H
#define ModuleB_H
#include "Logger.h"
class ModuleB {
public:
ModuleB() {}
void doSmth() {
Logger l;
l.log("ModuleB is doing smth");
}
};
#endif // ModuleB_H
A SubmoduleC could look like
#ifndef MODULEC_H
#define MODULEC_H
#include "Logger.h"
class ModuleC {
public:
ModuleC() {}
void doSmth(){
Logger l;
l.log("ModuleC is doing smth");
}
};
#endif // MODULEC_H