无法在 Windows 上使用 make 命令编译 Makefile
Cannot compile Makefile using make command on Windows
问题总结
我正在尝试安装一个名为 TACS 的开源并行有限元代码,可在 this github repository. To comply with the indicated prerequisites, I followed the instructions at this github repository, which allowed me to install SuiteSparse and METIS on Windows with precompiled BLAS/LAPACK DLLs. For the MPI, I installed both the Intel MPI Library and Open MPI through Cygwin. The final step should be to compile running make
, however this command is not directly available in Windows 10. As a consequence, I explored the options suggested in this question 获得,不幸的是没有成功。我觉得走到了死胡同,任何帮助将不胜感激。
我试过的
请看下面我的尝试。我主要是一个Windows用户,我不太了解使用Makefile
编译程序。我目前的理解是,我尝试编译的 Makefile
是为 Linux 编写的,而我使用的 Windows 的任何 GNU 编译器都不会工作,因为需要不同的语法。如果我错了,请纠正我。我无法理解的是为什么当我尝试使用 Ubuntu Bash 编译 Windows 10(下面列表的最后一次尝试)时也会出现错误。
Visual Studio nmake
运行 作为管理员的 VS 2019 开发人员命令提示符,我在 TACS 基本目录中键入 nmake -f Makefile
,我得到了 Makefile.in(28) : fatal error U1001: syntax error : illegal character '{' in macro Stop.
巧克力 make
运行 Windows 命令提示符作为管理员,C:\ProgramData\chocolatey\bin
在 PATH
环境变量的顶部,我在 TACS 基本目录中键入 make
并且我得到了
"" was unexpected at this time.
make: *** [Makefile:23: default] Error 255
Cygwin make
运行 Windows 命令提示符作为管理员,在 PATH
环境变量的顶部带有 C:\cygwin64\bin
,我在 TACS 基本目录中键入 make
,然后我出现三种类型的错误:
error: expected ',' or '...' before numeric constant
error: cannot convert 'int*' to 'idx_t*' {aka 'long int*'}
error: no matching function for call to 'TACSSchurMat::getBCSRMat(BCSRMat**, NULL, NULL, NULL)'
我尝试更改受影响脚本中的一些变量名称(例如 N_
代替 _N
),我摆脱了第一种和第三种类型的错误,但没有摆脱第二个
GnuWin make
运行 Windows 命令提示符作为管理员,C:\Program Files (x86)\GnuWin32\bin
在 PATH
环境变量的顶部,我在 TACS 基本目录中输入 make
然后我得到了
"" was unexpected at this time.
make: *** [Makefile:23: default] Error 255
MinGWmingw32-make
运行 Windows 命令提示符作为管理员,在 PATH
环境变量的顶部带有 C:\MinGW\bin
,我在 TACS 基本目录中键入 mingw32-make
,然后我得到了
"" was unexpected at this time.
Makefile:23: recipe for target 'default' failed
mingw32-make: *** [default] Error 255
MSYS MinGW 64 位make
运行 Windows 命令提示符作为管理员,在 PATH
环境变量的顶部带有 C:\msys64\usr\bin
,我在 TACS 基本目录中键入 make
,然后我得到了
make[1]: mpicxx: No such file or directory
make[1]: *** [../TACS_Common.mk:28: C:/Users/qa21944/git/tacs/src/TACSAssembler.o] Error 127
make[1]: *** Waiting for unfinished jobs....
make[1]: mpicxx: No such file or directory
make[1]: *** [../TACS_Common.mk:28: C:/Users/qa21944/git/tacs/src/TACSCreator.o] Error 127
make[1]: Leaving directory '/c/Users/qa21944/git/tacs/src'
make: *** [Makefile:23: default] Error 1
这对我来说很难理解,因为 mpicxx
文件是 C:\Program Files (x86)\Intel\oneAPI\mpi\latest\bin
,它又在 PATH
环境变量中。当我尝试将 C:\cygwin64\bin
添加到 PATH
(低于 C:\msys64\usr\bin
)并重新运行 make
时,我得到了
0 [main] opal_wrapper (14432) C:\cygwin64\bin\opal_wrapper.exe: *** fatal error - cygheap base mismatch detected - 0x180352408/0x180357408.
This problem is probably due to using incompatible versions of the cygwin DLL.
Search for cygwin1.dll using the Windows Start->Find/Search facility
and delete all but the most recent version. The most recent version *should*
reside in x:\cygwin\bin, where 'x' is the drive on which you have
installed the cygwin distribution. Rebooting is also suggested if you
are unable to find another cygwin DLL.
我尝试按照这些说明进行操作,然后重新启动了我的计算机,但没有任何改变。
Ubuntu Bash 对于 Windows 10 make
本次尝试的灵感来自this answer。我从 Microsoft Store 下载了 Ubuntu 并安装了 make
。从 Ubuntu Bash 我在 TACS 基本目录中输入 make
并且我得到
make[1]: Entering directory '/mnt/c/Users/qa21944/git/tacs/src'
Makefile:26: *** target pattern contains no '%'. Stop.
make[1]: Leaving directory '/mnt/c/Users/qa21944/git/tacs/src'
make: *** [Makefile:23: default] Error 1
我不明白为什么会出现此错误。我还确保所有行都以制表符而不是空格开头,但没有任何改变。
代码
下面你可以找到我正在使用的 Makefile.in
和 Makefile
。
Makefile.in
# Do not modify this file. Copy this file to Makefile.in and then modify it.
# In order to get TACS to compile, you'll need to fill in the
# following path information. Some of the items below are required
# only if you're going to use the python interface.
# the full path to the root TACS directory
TACS_DIR = C:/Users/qa21944/git/tacs
CXX = mpicxx
RM = rm -f
PYTHON = python
PYTHON_CONFIG = python-config
# Set up for parallel make
MAKE = make -j 8
# Set the ar flags
AR_FLAGS = rcs
# Flags for debugging and regular compilation versions
EXTRA_DEBUG_CC_FLAGS = -fPIC -g
EXTRA_CC_FLAGS = -fPIC -O3
# Use this if you have problems with mpich
# TACS_DEF = -DMPICH_IGNORE_CXX_SEEK
# Defines whether to use static or dynamic linking
# TACS_LD_CMD=${TACS_DIR}/lib/libtacs.a
TACS_LD_CMD=-L${TACS_DIR}/lib/ -Wl,-rpath,${TACS_DIR}/lib -ltacs
# For linux systems, use the following settings:
SO_EXT=so
SO_LINK_FLAGS=-fPIC -shared
# For MAC OS X, use the following settings:
# SO_EXT=so
# SO_LINK_FLAGS=-fPIC -dynamiclib
# This uses the default installation of LAPACK.
# Use an optimized version of LAPACK if available.
# You may also have to include -lblas as well.
LAPACK_LIBS = -LC:/SP_ROOT/lapack_windows/x64 -llapack -lpthread -lblas
# For MAC OSX use the accelerate framework
# LAPACK_LIBS=-framework accelerate
# METIS is handy for partitioning graphs, but can be problematic for
# compilation. If you compile METIS using a C++ compiler you must add
# -DTACS_CPLUSPLUS_METIS to the TACS_DEF arguments below. If you
# compile METIS using a C compiler, there should be no issues.
METIS_INCLUDE = -IC:/SP_ROOT/build/install/include
METIS_LIB = -LC:/SP_ROOT/build/install/lib -lmetis
# AMD is a set of routines for ordering matrices. It is not required by default.
AMD_INCLUDE = -IC:/SP_ROOT/build/install/include/suitesparse
AMD_LIBS = -LC:/SP_ROOT/build/install/lib -llibamd
生成文件
# ============================================
#
# Make file for TACS_DIR/
#
# ============================================
include Makefile.in
include TACS_Common.mk
TACS_SUBDIRS = src \
src/bpmat \
src/elements \
src/elements/dynamics \
src/elements/basis \
src/elements/shell \
src/constitutive \
src/functions \
src/io
TACS_OBJS := $(addsuffix /*.o, ${TACS_SUBDIRS})
default:
@if [ "${TACS_IS_COMPLEX}" = "true" ]; then \
echo "Building Complex TACS"; \
for subdir in $(TACS_SUBDIRS) ; do \
echo "making $@ in $$subdir"; \
echo; (cd $$subdir && $(MAKE) TACS_DIR=${TACS_DIR} TACS_DEF="${TACS_DEF} -DTACS_USE_COMPLEX") || exit 1; \
done \
else \
echo "Building Real TACS"; \
for subdir in $(TACS_SUBDIRS) ; do \
echo "making $@ in $$subdir"; \
echo; (cd $$subdir && $(MAKE) TACS_DIR=${TACS_DIR}) || exit 1; \
done \
fi
${CXX} ${SO_LINK_FLAGS} ${TACS_OBJS} ${TACS_EXTERN_LIBS} -o ${TACS_DIR}/lib/libtacs.${SO_EXT}
@if [ "${TACS_IS_COMPLEX}" = "true" ]; then \
echo "ctypedef complex TacsScalar" > tacs/TacsTypedefs.pxi; \
echo "TACS_NPY_SCALAR = np.NPY_CDOUBLE" > tacs/TacsDefs.pxi; \
echo "dtype = complex" >> tacs/TacsDefs.pxi; \
else \
echo "ctypedef double TacsScalar" > tacs/TacsTypedefs.pxi; \
echo "TACS_NPY_SCALAR = np.NPY_DOUBLE" > tacs/TacsDefs.pxi; \
echo "dtype = np.double" >> tacs/TacsDefs.pxi; \
fi
debug:
@if [ "${TACS_IS_COMPLEX}" = "true" ]; then \
echo "Building Complex TACS"; \
for subdir in $(TACS_SUBDIRS) ; do \
echo "making $@ in $$subdir"; \
echo; (cd $$subdir && $(MAKE) debug TACS_DIR=${TACS_DIR} TACS_DEF="${TACS_DEF} -DTACS_USE_COMPLEX") || exit 1; \
done \
else \
echo "Building Real TACS"; \
for subdir in $(TACS_SUBDIRS) ; do \
echo "making $@ in $$subdir"; \
echo; (cd $$subdir && $(MAKE) debug TACS_DIR=${TACS_DIR}) || exit 1; \
done \
fi
${CXX} ${SO_LINK_FLAGS} ${TACS_OBJS} ${TACS_EXTERN_LIBS} -o ${TACS_DIR}/lib/libtacs.${SO_EXT}
@if [ "${TACS_IS_COMPLEX}" = "true" ]; then \
echo "ctypedef complex TacsScalar" > tacs/TacsTypedefs.pxi; \
echo "TACS_NPY_SCALAR = np.NPY_CDOUBLE" > tacs/TacsDefs.pxi; \
echo "dtype = complex" >> tacs/TacsDefs.pxi; \
else \
echo "ctypedef double TacsScalar" > tacs/TacsTypedefs.pxi; \
echo "TACS_NPY_SCALAR = np.NPY_DOUBLE" > tacs/TacsDefs.pxi; \
echo "dtype = np.double" >> tacs/TacsDefs.pxi; \
fi
interface:
${PYTHON} setup.py build_ext --inplace
complex_interface:
${PYTHON} setup.py build_ext --inplace --define TACS_USE_COMPLEX
complex: TACS_IS_COMPLEX=true
complex: default
complex_debug: TACS_IS_COMPLEX=true
complex_debug: debug
clean:
${RM} lib/libtacs.a lib/libtacs.so
${RM} tacs/*.so tacs/*.cpp
@for subdir in $(TACS_SUBDIRS) ; do \
echo "making $@ in $$subdir"; \
echo; \
(cd $$subdir && $(MAKE) $@ TACS_DIR=${TACS_DIR}) || exit 1; \
done
编辑: 我正在按照评论中的要求添加 TACS_Common.mk
的片段。
TACS_Common.mk
TACS_LIB = ${TACS_DIR}/lib/libtacs.a
TACS_INCLUDE = -I${TACS_DIR}/src \
-I${TACS_DIR}/src/bpmat \
-I${TACS_DIR}/src/elements \
-I${TACS_DIR}/src/elements/dynamics \
-I${TACS_DIR}/src/elements/basis \
-I${TACS_DIR}/src/elements/shell \
-I${TACS_DIR}/src/constitutive \
-I${TACS_DIR}/src/functions \
-I${TACS_DIR}/src/io
# Set the command line flags to use for compilation
TACS_OPT_CC_FLAGS = ${TACS_DEF} ${EXTRA_CC_FLAGS} ${METIS_INCLUDE} ${AMD_INCLUDE} ${TACS_INCLUDE}
TACS_DEBUG_CC_FLAGS = ${TACS_DEF} ${EXTRA_DEBUG_CC_FLAGS} ${METIS_INCLUDE} ${AMD_INCLUDE} ${TACS_INCLUDE}
# By default, use the optimized flags
TACS_CC_FLAGS = ${TACS_OPT_CC_FLAGS}
# Set the linking flags to use
TACS_EXTERN_LIBS = ${AMD_LIBS} ${METIS_LIB} ${LAPACK_LIBS}
TACS_LD_FLAGS = ${EXTRA_LD_FLAGS} ${TACS_LD_CMD} ${TACS_EXTERN_LIBS}
# This is the one rule that is used to compile all the
# source code in TACS
%.o: %.cpp
${CXX} ${TACS_CC_FLAGS} -c $< -o $*.o
@echo
@echo " --- Compiled $*.cpp successfully ---"
@echo
我无法回答,但也许我可以给你定位。
首先nmake
不是make。它不适用于任何不是专门编写为 nmake makefile 的 makefile。而且它仅在 Windows 上可用。所以,最好忘记它的存在。
其次,了解 make 的工作原理很重要:makefile 中的规则是 targets/prerequisites 和配方的组合。配方不是“makefile”语法,它是一个 shell 脚本(批处理文件)。因此 make 与 shell 到 运行 命令协同工作。哪个shell?在像 GNU/Linux 和 MacOS 这样的 POSIX 系统上,它非常简单:一个 POSIX shell;默认 /bin/sh
.
在 Windows 系统上就没那么简单了:有很多选项。可能是 cmd.exe
。它可能是 PowerShell。它可能是由用户安装的 POSIX shell。默认选择哪一个取决于您的 make
版本是如何编译的。这就是为什么您会看到 make
到 Windows.
的不同“端口”的不同行为
因此,如果您查看您尝试使用的 makefile,您会发现它们无疑是专门为 POSIX 系统编写的,并且期望 POSIX shell 和 POSIX环境。任何尝试使用调用 cmd.exe
作为其默认值 shell 的 make
版本的任何尝试都将立即失败并出现语法错误(此时 "" 是意外的。).
好的,所以你找到了一个调用 POSIX shell 的 make 版本,你不会再收到那个错误了。
但是你必须应对另一个不同之处:目录分隔符。在 Windows 中,他们使用反斜杠。在 POSIX 系统中,他们使用正斜杠和反斜杠作为转义字符(因此它不只是通过 shell 原封不动地传递)。如果您打算在 POSIX shell 中使用路径,您需要确保您的路径使用正斜杠,否则 shell 会将它们作为转义字符删除。幸运的是,大多数 Windows 程序接受正斜杠和反斜杠作为目录分隔符(但不是所有:例如 cmd.exe
内置工具不接受)。
那么您就必须应对 Windows 被称为驱动器盘符的可憎事物。这对 make
来说是一个很大的问题,因为对于 make
,:
字符在很多地方都是特殊的。所以当 make 看到像 C:/foo:C:/bar
这样的行时,它的解析器会感到困惑,并且你会得到错误。为 Windows 编译的 make
的某些版本启用试探法,它会尝试查看路径是否看起来像驱动器号。有些只是假定 POSIX 风格的路径。它们对于 POSIX shell 也可能是一个问题:Windows 上的许多 POSIX 环境将驱动器号映射到标准 POSIX 路径,因此 C:\foo
写成 /c/foo
或 /mnt/c/foo
或其他。如果要向 makefile 添加路径,则需要找出正确的映射(如果有)并使用它。
这甚至还没有开始讨论 POSIX 和 Windows 之间的其他差异......有太多了。
根据您在上面显示的内容,编写此项目时并未考虑到 Windows 的任何可移植性。考虑到这一点的复杂性,这并不奇怪:它需要大量的工作。所以你有这些选项,我可以看到:
- 自己将其移植为Windows兼容
- 尝试让它在 cygwin 中工作(cygwin 旨在成为 运行 在 Windows 上的 POSIX 风格的环境)
- 尝试让它在 WSL 中工作
- 使用 VMWare、VirtualBox 等安装虚拟机。运行使用 Linux 发行版并构建 运行
不幸的是,我不太了解这些方法的优缺点,所以我无法就最佳方案向您提供建议。
很久很久以前,我选择的路线是完全摆脱 Windows,只使用 GNU/Linux。但当然这对每个人来说都是不可能的:)。
您需要一个真正的答案:您不能使用 Windows 命令提示符进行编译。
自己安装 MSYS2——它也将安装 MinGW-w64——并按照安装说明进行操作。然后启动 MSYS shell 以获得 unix-y 终端提示符(zsh、IIRC),并将目录更改为项目文件夹的头部。
要访问 Windows 文件系统,根目录将是 /c
或 /mnt/c
(抱歉,在我的移动 ATM 上,我可以在一两天内改进它)。例如,
C:\Users\qa21944\git\tacs
变成
/c/Users/qa21944/git/tacs
从那里 GNU/Windows make 命令应该可以工作:
mingw32-make
还有这个 post 在 Windows 下使用更现代的 *nix 环境:
不过,对于您所需要的,感谢可能有点过头了。
当我结束旅行并且可以坐下来好好看看这个问题时,我可以改进这个答案的细节,但是你需要一个 Linux shell 终端。
问题总结
我正在尝试安装一个名为 TACS 的开源并行有限元代码,可在 this github repository. To comply with the indicated prerequisites, I followed the instructions at this github repository, which allowed me to install SuiteSparse and METIS on Windows with precompiled BLAS/LAPACK DLLs. For the MPI, I installed both the Intel MPI Library and Open MPI through Cygwin. The final step should be to compile running make
, however this command is not directly available in Windows 10. As a consequence, I explored the options suggested in this question 获得,不幸的是没有成功。我觉得走到了死胡同,任何帮助将不胜感激。
我试过的
请看下面我的尝试。我主要是一个Windows用户,我不太了解使用Makefile
编译程序。我目前的理解是,我尝试编译的 Makefile
是为 Linux 编写的,而我使用的 Windows 的任何 GNU 编译器都不会工作,因为需要不同的语法。如果我错了,请纠正我。我无法理解的是为什么当我尝试使用 Ubuntu Bash 编译 Windows 10(下面列表的最后一次尝试)时也会出现错误。
Visual Studio nmake
运行 作为管理员的 VS 2019 开发人员命令提示符,我在 TACS 基本目录中键入 nmake -f Makefile
,我得到了 Makefile.in(28) : fatal error U1001: syntax error : illegal character '{' in macro Stop.
巧克力 make
运行 Windows 命令提示符作为管理员,C:\ProgramData\chocolatey\bin
在 PATH
环境变量的顶部,我在 TACS 基本目录中键入 make
并且我得到了
"" was unexpected at this time.
make: *** [Makefile:23: default] Error 255
Cygwin make
运行 Windows 命令提示符作为管理员,在 PATH
环境变量的顶部带有 C:\cygwin64\bin
,我在 TACS 基本目录中键入 make
,然后我出现三种类型的错误:
error: expected ',' or '...' before numeric constant
error: cannot convert 'int*' to 'idx_t*' {aka 'long int*'}
error: no matching function for call to 'TACSSchurMat::getBCSRMat(BCSRMat**, NULL, NULL, NULL)'
我尝试更改受影响脚本中的一些变量名称(例如 N_
代替 _N
),我摆脱了第一种和第三种类型的错误,但没有摆脱第二个
GnuWin make
运行 Windows 命令提示符作为管理员,C:\Program Files (x86)\GnuWin32\bin
在 PATH
环境变量的顶部,我在 TACS 基本目录中输入 make
然后我得到了
"" was unexpected at this time.
make: *** [Makefile:23: default] Error 255
MinGWmingw32-make
运行 Windows 命令提示符作为管理员,在 PATH
环境变量的顶部带有 C:\MinGW\bin
,我在 TACS 基本目录中键入 mingw32-make
,然后我得到了
"" was unexpected at this time.
Makefile:23: recipe for target 'default' failed
mingw32-make: *** [default] Error 255
MSYS MinGW 64 位make
运行 Windows 命令提示符作为管理员,在 PATH
环境变量的顶部带有 C:\msys64\usr\bin
,我在 TACS 基本目录中键入 make
,然后我得到了
make[1]: mpicxx: No such file or directory
make[1]: *** [../TACS_Common.mk:28: C:/Users/qa21944/git/tacs/src/TACSAssembler.o] Error 127
make[1]: *** Waiting for unfinished jobs....
make[1]: mpicxx: No such file or directory
make[1]: *** [../TACS_Common.mk:28: C:/Users/qa21944/git/tacs/src/TACSCreator.o] Error 127
make[1]: Leaving directory '/c/Users/qa21944/git/tacs/src'
make: *** [Makefile:23: default] Error 1
这对我来说很难理解,因为 mpicxx
文件是 C:\Program Files (x86)\Intel\oneAPI\mpi\latest\bin
,它又在 PATH
环境变量中。当我尝试将 C:\cygwin64\bin
添加到 PATH
(低于 C:\msys64\usr\bin
)并重新运行 make
时,我得到了
0 [main] opal_wrapper (14432) C:\cygwin64\bin\opal_wrapper.exe: *** fatal error - cygheap base mismatch detected - 0x180352408/0x180357408.
This problem is probably due to using incompatible versions of the cygwin DLL.
Search for cygwin1.dll using the Windows Start->Find/Search facility
and delete all but the most recent version. The most recent version *should*
reside in x:\cygwin\bin, where 'x' is the drive on which you have
installed the cygwin distribution. Rebooting is also suggested if you
are unable to find another cygwin DLL.
我尝试按照这些说明进行操作,然后重新启动了我的计算机,但没有任何改变。
Ubuntu Bash 对于 Windows 10 make
本次尝试的灵感来自this answer。我从 Microsoft Store 下载了 Ubuntu 并安装了 make
。从 Ubuntu Bash 我在 TACS 基本目录中输入 make
并且我得到
make[1]: Entering directory '/mnt/c/Users/qa21944/git/tacs/src'
Makefile:26: *** target pattern contains no '%'. Stop.
make[1]: Leaving directory '/mnt/c/Users/qa21944/git/tacs/src'
make: *** [Makefile:23: default] Error 1
我不明白为什么会出现此错误。我还确保所有行都以制表符而不是空格开头,但没有任何改变。
代码
下面你可以找到我正在使用的 Makefile.in
和 Makefile
。
Makefile.in
# Do not modify this file. Copy this file to Makefile.in and then modify it.
# In order to get TACS to compile, you'll need to fill in the
# following path information. Some of the items below are required
# only if you're going to use the python interface.
# the full path to the root TACS directory
TACS_DIR = C:/Users/qa21944/git/tacs
CXX = mpicxx
RM = rm -f
PYTHON = python
PYTHON_CONFIG = python-config
# Set up for parallel make
MAKE = make -j 8
# Set the ar flags
AR_FLAGS = rcs
# Flags for debugging and regular compilation versions
EXTRA_DEBUG_CC_FLAGS = -fPIC -g
EXTRA_CC_FLAGS = -fPIC -O3
# Use this if you have problems with mpich
# TACS_DEF = -DMPICH_IGNORE_CXX_SEEK
# Defines whether to use static or dynamic linking
# TACS_LD_CMD=${TACS_DIR}/lib/libtacs.a
TACS_LD_CMD=-L${TACS_DIR}/lib/ -Wl,-rpath,${TACS_DIR}/lib -ltacs
# For linux systems, use the following settings:
SO_EXT=so
SO_LINK_FLAGS=-fPIC -shared
# For MAC OS X, use the following settings:
# SO_EXT=so
# SO_LINK_FLAGS=-fPIC -dynamiclib
# This uses the default installation of LAPACK.
# Use an optimized version of LAPACK if available.
# You may also have to include -lblas as well.
LAPACK_LIBS = -LC:/SP_ROOT/lapack_windows/x64 -llapack -lpthread -lblas
# For MAC OSX use the accelerate framework
# LAPACK_LIBS=-framework accelerate
# METIS is handy for partitioning graphs, but can be problematic for
# compilation. If you compile METIS using a C++ compiler you must add
# -DTACS_CPLUSPLUS_METIS to the TACS_DEF arguments below. If you
# compile METIS using a C compiler, there should be no issues.
METIS_INCLUDE = -IC:/SP_ROOT/build/install/include
METIS_LIB = -LC:/SP_ROOT/build/install/lib -lmetis
# AMD is a set of routines for ordering matrices. It is not required by default.
AMD_INCLUDE = -IC:/SP_ROOT/build/install/include/suitesparse
AMD_LIBS = -LC:/SP_ROOT/build/install/lib -llibamd
生成文件
# ============================================
#
# Make file for TACS_DIR/
#
# ============================================
include Makefile.in
include TACS_Common.mk
TACS_SUBDIRS = src \
src/bpmat \
src/elements \
src/elements/dynamics \
src/elements/basis \
src/elements/shell \
src/constitutive \
src/functions \
src/io
TACS_OBJS := $(addsuffix /*.o, ${TACS_SUBDIRS})
default:
@if [ "${TACS_IS_COMPLEX}" = "true" ]; then \
echo "Building Complex TACS"; \
for subdir in $(TACS_SUBDIRS) ; do \
echo "making $@ in $$subdir"; \
echo; (cd $$subdir && $(MAKE) TACS_DIR=${TACS_DIR} TACS_DEF="${TACS_DEF} -DTACS_USE_COMPLEX") || exit 1; \
done \
else \
echo "Building Real TACS"; \
for subdir in $(TACS_SUBDIRS) ; do \
echo "making $@ in $$subdir"; \
echo; (cd $$subdir && $(MAKE) TACS_DIR=${TACS_DIR}) || exit 1; \
done \
fi
${CXX} ${SO_LINK_FLAGS} ${TACS_OBJS} ${TACS_EXTERN_LIBS} -o ${TACS_DIR}/lib/libtacs.${SO_EXT}
@if [ "${TACS_IS_COMPLEX}" = "true" ]; then \
echo "ctypedef complex TacsScalar" > tacs/TacsTypedefs.pxi; \
echo "TACS_NPY_SCALAR = np.NPY_CDOUBLE" > tacs/TacsDefs.pxi; \
echo "dtype = complex" >> tacs/TacsDefs.pxi; \
else \
echo "ctypedef double TacsScalar" > tacs/TacsTypedefs.pxi; \
echo "TACS_NPY_SCALAR = np.NPY_DOUBLE" > tacs/TacsDefs.pxi; \
echo "dtype = np.double" >> tacs/TacsDefs.pxi; \
fi
debug:
@if [ "${TACS_IS_COMPLEX}" = "true" ]; then \
echo "Building Complex TACS"; \
for subdir in $(TACS_SUBDIRS) ; do \
echo "making $@ in $$subdir"; \
echo; (cd $$subdir && $(MAKE) debug TACS_DIR=${TACS_DIR} TACS_DEF="${TACS_DEF} -DTACS_USE_COMPLEX") || exit 1; \
done \
else \
echo "Building Real TACS"; \
for subdir in $(TACS_SUBDIRS) ; do \
echo "making $@ in $$subdir"; \
echo; (cd $$subdir && $(MAKE) debug TACS_DIR=${TACS_DIR}) || exit 1; \
done \
fi
${CXX} ${SO_LINK_FLAGS} ${TACS_OBJS} ${TACS_EXTERN_LIBS} -o ${TACS_DIR}/lib/libtacs.${SO_EXT}
@if [ "${TACS_IS_COMPLEX}" = "true" ]; then \
echo "ctypedef complex TacsScalar" > tacs/TacsTypedefs.pxi; \
echo "TACS_NPY_SCALAR = np.NPY_CDOUBLE" > tacs/TacsDefs.pxi; \
echo "dtype = complex" >> tacs/TacsDefs.pxi; \
else \
echo "ctypedef double TacsScalar" > tacs/TacsTypedefs.pxi; \
echo "TACS_NPY_SCALAR = np.NPY_DOUBLE" > tacs/TacsDefs.pxi; \
echo "dtype = np.double" >> tacs/TacsDefs.pxi; \
fi
interface:
${PYTHON} setup.py build_ext --inplace
complex_interface:
${PYTHON} setup.py build_ext --inplace --define TACS_USE_COMPLEX
complex: TACS_IS_COMPLEX=true
complex: default
complex_debug: TACS_IS_COMPLEX=true
complex_debug: debug
clean:
${RM} lib/libtacs.a lib/libtacs.so
${RM} tacs/*.so tacs/*.cpp
@for subdir in $(TACS_SUBDIRS) ; do \
echo "making $@ in $$subdir"; \
echo; \
(cd $$subdir && $(MAKE) $@ TACS_DIR=${TACS_DIR}) || exit 1; \
done
编辑: 我正在按照评论中的要求添加 TACS_Common.mk
的片段。
TACS_Common.mk
TACS_LIB = ${TACS_DIR}/lib/libtacs.a
TACS_INCLUDE = -I${TACS_DIR}/src \
-I${TACS_DIR}/src/bpmat \
-I${TACS_DIR}/src/elements \
-I${TACS_DIR}/src/elements/dynamics \
-I${TACS_DIR}/src/elements/basis \
-I${TACS_DIR}/src/elements/shell \
-I${TACS_DIR}/src/constitutive \
-I${TACS_DIR}/src/functions \
-I${TACS_DIR}/src/io
# Set the command line flags to use for compilation
TACS_OPT_CC_FLAGS = ${TACS_DEF} ${EXTRA_CC_FLAGS} ${METIS_INCLUDE} ${AMD_INCLUDE} ${TACS_INCLUDE}
TACS_DEBUG_CC_FLAGS = ${TACS_DEF} ${EXTRA_DEBUG_CC_FLAGS} ${METIS_INCLUDE} ${AMD_INCLUDE} ${TACS_INCLUDE}
# By default, use the optimized flags
TACS_CC_FLAGS = ${TACS_OPT_CC_FLAGS}
# Set the linking flags to use
TACS_EXTERN_LIBS = ${AMD_LIBS} ${METIS_LIB} ${LAPACK_LIBS}
TACS_LD_FLAGS = ${EXTRA_LD_FLAGS} ${TACS_LD_CMD} ${TACS_EXTERN_LIBS}
# This is the one rule that is used to compile all the
# source code in TACS
%.o: %.cpp
${CXX} ${TACS_CC_FLAGS} -c $< -o $*.o
@echo
@echo " --- Compiled $*.cpp successfully ---"
@echo
我无法回答,但也许我可以给你定位。
首先nmake
不是make。它不适用于任何不是专门编写为 nmake makefile 的 makefile。而且它仅在 Windows 上可用。所以,最好忘记它的存在。
其次,了解 make 的工作原理很重要:makefile 中的规则是 targets/prerequisites 和配方的组合。配方不是“makefile”语法,它是一个 shell 脚本(批处理文件)。因此 make 与 shell 到 运行 命令协同工作。哪个shell?在像 GNU/Linux 和 MacOS 这样的 POSIX 系统上,它非常简单:一个 POSIX shell;默认 /bin/sh
.
在 Windows 系统上就没那么简单了:有很多选项。可能是 cmd.exe
。它可能是 PowerShell。它可能是由用户安装的 POSIX shell。默认选择哪一个取决于您的 make
版本是如何编译的。这就是为什么您会看到 make
到 Windows.
因此,如果您查看您尝试使用的 makefile,您会发现它们无疑是专门为 POSIX 系统编写的,并且期望 POSIX shell 和 POSIX环境。任何尝试使用调用 cmd.exe
作为其默认值 shell 的 make
版本的任何尝试都将立即失败并出现语法错误(此时 "" 是意外的。).
好的,所以你找到了一个调用 POSIX shell 的 make 版本,你不会再收到那个错误了。
但是你必须应对另一个不同之处:目录分隔符。在 Windows 中,他们使用反斜杠。在 POSIX 系统中,他们使用正斜杠和反斜杠作为转义字符(因此它不只是通过 shell 原封不动地传递)。如果您打算在 POSIX shell 中使用路径,您需要确保您的路径使用正斜杠,否则 shell 会将它们作为转义字符删除。幸运的是,大多数 Windows 程序接受正斜杠和反斜杠作为目录分隔符(但不是所有:例如 cmd.exe
内置工具不接受)。
那么您就必须应对 Windows 被称为驱动器盘符的可憎事物。这对 make
来说是一个很大的问题,因为对于 make
,:
字符在很多地方都是特殊的。所以当 make 看到像 C:/foo:C:/bar
这样的行时,它的解析器会感到困惑,并且你会得到错误。为 Windows 编译的 make
的某些版本启用试探法,它会尝试查看路径是否看起来像驱动器号。有些只是假定 POSIX 风格的路径。它们对于 POSIX shell 也可能是一个问题:Windows 上的许多 POSIX 环境将驱动器号映射到标准 POSIX 路径,因此 C:\foo
写成 /c/foo
或 /mnt/c/foo
或其他。如果要向 makefile 添加路径,则需要找出正确的映射(如果有)并使用它。
这甚至还没有开始讨论 POSIX 和 Windows 之间的其他差异......有太多了。
根据您在上面显示的内容,编写此项目时并未考虑到 Windows 的任何可移植性。考虑到这一点的复杂性,这并不奇怪:它需要大量的工作。所以你有这些选项,我可以看到:
- 自己将其移植为Windows兼容
- 尝试让它在 cygwin 中工作(cygwin 旨在成为 运行 在 Windows 上的 POSIX 风格的环境)
- 尝试让它在 WSL 中工作
- 使用 VMWare、VirtualBox 等安装虚拟机。运行使用 Linux 发行版并构建 运行
不幸的是,我不太了解这些方法的优缺点,所以我无法就最佳方案向您提供建议。
很久很久以前,我选择的路线是完全摆脱 Windows,只使用 GNU/Linux。但当然这对每个人来说都是不可能的:)。
您需要一个真正的答案:您不能使用 Windows 命令提示符进行编译。
自己安装 MSYS2——它也将安装 MinGW-w64——并按照安装说明进行操作。然后启动 MSYS shell 以获得 unix-y 终端提示符(zsh、IIRC),并将目录更改为项目文件夹的头部。
要访问 Windows 文件系统,根目录将是 /c
或 /mnt/c
(抱歉,在我的移动 ATM 上,我可以在一两天内改进它)。例如,
C:\Users\qa21944\git\tacs
变成
/c/Users/qa21944/git/tacs
从那里 GNU/Windows make 命令应该可以工作:
mingw32-make
还有这个 post 在 Windows 下使用更现代的 *nix 环境:
当我结束旅行并且可以坐下来好好看看这个问题时,我可以改进这个答案的细节,但是你需要一个 Linux shell 终端。