我有两个文件main.cpp和simd.cpp。我像这样编译它们:
g++ -c -mavx -O3 simd.cpp -o simd_avx.o
g++ -c -msse2 -O3 simd.cpp -o simd_sse2.o
g++ -O3 main.cpp simd_avx.o simd_sse2.o
现在我想用Cmake构建它。这是我的CMakeLists.txt文件:
add_library(avx OBJECT simd.cpp)
add_library(sse2 OBJECT simd.cpp)
IF(MSVC)
set(COMPILE_FLAGS "/openmp /Wall")
set_target_properties (avx PROPERTIES COMPILE_FLAGS "/arch:AVX")
set_target_properties (sse2 PROPERTIES COMPILE_FLAGS "/arch:SSE2 -D__SSE2__")
set(CMAKE_CXX_FLAGS ${COMPILE_FLAGS})
set(CMAKE_CXX_FLAGS_RELEASE "${COMPILE_FLAGS}")
ELSE()
set(COMPILE_FLAGS "-fopenmp -Wall")
set_target_properties (avx PROPERTIES COMPILE_DEFINITIONS "-mavx")
set_target_properties (sse2 PROPERTIES COMPILE_DEFINITIONS "-msse2")
set(CMAKE_CXX_FLAGS ${COMPILE_FLAGS})
set(CMAKE_CXX_FLAGS_RELEASE "${COMPILE_FLAGS} -O3")
ENDIF()
add_executable(dispatch main.cpp $<TARGET_OBJECTS:avx> $<TARGET_OBJECTS:sse2>)
使用MSVC2012,这很好用。但是,它在构建文件sse和avx中创建了两个单独的文件夹,每个文件夹指向相同的simd.cpp。我想这是一个很好的解决方案,因为我可以为每个文件夹单独设置属性。有两次显示相同的源文件有点烦人。
但是当我在Linux中为GCC创建一个makefile时,我得到错误:
<command-line>:0:1: error: macro names must be identifiers
make[2]: *** [src/CMakeFiles/avx.dir/simd.cpp.o] Error 1
make[1]: *** [src/CMakeFiles/avx.dir/all] Error 2
make: *** [all] Error 2
你能解释为什么Makefile失败了吗?你能建议一个更好的CMakeLists.txt文件来做我想做的事吗?
simd.cpp
#include <stdio.h>
#ifdef __AVX__
void func_avx() {
printf("avx\n");
}
#elif defined ( __SSE2__ )
void func_sse2() {
printf("sse2\n");
}
#else
// scalar code
#endif
的main.cpp
extern void func_sse2();
extern void func_avx();
void func_dispatch();
void (*fp)() = &func_dispatch;
void func_dispatch() {
#ifdef __AVX__
fp = func_avx;
#else
fp = func_sse2;
#endif
fp();
}
void func() {
fp();
}
int main() {
func();
}
答案 0 :(得分:2)
原因是印刷错误:
set_target_properties(avx PROPERTIES COMPILE_DEFINITIONS "-mavx")
编译器输出:
> cmake -H. -B_builds -DCMAKE_VERBOSE_MAKEFILE=ON
c++ -D-mavx ...
In file included from <built-in>:
<command line>:1:9: error: macro names must be identifiers
#define -mavx 1
因此定义-mavx
传递给编译器。
CMAKE_CXX_FLAGS
和CMAKE_CXX_FLAGS_RELEASE
(对于发布版本)。因此,如果CMAKE_CXX_FLAGS_RELEASE
已经修改,则无需修改CMAKE_CXX_FLAGS
:edit #1 -O3
选项已经传递给CMAKE_CXX_FLAGS_RELEASE
,无需修改它(顺便提一下,你重写-DNDEBUG
发布选项,我认为这非常重要):
edit #2 COMPILE_DEFINITIONS
修改-D...
标记(btw仅为msvc定义__SSE2__
,是否正确?):edit #3 set(CMAKE_CXX_FLAGS "my flags")
。默认情况下(有时根据用户需求)CMAKE_CXX_FLAGS
不是空变量,因此修改它的正确方法是:set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} my flags")
:
edit #5