Linker command - No rule to make target for 3rd party lib - c++

In my code I make reference this pugixml like this:
#include "pugi/pugixml.hpp"
When compiling I get this error:
main in main-bf0b72.o
"pugi::xml_node::children(char const*) const", referenced from:
_main in main-bf0b72.o
ld: symbol(s) not found for architecture x86_64
clang: error: linker command failed with exit code 1 (use -v to see invocation)
make: *** [main] Error 1
From another question I was told to pugi as an additional translation unit and link them accordingly like this in my Makefile:
CC = g++
CFLAGS = -g -Wall -std=c++11
SRC = src
INCLUDES = include
TARGET = main
all: $(TARGET)
$(TARGET): $(SRC)/$(TARGET).cpp pugi/pugixml.cpp
$(CC) $(CFLAGS) -I $(INCLUDES) -o $# $^
clean:
$(RM) $(TARGET)
However when I try to run my Makefile after this change I get this error:
make: *** No rule to make target `pugi/pugixml.cpp', needed by `main'. Stop.
I'm really not sure what I am meant to be doing. Should pugi have it's own Makefile to build it individually, or should I give it is't own "target" in my Makefile?
Edit
This is my file system:
root/Makefile
root/src/main.cpp
root/include/pugi/pugixml.hpp
root/include/pugi/pugixml.cpp
root/include/pugi/pugiconfig.hpp

In your Makefile you try to compile pugi/pugixml.cpp file, but on filesystem it located in include/pugi/pugixml.cpp (relatively to Makefile itself). You should:
Create root/pugi directory and put pugixml.cpp file there
OR
Or replace pugi/pugixml.cpp with include/pugi/pugixml.cpp in your Makefile (but keeping source files in include/ subdirectory is bad idea).

Related

How to adapt C++ Makefile to allow for using openmpi parallelization compiling several files into 1 executable

Just a disclaimer I'm not too experienced with Make files, so forgive me if the answer is simple! I have a Make file that compiles several .cpp & .h files into .o files, and then produces an executable. I am using g++ as the compiler currently. I'd like to adapt this file to allow for openmpi multi-core computing. To note: I'm on a Windows 11 x 64 architecture, using Cygwin to build run this cpp code. I also would like this to run on MacOS systems as well.
In particular, the parallelization macros are only in 1 .cpp file, what I'd consider the 'main' file of this project (mag_spec_tracker.cpp). I don't know if that makes a difference here but thought it could be useful to let be known.
My current Makefile is below - note I added a line to try and grab the mpicc compile flags, but I am unsure on how to use them here.
IDIR = include
CXX = g++
CXXFLAGS = -I$(IDIR) -std=c++17
ODIR = obj
_DEPS = my_functions.h particle.h beam.h threevector.h threematrix.h screen.h magnet.h
DEPS = $(patsubst %,$(IDIR)/%,$(_DEPS))
_OBJ = my_functions.o particle.o beam.o mag_spec_tracker.o screen.o magnet.o
OBJ = $(patsubst %,$(ODIR)/%,$(_OBJ))
$(ODIR)/%.o: %.cpp $(DEPS)
$(CXX) -c -o $# $< $(CXXFLAGS)
run: $(OBJ)
$(CXX) -o $# $^ $(CXXFLAGS)
.PHONY: clean
clean:
rm -f $(ODIR)/*.o *~ core $(IDIR)/*~
I have tried adding lines into the Makefile to get the mpi compile flags based on other reference I've found online, but was unsure how to adapt my current code to add these flags to allow for correct usage of openmpi. The lines I added to grab compile flags were:
MPI_COMPILE_FLAGS = $(shell mpicc --showme:compile)
MPI_LINK_FLAGS = $(shell mpicc --showme:link)
Thank you in advance!
Update (12/6/2022)
Responding to the comment from Matzeri ('for opempi the compiler is mpicc not gcc. for c++ is mpicxx not g++'), I replaced 'g++' in my makefile with 'mpicxx' and recieved the following error:
$ make
mpicxx -c -o obj/mag_spec_tracker.o mag_spec_tracker.cpp -Iinclude -std=c++17
mpicxx -o run obj/my_functions.o obj/particle.o obj/beam.o obj/mag_spec_tracker.o obj/screen.o obj/magnet.o -Iinclude -std=c++17
C:/Users/Jason/mingw64/bin/../lib/gcc/x86_64-w64-mingw32/12.2.0/../../../../x86_64-w64-mingw32/bin/ld.exe: cannot find -lmpi_cxx: No such file or directory
C:/Users/Jason/mingw64/bin/../lib/gcc/x86_64-w64-mingw32/12.2.0/../../../../x86_64-w64-mingw32/bin/ld.exe: cannot find -lmpi: No such file or directory
C:/Users/Jason/mingw64/bin/../lib/gcc/x86_64-w64-mingw32/12.2.0/../../../../x86_64-w64-mingw32/bin/ld.exe: cannot find -lopen-rte: No such file or directory
C:/Users/Jason/mingw64/bin/../lib/gcc/x86_64-w64-mingw32/12.2.0/../../../../x86_64-w64-mingw32/bin/ld.exe: cannot find -lopen-pal: No such file or directory
collect2.exe: error: ld returned 1 exit status
make: *** [Makefile:19: run] Error 1
I notice that its looking for an ld executable in 'mingw64'. I tried removing that directory (previously I had installed mingw64, but switched to cygwin), and got the following error:
$ make
mpicxx -o run obj/my_functions.o obj/particle.o obj/beam.o obj/mag_spec_tracker.o obj/screen.o obj/magnet.o -Iinclude -std=c++17
--------------------------------------------------------------------------
The Open MPI wrapper compiler was unable to find the specified compiler
g++ in your PATH.
Note that this compiler was either specified at configure time or in
one of several possible environment variables.
--------------------------------------------------------------------------
make: *** [Makefile:19: run] Error 1
I also added c:\cygwin\bin to my environment paths, and this issue still occurs. I confirmed that mpicxx is in that bin folder.
Any ideas?

Issue running clang++ compiler on m1 pro?

I get the following error when trying to compile my simple program with make all:
❯ make all
clang++ --std=c++11 -Wall main.cpp
Undefined symbols for architecture arm64:
"file_reader::read_file()", referenced from:
_main in main-99040e.o
"file_reader::file_reader(std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >)", referenced from:
_main in main-99040e.o
ld: symbol(s) not found for architecture arm64
clang: error: linker command failed with exit code 1 (use -v to see invocation)
make: *** [main.o] Error 1
I can compile the program manually if I do clang++ --std=clang++11 main.cpp file_reader.cpp (and the executable works correctly), so I don't think it's an architecture error like it suggests. I think it might be a problem with my makefile, which I will include below, so if anyone has any insight that would be really helpful. I looked up several conventions for makefiles and none of them helped. The structure is pretty basic with main.cpp creating an object of type file_reader and then referencing one of its methods, so I use #include "file_reader.h" in my main.cpp.
makefile:
# compiler
CXX = clang++
# compiler flags:
# --std=clang++11 : verion
CXXFLAGS = --std=c++11 -Wall
all: main.out
main.out: main.o file_reader.o
$(CXX) main.o file_reader.o -o main
main.o: main.cpp file_reader.h
$(CXX) $(CXXFLAGS) main.cpp
file_reader.o: file_reader.cpp file_reader.h
$(CXX) $(CXXFLAGS) file_reader.cpp
clean:
rm -rf *.o restaurant

g++: /usr/bin/ld: cannot find -lmax7219 linking error

If I try to compile my project, I get following error:
/usr/bin/ld: cannot find -larmbianio
/usr/bin/ld: cannot find -lmax7219
collect2: error: ld returned 1 exit status
make: *** [makefile:12: all] Error 1
My folder structure looks as follows:
/home/bsy139/project/
> lib/
--> armbianio
---> armbianio.c
---> armbianio.h
---> armbianio.o (renamed to .a)
---> makefile
--> max7219
---> max7219.c
---> max7219.h
---> max7219.o (renamed to .a)
> bsy-pi.cpp
> classes
> classes.h
> LCDisplay.cpp
> makefile
> Sensors.cpp
The makefile looks like:
# the compiler: gcc for C program, define as g++ for C++
CC = g++
# compiler flags:
# -g adds debugging information to the executable file
# -Wall turns on most, but not all, compiler warnings
CFLAGS = -g -Wall
# the build target executable:
all: bsy-pi.cpp
g++ -g -Wall -I/home/bsy139/project/lib -L/home/bsy139/project/lib -o bsy-pi bsy-pi.cpp -lpthread -lm -larmbianio -lmax7219
clean:
$(RM) bsy-pi
I don't understand, why g++ can't find the two libs. The makefile of these two libs wanted to sudo cp libarmbianio.a /usr/local/lib ;\ sudo cp armbianio.h /usr/local/include but I dont have permission on the machine. I think what that does is, that I can use #include <> in the Code instead of #include ""
Do you have some ideas? Thanks in advance.
You have to include the subdirectories in the lib folder, -L/home/bsy139/project/lib/max7219 for example. It does not do recursive lookups.
If you have an *.o file you can just add it directly to the linker arguments. I don't think adding it as a lib would work without having a proper *.a file. Note that there is a naming convention. If you add "-lmax7219" the linker is looking for "libmax7219.a".

GCC and Crypto++ on makefile

I'm trying to compile C++ project with gcc-make command but program giving this error. I already compiled Crypto++ and added include and lib folder but I dont know how to add this dir to gcc.
What should I do for fixing this "-lcrytopp" error?
I'm using makefile and this is line of 33-34.
$(TARGET): build $(OBJECTS)
$(CC) $(OBJECTS) -o $(TARGET) -lcryptopp
Error:
D:\Osman\CnC RA2\Mix\ccmix-crypto\ccmix-crypto>make
g++ src/mix_db_gamedb.o src/mix_db_gmd.o src/mix_header.o src/mix_db_lmd.o
src/mixid.o src/ccmix.o src/mix_file.o -o build/ccmix -lcryptopp
c:/mingw/bin/../lib/gcc/mingw32/5.3.0/../../../../mingw32
/bin/ld.exe: cannot find -lcryptopp
collect2.exe: error: ld returned 1 exit status
Makefile:34: recipe for target 'build/ccmix' failed
make: *** [build/ccmix] Error 1
Crypto++ directory:
Compile error:
You haven't added the directory containing the library to your link line. It should be something like -Lxxx where xxx is the path to the directory containing the cryptopp library:
$(TARGET): build $(OBJECTS)
$(CC) $(OBJECTS) -o $(TARGET) -Lxxx -lcryptopp
(replace xxx with the directory containing the cryptopp library)
What should I do for fixing this "-lcrytopp" error?
When working from the Crypto++ build directory on Unix compatibles, the project does not use include and lib (as your picture shows). Everything is placed in the root directory (as your picture shows).
If you perform a make install, then the directories are setup, but it appears you did not install. I should also say that MinGW is not usually tested anymore because the project is abandoned, so I'm not sure where make install actually installs to on MinGW.
To fix the compile error, tweak your make recipe:
$(TARGET): build $(OBJECTS)
$(CXX) $(CXXFLAGS) -I. $(OBJECTS) ./libcryptopp.a -o $(TARGET)
The recipe above uses CXX (C++ compiler) rather than CC (C compiler); it uses CXXFLAGS (which should be something like -DNDEBUG -g2 -O2); it calls out the header path (-I.); and it links to the static library (./libcryptopp.a). Linking to the static library will avoid your next set of problems.
You can follow MadScientist's advice and use -LXXX and -lcryptopp. You might even add a runpath with -Wl,-rpath,D:\Osman\CnC RA2\Mix\ccmix-crypto\ccmix-crypto. But at the end of the day, using -L and -l causes a fair amount of trouble. Avoid the future problems by statically linking libcryptopp.a.
Also see GNUmakefile | Compiling and Linking on the Crypto++ wiki.
Your fist picture shows ipch and Win32 directories. That usually means you built the Crypto++ library with Visual Studio. Now you are building a program with GCC. You should not mix and match compilers like that. Nothing good will come of it.

Makefile fails to see main.o one out of two times

Ok, I'm trying to build a makefile in order to compile a program on different environments. On Linux (Mint) it works just fine, but under Mac OS I get this error:
Undefined symbols for architecture x86_64:
"_main", referenced from:
implicit entry/start for main executable
ld: symbol(s) not found for architecture x86_64
clang: error: linker command failed with exit code 1 (use -v to see invocation)
make: *** [build] Error 1
With the '-v':
Apple LLVM version 5.1 (clang-503.0.40) (based on LLVM 3.4svn)
Target: x86_64-apple-darwin13.1.0
Thread model: posix
"/Library/Developer/CommandLineTools/usr/bin/ld" -demangle -dynamic -arch x86_64 -macosx_version_min 10.9.0 -w -o bin/Darwin/main ./cfprintf.o ./file.o ./inputmanager.o ./neditfile.o ./neditmanager.o ./neditscreen.o ./n_string.o ./sys_booter.o ./sys_display.o ./sys_manager.o ./sys_screen.o -lc++ -lSystem /Library/Developer/CommandLineTools/usr/bin/../lib/clang/5.1/lib/darwin/libclang_rt.osx.a
Undefined symbols for architecture x86_64:
"_main", referenced from:
implicit entry/start for main executable
ld: symbol(s) not found for architecture x86_64
clang: error: linker command failed with exit code 1 (use -v to see invocation)
make: *** [build] Error 1
Now here's the makefile:
CC = clang++
LIB =
INC = -I src/
OPTIONS = -w
OBJS = $(shell find ./src/obj -name '*.cpp')
IO = $(shell find ./src/io -name '*.cpp')
SYS = $(shell find ./src/sys -name '*.cpp')
APPS = $(shell find ./src/apps -name '*.cpp')
EXEC = bin/$(shell uname)/main
.PHONY: dummy build all objects io sys apps incBC clear run
build: clear incBC objects io sys apps
#echo "-> Compiling main... "
#$(CC) -c src/main.cpp $(INC) $(OPTIONS)
#echo "-> Building environment... "
#$(CC) $(shell find . -name '*.o') $(LIB) $(OPTIONS) -o $(EXEC) -v
#echo "-> Removing all objects file from compilation... "
#rm *.o
objects:
#echo "-> Building objects files and classes... "
#$(CC) -c $(OBJS) $(INC) $(OPTIONS)
io:
#echo "-> Building input/output files and classes..."
#$(CC) -c $(IO) $(INC) $(OPTIONS)
sys:
#echo "-> Building system files and classes..."
#$(CC) -c $(SYS) $(INC) $(OPTIONS)
apps:
#echo "-> Building all apps files and classes..."
#$(CC) -c $(APPS) $(INC) $(OPTIONS)
incBC:
#echo "-> Updated build count..."
#./incBC.sh
clear:
clear
run:
cd bin/$(shell uname)/ && clear && ./main
Now what's (al least to me) really weird, is that when I type make it fails one out of two times... LITERALLY one out of two! And when it does fail, I get the error message above. What I've noticed from that message is that, in the ld command, there is no main.o which is probably why I get the undefined reference. My question is: why? Why specifically one out of two times, and how can I fix this?
This is a bizarre makefile. Why not just write a shell script? There's nothing in this makefile that takes any advantage of make itself: it will always rebuild everything every time. The point of writing a makefile, instead of a shell script, is so you can avoid rebuilding objects that haven't changes.
Anyway, the reason you're seeing failures is that you're using make's $(shell ...) function inside of a recipe. This is not necessary, because a recipe is already running in a shell. The reason this fails for you is that make will expand the entire recipe (all lines) first, before it starts your recipe (it has to do this obviously). That means that because you're using $(shell ...) that find command is run before the recipe runs, and before the recipe runs you haven't compiled your main.o, so the find command doesn't include it in the list of object files found. Then the next time you run it, main.o exists from the previous run so the find command finds it.
Change this line:
#$(CC) $(shell find . -name '*.o') $(LIB) $(OPTIONS) -o $(EXEC) -v
to this:
#$(CC) `find . -name '*.o'` $(LIB) $(OPTIONS) -o $(EXEC) -v
and it will work.
Although it's still not very useful as a makefile.