1

I'm looking at replacing a configure/make style build process with CMake. CMake performs well on the complicated stuff, but it is more verbose on simple things. For instance the GNU Make file:

hello:
    echo "hello world" >$@

In CMake it would be:

add_custom_command(OUTPUT hello
  COMMAND echo "hello world" > hello)
add_custom_target(all ALL DEPENDS hello)

See also Adding a custom command with the file name as a target.

Which is actually more like:

hello:
    echo "hello world" >hello

all: hello

With more complex builds the absence of automatic variables is very noticeable.

After much routing around (it seems to be hard to search for $@) I found:

Automatic variables in CMake

Which suggests using wrapper functions and

Path to target output file

which suggests using generator expressions that are close to automatic variables, but not close enough.

I have several related questions:

1a) Has CMake itself or best practice for doing this moved on since that question was asked?

1b) Is it likely CMake will ever provide an equivalent to automatic variables? If not, why not?

Individual problems are quite well covered on Stack Overflow and elsewhere on the Internet, but:

2a) Are there any good guides or cheat sheets to help with migrating from using GNU make directly.

2b) Are they any good best practice guides for CMake?

That is beyond the suggestions in Makefile equivalent in CMake. I am gradually evolving my own style, but I would like to avoid horseless carriage type mistakes and needless complexity.

Peter Mortensen
  • 30,738
  • 21
  • 105
  • 131
Bruce Adams
  • 4,953
  • 4
  • 48
  • 111
  • For 2a+b I'm really looking for some compiled hindsight such as you might get from a book like effective C++. What you get there is not just a set of rules but the reasoning behind those rules. – Bruce Adams Jan 02 '14 at 16:04
  • I found the following list of cmake anti-patterns: http://voices.canonical.com/jussi.pakkanen/2013/03/26/a-list-of-common-cmake-antipatterns/ – Bruce Adams Jan 31 '14 at 14:56

1 Answers1

0

This is hard to answer, because CMake is not equivalent to make. It's much easier to compare CMake to autotools, for example, because it is a build system generator rather than a build system by itself.

Regardless, let's try to provide some answers.

1a+b) No, because it is not in the scope and philosophy of CMake to provide such constructs.
CMake's syntax is usually more on the side of verbosity, with explicit variable names such as ${CMAKE_CURRENT_SOURCE_DIR} as well as named command parameters. It looks more like a "classical" imperative programming language rather than a specialized textual description of a dependency graph which Makefiles are.
Also, CMake's output can be Makefiles or pretty much anything else, so a certain level of abstraction is needed.

The best practice in your case would be to use macros:

macro(build_echo_foo ${target})
    add_custom_command(OUTPUT ${target}
        COMMAND echo "hello world" > ${target})
    add_custom_target(${target}_target ALL DEPENDS ${target})
endmacro()

build_echo_foo(hello)
build_echo_foo(another_hello)

Where Makefiles encourage the author to be as generic as possible, to minimize typing, CMake tries to make things as unambiguous as possible, for example by encouraging the maintainer to explicitly list source files instead of providing wildcards.

2a+b) Answering this is not exactly in the scope of Stack Overflow, but I'll say this. The best source of inspiration is open-source projects using this system. As of 2014, there are a good number of high-profile projects that have migrated to CMake. You can even study CMake's own source code, which uses itself as build system.

Peter Mortensen
  • 30,738
  • 21
  • 105
  • 131
SirDarius
  • 41,440
  • 8
  • 86
  • 100
  • I most definitely do not want to write build files imperatively. However, cmake still tries to be declarative (mostly). add_executable() etc. are just higher level declarations of what you are trying to do. So I disagree that cmake is imperative in style. – Bruce Adams Jan 02 '14 at 16:00
  • @BruceAdams true, after all they are named CMake lists for a reason. Strictly speaking, the imperative side of cmake lies in its ability to specify custom commands, because we tell it *how* to build a target instead of relying on its default mechanisms. – SirDarius Jan 02 '14 at 16:01
  • My beef is not so much with the verbosity but with the repetition. If I have specified values to OUTPUT I do not wish to repeat them. Wrapping in a macro or function is not ideal as different commands may reference different sets of output files and dependencies. I will likely end up with many such functions, possibly ill-named. So I see this as both a problem with the cmake syntax and possibly something than can be avoided by adopting some good rules. – Bruce Adams Jan 02 '14 at 16:01