Rozważ następujący uproszczony przypadek:

cmake ... -DMY_MACRO_USED_IN_CXX_CODE=1
make my_target
echo $(md5 my_target)
cmake ... -DMY_MACRO_USED_IN_CXX_CODE=2
make my_target
echo $(md5 my_target)

Używam makra, aby selektywnie używać fragmentów kodów w moim projekcie C ++. Podczas wielu biegów tego skryptu powłoki czasami md5 my_target nie zmienia się! Dzieje się tak, nawet jeśli włożę sleep 1s po każdym połączeniu do cmake. Ciekawe, co się tutaj dzieje? Jak temu zapobiec? Inny niż spać dla niektórych losowo długich okresów?

Minimalny przykład:

# files
main.cc
test.sh
CMakeLists.txt
# CMakeLists.txt
cmake_minimum_required(VERSION 3.9.0)
project(minimal-cmake-flags)
if (NOT DEFINED MY_MACRO OR "${MY_MACRO}" STREQUAL "")
  set(MY_MACRO 2000)
endif()
add_executable(main main.cc)
target_compile_definitions(main PUBLIC
  MY_MACRO=${MY_MACRO})
#! /bin/bash
function f() {
  cmake . -DMY_MACRO=$1 &> /dev/null
  make main &> /dev/null
  echo $(md5 main)
  ./main
  rm main
}
for i in $(seq 1 10); do
  f $i
done
// main.cc
#include <iostream>
using namespace std;
#ifndef MY_MACRO
#define MY_MACRO (1)
#endif
int main() {
  cout << MY_MACRO << endl;
}

Uruchom bash test.sh na mojej maszynie i drukuje:

MD5 (main) = e701db90ef8119715a918c97b56e919a
1
MD5 (main) = e701db90ef8119715a918c97b56e919a
1
MD5 (main) = 962a6a241bb4b39c0a99371ddd422eb4
3
MD5 (main) = 3493284e39a9d0ce3ade28201f54c32a
4
MD5 (main) = 82ae5011fe74d8612b996b2ba7ada13d
5
MD5 (main) = 938639953c59c99237110c606a543a50
6
MD5 (main) = 938639953c59c99237110c606a543a50
6
MD5 (main) = b1dddef9f2aba5680213f3e7bdce276c
8
MD5 (main) = b1dddef9f2aba5680213f3e7bdce276c
8
MD5 (main) = b88c362506aaaf6c6d74e3c734826734
10

Dodałem sleep 5s przed make i nadal się dzieje:

++ md5 main
+ echo MD5 '(main)' = b1dddef9f2aba5680213f3e7bdce276c
MD5 (main) = b1dddef9f2aba5680213f3e7bdce276c
+ ./main
8
+ rm main
+ for i in '$(seq 1 10)'
+ f 9
+ cmake . -DMY_MACRO=9
+ sleep 5s
+ make main
Scanning dependencies of target main
[ 50%] Linking CXX executable main
[100%] Built target main
++ md5 main
+ echo MD5 '(main)' = b1dddef9f2aba5680213f3e7bdce276c
MD5 (main) = b1dddef9f2aba5680213f3e7bdce276c
+ ./main
8

Aktualizacja: Używam innego make z homebrew, a problem zniknął. Może to być problem z MacOS make.

1
Camouflager 15 październik 2020, 13:06

1 odpowiedź

Najlepsza odpowiedź

Problem polega na znacznikach czasu. sleep należy włożyć przed połączeniem do cmake lub po połączeniu do make, aby uniknąć problemu z czasem znacznika (przez wydłużenie luki między najnowszą wyjściem {x3}} i ten cel).

GNU-MAIT, który jest wyposażony w narzędzia do deweloperów Macos pochodzi z 2006 roku. Najnowsza wersja Gnu-Make nie ma tego problemu.

0
Camouflager 16 październik 2020, 09:54