Ответ 1
Цитата документация CMake:
Ссылка на переменную имеет форму
${variable_name}
и оценивается внутри аргумента с кавычками или без кавычек. Ссылка на переменные заменяется значением переменной или пустой строкой, если переменная не установлена.
Другими словами, запись PROJECT_BINARY_DIR
в буквальном смысле относится к строке "PROJECT_BINARY_DIR". Инкапсуляция в ${...}
дает вам содержимое переменной с именем PROJECT_BINARY_DIR.
Рассмотрим:
set(FOO "Hello there!")
message(FOO) # prints FOO
message(${FOO}) # prints Hello there!
Как вы уже догадались, include_directories(PROJECT_BINARY_DIR)
просто пытается добавить подкаталог имени PROJECT_BINARY_DIR в каталоги include. В большинстве систем сборки, если такой каталог не существует, он просто игнорирует команду, которая могла бы обмануть вас в впечатлении, что она работает так, как ожидалось.
Популярный источник замешательства исходит из того, что if()
не требует явного разыменования переменных:
set(FOO TRUE)
if(FOO)
message("Foo was set!")
endif()
Снова документация объясняет это поведение:
if(<constant>)
Истинно, если константа равна 1, ON, YES, TRUE, Y или ненулевому числу. False, если константа равна 0, OFF, NO, FALSE, N, IGNORE, NOTFOUND, пустая строка или заканчивается в суффиксе -NOTFOUND. Именованные логические константы нечувствительны к регистру. Если аргумент не является одной из этих констант, он рассматривается как переменная.
if(<variable>)
Истинно, если переменная определяется значением, которое не является ложной константой. В противном случае. (Примечание: макросы не являются переменными.)
В частности, можно найти такие странные примеры, как:
unset(BLA)
set(FOO "BLA")
if(FOO)
message("if(<variable>): True")
else()
message("if(<variable>): False")
endif()
if(${FOO})
message("if(<constant>): True")
else()
message("if(<constant>): False")
endif()
который примет ветвь TRUE
в переменном случае, а ветвь FALSE
- в постоянном случае. Это связано с тем, что в постоянном случае CMake будет искать переменную BLA
для выполнения проверки (которая не определена, поэтому мы попадаем в ветвь FALSE).