我正在尝试调试复杂的Makefile.你如何让GNU make打印它运行的所有命令?我在man页面中找不到答案(使用-d标志似乎不打印它).
(这不是回答我的问题的必要信息,但是如果你想知道:我在编译基于NVIDIA的CUDA库的项目时遇到了问题.我可以自己编译它,但是使用它们的Makefile导致一个讨厌的编译器错误我想使用他们提供的Makefile来更容易打包,并包含他们已经链接过的其他包.)
我使用gcc(运行as g++)和GNU make.我使用gcc预编译头文件precompiled.h,创建precompiled.h.gch; Makefile中的以下行执行此操作:
# MYCCFLAGS is a list of command-line parameters, e.g. -g -O2 -DNDEBUG
precompiled.h.gch: precompiled.h
g++ $(MYCCFLAGS) -c $< -o $@
Run Code Online (Sandbox Code Playgroud)
一切都很好,直到我不得不运行g++不同的命令行参数.在这种情况下,即使precompiled.h.gch存在,也无法使用,编译速度会慢得多.在gcc文档中,我已经读过要处理这种情况,我必须创建一个目录precompiled.h.gch并将预编译的头文件放在那里,每个g++命令行参数都有一个文件.
所以现在我想知道我应该如何改变我的Makefile以告诉我用g++这种方式创建gch文件.也许我可以运行g++只是为了测试它是否可以使用precompiled.h.gch目录中的任何现有文件,如果没有,则生成具有唯一文件名的新预编译头.
gcc是否支持进行此类测试?
也许我可以用另一种方式实现我想要的东西?
bash命令是否rm *~只删除以代字号结尾的文件,或者是否存在更高级的bash或gnu make模式?谷歌似乎无法搜索这两个符号组合.我在Makefile clean:target中找到了这个.
gnu会不会只使用隐式规则创建带尾随的文件?
我写了一个像这样的makefile:
HEADER = -I./cygdrive/c/cpros/kajj/source4
LIBB = -L./cygdrive/c/cpros/kajj/source1 -L./cygdrive/c/cpros/kajj/source2
LIBRA = -larith -ldekk
target : game.o
gcc $(HEADER) $(LIBB) $< -o $@ $(LIBRA)
game.o : game.c
gcc -c game.c
Run Code Online (Sandbox Code Playgroud)
我创建了自己的静态库,包括头文件路径和库路径.当我执行我的makefile时,它会给出一个错误,指出
/usr/lib/gcc无法找到-larith -ldekk.
它指向的lib /目录,但它不是在那里:-ldekk和-larith分别是源1以及源文件.
如何解决这个错误?
我有以下问题:
cc -g -O2 -Wall -Wextra -Isrc -rdynamic -DNDEBUG build/liblcthw.a tests/list_tests.c -o tests/list_tests
/tmp/ccpvGjZp.o: In function `test_create':
~/lcthw/tests/list_tests.c:12: undefined reference to `List_create'
collect2: ld returned 1 exit status
make: *** [tests/list_tests] Error 1
Run Code Online (Sandbox Code Playgroud)
但
cc -g -O2 -Wall -Wextra -Isrc -rdynamic -DNDEBUG tests/list_tests.c build/liblcthw.a -o tests/list_tests
Run Code Online (Sandbox Code Playgroud)
运行得很好,nm显示预期的内容,测试运行,每个人都很开心,等等.
我搜索了SO并找到了很多答案(例如链接器命令 - GCC),所以很明显链接器的工作原理应该如此.那么,我应该如何修改我的makefile以遵循命令呢?
到目前为止,这是Makefile:
CFLAGS=-g -O2 -Wall -Wextra -Isrc -rdynamic -DNDEBUG $(OPTFLAGS)
LIBS=$(OPTLIBS)
PREFIX?=/usr/local
BUILD=build
SOURCES=$(wildcard src/**/*.c src/*.c)
OBJECTS=$(patsubst %.c,%.o,$(SOURCES))
TEST_SRC=$(wildcard tests/*_tests.c)
TESTS=$(patsubst %.c,%,$(TEST_SRC))
TARGET=$(BUILD)/liblcthw.a
TARGET_LINK=lcthw
SO_TARGET=$(patsubst %.a,%.so,$(TARGET))
#The …Run Code Online (Sandbox Code Playgroud) 在gnu-make进程的后期阶段,gmake发送了一个类似于的命令:
gcc -static foo.so.0 bar.o bizz.o buzz.o -pthreads -lrt
Run Code Online (Sandbox Code Playgroud)
在那个命令中,-lrt是什么意思?
我试图构建和编译我的程序时遇到此错误.现在我无法打开程序中的所有.cpp文件.
make [2]:*没有规则来制作目标
Checker.cpp', needed by构建/调试/ GNU-Linux-x86/Checker.o'.停止.
有人可以帮我这个吗?我检查了所有在线资源,但我似乎无法找到解决方案.我迫切需要这个解决.感谢给予的任何帮助.
我注意到在Gnu Make中的隐式规则是变量$(TARGET_ARCH),例如:
$(LINK.o) $^ $(LOADLIBES) $(LDLIBS) -o $@
LINK.o = $(CC) $(LDFLAGS) $(TARGET_ARCH)
Run Code Online (Sandbox Code Playgroud)
我认为交叉编译需要这个变量,但我没有在Gnu Make文档中找到任何关于它的信息.
我在make文件中定义了一个列表,用户应该设置一个我需要在此列表中找到的环境变量.有没有办法使用gnu make来做到这一点?在开始构建任何目标之前,我想在任何配方之外执行此操作.这是一个QA检查,以确保用户设置env.变量到范围/列表中的值.
在终端上:
setenv ENV_PARAM x
Run Code Online (Sandbox Code Playgroud)
在Makefile中:
PARAMS := a b c
if ${ENV_PARAM} exists in $(PARAMS)
true
else
false
endif
Run Code Online (Sandbox Code Playgroud)
@MadScientist的答案有效.有没有办法用foreach循环包装if块来测试多个参数?
KEYS := PARAMS FACTORS
PARAMS := a b c
FACTORS := x y z
foreach v in ($(KEYS)) {
ifneq ($(filter $(ENV_$(v)),$(v)),)
$(info $(ENV_$(v)) exists in $(v))
else
$(info $(ENV_$(v)) does not exist in $(v))
endif
}
Run Code Online (Sandbox Code Playgroud) 我有一个带有几个子模块的git项目(回想起来我有点后悔的选择).它使用gnumake
目前,我希望人们在第一次构建项目之前手动发布git submodule update --init1,并且在提取任何更新子模块引用的更改之后.
但是,我希望Makefile在需要时自动发出这些命令.如果他们有时在不需要时发出命令(虚假更新),这是可以的 - 但它不应该经常发生.
对于初始init,似乎有足够的规则(对于存在于目录中的子模块module1:
module1/.git:
git submodule update --init
Run Code Online (Sandbox Code Playgroud)
在这里选择.git作为"表示"子模块的文件是相当随意的,它可能是一些其他文件.
但是,在更新引用时更新子模块效果不佳.我想我可以让子模块依赖于根.gitmodules文件,我想在子模块引用更新时应该更改,例如:
module1/.git: .gitmodules
git submodule update --init
Run Code Online (Sandbox Code Playgroud)
这里使用.git似乎是错误的:可能是在update运行时不一定直接更新(特别是如果没有更新此特定子模块),这将使更新命令每次都运行.
在这里寻找更清洁的解决方案.
1或者可能--recursive在初始化上使用参数clone,这具有相同的效果.