如何在SWIG文件更改后重建项目?

时间:2016-10-03 11:32:24

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

鉴于以下makefile:

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文件时,都应生成一个新的包装文件(即:swig -python -c ++ file_has_changed.cpp),然后重建项目
  • 我想避免使用硬编码的目标文件。例如,我想以某种方式使用通配符来使用所有cpp文件

我已经阅读了一些关于Makefiles的文档,但我仍然非常困惑。我怎么能做到这一点?

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

参考

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

2 个答案:

答案 0 :(得分:3)

从任何类型的源生成任何类型的目标,这是makefile的本质:

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

如果因as opposed to GNU make nmake文件遗失.cpp文件,这种优雅会与nmakenmake doesn't try to chain inference rules through a missing link)决裂。 而且,它会默默地打破并且#34; build&#34;来自构建链中较晚的文件的旧版本(包括生成的可执行文件)(如果它们存在)。

可能的 kludges 此处的解决方法(当然,除了丢弃nmake)是:

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

    • 这需要一个外部脚本,它很可能是另一个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
  • 不仅仅依赖于推理规则,而且每个!INCLUDE都有一个明确的规则(这是CMake所做的事情)

    • 这要求Makefile的相关部分自动生成。该部分可以是nmake,但仍然需要外部代码才能在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) 开始处理结果之前进行生成。示例代码(再次,在Python中):

      $serverAddress = 'ftp.someServerAddress';
      $connId = ftp_connect($serverAddress);
      if($connId) {
          if (ftp_login($connId, 'UserName', 'password')) {
              // do some stuff
          } else {
              echo 'login failed';
          }
      } else {
          echo 'connection failed';
      }
      

答案 1 :(得分:1)

我已经使用CMake解决了这个问题,这直接转换为使用autoconfautomake,从而生成文件。

我们的想法是引入以下变量

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

并让你的目标依赖于此。以上内容生成了SWIG接口文件可能包含的所有头文件和.i文件的依赖关系列表。