【问题标题】:Whats the equivalent of Makefile's include for SConstruct?什么相当于 Makefile 对 SConstruct 的包含?
【发布时间】:2019-05-14 12:34:45
【问题描述】:

我正在尝试找到在 SConstruct 中复制 Makefile 的最佳方法。我想出了一个解决方案,但是它很混乱,依赖于用户传递特定的命令行参数,而且肯定不是最好的选择。

我的文件结构是这样的:

Working_Dir/
   |-> includes/
   |    |-> filename.mk
   |    |-> filename.py
   |-> Makefile
   |-> main.c
   |-> SConstruct

这些是我的文件内容

生成文件

all: main.o
    echo "Version is: $(VERSION)"
    gcc $^ -o main

include includes/filename.mk

文件名.mk

VERSION := "1.6.2"

%.o: %.c
    gcc -c -o $@ $<

S构造

import filename

env=Environment()
filename.Init(env)

#Create new builder
prog = Builder(action=["gcc $SOURCE -o $TARGET"])

#Add the builder
builder = { "Prog": prog}
env.Append(BUILDERS=builder)

print "Version is: " + env['VERSION']
env.Prog(target = "main", source = "main.o")

文件名.py

from SCons.Script import *  # Needed so we can use scons stuff like builders

def Init(env):
    #Make builder
    obj = Builder(action="gcc -c -o $TARGET $SOURCE")

    #Add stuff
    env.Append(BUILDERS= {'Obj': obj})
    env.Append(VERSION= "1.6.2")

(忽略 SCons 有自己的对象构建器这一事实,这只是我为一个更大的项目学习的一个简化示例)

要使用 makefile 进行编译,我运行 make,对于 SCons,运行 scons --site-dir="includes",因为我包含的文件不在标准路径中。据我所知,site_dir 选项是在 scons as seen here 中包含您自己的代码/构建器的唯一方法。另请注意,SConscript 文件不是我想要的,因为当您调用它们时,它们会在自己的目录中执行它们的指令,而不仅仅是将变量和构建器加载到调用者中。

我希望它让用户可以运行scons 并且它可以工作。我已阅读我可以在第 10.1.1 节中将这些设置全局设置为我的 bash 配置文件 as seen here,但我不想这样做,因为我不希望我系统上的每个 SCons 项目都默认使用此目录。我还查看了SetOption() 函数,但它是有限的,实际上根本不允许您设置此特定参数。

我能想到的唯一解决方案是开始使用GetOption('site_dir'),如果它不是我期望的目录,我会使用所有相同的参数调用一个新的 SCons 调用,但现在使用正确的site_dir选项。

但是,这感觉非常贫民窟,我觉得我错过了一个更好的解决方案。有没有更好的解决方案?

编辑:

我使用这个“includes”目录而不是“site_scons”目录的原因是因为在我较大的项目中,“includes”目录与项目不在同一个目录中,它在一个完全不同的目录中(该目录的路径是已知的)。 filename.py 将用于我的多个依赖它的 SCons 项目,但不是我机器上的每个 SCons 项目都应该使用它(即它不应该是全局的)。

【问题讨论】:

  • 为什么不能将includes 文件夹重命名为site_scons
  • 如果您能解释为什么 site_scons 不适合您,那么也许我们可以给出一个合理的答案。
  • 我的错,我将site_scons 误解为一个全局系统文件夹,每个 SCons 项目都可以访问它,而不仅仅是本地项目。我的问题仍然存在,我已经更新了描述以阐明我的系统的行为(编辑部分)。
  • 但是SCons 怎么知道你的哪些项目可能依赖于全局/本地定义呢?我看不到某种形式的命令行开关或列出可用项目及其特殊配置设置的全局查找表的方法。我不是在谈论任何具体细节,而只是从高层次的角度。如果您希望某些项目的处理方式与其他项目不同,那么 SCons 应该如何知道...没有用户提供所需的信息?
  • 当你的“更大”项目使用 make 时,它怎么知道它不应该在本地“includes”文件夹中搜索,而是在其他地方的不同目录中搜索硬盘?更多地考虑配置文件的方向(Python对此有很好的直接支持)以保存程序版本等数据,这可能是要走的路......然后你可以在每个SConstruct中提供配置文件的硬连线路径到你的filename.Init()

标签: python makefile options scons


【解决方案1】:

我自己想出来的。我刚刚将该文件作为普通 python 模块加载,如最佳答案here 所示。我专门使用了 Python 2 答案,因为我的系统上似乎配置了 SCons 以使用 python 2。

多亏了这一点,我能够从计算机上的任何位置加载任何 python 文件,包括与 scons 相关的代码,这正是我想要的。

对于那些好奇的人,这是我需要添加的代码

file_path = "/path/to/my/file/filename.py"

import imp
extra_stuff = imp.load_source('filename', file_path)

env=Environment()
extra_stuff.Init(env)

【讨论】:

  • import includes.filename 应该足够了
  • 如编辑部分所述,该解决方案不起作用,因为它仅在 includes 与调用脚本(我的 SCons 文件)位于同一目录中时才起作用。对于我的使用,我必须假设 includes 目录的位置在计算机上的任何位置。
猜你喜欢
  • 2011-12-25
  • 2015-11-14
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多