gpt4 book ai didi

cmake - 交叉编译c/c++/cuda程序时尝试使用CMake

转载 作者:行者123 更新时间:2023-12-04 11:01:31 29 4
gpt4 key购买 nike

我正在尝试使用 CMake 来交叉编译程序,但它失败并显示以下消息:

/bin/sh: 1: Syntax error: ";;" unexpected

该程序使用原始 完美编译生成文件

这是我的 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() ,见 here .
  • 我终于放弃了像我在 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() 中的换行符和空格为您指挥和处理。从文档:

    Multiple arguments will be joined as a semicolon-separated list to form the actual variable value to be 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() 的调用;您已经通过调用 add_library() 将 C、C++ 和 Cuda 源代码编译为静态库。 ,所以也许只有一个 main.cpp (定义您对 main() 的调用)您可以包含在此调用中:
    add_executable(my_target
    main.cpp
    ${src_h}
    )

    关于cmake - 交叉编译c/c++/cuda程序时尝试使用CMake,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/58771673/

    29 4 0
    Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
    广告合作:1813099741@qq.com 6ren.com