Syndicate content

Writing a Shell Script from cmake

In cmake, you have a cool feature which allows you to create a file.

First you use a WRITE, then you use the APPEND to add more lines to the file.

That file may be a shell script, though. In that case, you run in a problem whenever you want to write a variable which uses the curly brackets (as in ${TEST}), because cmake sees those as its own variables.

There is an example of script that we use in our Snap! development.

file( WRITE  ${lint_script} "#!${BASH}\n"                                                            )
file( APPEND ${lint_script} "if test \${3##*.} = 'dtd'; then\n" )
file( APPEND ${lint_script} "  ${XMLLINT} --dtdvalid $3 --output $2 $1 && exit 0 || (rm $2; exit 1)\n" )
file( APPEND ${lint_script} "else\n" )
file( APPEND ${lint_script} "  ${XMLLINT} --schema $3 --output $2 $1 && exit 0 || (rm $2; exit 1)\n" )
file( APPEND ${lint_script} "fi\n" )

As we can see, we have many variables defined and used here.

The $1, $2, and $3 are the usual first, second and third parameters specified on the command line when calling the script.

The ${XMLLINT} variable is set by cmake with a find_program() call:

find_program( XMLLINT xmllint /usr/bin )

The ${BASH} variable is similar, we look for the location of the bash shell script and use the variable to generate the script from cmake.

However, $3 represents a path and a filename with an extension. We expect .dtd or .xsd as the extension of that file. Since it is dynamic and various calls to the script may use various setup, the script extracts the extension and then compares it with the 'dtd' string. To extract the string, we use the special shell syntax:


Which says: "Remove everything up to the last period and the last period."

Here we have a problem because the cmake interpretor wants to convert the ${3##*.} with the contents of the variable named "3##*." and that's not considered a valid name as per cmake so it generates an error and bails out.

To palliate to that problem, we have to escape the { character as we have shown in our first example:


and then cmake will write "${3##*.}", without the backslash (\), to the output file.


Syndicate content

Diverse Realty

Diverse Realty Team

Want a New Home?
Want to Sell Your House?

Call Alex at
+1 (916)
220 6482

Alexis Wilke, Realtor
Lic. # 02024063

Cory Marcus, Broker
Lic. # 01079165


Terms of Site Index

Find the page/content you are looking for with our index.

  • SysInternals
    A set of tools to check the internals of the Microsoft Windows system. Some of these tools peek and poke directly in totally undefined kernel objects. Microsoft aquired SysInternals in 2006 from Mark Russinovich and Bryce Cogswell who are the original authors and started their work in 1996.
  • libwww
  • live
  • pg_connect
  • views

    A module Drupal that let people define lists of nodes, blocks, feeds, and whatever other data available in your Drupal installation.