I'm making a new project that is dependent on two other projects (written by others). While I'm developing my code I would like to use g++ options such as -Wall -pedantic -Werror but when I use these options I get a flood of warnings by including files from the other two projects.
Is there any way I can ignore the warnings from those two projects but still see the warnings from my own project?
If you're compiling their source directly via a makefile, you can make optional CPPFLAGSwhich you can use for conditional compilation parameters. For example:
CPPFLAGS=-Wall -pedantic -Werror for your project and CPPFLAGS=-g for their project files (or something).
Take the following sample makefile. Assume you wrote factorial.cpp and hello.cpp and they wrote main.cpp:
CPPFLAGS+=-Wall -pedantic -Werror
all: hello
hello: main.o factorial.o hello.o
g++ main.o factorial.o hello.o -o hello
main.o: main.cpp
g++ -c main.cpp
factorial.o: factorial.cpp
g++ -c $(CPPFLAGS) factorial.cpp
hello.o: hello.cpp
g++ -c $(CPPFLAGS) hello.cpp
clean:
rm -rf *o hello
Try something like that and get back to me.
Related
I am trying to compile a simple Antlr4 project. When I do it in single g++ command, it compiles successfully. However, when I compile and link separately, it fails.
Single stage compilation (succeeds):
g++ -std=c++11 -Wall -Wextra *.cpp -L. -l antlr4-runtime -I/usr/local/include/antlr4-runtime -. -o exec
Two stage (fails: cannot link properly to antlr library and gives a lot of undefined reference errors):
main: $(OBJS)
g++ -L. -l antlr4-runtime $^ -o exec
%.o: %.cpp
g++ -std=c++11 -Wall -Wextra -I/usr/local/include/antlr4-runtime -I. -c $<
I wonder why linking fails in the latter case, while it has similar linking options to single stage compiling.
The title might be confusing, but that's what happened...
Here's my Makefile.
all:mystdio libmystdio.a main.o myscanf.o myprintf.o
mystdio: main.o libmystdio.a
clang++ -o mystdio main.o -L. -lmystdio -Wall -g -std=c++17
libmystdio.a: myscanf.o myprintf.o
ar cr libmystdio.a myprintf.o myscanf.o
main.o: main.cpp mystdio.hpp
clang++ -c main.cpp -Wall -g -std=c++17
myscanf.o: myscanf.cpp mystdio.hpp utilities.hpp
clang++ -c myscanf.cpp -Wall -g -std=c++17
myprintf.o: myprintf.cpp mystdio.hpp utilities.hpp
clang++ -c myprintf.cpp -Wall -g -std=c++17
clean:
rm -rf mystdio *.o *.a *.a
When I made changes in myscanf.cpp or myprintf.cpp and then make file, the output showed that it had been compiled and mystdio is updated. But actually nothing happened.
For example, let's assume I add printf(":)\n"); at the beginning of a function in myscanf.cpp. Then I call the function in main.cpp. After making file, output in the terminal tells me that myscanf.o and related files were recompiled. But when the program runs, no :) is outputed.
However, when I add printf(":)\n"); in the main function and make file, it was outputed. This did confuse me. I wonder how can I solve it.
command used:
make && ./mystdio
When I changed something in myprintf.cpp and make again, here's output from the terminal.
clang++ -c myprintf.cpp -Wall -g -std=c++17
ar cr libmystdio.a myprintf.o myscanf.o
clang++ -o mystdio main.o -L. -lmystdio -Wall -g -std=c++17
By the way, if I use make clean before make && ./mystdio, it'll work correctly, but of course that's not what "make" is designed for...
Thanks for your help in advance!
I've got a basic, minimal makefile to compile C++ source; a stripped-down version looks like this:
TARGET = main
OBJ = $(patsubst %.cpp,%.o,$(wildcard *.cpp))
CPPFLAGS = -std=c++11 -Wall
build: $(TARGET)
$(TARGET): $(OBJ)
#echo "$? --> $#"
g++ $(CPPFLAGS) -o $# $?
#echo
%.o: %.cpp
#echo "$< --> $#"
g++ $(CPPFLAGS) -c $<
#echo
When building from scratch, everything works as expected:
clock.cpp --> clock.o
g++ -std=c++11 -Wall -c clock.cpp
main.cpp --> main.o
g++ -std=c++11 -Wall -c main.cpp
clock.o main.o --> main
g++ -std=c++11 -Wall -o main clock.o main.o
After a change in one of the source files, make rebuilds the corresponding object file, but for some reason skips the existing (unchanged) object file when trying to link (clock.o --> main instead of clock.o main.o --> main):
clock.cpp --> clock.o
g++ -std=c++11 -Wall -c clock.cpp
clock.o --> main
g++ -std=c++11 -Wall -o main clock.o
When running make again, without changing any file, the linking works as expected:
clock.o main.o --> main
g++ -std=c++11 -Wall -o main clock.o main.o
What's the reason for this behavior, and how could it be prevented?
I'm running GNU Make 4.1 on i686 Linux 4.4
You use wrong automatic variable in g++ $(CPPFLAGS) -o $# $? recipe.
https://www.gnu.org/software/make/manual/html_node/Automatic-Variables.html:
$?
The names of all the prerequisites that are newer than the target,
with spaces between them.
So Make does exactly what you ask it to do: link main target from all updated prerequisites and skip untouched prerequisites.
g++ $(CPPFLAGS) -o $# $^ recipe will fix the problem.
I want to automate the compilation of a toy library using CUDA and C++. Then I write a Makefile as follows
CC=g++
NVCC=nvcc
CXXFLAGS= -fopenmp -O3 -Wextra -std=c++11
CUDAFLAGS= -std=c++11 -c -arch=sm_20
LIBS= -lopenblas -lpthread -lcudart -lcublas
LIBDIRS=-L/usr/local/cuda-7.5/lib64
INCDIRS=-I/usr/local/cuda-7.5/include
matrix_cuda.o: marix_cuda.cu
$(NVCC) $(CUDAFLAGS) matrix_cuda.cu
all: matrix_cuda.o
$(CC) -o test matrix_blas.cpp alg.cpp test.cpp matrix_cuda.o $(LIBDIRS) $(INCDIRS) $(LIBS) $(CXXFLAGS)
clean:
rm -rf test *.o
Typing make I get
make: *** No rule to make target `marix_cuda.cu', needed by `matrix_cuda.o'. Stop.
I never wrote a Makefile before. Where did I go wrong?
I think you have a typo in the CUDA file name
matrix_cuda.o: marix_cuda.cu
$(NVCC) $(CUDAFLAGS) matrix_cuda.cu
IMHO it should be
matrix_cuda.o: matrix_cuda.cu
$(NVCC) $(CUDAFLAGS) matrix_cuda.cu
This may take a couple of iterations.
1) First try this:
nvcc -std=c++11 -c -arch=sm_20 matrix_cuda.cu
If that works (and produces matrix_cuda.o, I presume), remove matrix_cuda.o and
2) try this makefile:
matrix_cuda.o: matrix_cuda.cu
nvcc -std=c++11 -c -arch=sm_20 matrix_cuda.cu
If that works,
3) try this:
g++ -o test matrix_blas.cpp alg.cpp test.cpp matrix_cuda.o -L/usr/local/cuda-7.5/lib64 -I/usr/local/cuda-7.5/include -lopenblas -lpthread -lcudart -lcublas -fopenmp -O3 -Wextra -std=c++11
If that works, remove test and
4) try this makefile:
test: matrix_cuda.o
g++ -o test matrix_blas.cpp alg.cpp test.cpp matrix_cuda.o -L/usr/local/cuda-7.5/lib64 -I/usr/local/cuda-7.5/include -lopenblas -lpthread -lcudart -lcublas -fopenmp -O3 -Wextra -std=c++11
matrix_cuda.o: matrix_cuda.cu
nvcc -std=c++11 -c -arch=sm_20 matrix_cuda.cu
If that works, remove test and matrix_cuda.o and
5) try that makefile again.
If that works, there are further refinements we can make.
Also your first make rule corresponds to compiling the object file matrix_cuda.o. The all make rule should come first since the first rule in the make file is the one that gets updated first when invoking the command make. GNU Make has great documentation explaining how to make simple to complex makefiles. You can check it out here:
https://www.gnu.org/software/make/manual/make.html.
Also another issue you are going to run into is that in your make recipe for the all rule, you are supposed to be linking together only object files to create the final executable. However you are trying to include matrix_blas.cpp alg.cpp test.cpp in this linking step. Instead of .cpp versions of these files they need to be .o versions (the compiled objects). Make can generate these object files for you. You just need to have a make rule and recipe for each one. For example:
matrix_blas.o: matrix_blas.cpp
$(CC) $(CXXFLAGS) -c matrix_blas.cpp -o matrix_blas.o
I want to add some commentary on this Makefile for future reference and better automation :
1. NVCC=nvcc environment variable is superfluous. There is only one compiler for NVIDIA GPUs and you would nonetheless have to change a lot of flags to compile for other architectures like AMD.
-arch=native is better suited if you want to deploy your code on multiple machines with GPUs having different architectures
-dc is the flag for separate compilation. The architecture must be specified before -dc see (with a generic Makefile): https://developer.nvidia.com/blog/separate-compilation-linking-cuda-device-code/
You should add automatic rule to avoid these typos errors :
%.o: %.cu
nvcc -dc $(CUDAFLAGS) $< -o $#
The Makefile will look for all dependencies ending by .o. If it needs to build one, it looks if it has the corresponding .cu file. I would actually remove the -dc from flags and be explicit here that I want to build object files.
$# is the name of the rule target. $< is the first prerequisite. Only one file at a time can be passed to nvcc with the -dc flag, so here $< is better than $^.
You may add the name of the executable in a variable so that you delete the same executable that you generated (and facilitate name change).
I added a .PHONY rule. This only removes the confusion that happens whenever someone writes a file named clean in the directory.
The Makefile can not differenciate between the file and the make clean rule.
CC=g++
CXXFLAGS= -fopenmp -O3 -Wextra -std=c++11
CUDAFLAGS= -std=c++11 -arch=sm_20
LIBS= -lopenblas -lpthread -lcudart -lcublas
LIBDIRS=-L/usr/local/cuda-7.5/lib64
INCDIRS=-I/usr/local/cuda-7.5/include
PROGRAM= test
%.o: %.cu
nvcc -dc $(CUDAFLAGS) $< -o $#
all: matrix_cuda.o
$(CC) -o $(PROGRAM) matrix_blas.cpp alg.cpp test.cpp matrix_cuda.o $(LIBDIRS) $(INCDIRS) $(LIBS) $(CXXFLAGS)
.PHONY: clean
clean:
rm -rf $(PROGRAM) *.o
I am pretty new to Makefiles and i am trying to build an executable from 3 files, file1.c, file2.c, and file1.h into an executable called exFile. Here's what I got:
all: exFile
exFile: file1.o file2.o
gcc -Wall -g -m32 repeat.o show.o -o repeat
file1.o: file1.c file1.h
gcc -Wall -g -m32 -S file1.c -o file1.o
file2.o: file2.c
gcc -Wall -g -m32 -S file2.c -o file2.o
I've searched the web for makefiles in this format, but i came up empty handed so i was wondering if someone can help. When it tries to compile i get:
usr/bin/ld:file1.o:1: file format not recognized; treating as linker script
I've compiled programs using assembly files but I'm not to sure what to do with c files or the file1.h file. file1.c includes file1.h so i have to link them (I think?). Any suggestions or links to a reference would be appreciated
You have two problems with your gcc command-line. First, you're specifying the -S flag, which causes gcc to emit assembly code, rather than object code. Second, you're missing the -c flag, which tells gcc to compile the file to an object file, but not link it. If you just remove -S and change nothing else, you'll end up with an executable program named file1.o and another named file2.o, rather than two object files.
Besides those errors, you could simplify your makefile by the use of pattern rules. I suggest you try the following instead:
all: exFile
exFile: file1.o file2.o
gcc -Wall -g -m32 $^ -o $#
%.o: %.c
gcc -Wall -g -m32 -c $< -o $#
file1.o: file1.h
Or, as EmployedRussian points out, you can go with something even more minimal that leverages more of the built-in features of GNU make:
CC=gcc
CFLAGS=-Wall -g -m32
all: exFile
exFile: file1.o file2.o
$(LINK.c) $^ -o $#
file1.o: file1.h
The -S switch to gcc tells it to output assembler so this:
gcc -Wall -g -m32 -S file1.c -o file1.o
Is putting assembler into file1.o but you want, presumably, to compile file1.c into object code:
gcc -Wall -g -m32 file1.c -o file1.o
When the linker gets your file1.o it is confused because file1.o is assembler when the linker is expecting object code, hence your error.
So get rid of the -S switches for file1.o and file2.o.