【问题标题】:How to rebuild project after SWIG files changed?SWIG 文件更改后如何重建项目?
【发布时间】:2016-10-03 11:32:23
【问题描述】:

鉴于以下生成文件:

TARGET = _example.pyd
OFILES = example.obj example_wrap.obj
HFILES =

CC = cl
CXX = cl
LINK = link
CPPFLAGS = -DNDEBUG -DUNICODE -DWIN32 -I. -Id:\virtual_envs\py351\include
CFLAGS = -nologo -Zm200 -Zc:wchar_t- -FS -Zc:strictStrings -O2 -MD -W3 -w44456 -w44457 -w44458
CXXFLAGS = -nologo -Zm200 -Zc:wchar_t- -FS -Zc:strictStrings -D_HAS_EXCEPTIONS=0 -O2 -MD -W3 -w34100 -w34189 -w44996 -w44456 -w44457 -w44458 -wd4577
LFLAGS = /LIBPATH:. /NOLOGO /DYNAMICBASE /NXCOMPAT /DLL /MANIFEST /MANIFESTFILE:$(TARGET).manifest /SUBSYSTEM:WINDOWS /INCREMENTAL:NO
LIBS = /LIBPATH:d:\virtual_envs\py351\libs python35.lib
.SUFFIXES: .c .cpp .cc .cxx .C


{.}.cpp{}.obj::
    $(CXX) -c $(CXXFLAGS) $(CPPFLAGS) -Fo @<<
    $<
<<

{.}.cc{}.obj::
    $(CXX) -c $(CXXFLAGS) $(CPPFLAGS) -Fo @<<
    $<
<<

{.}.cxx{}.obj::
    $(CXX) -c $(CXXFLAGS) $(CPPFLAGS) -Fo @<<
    $<
<<

{.}.C{}.obj::
    $(CXX) -c $(CXXFLAGS) $(CPPFLAGS) -Fo @<<
    $<
<<

{.}.c{}.obj::
    $(CC) -c $(CFLAGS) $(CPPFLAGS) -Fo @<<
    $<
<<

all: $(TARGET)

$(OFILES): $(HFILES)

$(TARGET): $(OFILES)
    $(LINK) $(LFLAGS) /OUT:$(TARGET) @<<
      $(OFILES) $(LIBS)
<<
    mt -nologo -manifest $(TARGET).manifest -outputresource:$(TARGET);2

install: $(TARGET)
    @if not exist d:\virtual_envs\py351\Lib\site-packages mkdir d:\virtual_envs\py351\Lib\site-packages
    copy /y $(TARGET) d:\virtual_envs\py351\Lib\site-packages\$(TARGET)

clean:
    -del $(TARGET)
    -del *.obj
    -del *.exp
    -del *.lib
    -del $(TARGET).manifest

test:
    python runme.py

我想在这里改进几件事:

  • 我想在 makefile 中考虑 swig 文件 (*.i)。例如,每次更改某个 swig 文件时,都应生成一个新的 wrap 文件(即:swig -python -c++ file_has_changed.cpp),然后重新构建项目
  • 我想避免硬编码目标文件。例如,我想以某种方式使用所有使用通配符的 cpp 文件

我读过一些关于Makefiles 的文档,但我仍然很困惑。我怎样才能做到这一点?

现在我正在使用像 swig -python -c++ whatever_file.i &amp;&amp; nmake 这样的 hacky 解决方案,当然它一点也不理想

参考文献

these steps 之后在 Visual Studio IDE 中实现这一点很容易,但我想在 SublimeText 中使用这个 makefile,这就是为什么我很想知道如何拥有一个合适的 Makefile

【问题讨论】:

    标签: python c++ makefile visual-studio-2015 swig


    【解决方案1】:

    从任何来源生成任何类型的目标,这就是 makefile 的精髓:

    .i.cpp:
        swig -python -c++ $<
    

    但是,如果由于nmake doesn't try to chain inference rules through a missing link 而丢失了.cpp 文件,那么这种优雅将与nmake (as opposed to GNU make) 中断。
    此外,如果存在,它将静默中断并从构建链中稍后的文件(包括生成的可执行文件)的陈旧版本“构建”。

    这里可能的kludges解决方法(当然,除了放弃nmake)是:

    • 多次调用nmake,首先,生成作为两个inference rules之间的中间步骤的所有文件(如果它们是从彼此生成的,则可能需要多次调用),然后是最终目标

      • 这需要一个外部脚本,它很可能是另一个 makefile。例如。: 将当前的Makefile 移动到main_makefile 并创建一个新的Makefile,其中包含如下主要目标的命令:

        python -c "import os,os.path,subprocess;
                   subprocess.check_call(['nmake', '/F', 'main_makefile']
                       +[os.path.splitext(f)[0]+'.cpp'
                         for f in os.listdir('.') if os.path.isfile(f)
                                                     and f.endswith('.i')])"
        nmake /F main_makefile
        
    • 不要仅仅依赖推理规则,而是为每个要生成的.cpp 制定明确的规则(顺便说一句,这就是 CMake 所做的)

      • 这要求自动生成 Makefile 的相关部分。该部分可以是!INCLUDE'd,但在nmake 开始处理结果之前,仍然需要外部代码来进行生成。示例代码(同样,在 Python 中):

        import os,os.path,subprocess
        for f in os.listdir('.') if os.path.isfile(f) and f.endswith('.i'):
            print '"%s": "%s"'%(os.path.splitext(f)[0]+'.cxx',f)
            #quotes are to allow for special characters,
            # see https://msdn.microsoft.com/en-us/library/956d3677.aspx
            #command is not needed, it will be added from the inferred rule I gave
            # in the beginning, see http://www.darkblue.ch/programming/Namke.pdf, p.41 (567)
        

    【讨论】:

    • 您的语法是一个批处理规则:在其中,一个命令只会被调用一次并提供所有源。虽然将分别为每个源调用我的('因为我不知道 swig 是否可以在一次调用中处理多个文件)。请参阅 Batch-Mode Rules - MSDN 获取插图。
    • @BPL 我设法为nmake 的缺陷设计了解决方法。他们需要通过外部逻辑运行它,但从 stackoverflow.com/questions/4808674/… 判断,这正是它的设计者所想的。
    【解决方案2】:

    我已经使用 CMake 解决了这个问题,这直接转化为使用 autoconfautomake 从而使用 makefile。

    思路是引入如下变量

    DEPENDENCIES = `swig -M -python -c++ -I. example.i | sed 's/\//g'`
    

    并使您的目标依赖于此。以上生成所有头文件的依赖项列表和您的 SWIG 接口文件可能包含的 .i 文件。

    【讨论】:

      猜你喜欢
      • 2022-01-18
      • 2017-12-19
      • 1970-01-01
      • 1970-01-01
      • 2013-11-21
      • 2015-12-21
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多