鉴于以下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
我想在这里改进一些事情:
我已经阅读了一些关于Makefiles的文档,但我仍然非常困惑。我怎么能做到这一点?
现在我正在使用像swig -python -c++ whatever_file.i && nmake
这样的 hacky 解决方案,当然它根本不理想
参考
在these steps之后实现这个内部Visual Studio IDE非常容易,但是我想在SublimeText中使用这个makefile,这就是为什么我对知道如何拥有它很感兴趣一个合适的Makefile
答案 0 :(得分:3)
从任何类型的源生成任何类型的目标,这是makefile的本质:
.i.cpp:
swig -python -c++ $<
如果因as opposed to GNU make
nmake
文件遗失.cpp
文件,这种优雅会与nmake
(nmake
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解决了这个问题,这直接转换为使用autoconf
和automake
,从而生成文件。
我们的想法是引入以下变量
DEPENDENCIES = `swig -M -python -c++ -I. example.i | sed 's/\//g'`
并让你的目标依赖于此。以上内容生成了SWIG接口文件可能包含的所有头文件和.i
文件的依赖关系列表。