I don't really know how to phrase this question exactly, but this is my best attempt...
I recently started working on a large-ish project, which I wanted to break down into several component parts.
Here's how two of those components work:
- First component: Is itself an execuable program. Produced by CMake. Takes some source files for library code and compiles and links with a
main.cpp
file. - Second component: Should use the same libraries compiled in the first component, but a different
main.cpp
file, plus some new libraries.
The "libraries" in this instance are just header and source files containing some classes which themselves are dependent on some other libraries. (SDL, to be exact.)
What I want to do is somehow get CMake to compile the "First component" and also produce one or more object files which I can link to (again using CMake) in the "Second component".
I hope that makes sense, but it probably isn't obvious, so here are some further details:
First component uses SDL to render and draw text to an SDL window. The various classes I have written do a bunch of things including loading fonts from file, finding them on the system, as well as managing SDL objects (such as a window and the rendered text objects). The
main.cpp
file is just for testing purposes. It allows an executable to be compiled which demonstrates that everything works as expected. Consider it a test driven development file if you wish, although it doesn't contain any formal tests.The second component depends on the object files which gcc/g++ would normally produce from compilation of the first component. In other words, I want to be able to take some object files from the first component and use them to compile the second component. I could copy and paste the source files from the first component to the second and compile everything from scratch, but this will mess up my git repository and also isn't particularly efficient.
I am sure it must be possible to get cmake to produce some object files from the first component and then link those when compiling the second component. Of course, it will require two seperate cmake processes, probably, but that is fine.
Please note; I do not want to compile a shared object. I assume what I want is to statically link my object files, however I would assume by default cmake will invoke a dynamic link process. In other words, the SDL libraries should still be dynamically linked. My own libraries should not be dynamically linked because they are not available on linux systems, they are only available on my own linux system.
Minimal working example?
This is the kind of thing which a MWE is a bit pointless for, but here is an attempt none the less.
The first directory is setup like this
first/
main.cpp
first.h
first.cpp
CMakeLists.txt
build [d]
The second directory contains only a main.cpp file.
CMakeLists.txt:
cmake_minimum_required(VERSION 3.7)
project(testproject)
set(CMAKE_CXX_STANDARD 14)
set(CMAKE_CXX_STANDARD_REQUIRED True)
find_package(SDL2 REQUIRED)
include_directories(testproject ${SDL2_INCLUDE_DIRS})
set(SOURCE_FILES main.cpp first.cpp)
add_executable(testproject ${SOURCE_FILES})
target_link_libraries(testproject ${SDL2_LIBRARIES})
main.cpp:
#include "first.h"
int main()
{
SDL_Init(SDL_INIT_VIDEO);
// using first library in main function
SDL_Window *window = GetWindow();
// doesn't draw anything, but you can
// press the window X to quit
for(bool quit = false; quit == false; )
{
SDL_Event event;
while(SDL_PollEvent(&event) != 0)
{
if(event.type == SDL_QUIT)
{
quit = true;
}
}
}
FreeWindow(window);
SDL_Quit();
return 0;
}
first.h:
#ifndef FIRST_H
#define FIRST_H
#include <SDL2/SDL.h>
SDL_Window* GetWindow();
void FreeWindow(SDL_Window* &window);
#endif // FIRST_H
first.cpp
#include "first.h"
SDL_Window* GetWindow()
{
SDL_Window *window =
SDL_CreateWindow(
"a test window",
SDL_WINDOWPOS_UNDEFINED, SDL_WINDOWPOS_UNDEFINED,
800, 600, SDL_WINDOW_SHOWN);
return window;
}
void FreeWindow(SDL_Window *&window)
{
SDL_DestroyWindow(window);
window = nullptr;
}
It's a bit of a weird example. I've tried to include some very minimal functions which would produce an object file as well as making use of the external SDL library. The second folder in this case could literally just be a copy of main.cpp, a copy of the header file, or a line in CMakeLists.txt
to tell the make system where to find the header, and then it should have some way to find the object files, which currently don't exist, becuase the first CMakeLists.txt
doesn't produce them yet.
Things I don't know how to do:
- Tell cmake in the directory first to produce a directory with (ideally a single) object file containing the library code, but not the object code for
main.cpp
- Tell cmake in the directory second where the header files are inside first
- Tell cmake in the directory second where the object file for the library code produced by the directory first is, and then how to link that to a new main.cpp file in second
Hopefully that is clear enough but this is presumably a somewhat non-trivial thing.