【问题标题】:Makefiile with many flags带有许多标志的 Makefile
【发布时间】:2015-08-28 20:53:44
【问题描述】:

我正在尝试了解 Makefile 的外观,当涉及到标志时,尤其是链接标志。这是我的 Makefile:

OBJS    = n.o
SOURCE  = n.cpp
# HEADER = there are no header files, so I commented that
OUT     =       test
CXX     = ../mpich-install/bin/mpic++
FLAGS   =       -I../intel/mkl/include  ../intel/mkl/lib/intel64/libmkl_scalapack_ilp64.a       -Wl,--start-group       ../intel/mkl/lib/intel64/libmkl_intel_ilp64.a ../intel/mkl/lib/intel64/libmkl_core.a  ../intel/mkl/lib/intel64/libmkl_sequential.a    -Wl,--end-group ../intel/mkl/lib/intel64/libmkl_blacs_intelmpi_ilp64.a -lpthread       -lm     -ldl

all: $(OBJS)
        $(CXX)  $(OBJS) -o $(OUT)       $(FLAGS)

# create/compile the individual files >>separately<<
n.o:    n.cpp
        $(CXX)  -c      n.cpp   $(FLAGS)

.PHONY : all
# clean house
clean:
        rm -f $(OBJS)

然后我得到:

../mpich-install/bin/mpic++     -c      n.cpp   -I../intel/mkl/include  ../intel/mkl/lib/intel64/libmkl_scalapack_ilp64.a       -Wl,--start-group       ../intel/mkl/lib/intel64/libmkl_intel_ilp64.a   ../intel/mkl/lib/intel64/libmkl_core.a  ../intel/mkl/lib/intel64/libmkl_sequential.a    -Wl,--end-group ../intel/mkl/lib/intel64/libmkl_blacs_intelmpi_ilp64.a  -lpthread       -lm     -ldl
g++: warning: ../intel/mkl/lib/intel64/libmkl_scalapack_ilp64.a: linker input file unused because linking not done
g++: warning: ../intel/mkl/lib/intel64/libmkl_intel_ilp64.a: linker input file unused because linking not done
g++: warning: ../intel/mkl/lib/intel64/libmkl_core.a: linker input file unused because linking not done
g++: warning: ../intel/mkl/lib/intel64/libmkl_sequential.a: linker input file unused because linking not done
g++: warning: ../intel/mkl/lib/intel64/libmkl_blacs_intelmpi_ilp64.a: linker input file unused because linking not done
../mpich-install/bin/mpic++     n.o -o test     -I../intel/mkl/include  ../intel/mkl/lib/intel64/libmkl_scalapack_ilp64.a       -Wl,--start-group       ../intel/mkl/lib/intel64/libmkl_intel_ilp64.a   ../intel/mkl/lib/intel64/libmkl_core.a  ../intel/mkl/lib/intel64/libmkl_sequential.a    -Wl,--end-group ../intel/mkl/lib/intel64/libmkl_blacs_intelmpi_ilp64.a  -lpthread       -lm     -ldl

这意味着我应该只在过程的最后部分使用一些标志。处理这种情况的正确方法是什么?也许创建FLAGS1FLAGS2?它应该可以工作,但我想知道哪种方法正确。

【问题讨论】:

  • 用于编译和链接的标志不同。您需要为每个步骤中的每个步骤使用适当的标志。查看make -qp 的输出(将其保存到文件中)并查看make 内置的用于编译和链接C 和C++ 文件的默认规则。这应该有助于澄清一些事情。
  • 您将FLAGS 用作通用的“我不在乎我们处于构建的哪个阶段”类型的论点——这不是正确的做事方式。编译标志(大部分)与链接标志不同,因此您不应该将它们连接在一起。相反,请将您的 CFLAGS(或在这种情况下为 CPPFLAGS)与您的 LFLAGS 分开。
  • 感谢@mah 和 Etan!

标签: c++ linux makefile linker intel-mkl


【解决方案1】:

"...但我想知道哪种方法正确。"

正确的方法是跟上make标准变量名,尤其是CXXFLAGSLDFLAGS

您不想像在此处尝试那样为链接器标志指定库(实际上是指定主题):

FLAGS   =  ... ../intel/mkl/lib/intel64/libmkl_scalapack_ilp64.a

与其使用FLAGS 并给出链接的直接主题,不如使用标准的LDFLAGS makefile 变量来设置路径,并让链接器找到适当的静态或共享库:

  LDFLAGS += -L../intel/mkl/lib/intel64 -lmkl_scalapack_ilp64
# ^^^^^^^ Note the standard build system uses $(LDFLAGS) at the linker stage rule
# -L specifies the paths for finding libraries
# -l<MyLib> actually searches for certain libraries in the given paths,
#           expanding to search for files like libMyLib.a or libMyLib.so.

all: $(OBJS)
        $(CXX)  $(OBJS) -o $(OUT) $(CXXFLAGS) $(LDFLAGS)
#                                          ^^^^^^^^^^ Use them separately at
#                                                     linking stage  
        make    -f      Makefile        clean
#       ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ This whole line looks very (!!!) suspicious,
#                                             and would just make it harder to debug your
#                                             build system. It's an indicator, you did
#                                             dependencies management wrong.
#                                             Consider to use the compiler's --MF options 
#                                             family, to create a dependency file for the 
#                                             headers, and include it in your makefile.

区分编译阶段标志 (CXXFLAGS) 和链接阶段标志 (LDFLAGS)。


旁白:

为了避免这种情况

make    -f      Makefile        clean

在您的最终目标规则中添加操作(可能是为了避免丢失以赶上标头依赖项),将-MF 选项添加到CXXFLAGS,并包含结果。

以下是有关各种技术的更多详细信息:

Auto-Dependency Generation

【讨论】:

  • 那么,$(FLAGS) 在这种情况下应该是什么?
  • @gsamaras $(CXXFLAGS)
  • 不,事实并非如此。我添加了这个干净,以便我可以摆脱使测试人员难以在我的项目中找到源文件和头文件的对象文件(我从以前的 Makefile 中获得了许多文件)。现在,我很困惑,我所拥有的没有编译。对不起。
  • @gsamaras 您最好考虑使用out of source tree 构建来提供工件,并将它们与源代码分开。请注意,clean 目标也应该删除刚刚创建的可执行目标。
  • 我认为这不是理想的解决方案。我认为您过于关注这个make -f Makefile clean,所以我就摆脱了它。所以忘了它,我也从问题中删除。也许编辑您的答案会很好,因为这不是我的问题的精神。我试图玩弄你的答案,但它只是失败了,我得到了未定义的引用。我的意思是我想接受你的回答,但我不能!
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2014-11-08
  • 2014-12-28
  • 2018-11-15
  • 2015-07-22
  • 1970-01-01
相关资源
最近更新 更多