Как использовать глобальную переменную внутри пользовательской переменной в CMAKE? [Дубликат]

NullPointerException s - исключения, возникающие при попытке использовать ссылку, которая указывает на отсутствие местоположения в памяти (null), как если бы она ссылалась на объект. Вызов метода по нулевой ссылке или попытка получить доступ к полю нулевой ссылки вызовет функцию NullPointerException. Они наиболее распространены, но другие способы перечислены на странице NullPointerException javadoc.

Вероятно, самый быстрый пример кода, который я мог бы придумать для иллюстрации NullPointerException, be:

public class Example {

    public static void main(String[] args) {
        Object obj = null;
        obj.hashCode();
    }

}

В первой строке внутри main я явно устанавливаю ссылку Object obj равной null. Это означает, что у меня есть ссылка, но она не указывает на какой-либо объект. После этого я пытаюсь обработать ссылку так, как если бы она указывала на объект, вызывая метод на нем. Это приводит к NullPointerException, потому что нет кода для выполнения в местоположении, на которое указывает ссылка.

(Это техничность, но я думаю, что она упоминает: ссылка, которая указывает на null, равна 't то же, что и указатель C, указывающий на недопустимую ячейку памяти. Нулевой указатель буквально не указывает на в любом месте , который отличается от указаний на местоположение, которое оказывается недопустимым.)

14
задан Gerald Senarclens de Grancy 18 June 2014 в 19:44
поделиться

4 ответа

Мое кросс-платформенное решение при первом запуске CMake создает файл timestamp.cmake в двоичном каталоге и определяет цель timestamp, которая запускает сгенерированный файл. Файл timestamp.cmake формирует строку штампа ISO 8601 с использованием команды STRING CMake и записывает ее в файл timestamp.h с предваряющей директивой #define _TIMEZ_ preprocessor preended (определяет с одним ведущим подчеркиванием в порядке, определяет с двумя ведущими подчеркиваниями не должен быть определен пользователем).

Включите следующее в основной файл CMake.

# build time in UTC ISO 8601
FILE (WRITE ${CMAKE_BINARY_DIR}/timestamp.cmake "STRING(TIMESTAMP TIMEZ UTC)\n")
FILE (APPEND ${CMAKE_BINARY_DIR}/timestamp.cmake "FILE(WRITE timestamp.h \"#ifndef TIMESTAMP_H\\n\")\n")
FILE (APPEND ${CMAKE_BINARY_DIR}/timestamp.cmake "FILE(APPEND timestamp.h \"#define TIMESTAMP_H\\n\\n\")\n")
FILE (APPEND ${CMAKE_BINARY_DIR}/timestamp.cmake "FILE(APPEND timestamp.h \"#define _TIMEZ_ \\\"\${TIMEZ}\\\"\\n\\n\")\n")
FILE (APPEND ${CMAKE_BINARY_DIR}/timestamp.cmake "FILE(APPEND timestamp.h \"#endif // TIMESTAMP_H\\n\")\n")
ADD_CUSTOM_TARGET (
    timestamp
    COMMAND ${CMAKE_COMMAND} -P ${CMAKE_BINARY_DIR}/timestamp.cmake
    ADD_DEPENDENCIES ${CMAKE_BINARY_DIR}/timestamp.cmake)

Затем используйте команду ADD_DEPENDENCIES CMake, чтобы сделать вашу основную цель (возможно, главный исполняемый файл), зависящий от цели timestamp.

ADD_DEPENDENCIES (${CMAKE_BINARY_DIR}/${BINARY_NAME} timestamp)

Вы можете указать несколько дополнительных зависимостей, разделенных символом если вам нужно это сделать.

Тогда вы можете просто #include "timestamp.h" (если предположить, что двоичный каталог CMake находится в включенном пути, который обычно есть. Если нет, это просто: INCLUDE_DIRECTORIES (${CMAKE_BINARY_DIR})) и используйте _TIMEZ_ всякий раз, когда вы хотите иметь штамп времени сборки в формате ISO 8601 (или, фактически, что угодно: вы можете указать его самостоятельно, см. документацию CMake для использования команды STRING ).

Это могло быть упрощено непосредственно (вручную), создав файл timestamp.cmake и добавив его в ваш репозиторий кода, но я счел его не чистым достаточно. Это общий недостаток CMake, который не может получить доступ к процедуре формирования строки штампа времени (той, которая используется в команде STRING CMake) на этапе, где бэкэнд CMake, независимо от того, что он (например, GNU make) работает, поэтому нужно используйте отдельный файл CMake и вызовите его на этом этапе. Это можно было бы сделать намного проще и чище, если бы вы могли вызвать процедуру формирования строки штампа CMake в «режиме команд CMake» (тип вызова cmake -E), например, например: cmake -E date [format] [UTC], но, увы , Я отправил билет в трекер Mathis для отслеживания ошибок Mateis .

Вы можете помочь, чтобы это произошло, поддерживая мой запрос функции, размещая некоторые комментарии, показывающие, сколько вам нужно на этом.

3
ответ дан dbanet 18 August 2018 в 23:35
поделиться
  • 1
    Определяет с верхним подчеркиванием , а затем заглавная буква на самом деле не в порядке. (Не то, чтобы это было слишком важно.) – Praxeolitic 24 May 2016 в 14:11

Возможно, вы могли бы использовать макросы компилятора __DATE__ __TIME__ внутри своего кода, а не получать его из cmake. Стоит упомянуть, что вам нужно будет очистить / сделать, чтобы обновить эти значения (поскольку GCC внедряет его, если объект уже скомпилирован, он не будет компилироваться снова, поэтому нет изменения даты / времени)

2
ответ дан Lucas Teske 18 August 2018 в 23:35
поделиться

Для относительно недавних версий CMake (> = 2.8.11):

string (TIMESTAMP {output variable} [{format string}] [UTC])

(см. [д0] http://www.cmake.org/cmake/help/v3.0/command/string.html [/ д0]). Например, STRING (TIMESTAMP TODAY "% Y% m% d")

13
ответ дан mathias 18 August 2018 в 23:35
поделиться
  • 1
    Не могли бы вы добавить несколько примеров? – Alfishe 9 August 2017 в 18:39
  • 2
    string(TIMESTAMP ... кэшируется до тех пор, пока вы не отредактируете CMakeLists.txt – Orient 14 June 2018 в 13:11

Я получаю следующее решение:

if(CMAKE_SIZEOF_VOID_P EQUAL 8)
    add_custom_target(
        "linktimestamp"
        ALL
        COMMAND date +'%Y-%m-%d %H:%M:%S' > "linktimestamp.txt"
        COMMAND objcopy --input binary --output elf64-x86-64 --binary-architecture i386:x86-64 --rename-section .data=.rodata,CONTENTS,ALLOC,LOAD,READONLY,DATA "linktimestamp.txt" "linktimestamp.o"
        WORKING_DIRECTORY "${CMAKE_CURRENT_BINARY_DIR}"
        COMMENT "link timestamp: ${LINK_TIMESTAMP}"
        )
else()
    add_custom_target(
        "linktimestamp"
        ALL
        COMMAND date +'%Y-%m-%d %H:%M:%S' > "linktimestamp.txt"
        COMMAND objcopy --input binary --output elf32-i386 --binary-architecture i386 --rename-section .data=.rodata,CONTENTS,ALLOC,LOAD,READONLY,DATA "linktimestamp.txt" "linktimestamp.o"
        WORKING_DIRECTORY "${CMAKE_CURRENT_BINARY_DIR}"
        COMMENT "link timestamp: ${LINK_TIMESTAMP}"
        )
endif()
#add_dependencies(${PROJECT_NAME} "linktimestamp")
target_link_libraries(${PROJECT_NAME} PRIVATE "${CMAKE_CURRENT_BINARY_DIR}/linktimestamp.o")

Бинарная цель ${PROJECT_NAME}, связанная каждый раз с обновленным сектором.

Qt код для получить эту метку времени:

extern char _binary_linktimestamp_txt_start[];
//extern char _binary_linktimestamp_txt_end[];
extern char _binary_linktimestamp_txt_size[];
const auto text = QByteArray::fromRawData(_binary_linktimestamp_txt_start, reinterpret_cast< std::intptr_t >(_binary_linktimestamp_txt_size));
qDebug() << QDateTime::fromString(QString::fromUtf8(text), "yyyy-MM-dd HH:mm:ss\n"));
0
ответ дан Orient 18 August 2018 в 23:35
поделиться
Другие вопросы по тегам:

Похожие вопросы: