这是对我之前发布的一个问题的一点后续。我的基本问题是使用Gambit Scheme构建应用程序。
虽然上述问题中建议的解决方案有效,但它有点麻烦,所以我决定尝试将 Gambit Scheme 作为自定义编译器/语言添加到 CMake。按照这个问题中的建议,我创建了以下文件:
cmake/CMakeDetermineGambitCompiler.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 )
cmake/CMakeGambitInformation.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 )
cmake/CMakeGambitCompiler.cmake.in:
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@" )
cmake/CMakeTestGambitCompiler.cmake:
# For now do nothing
set( CMAKE_Gambit_COMPILER_WORKS 1 CACHE INTERNAL "" )
然后,在我的项目根目录中,我还有两个文件:
CMakeTexts.txt:
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:
;;; Simple Scheme example
(begin (write "Hello, Schemer!")
(newline))
给出以下结构:
project_root/
cmake/
CMakeDetermineGambitCompiler.cmake
CMakeGambitCompiler.cmake.in
CMakeGambitInformation.cmake
CMakeTestGambitCompiler.cmake
CMakeLists.txt
main.scm
虽然这适用于单个文件,但一旦我添加了另一个源文件,我需要 Gambit 首先为从 Scheme 源生成的所有 C 文件创建一个链接文件。这是一个简单的例子:
假设我添加了第二个文件factmodule.scm:
;;; This is a simple Scheme module that provides a functions that will
;;; calculate the factorial of a number n
(define fact
(lambda (n)
(if (zero? n)
1
(* n (fact (- n 1))))))
并更新main.scm:
(begin (write "Hello, Schemer!")
(newline)
(write "10! = ")
(write (number->string (fact 10)))
(newline))
为了“手动”构建这个,我执行以下操作:
$ gambitc -c factmodule.scm main.scm # generate C files from Scheme
$ gambitc -o link_file.c -link factmodule.c main.c # generate a link file
$ gambitc -obj factmodule.c main.c link_file.c # compile the C files in object files
$ gcc -o myexec -factmodule.o main.o link_file.o -lgambit # link the final executable
我的问题是第二步,创建链接文件。理想情况下,我想在cmake/CMakeGambitInformation.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
)
但这有两个问题。一、<OBJECTS>
保存生成的C文件;据我了解,给出的命令CMAKE_Gambit_COMPILE_OBJECT
是在每个源文件基础上执行的。二,我显然只想运行最后两个命令一次,但在CMAKE_Gambit_LINK_EXECUTABLE
调用给定的命令之前。
有没有办法在创建对象之后但在它们链接之前执行自定义命令?
我查看了CMake/Modules中的其他一些编译器,但找不到真正能做到这一点的语言。而且这个条目似乎是添加新语言最完整的文档,官方文档似乎并没有真正提及它。