我正在尝试使用CMake交叉编译程序,但此消息失败:
/bin/sh: 1: Syntax error: ";;" unexpected
该程序可以使用原始Makefile完美编译
这是我的CMake文件:
cmake_minimum_required(VERSION 3.9)
project(my_target LANGUAGES CUDA CXX C)
include(CheckLanguage)
check_language(CUDA)
# STD
if (NOT DEFINED CMAKE_CUDA_STANDARD)
set(CMAKE_CUDA_STANDARD 11)
set(CMAKE_CUDA_STANDARD_REQUIRED ON)
endif()
find_package(Poco REQUIRED Foundation Util)
# Flags
set (
CMAKE_C_STANDARD 11
)
set(
CMAKE_CXX_STANDARD 11
)
set(
CMAKE_C_FLAGS
${CMAKE_C_FLAGS}
-c -Wall -fopenmp
)
set(
CMAKE_CXX_FLAGS
${CMAKE_CXX_FLAGS}
-c -Wall -fopenmp
)
set(
CMAKE_CUDA_FLAGS
${CMAKE_NVCC_FLAGS}
--ccbin $(CMAKE_CXX_COMPILER) -O2 -gencode -std=c++11 -dc -Werror deprecated-declarations
)
# Compile Objects
file(GLOB_RECURSE src_c src/*.c )
file(GLOB_RECURSE src_cpp src/*.cpp)
file(GLOB_RECURSE src_cu src/*.cu )
file(GLOB_RECURSE src_h src/*.h )
add_library(cobjs STATIC ${src_c} ${src_h} )
add_library(cppobjs STATIC ${src_cpp} ${src_h})
add_library(cuobjs STATIC ${src_cu} ${src_h} )
target_compile_options(cobjs PUBLIC ${CMAKE_C_FLAGS} )
target_compile_options(cppobjs PUBLIC ${CMAKE_CXX_FLAGS})
target_compile_options(cuobjs PUBLIC ${CMAKE_NVCC_FLAGS})
set_target_properties( cuobjs
PROPERTIES CUDA_SEPARABLE_COMPILATION ON)
add_executable(my_target
${cobjs} ${cppobjs} ${cuobjs}
${src_h}
)
# Include Dirs
target_include_directories(cobjs PUBLIC
include src
)
target_include_directories(cppobjs PUBLIC
include src
)
target_include_directories(cuobjs PUBLIC
include src
)
target_include_directories(my_target PUBLIC
include src
)
link_directories(
${POCO_HOME}
${METIS_HOME}
)
target_link_libraries(my_target PUBLIC
cobjs
cppobjs
cuobjs
-lPocoFoundation
-lPocoUtil
-lpthread
-lgomp
-lmetis
)
和正常的Makefile:
#===============================================================================
CUDA_PATH := /usr/local/cuda
METIS_PATH := ${METIS_HOME}
POCO_PATH := ${POCO_HOME}
# D-debug R-release
COMPILEMD := R
EXE := coupled.exe
CC := gcc
CXX := g++
#===============================================================================
DIR_BIN := bin
DIR_SRC := src
CCFLAGS := -Iinclude -I$(DIR_SRC) -std=c11 -c -Wall -fopenmp
CXXFLAGS := -I$(CUDA_PATH)/include -I$(METIS_PATH)/include -I$(POCO_PATH)/include -Iinclude -I$(DIR_SRC) -std=c++11 -c -Wall -fopenmp
NVCCFLAGS := -I$(POCO_PATH)/include -I$(DIR_SRC) -std=c++11 -dc -Werror deprecated-declarations
LDFLAGS := -L$(METIS_PATH)/lib -lmetis -L$(POCO_PATH)/lib -lPocoUtil -lPocoFoundation -Llib -ltecio -lpthread -lgomp
BASENM := $(basename $(EXE))
SUFFIX := $(suffix $(EXE))
SRC_C := $(shell find $(DIR_SRC) -name *.c)
SRC_CPP := $(shell find $(DIR_SRC) -name *.cpp)
SRC_CU := $(shell find $(DIR_SRC) -name *.cu)
OBJ_C := $(SRC_C:%.c=%.o)
OBJ_CPP := $(SRC_CPP:%.cpp=%.o)
OBJ_CU := $(SRC_CU:%.cu=%.o)
ifeq ($(COMPILEMD), D)
CCFLAGS += -D_DEBUG -g
CXXFLAGS += -D_DEBUG -g
NVCCFLAGS += -D_DEBUG -g -G
else ifeq ($(COMPILEMD), R)
CCFLAGS += -DNDEBUG -O2
CXXFLAGS += -DNDEBUG -O2
NVCCFLAGS += -DNDEBUG -O2
else
$(error error COMPILEMD($(COMPILEMD)))
endif
CCFLAGS += -DKS_FP_DOUBLE -march=native
CXXFLAGS += -DKS_FP_DOUBLE -march=native
NVCCFLAGS += -DKS_FP_DOUBLE
BASENM := $(BASENM)DP$(COMPILEMD)
ifeq ($(SRC_CU), )
LD := $(CXX)
else
NVCC := $(CUDA_PATH)/bin/nvcc -ccbin $(CXX)
DEVICE_SM := 50 52 60 61 #70 75
$(foreach SM,$(DEVICE_SM),$(eval NVCCFLAGS += -gencode arch=compute_$(SM),code=sm_$(SM)))
$(foreach SM,$(DEVICE_SM),$(eval LDFLAGS += -gencode arch=compute_$(SM),code=sm_$(SM)))
LD := $(NVCC)
endif
OBJ := $(OBJ_C) $(OBJ_CPP) $(OBJ_CU)
EXE := $(DIR_BIN)/$(BASENM)$(SUFFIX)
#===============================================================================
all: $(EXE)
.PHONY: all clean cleanall
$(EXE): $(OBJ)
@mkdir -p $(DIR_BIN)
$(LD) $^ $(LDFLAGS) -o $@
$(OBJ_C): %.o: %.c
$(CC) $< $(CCFLAGS) -o $@
$(OBJ_CPP): %.o: %.cpp
$(CXX) $< $(CXXFLAGS) -o $@
$(OBJ_CU): %.o: %.cu
$(NVCC) $< $(NVCCFLAGS) -o $@
clean:
-rm -rf $(OBJ) $(EXE)
cleanall:
-rm -rf $(OBJ) $(DIR_BIN)/*log $(DIR_BIN)/*.exe $(DIR_BIN)/*.dat
很抱歉,我无法提供项目的源代码。
我是CMake的新手,我们将不胜感激!
编辑
我尝试了@squareskittles提供的解决方案,似乎可以解决/bin/sh: 1: Syntax error: ";;" unexpected
问题。但是我收到了一个新错误,内容为:
c++: fatal error: no input files
但是在相应的build.make
文件中,错误行写道:
/usr/bin/c++ $(CXX_DEFINES) $(CXX_INCLUDES) $(CXX_FLAGS) -o <path-to-my-cpp>/my.cpp.o -c <path-to-my-cpp>/my.cpp
编辑2
感谢@squareskittles的回答,我终于了解了CMake的工作原理。实际上,CMakeLists.txt文件中有多个不正确的部分:
CMake自动将-c
标志添加到C和C ++编译器,因此无需手动添加。
与相比,最好使用add_compile_options()
添加编译标志set(CMAKE_<LANG>_FLAGS ...)
。
link_directories
应该总是去之前add_library()
和之后add_executable()
。而是使用一种现代方法find_library()
,请参见此处。
我最终放弃了像在Makefile中一样手动编写多阶段编译的方法,而是在中添加了所有源文件add_executable()
。CMake似乎完美地处理了不同的情况。
我的最终工作版本:
cmake_minimum_required(VERSION 3.9)
project(my_target LANGUAGES CUDA CXX C)
# STD
if (NOT DEFINED CMAKE_CUDA_STANDARD)
set(CMAKE_CUDA_STANDARD 11)
set(CMAKE_CUDA_STANDARD_REQUIRED ON)
endif()
find_package(Poco REQUIRED Foundation Util)
# Flags
set (
CMAKE_C_STANDARD 11
)
set(
CMAKE_CXX_STANDARD 11
)
# Compile Objects
file(GLOB_RECURSE src_c src/*.c )
file(GLOB_RECURSE src_cpp src/*.cpp)
file(GLOB_RECURSE src_cu src/*.cu )
file(GLOB_RECURSE src_h src/*.h )
# message(STATUS "src_c = ${src_c}" )
# message(STATUS "src_cpp = ${src_cpp}")
# message(STATUS "src_cu = ${src_cu}" )
# message(STATUS "src_h = ${src_h}" )
add_definitions(-DKS_FP_DOUBLE)
link_directories(
${POCO_HOME}
${METIS_HOME}
)
add_executable(my_target
${src_c}
${src_cpp}
${src_cu}
${src_h}
)
# Include Dirs
target_include_directories(my_target PUBLIC
include src
)
set_target_properties(my_target
PROPERTIES CUDA_SEPARABLE_COMPILATION ON
)
target_link_libraries(my_target PUBLIC
# cobjs
# cppobjs
# cuobjs
-lPocoFoundation
-lPocoUtil
-lpthread
-lgomp
-lmetis
)
设置CMake编译器标志变量(或任何其他CMake变量)时,不需要插入分号;
来分隔参数/标志。CMake将识别set()
命令中的换行符和空格并为您处理。从文档:
多个参数将以分号分隔的列表形式连接,以形成要设置的实际变量值。
尝试这个:
set(
CMAKE_C_FLAGS
${CMAKE_C_FLAGS}
-c -Wall -fopenmp
)
set(
CMAKE_CXX_FLAGS
${CMAKE_CXX_FLAGS}
-c -Wall -fopenmp
)
set(
CMAKE_CUDA_FLAGS
${CMAKE_NVCC_FLAGS}
--ccbin $(CMAKE_CXX_COMPILER) -O2 -gencode -std=c++11 -dc -Werror deprecated-declarations
)
您发布的CMake文件还有一个问题。该add_executable()
命令仅将源文件作为参数。您不能将先前定义的目标用作参数。尝试将您的呼叫修改为add_executable()
; 您已经通过对的调用将C,C ++和Cuda源代码编译到静态库中add_library()
,因此也许可以在此调用中包含一个main.cpp
(定义对的调用main()
):
add_executable(my_target
main.cpp
${src_h}
)
本文收集自互联网,转载请注明来源。
如有侵权,请联系[email protected] 删除。
我来说两句