Using Cmake with existing stuff

Hi,
Is there an option in CMake to use an existing makefile/solution?
Or maybe, just check if the depende
There is no reason whatsoever to re-create whats already been done and tested…

Thank you.

yes, you can use ExternalProject for your existing build system. To use the products of the existing build in CMake you would have to find the products.

Hi,
And what if I don’t have a binaries on the system.

Consider following scenario

Project A (main) depends on projects B and C. Both B and C are libraries.
Now project B is an external dependency which already have a Makefile, and project C is in internal library.

As far as I understand CMake will generate Makefile for all 3 projects and then initiate the build.

What I’d like to know if it is possible to generate the Makefiles only for projects A and C and use the existing Makefile for project B for the build.

Thank you.

With CMake you are flexible enough to generate the builds of your preference. If you’re not comfortable with Makefile then you could just use Ninja, for example. Or, since B already uses Makefile then why not use Makefile for all projects? Up to you.

CMake cannot generate Makefile for project B because it is not a CMake project - it doesn’t understand it well enough. The solution is to use the existing Make project, instead. ExternalProject makes that easy for you. It is an interface that drives the build steps for project B. It also controls the build order such that project A can link against project B.

The book “Professional CMake” describes in detail the “Superbuild Structure”.

What you need looks something like this (incomplete example):

include(ExternalProject)
# make sure B and C are build before A
ExternalProject_Add(ProjectA DEPENDS ProjectB ProjectC
	# install to a common location
	INSTALL_DIR ${installDir}
	# tell CMake where to find the sources for A
	SOURCE_DIR "/path/to/projecta/sources" 
	# among other options
	... )

ExternalProject_Add(ProjectB
	# tell CMake where to find the sources for B
	SOURCE_DIR "/path/to/projectb/sources"
	# drive the configure step for the Makefile project (skipped in this case)
	CONFIGURE_COMMAND ""
	# use the existing Makefile for project B
	BUILD_IN_SOURCE   ON
)

ExternalProject_Add(ProjectC
	# install to a common location
	INSTALL_DIR ${installDir}
	# tell CMake where to find the sources for C
	SOURCE_DIR "/path/to/projectc/sources" 
	# among other options
	... )
  • CMake has a generic understanding about projects A, B, C. It automatically knows how to build targets such as all, test, install. Anything else must be manually added to the ExternalProject_Add calls above. This means you’ll need to override the [BUILD|TEST|INSTALL]_COMMAND arguments
  • everything is installed into the same directory ${installDir} - this makes it easier later to link against /path/to/libB.so

Hi,

With CMake you are flexible enough to generate the builds of your preference. If you’re not
comfortable with Makefile then you could just use Ninja, for example. Or, since B already uses
Makefile then why not use Makefile for all projects? Up to you.

What do you mean by saying “use Makefile for all projects”?

During the development I ingtend to do just that - use Makefile.
However, when I deliver the final product and it needs to be built - its a different story.

Going back to my example.
Project B is an external project and so already have the Makefile. And so there is no need regenerate it. But projects A and C are the executable and the library that is developed by me (the developer).

So I’d rather regenerate the Makefile for A and C but there is no need to regenerate one for B.

Thank you.

Oh, i think i misunderstood what you meant with “CMake will generate Makefile for all 3 projects”. If you’re new to CMake but familiar with Makefiles then it might help you to choose the “Unix Makefiles” generator, because you can see what CMake does under the hood. But normally you only care about CMake scripts.

More importantly, CMake is able to do what you want. It is not going to generate a Makefile for B, it uses your existing Makefile. It basically uses this file as you would on the command line with make all && make install. But it can do much more than that, it is very convenient. Perhaps the following CMake code snippet makes it more clear what ExternalProject does:

cmake_minimum_required(VERSION 3.16)
project(MyProj)

include(ExternalProject)
ExternalProject_Add(ProjectB
	SOURCE_DIR        ${CMAKE_CURRENT_SOURCE_DIR}/src/projectb
	CONFIGURE_COMMAND ""
	BUILD_COMMAND     make
	INSTALL_COMMAND   make install
	TEST_COMMAND      make test
	BUILD_IN_SOURCE   ON
)

assuming the following file structure:

.
├── CMakeLists.txt
└── src
    └── projectb
        └── Makefile

as you can see it doesn’t generate a Makefile for B - it drives the build steps for the existing Makefile.