Alex Rivera | Logout

Call cmake from make to create Makefiles?

Asked 2009-01-02T04:21:29.660
19

I am using cmake to build my project. For UNIX, I would like to type make from my project's root directory, and have cmake invoked to create the proper Makefiles (if they don't exist yet) and then build my project. I would like the cmake "internal" files (object files, cmake internal Makefiles, etc.) to be hidden (e.g. put in a .build directory) so it doesn't clutter my project directory.

My project has several sub-projects (in particular, a library, a user executable, and a unit test executable). I would like Makefiles (i.e. I type make and this happens) for each sub-project to execute cmake (as above) and build only that sub-project (with dependencies, so the library would be built from the executables' Makefiles, if needed). The resulting binary (.so library or executable) should be in the sub-project's directory.

I made a Makefile which does the main project bit somewhat well, though it feels somewhat hackish. I can't build specific targets using it, because my Makefile simply calls make in cmake's build directory.

Note that because the library is a sole dependency (and probably doesn't need to be build manually, and because I'm lazy) I omitted it in my Makefile.

BUILD_DIR   :=  .build

.PHONY: all clean project-gui ${BUILD_DIR}/Makefile

all:    project-gui project-test

clean:
    @([ -d ${BUILD_DIR} ] && make -C ${BUILD_DIR} clean && rm -r ${BUILD_DIR}) || echo Nothing to clean

project-gui:  ${BUILD_DIR}/Makefile
    @make -C ${BUILD_DIR} project-gui
    @cp ${BUILD_DIR}/project-gui/project-gui $@

project-test:  ${BUILD_DIR}/Makefile
    @make -C ${BUILD_DIR} project-test
    @cp ${BUILD_DIR}/project-test/project-test $@

${BUILD_DIR}/Makefile:
    @[ -d ${BUILD_DIR} ] || mkdir -p ${BUILD_DIR}
    @[ -f ${BUILD_DIR}/Makefile ] || (cd ${BUILD_DIR} && cmake ${C
Edit
Report

1 Answer

8

If cmake is generating the makefiles, you can simply include the generated makefile in the master makefile, eg

# makefile
all:                # Default
include $GENERATED
$GENERATED:$CMAKEFILE
   #  Generate the makefile here`

The included files are generated then make is restarted with the new included files. The included files should detail the targets, etc.

You should be able to change the location of used files using the vpath directive, see e.g. the Gnu make manual,

vpath %.o project/.build

else the tedious way is to rewrite the rules making note of the necessary directory.

Ed: Perhaps we shouldn't use a flat makefile.

Try something like:

# makefile
all: gui test
clean:
    $(MAKE) -f $(GUI-MAKE) clean
    $(MAKE) -f $(TEST-MAKE) clean

gui:$(GUI-MAKE)
    $(MAKE) -f $(GUI-MAKE) all
$(GUI-MAKE):$(GUI-CMAKE)
    # Generate

# Same for test

This should work if the $(MAKE) -f $(GUI-MAKE) all command works on the command line, and we've hidden cmake in the generating target. You would have to copy any other targets to the master makefile as well, and take care running make in parallel.

Propagating object files through should involve something like

%.o:$(GUI-MAKE)
    $(MAKE) -f $(GUI-MAKE) $@

although you'll probably get errors trying to make test objects

answered 2009-01-02T05:29:42.457

Your Answer