Organization
- Directories that contain CMakeLists.txt are the entry point for the build system generator. Subdirectories can be added with the add_subdirectory() and must contain a CMakeLists.txt too.
 - Scripts are <script>.cmake files that can be executed with the cmake -P <script>.cmake. Not all commands are supported.
 - Modules are <script>.cmake files located in the CMAKE_MODULE_PATH. MOdules can be loaded with the include() command.
 
Commands
-----
command_name(space seperated list of strings)
-----
- Scripting commands change the state of command processor
- set variables
 - change behavior of other commands
 
 - Project commands
- create build targets
 - modify build targets
 
 - Command invocations are not expressions.
 
Variables
-----
set(myvar world)
message(STATUS "hello ${myvar})
-----
- Set withe the set() command.
 - Expand with ${}.
 - Variables and values are strings.
 - Lists are ; seperated strings.
 - CMake variables are not environment variables (unlike Makefile).
 - Unset variable expands to empty string.
 
Comments
Use # for single line comments.
Custom Functions/Macros
- Commands can be added with function() or macro().
 - When a new command replaces an existing command, the old one can be accessed with a _ prefix.
 
function(my_command input output)
   # some comment
   set(${output} ... PARENT_SCOPE)
 endfunction()  
 my_command(foo bar)
  | 
- Variables are scoped to the function unless set with the PARENT_SCOPE. 
 - Available variables: input, output, ARGC, ARGN, ARG0, ARG1, ...
 - Example: ${output} expands to bar.
 
macro(my_command input output)
   # some comment
 endmacro()
 my_command(foo bar)
  | 
- No extra scope with macros.
 - Text replacements: ${input}, ${output}, ${ARGC}, ${ARGV}, ${ARGN}, ${ARG0}, ...
 - Example: ${output} is replace by bar.
 
CREATE macros to wrap commands that have output parameters. Otherwise, create functions.
References
https://www.youtube.com/watch?v=bsXLMQ6WgIk