使用 CMake 的 C++ 代码在带有 clang 的 MacO 上编译,但在 Linux 上引发语法错误
C++ code using CMake compiles on MacOs with clang but raise syntax errors on Linux
我需要我的代码在 Linux 和 MacOs 上都能工作。
这是我用来生成 Makefile 的 CMakeLists.txt 文件。
cmake_minimum_required(VERSION 3.10)
# set the project name and version
project(PCATests VERSION 0.1
DESCRIPTION "tests of the framework for building Cellular Automata"
LANGUAGES CXX)
# specify the C++ standard
set(CMAKE_CXX_STANDARD 17)
set(CMAKE_CXX_STANDARD_REQUIRED True)
find_package(OpenMP REQUIRED)
if (${OPENMP_FOUND})
include_directories(${INCLUDE_DIRS})
endif()
include_directories(../../include ../ext)
link_directories(../../build)
# compile options
if (MSVC)
# warning level 4 and all warnings as errors
add_compile_options(/W4 /WX)
# if the compiler supports OpenMP, use the right flags
if (${OPENMP_FOUND})
add_compile_options(${OpenMP_CXX_FLAGS})
endif()
else()
# lots of warnings and all warnings as errors
add_compile_options(-Wall -Wextra -pedantic -Werror)
if (NOT CMAKE_CXX_COMPILER_ID MATCHES "GNU")
add_compile_options(-Wno-error=unused-command-line-argument)
endif()
# optimizations and debug informations
add_compile_options(-g -O3)
# if the compiler supports OpenMP, use the right flags
if (${OPENMP_FOUND})
add_compile_options(${OpenMP_CXX_FLAGS})
endif()
endif()
set(unit_test_targets
test_sequential_all
test_operators
test_library_imports
test_sequential_automaton
test_utilities
test_sequential_leaks_valgrind
test_omp_automaton
)
foreach(TARGET ${unit_test_targets})
add_executable(${TARGET} ${TARGET}.cpp)
target_link_libraries(${TARGET} parallelcellularautomata)
endforeach()
在 MacO 上,以下步骤有效,我得到了最终的可执行文件:
~/repos/parallel-cellular-automata/tests/unit/build$ pwd
/Users/gerardozinno/repos/parallel-cellular-automata/tests/unit/build
~/repos/parallel-cellular-automata/tests/unit/build$ cmake ..
-- The CXX compiler identification is AppleClang 11.0.0.11000033
-- Detecting CXX compiler ABI info
-- Detecting CXX compiler ABI info - done
-- Check for working CXX compiler: /Library/Developer/CommandLineTools/usr/bin/c++ - skipped
-- Detecting CXX compile features
-- Detecting CXX compile features - done
-- Found OpenMP_CXX: -Xclang -fopenmp (found version "3.1")
-- Found OpenMP: TRUE (found version "3.1")
-- Configuring done
-- Generating done
-- Build files have been written to: /Users/gerardozinno/repos/parallel-cellular-automata/tests/unit/build
~/repos/parallel-cellular-automata/tests/unit/build$ make
Scanning dependencies of target test_omp_automaton
...
Scanning dependencies of target test_sequential_automaton
[ 7%] Building CXX object CMakeFiles/test_sequential_leaks_valgrind.dir/test_sequential_leaks_valgrind.cpp.o
...
[100%] Built target test_sequential_all
在这个编译过程之后我有了我的可执行文件,没有出现警告或错误。
同时,如果我尝试使用相同的命令在 linux Ubuntu 上编译相同的代码:
gerardo@newton:~/repos/parallel-cellular-automata/tests/unit/build$ pwd
/home/gerardo/repos/parallel-cellular-automata/tests/unit/build
gerardo@newton:~/repos/parallel-cellular-automata/tests/unit/build$ cmake ..
-- The CXX compiler identification is GNU 9.3.0
-- Check for working CXX compiler: /usr/bin/c++
-- Check for working CXX compiler: /usr/bin/c++ -- works
-- Detecting CXX compiler ABI info
-- Detecting CXX compiler ABI info - done
-- Detecting CXX compile features
-- Detecting CXX compile features - done
-- Found OpenMP_CXX: -fopenmp (found version "4.5")
-- Found OpenMP: TRUE (found version "4.5")
-- Configuring done
-- Generating done
-- Build files have been written to: /home/gerardo/repos/parallel-cellular-automata/tests/unit/build
gerardo@newton:~/repos/parallel-cellular-automata/tests/unit/build$ make
Scanning dependencies of target test_omp_automaton
[ 7%] Building CXX object CMakeFiles/test_omp_automaton.dir/test_omp_automaton.cpp.o
我开始遇到类似这些错误。
对于每个 for 循环,我都会收到此错误:
In file included from /home/gerardo/repos/parallel-cellular-automata/tests/unit/../../include/cellular_automata.hpp:6,
from /home/gerardo/repos/parallel-cellular-automata/tests/unit/test_omp_automaton.cpp:7:
/home/gerardo/repos/parallel-cellular-automata/tests/unit/../../include/omp_automaton.hpp: In member function ‘virtual void ca::omp::CellularAutomaton<T>::sim
ulate(unsigned int)’:
/home/gerardo/repos/parallel-cellular-automata/tests/unit/../../include/omp_automaton.hpp:93:22: error: expected ‘=’ before ‘{’ token
93 | for (size_t i{0}; i < rows; ++i)
说'='应该在'{'之前,下面是我从未遇到过的错误:
/home/gerardo/repos/parallel-cellular-automata/tests/unit/../../include/omp_automaton.hpp:93:9: error: use of local variable with automatic storage from conta
ining function
93 | for (size_t i{0}; i < rows; ++i)
| ^~~
/home/gerardo/repos/parallel-cellular-automata/tests/unit/../../include/omp_automaton.hpp:93:21: note: ‘size_t i’ declared here
93 | for (size_t i{0}; i < rows; ++i)
| ^
说使用包含函数的自动存储的局部变量。
怎么可能在 MacOs 上一切正常,而在 linux 上却出现错误?
我该如何解决它们?我可以发誓该代码过去在 linux 上运行良好,我认为在我包含
后它开始无法编译
if (NOT CMAKE_CXX_COMPILER_ID MATCHES "GNU")
add_compile_options(-Wno-error=unused-command-line-argument)
endif()
在 CMakeLists.txt 中,但现在即使我注释掉那行代码也不起作用。
使用的编译器显示在 cmake 输出的第一行。
我也在另一台 linux 机器上尝试了代码,但得到了同样的错误。
正如 Tsyvarev 在评论中指出的那样,问题是我在 Linux 上的 OpenMp 不支持 for
迭代器的大括号初始化程序。
我需要我的代码在 Linux 和 MacOs 上都能工作。
这是我用来生成 Makefile 的 CMakeLists.txt 文件。
cmake_minimum_required(VERSION 3.10)
# set the project name and version
project(PCATests VERSION 0.1
DESCRIPTION "tests of the framework for building Cellular Automata"
LANGUAGES CXX)
# specify the C++ standard
set(CMAKE_CXX_STANDARD 17)
set(CMAKE_CXX_STANDARD_REQUIRED True)
find_package(OpenMP REQUIRED)
if (${OPENMP_FOUND})
include_directories(${INCLUDE_DIRS})
endif()
include_directories(../../include ../ext)
link_directories(../../build)
# compile options
if (MSVC)
# warning level 4 and all warnings as errors
add_compile_options(/W4 /WX)
# if the compiler supports OpenMP, use the right flags
if (${OPENMP_FOUND})
add_compile_options(${OpenMP_CXX_FLAGS})
endif()
else()
# lots of warnings and all warnings as errors
add_compile_options(-Wall -Wextra -pedantic -Werror)
if (NOT CMAKE_CXX_COMPILER_ID MATCHES "GNU")
add_compile_options(-Wno-error=unused-command-line-argument)
endif()
# optimizations and debug informations
add_compile_options(-g -O3)
# if the compiler supports OpenMP, use the right flags
if (${OPENMP_FOUND})
add_compile_options(${OpenMP_CXX_FLAGS})
endif()
endif()
set(unit_test_targets
test_sequential_all
test_operators
test_library_imports
test_sequential_automaton
test_utilities
test_sequential_leaks_valgrind
test_omp_automaton
)
foreach(TARGET ${unit_test_targets})
add_executable(${TARGET} ${TARGET}.cpp)
target_link_libraries(${TARGET} parallelcellularautomata)
endforeach()
在 MacO 上,以下步骤有效,我得到了最终的可执行文件:
~/repos/parallel-cellular-automata/tests/unit/build$ pwd
/Users/gerardozinno/repos/parallel-cellular-automata/tests/unit/build
~/repos/parallel-cellular-automata/tests/unit/build$ cmake ..
-- The CXX compiler identification is AppleClang 11.0.0.11000033
-- Detecting CXX compiler ABI info
-- Detecting CXX compiler ABI info - done
-- Check for working CXX compiler: /Library/Developer/CommandLineTools/usr/bin/c++ - skipped
-- Detecting CXX compile features
-- Detecting CXX compile features - done
-- Found OpenMP_CXX: -Xclang -fopenmp (found version "3.1")
-- Found OpenMP: TRUE (found version "3.1")
-- Configuring done
-- Generating done
-- Build files have been written to: /Users/gerardozinno/repos/parallel-cellular-automata/tests/unit/build
~/repos/parallel-cellular-automata/tests/unit/build$ make
Scanning dependencies of target test_omp_automaton
...
Scanning dependencies of target test_sequential_automaton
[ 7%] Building CXX object CMakeFiles/test_sequential_leaks_valgrind.dir/test_sequential_leaks_valgrind.cpp.o
...
[100%] Built target test_sequential_all
在这个编译过程之后我有了我的可执行文件,没有出现警告或错误。
同时,如果我尝试使用相同的命令在 linux Ubuntu 上编译相同的代码:
gerardo@newton:~/repos/parallel-cellular-automata/tests/unit/build$ pwd
/home/gerardo/repos/parallel-cellular-automata/tests/unit/build
gerardo@newton:~/repos/parallel-cellular-automata/tests/unit/build$ cmake ..
-- The CXX compiler identification is GNU 9.3.0
-- Check for working CXX compiler: /usr/bin/c++
-- Check for working CXX compiler: /usr/bin/c++ -- works
-- Detecting CXX compiler ABI info
-- Detecting CXX compiler ABI info - done
-- Detecting CXX compile features
-- Detecting CXX compile features - done
-- Found OpenMP_CXX: -fopenmp (found version "4.5")
-- Found OpenMP: TRUE (found version "4.5")
-- Configuring done
-- Generating done
-- Build files have been written to: /home/gerardo/repos/parallel-cellular-automata/tests/unit/build
gerardo@newton:~/repos/parallel-cellular-automata/tests/unit/build$ make
Scanning dependencies of target test_omp_automaton
[ 7%] Building CXX object CMakeFiles/test_omp_automaton.dir/test_omp_automaton.cpp.o
我开始遇到类似这些错误。
对于每个 for 循环,我都会收到此错误:
In file included from /home/gerardo/repos/parallel-cellular-automata/tests/unit/../../include/cellular_automata.hpp:6,
from /home/gerardo/repos/parallel-cellular-automata/tests/unit/test_omp_automaton.cpp:7:
/home/gerardo/repos/parallel-cellular-automata/tests/unit/../../include/omp_automaton.hpp: In member function ‘virtual void ca::omp::CellularAutomaton<T>::sim
ulate(unsigned int)’:
/home/gerardo/repos/parallel-cellular-automata/tests/unit/../../include/omp_automaton.hpp:93:22: error: expected ‘=’ before ‘{’ token
93 | for (size_t i{0}; i < rows; ++i)
说'='应该在'{'之前,下面是我从未遇到过的错误:
/home/gerardo/repos/parallel-cellular-automata/tests/unit/../../include/omp_automaton.hpp:93:9: error: use of local variable with automatic storage from conta
ining function
93 | for (size_t i{0}; i < rows; ++i)
| ^~~
/home/gerardo/repos/parallel-cellular-automata/tests/unit/../../include/omp_automaton.hpp:93:21: note: ‘size_t i’ declared here
93 | for (size_t i{0}; i < rows; ++i)
| ^
说使用包含函数的自动存储的局部变量。
怎么可能在 MacOs 上一切正常,而在 linux 上却出现错误? 我该如何解决它们?我可以发誓该代码过去在 linux 上运行良好,我认为在我包含
后它开始无法编译if (NOT CMAKE_CXX_COMPILER_ID MATCHES "GNU")
add_compile_options(-Wno-error=unused-command-line-argument)
endif()
在 CMakeLists.txt 中,但现在即使我注释掉那行代码也不起作用。
使用的编译器显示在 cmake 输出的第一行。
我也在另一台 linux 机器上尝试了代码,但得到了同样的错误。
正如 Tsyvarev 在评论中指出的那样,问题是我在 Linux 上的 OpenMp 不支持 for
迭代器的大括号初始化程序。