在CMake中向自定义编译器/语言添加额外的编译步骤
这是对之前的一项研究的一点后续。我的基本问题是使用构建应用程序 虽然上述问题中建议的解决方案可行,但有点麻烦,所以我决定尝试将Gambit Scheme作为自定义编译器/语言添加到CMake中。根据本文中的建议,我创建了以下文件: cmake/CMakeDetermineGambitCompiler.cmake:在CMake中向自定义编译器/语言添加额外的编译步骤,cmake,scheme,gambit,Cmake,Scheme,Gambit,这是对之前的一项研究的一点后续。我的基本问题是使用构建应用程序 虽然上述问题中建议的解决方案可行,但有点麻烦,所以我决定尝试将Gambit Scheme作为自定义编译器/语言添加到CMake中。根据本文中的建议,我创建了以下文件: cmake/CMakeDetermineGambitCompiler.cmake: # Find the compiler find_program( CMAKE_Gambit_COMPILER NAMES "gambitc&quo
# Find the compiler
find_program(
CMAKE_Gambit_COMPILER
NAMES "gambitc"
HINTS "${CMAKE_SOURCE_DIR}"
DOC "Gambit Scheme compiler"
)
mark_as_advanced( CMAKE_Gambit_COMPILER )
set( CMAKE_Gambit_SOURCE_FILE_EXTENSIONS scm;six )
# Remember this as a potential error
set( CMAKE_Gambit_OUTPUT_EXTENSION .c )
set( CMAKE_Gambit_COMPILER_ENV_VAR "" )
# Configure variables set in this file for fast reload later on
configure_file( ${CMAKE_CURRENT_LIST_DIR}/CMakeGambitCompiler.cmake.in
${CMAKE_PLATFORM_INFO_DIR}/CMakeGambitCompiler.cmake )
# This file sets the basic flags for the GAMBIT compiler
# Generate the C files
set( CMAKE_Gambit_COMPILE_OBJECT
"<CMAKE_Gambit_COMPILER> -o <OBJECT> -c <SOURCE>"
)
# Build a executable
set( CMAKE_Gambit_LINK_EXECUTABLE
"<CMAKE_Gambit_COMPILER> -o <TARGET> -exe <OBJECTS>"
)
set( CMAKE_Gambit_INFORMATION_LOADED 1 )
set( CMAKE_Gambit_COMPILER "@CMAKE_Gambit_COMPILER@" )
set( CMAKE_Gambit_COMPILER_LOADED 1 )
set( CMAKE_Gambit_SOURCE_FILE_EXTENSIONS @CMAKE_Gambit_SOURCE_FILE_EXTENSIONS@ )
set( CMAKE_Gambit_OUTPUT_EXTENSION @CMAKE_Gambit_OUTPUT_EXTENSION@ )
set( CMAKE_Gambit_COMPILER_ENV_VAR "@CMAKE_Gambit_COMPILER_ENV_VAR@" )
# For now do nothing
set( CMAKE_Gambit_COMPILER_WORKS 1 CACHE INTERNAL "" )
cmake_minimum_required( VERSION 3.10...3.18 )
if( ${CMAKE_VERSION} VERSION_LESS 3.12 )
cmake_policy( VERSION ${CMAKE_MAJOR_VERSION}.${CMAKE_MINOR_VERSION} )
endif()
# Give the project a name
project( cmake-scheme-template NONE )
# Build simple Gambit Scheme program
list( APPEND CMAKE_MODULE_PATH "${CMAKE_SOURCE_DIR}/cmake")
enable_language( Gambit )
add_executable( ${PROJECT_NAME} main.scm )
cmake/CMakeGambitInformation.cmake:
# Find the compiler
find_program(
CMAKE_Gambit_COMPILER
NAMES "gambitc"
HINTS "${CMAKE_SOURCE_DIR}"
DOC "Gambit Scheme compiler"
)
mark_as_advanced( CMAKE_Gambit_COMPILER )
set( CMAKE_Gambit_SOURCE_FILE_EXTENSIONS scm;six )
# Remember this as a potential error
set( CMAKE_Gambit_OUTPUT_EXTENSION .c )
set( CMAKE_Gambit_COMPILER_ENV_VAR "" )
# Configure variables set in this file for fast reload later on
configure_file( ${CMAKE_CURRENT_LIST_DIR}/CMakeGambitCompiler.cmake.in
${CMAKE_PLATFORM_INFO_DIR}/CMakeGambitCompiler.cmake )
# This file sets the basic flags for the GAMBIT compiler
# Generate the C files
set( CMAKE_Gambit_COMPILE_OBJECT
"<CMAKE_Gambit_COMPILER> -o <OBJECT> -c <SOURCE>"
)
# Build a executable
set( CMAKE_Gambit_LINK_EXECUTABLE
"<CMAKE_Gambit_COMPILER> -o <TARGET> -exe <OBJECTS>"
)
set( CMAKE_Gambit_INFORMATION_LOADED 1 )
set( CMAKE_Gambit_COMPILER "@CMAKE_Gambit_COMPILER@" )
set( CMAKE_Gambit_COMPILER_LOADED 1 )
set( CMAKE_Gambit_SOURCE_FILE_EXTENSIONS @CMAKE_Gambit_SOURCE_FILE_EXTENSIONS@ )
set( CMAKE_Gambit_OUTPUT_EXTENSION @CMAKE_Gambit_OUTPUT_EXTENSION@ )
set( CMAKE_Gambit_COMPILER_ENV_VAR "@CMAKE_Gambit_COMPILER_ENV_VAR@" )
# For now do nothing
set( CMAKE_Gambit_COMPILER_WORKS 1 CACHE INTERNAL "" )
cmake_minimum_required( VERSION 3.10...3.18 )
if( ${CMAKE_VERSION} VERSION_LESS 3.12 )
cmake_policy( VERSION ${CMAKE_MAJOR_VERSION}.${CMAKE_MINOR_VERSION} )
endif()
# Give the project a name
project( cmake-scheme-template NONE )
# Build simple Gambit Scheme program
list( APPEND CMAKE_MODULE_PATH "${CMAKE_SOURCE_DIR}/cmake")
enable_language( Gambit )
add_executable( ${PROJECT_NAME} main.scm )
cmake/CMakeTestGambitCompiler.cmake:
# Find the compiler
find_program(
CMAKE_Gambit_COMPILER
NAMES "gambitc"
HINTS "${CMAKE_SOURCE_DIR}"
DOC "Gambit Scheme compiler"
)
mark_as_advanced( CMAKE_Gambit_COMPILER )
set( CMAKE_Gambit_SOURCE_FILE_EXTENSIONS scm;six )
# Remember this as a potential error
set( CMAKE_Gambit_OUTPUT_EXTENSION .c )
set( CMAKE_Gambit_COMPILER_ENV_VAR "" )
# Configure variables set in this file for fast reload later on
configure_file( ${CMAKE_CURRENT_LIST_DIR}/CMakeGambitCompiler.cmake.in
${CMAKE_PLATFORM_INFO_DIR}/CMakeGambitCompiler.cmake )
# This file sets the basic flags for the GAMBIT compiler
# Generate the C files
set( CMAKE_Gambit_COMPILE_OBJECT
"<CMAKE_Gambit_COMPILER> -o <OBJECT> -c <SOURCE>"
)
# Build a executable
set( CMAKE_Gambit_LINK_EXECUTABLE
"<CMAKE_Gambit_COMPILER> -o <TARGET> -exe <OBJECTS>"
)
set( CMAKE_Gambit_INFORMATION_LOADED 1 )
set( CMAKE_Gambit_COMPILER "@CMAKE_Gambit_COMPILER@" )
set( CMAKE_Gambit_COMPILER_LOADED 1 )
set( CMAKE_Gambit_SOURCE_FILE_EXTENSIONS @CMAKE_Gambit_SOURCE_FILE_EXTENSIONS@ )
set( CMAKE_Gambit_OUTPUT_EXTENSION @CMAKE_Gambit_OUTPUT_EXTENSION@ )
set( CMAKE_Gambit_COMPILER_ENV_VAR "@CMAKE_Gambit_COMPILER_ENV_VAR@" )
# For now do nothing
set( CMAKE_Gambit_COMPILER_WORKS 1 CACHE INTERNAL "" )
cmake_minimum_required( VERSION 3.10...3.18 )
if( ${CMAKE_VERSION} VERSION_LESS 3.12 )
cmake_policy( VERSION ${CMAKE_MAJOR_VERSION}.${CMAKE_MINOR_VERSION} )
endif()
# Give the project a name
project( cmake-scheme-template NONE )
# Build simple Gambit Scheme program
list( APPEND CMAKE_MODULE_PATH "${CMAKE_SOURCE_DIR}/cmake")
enable_language( Gambit )
add_executable( ${PROJECT_NAME} main.scm )
然后,在我的项目根目录中,我还有两个文件:
CMakeTexts.txt:
# Find the compiler
find_program(
CMAKE_Gambit_COMPILER
NAMES "gambitc"
HINTS "${CMAKE_SOURCE_DIR}"
DOC "Gambit Scheme compiler"
)
mark_as_advanced( CMAKE_Gambit_COMPILER )
set( CMAKE_Gambit_SOURCE_FILE_EXTENSIONS scm;six )
# Remember this as a potential error
set( CMAKE_Gambit_OUTPUT_EXTENSION .c )
set( CMAKE_Gambit_COMPILER_ENV_VAR "" )
# Configure variables set in this file for fast reload later on
configure_file( ${CMAKE_CURRENT_LIST_DIR}/CMakeGambitCompiler.cmake.in
${CMAKE_PLATFORM_INFO_DIR}/CMakeGambitCompiler.cmake )
# This file sets the basic flags for the GAMBIT compiler
# Generate the C files
set( CMAKE_Gambit_COMPILE_OBJECT
"<CMAKE_Gambit_COMPILER> -o <OBJECT> -c <SOURCE>"
)
# Build a executable
set( CMAKE_Gambit_LINK_EXECUTABLE
"<CMAKE_Gambit_COMPILER> -o <TARGET> -exe <OBJECTS>"
)
set( CMAKE_Gambit_INFORMATION_LOADED 1 )
set( CMAKE_Gambit_COMPILER "@CMAKE_Gambit_COMPILER@" )
set( CMAKE_Gambit_COMPILER_LOADED 1 )
set( CMAKE_Gambit_SOURCE_FILE_EXTENSIONS @CMAKE_Gambit_SOURCE_FILE_EXTENSIONS@ )
set( CMAKE_Gambit_OUTPUT_EXTENSION @CMAKE_Gambit_OUTPUT_EXTENSION@ )
set( CMAKE_Gambit_COMPILER_ENV_VAR "@CMAKE_Gambit_COMPILER_ENV_VAR@" )
# For now do nothing
set( CMAKE_Gambit_COMPILER_WORKS 1 CACHE INTERNAL "" )
cmake_minimum_required( VERSION 3.10...3.18 )
if( ${CMAKE_VERSION} VERSION_LESS 3.12 )
cmake_policy( VERSION ${CMAKE_MAJOR_VERSION}.${CMAKE_MINOR_VERSION} )
endif()
# Give the project a name
project( cmake-scheme-template NONE )
# Build simple Gambit Scheme program
list( APPEND CMAKE_MODULE_PATH "${CMAKE_SOURCE_DIR}/cmake")
enable_language( Gambit )
add_executable( ${PROJECT_NAME} main.scm )
要生成的实际代码,main.scm:
# Find the compiler
find_program(
CMAKE_Gambit_COMPILER
NAMES "gambitc"
HINTS "${CMAKE_SOURCE_DIR}"
DOC "Gambit Scheme compiler"
)
mark_as_advanced( CMAKE_Gambit_COMPILER )
set( CMAKE_Gambit_SOURCE_FILE_EXTENSIONS scm;six )
# Remember this as a potential error
set( CMAKE_Gambit_OUTPUT_EXTENSION .c )
set( CMAKE_Gambit_COMPILER_ENV_VAR "" )
# Configure variables set in this file for fast reload later on
configure_file( ${CMAKE_CURRENT_LIST_DIR}/CMakeGambitCompiler.cmake.in
${CMAKE_PLATFORM_INFO_DIR}/CMakeGambitCompiler.cmake )
# This file sets the basic flags for the GAMBIT compiler
# Generate the C files
set( CMAKE_Gambit_COMPILE_OBJECT
"<CMAKE_Gambit_COMPILER> -o <OBJECT> -c <SOURCE>"
)
# Build a executable
set( CMAKE_Gambit_LINK_EXECUTABLE
"<CMAKE_Gambit_COMPILER> -o <TARGET> -exe <OBJECTS>"
)
set( CMAKE_Gambit_INFORMATION_LOADED 1 )
set( CMAKE_Gambit_COMPILER "@CMAKE_Gambit_COMPILER@" )
set( CMAKE_Gambit_COMPILER_LOADED 1 )
set( CMAKE_Gambit_SOURCE_FILE_EXTENSIONS @CMAKE_Gambit_SOURCE_FILE_EXTENSIONS@ )
set( CMAKE_Gambit_OUTPUT_EXTENSION @CMAKE_Gambit_OUTPUT_EXTENSION@ )
set( CMAKE_Gambit_COMPILER_ENV_VAR "@CMAKE_Gambit_COMPILER_ENV_VAR@" )
# For now do nothing
set( CMAKE_Gambit_COMPILER_WORKS 1 CACHE INTERNAL "" )
cmake_minimum_required( VERSION 3.10...3.18 )
if( ${CMAKE_VERSION} VERSION_LESS 3.12 )
cmake_policy( VERSION ${CMAKE_MAJOR_VERSION}.${CMAKE_MINOR_VERSION} )
endif()
# Give the project a name
project( cmake-scheme-template NONE )
# Build simple Gambit Scheme program
list( APPEND CMAKE_MODULE_PATH "${CMAKE_SOURCE_DIR}/cmake")
enable_language( Gambit )
add_executable( ${PROJECT_NAME} main.scm )
;;;简单方案示例
(开始(写“你好,阴谋家!”)
(新行)
给出以下结构:
project_root/
cmake/
CMakeDetermineGambitCompiler.cmake
CMakeGambitCompiler.cmake.in
CMakeGambitInformation.cmake
CMakeTestGambitCompiler.cmake
CMakeLists.txt
main.scm
虽然这适用于单个文件,但只要我添加了另一个源文件,我就需要Gambit首先为从Scheme源生成的所有C文件创建一个链接文件。下面是一个简单的例子:
假设我添加第二个文件,factmodule.scm:
# Find the compiler
find_program(
CMAKE_Gambit_COMPILER
NAMES "gambitc"
HINTS "${CMAKE_SOURCE_DIR}"
DOC "Gambit Scheme compiler"
)
mark_as_advanced( CMAKE_Gambit_COMPILER )
set( CMAKE_Gambit_SOURCE_FILE_EXTENSIONS scm;six )
# Remember this as a potential error
set( CMAKE_Gambit_OUTPUT_EXTENSION .c )
set( CMAKE_Gambit_COMPILER_ENV_VAR "" )
# Configure variables set in this file for fast reload later on
configure_file( ${CMAKE_CURRENT_LIST_DIR}/CMakeGambitCompiler.cmake.in
${CMAKE_PLATFORM_INFO_DIR}/CMakeGambitCompiler.cmake )
# This file sets the basic flags for the GAMBIT compiler
# Generate the C files
set( CMAKE_Gambit_COMPILE_OBJECT
"<CMAKE_Gambit_COMPILER> -o <OBJECT> -c <SOURCE>"
)
# Build a executable
set( CMAKE_Gambit_LINK_EXECUTABLE
"<CMAKE_Gambit_COMPILER> -o <TARGET> -exe <OBJECTS>"
)
set( CMAKE_Gambit_INFORMATION_LOADED 1 )
set( CMAKE_Gambit_COMPILER "@CMAKE_Gambit_COMPILER@" )
set( CMAKE_Gambit_COMPILER_LOADED 1 )
set( CMAKE_Gambit_SOURCE_FILE_EXTENSIONS @CMAKE_Gambit_SOURCE_FILE_EXTENSIONS@ )
set( CMAKE_Gambit_OUTPUT_EXTENSION @CMAKE_Gambit_OUTPUT_EXTENSION@ )
set( CMAKE_Gambit_COMPILER_ENV_VAR "@CMAKE_Gambit_COMPILER_ENV_VAR@" )
# For now do nothing
set( CMAKE_Gambit_COMPILER_WORKS 1 CACHE INTERNAL "" )
cmake_minimum_required( VERSION 3.10...3.18 )
if( ${CMAKE_VERSION} VERSION_LESS 3.12 )
cmake_policy( VERSION ${CMAKE_MAJOR_VERSION}.${CMAKE_MINOR_VERSION} )
endif()
# Give the project a name
project( cmake-scheme-template NONE )
# Build simple Gambit Scheme program
list( APPEND CMAKE_MODULE_PATH "${CMAKE_SOURCE_DIR}/cmake")
enable_language( Gambit )
add_executable( ${PROJECT_NAME} main.scm )
;;;这是一个简单的Scheme模块,提供了
;;; 计算一个数n的阶乘
(定义事实)
(λ(n)
(如果(零?n)
1.
(*n(事实(-n1(()())))
并更新main.scm:
# Find the compiler
find_program(
CMAKE_Gambit_COMPILER
NAMES "gambitc"
HINTS "${CMAKE_SOURCE_DIR}"
DOC "Gambit Scheme compiler"
)
mark_as_advanced( CMAKE_Gambit_COMPILER )
set( CMAKE_Gambit_SOURCE_FILE_EXTENSIONS scm;six )
# Remember this as a potential error
set( CMAKE_Gambit_OUTPUT_EXTENSION .c )
set( CMAKE_Gambit_COMPILER_ENV_VAR "" )
# Configure variables set in this file for fast reload later on
configure_file( ${CMAKE_CURRENT_LIST_DIR}/CMakeGambitCompiler.cmake.in
${CMAKE_PLATFORM_INFO_DIR}/CMakeGambitCompiler.cmake )
# This file sets the basic flags for the GAMBIT compiler
# Generate the C files
set( CMAKE_Gambit_COMPILE_OBJECT
"<CMAKE_Gambit_COMPILER> -o <OBJECT> -c <SOURCE>"
)
# Build a executable
set( CMAKE_Gambit_LINK_EXECUTABLE
"<CMAKE_Gambit_COMPILER> -o <TARGET> -exe <OBJECTS>"
)
set( CMAKE_Gambit_INFORMATION_LOADED 1 )
set( CMAKE_Gambit_COMPILER "@CMAKE_Gambit_COMPILER@" )
set( CMAKE_Gambit_COMPILER_LOADED 1 )
set( CMAKE_Gambit_SOURCE_FILE_EXTENSIONS @CMAKE_Gambit_SOURCE_FILE_EXTENSIONS@ )
set( CMAKE_Gambit_OUTPUT_EXTENSION @CMAKE_Gambit_OUTPUT_EXTENSION@ )
set( CMAKE_Gambit_COMPILER_ENV_VAR "@CMAKE_Gambit_COMPILER_ENV_VAR@" )
# For now do nothing
set( CMAKE_Gambit_COMPILER_WORKS 1 CACHE INTERNAL "" )
cmake_minimum_required( VERSION 3.10...3.18 )
if( ${CMAKE_VERSION} VERSION_LESS 3.12 )
cmake_policy( VERSION ${CMAKE_MAJOR_VERSION}.${CMAKE_MINOR_VERSION} )
endif()
# Give the project a name
project( cmake-scheme-template NONE )
# Build simple Gambit Scheme program
list( APPEND CMAKE_MODULE_PATH "${CMAKE_SOURCE_DIR}/cmake")
enable_language( Gambit )
add_executable( ${PROJECT_NAME} main.scm )
(开始(写“你好,Schemer!”)
(新行)
(写“10!=”)
(写入(数字->字符串(事实10)))
(新行)
要“手动”构建此功能,我将执行以下操作:
$gambitc-c factmodule.scm main.scm#从方案生成c文件
$gambitc-o link_file.c-link factmodule.c main.c#生成链接文件
$gambitc-obj factmodule.c main.c link_file.c#在对象文件中编译c文件
$gcc-o myexec-factmodule.o main.o link_file.o-lgambit#链接最终的可执行文件
我的问题是第二步,创建链接文件。理想情况下,我想向cmake/cmakgambitinformation.cmake添加如下内容:
# Generate the C, link, and object files
set( CMAKE_Gambit_COMPILE_OBJECT
"<CMAKE_Gambit_COMPILER> -o <OBJECT> -c <SOURCE>" # generate C files
"<CMAKE_Gambit_COMPILER> -o link_file.c -link <OBJECTS>" # generate link file
"<CMAKE_Gambit_COMPILER> -obj <OBJECTS>" # compile C and link files
)
#生成C、链接和对象文件
set(CMAKE\u Gambit\u COMPILE\u对象
“-o-c”#生成c文件
“-o link_file.c-link”#生成链接文件
“-obj”#编译C和链接文件
)
但这有两个问题。一个,
保存生成的C文件;据我所知,CMAKE\u Gambit\u COMPILE\u OBJECT
中给出的命令是基于每个源文件执行的。第二,我显然只想运行最后两个命令一次,但是在调用给CMAKE\u Gambit\u LINK\u EXECUTABLE
的命令之前
有没有一种方法可以在创建对象之后但在链接对象之前执行自定义命令
我在中查看了一些其他编译器,但没有找到一种真正做到这一点的语言。这似乎是添加新语言的最完整的文档,但似乎并没有真正提到它。下面的hack应该可以实现您的目标。解决方案揭示了
gsc
和cmake
并不总是友好相处,因为它们都有自己隐式处理文件扩展名的方法。不管怎样,让我们开始吧
我打算从cmake
中复制的一系列命令(文件名略有不同)如下
这里,linkstub.scm
是一个空的(生成的)虚拟文件。我们需要将其用于最终链接,因为我们无法修改传递给CMAKE\u Gambit\u LINK\u可执行文件的
列表。相应的linkstub.c
文件将是由gsc-o linkstub.c-link…
生成的实际链接文件。这是通过add_custom_command
及其PRE_LINK
选项实现的(每次链接目标时执行一个命令)。同样的自定义命令还将linkstub.c
编译成一个对象文件;在最终链接开始之前,新创建的链接将覆盖上一个linkstub.o
。通过这种方式,我们可以欺骗CMake吞下一个linkstub.o
,它在编译所有其他对象文件时都会更新
让我们开始吧。我们需要在各自的文件中更改编译器命令和对象扩展名:
set(CMAKE_Gambit_COMPILE_OBJECT
"<CMAKE_Gambit_COMPILER> -o <SOURCE>.c -c <SOURCE>"
"<CMAKE_Gambit_COMPILER> -o <OBJECT> -obj <SOURCE>.c")
set(CMAKE_Gambit_OUTPUT_EXTENSION .o)
同样,这只是将相应的对象文件放入目标的对象依赖项中的一种方法。现在所有其他人:
set(sources
factmodule.scm
main.scm)
list(TRANSFORM sources
APPEND ".c"
OUTPUT_VARIABLE cSources)
list(TRANSFORM cSources
PREPEND "${CMAKE_CURRENT_SOURCE_DIR}/"
OUTPUT_VARIABLE cSources)
list(REMOVE_ITEM cSources
linkstub.scm.c)
add_executable(test ${sources} ${linkstub})
add_custom_command(TARGET test
PRE_LINK
COMMAND ${CMAKE_Gambit_COMPILER}
-o
${CMAKE_CURRENT_BINARY_DIR}/linkstub.scm.c
-link
${cSources}
COMMAND ${CMAKE_Gambit_COMPILER}
-o
${CMAKE_CURRENT_BINARY_DIR}/CMakeFiles/test.dir/linkstub.scm.o
-obj
${CMAKE_CURRENT_BINARY_DIR}/linkstub.scm.c
COMMAND ${CMAKE_COMMAND} -E remove ${cSources})
最后一个命令发挥了所有的魔力。它重新写入linkstub.scm.c
,将其编译成一个目标文件,最后删除源代码树中所有生成的.scm.c
文件。请注意,在其中一个路径中有一个丑陋的、硬编码的CMakeFiles/test.dir/
,应该有一种从目标查询此路径的方法来绕过此问题
请再次注意,文件扩展名在这里有些关键,解决方案很脆弱。CMake似乎绝对需要附加.o
的对象文件,即.scm.o
gsc
但是,如果没有另外说明,它将生成一个.c
而不是.scm.c
,这会导致-link
步骤生成与编译到.scm.o
中的符号不匹配的符号
作为旁注,这种方法显然不会处理方案源之间的任何动态/隐式依赖关系-如果您更改factmodule.scm
,而main.scm
需要重新传输和重新编译,则您将无法解决此问题。据我所知,目前还没有办法教CMake您想注册一个自定义依赖项扫描程序来解析.scm
文件
看起来一个普通的makefile
可能会做得更好。@lubgr是的,这是准确的,我正在Arch Linux上运行。从两个文件中删除(##…)
行;对不起,那些是左边的