Makefile with MSVC and CLION - visual-c++

I use the ATL library so I have to use MSVC instead of MinGW. But with MSVC libraries written in Makefile are not seen (with Makefile they are). I suppose that MSVC doesn't see Makefile at all. Are there any supposes about how to compile the project?
# Remove NDEBUG define to trigger asserts
CPPFLAGS+=-O2 -std=gnu++11 -I. -DNDEBUG -Wall -Wno-sign-compare -Wno-unused -g -D_FILE_OFFSET_BITS=64 -D_LARGEFILE_SOURCE -DOPENSSL
LDFLAGS+=-levent -lstdc++ -lssl -lcrypto
uname_S := $(shell sh -c 'uname -s 2>/dev/null || echo not')
ifeq ($(uname_S),FreeBSD)
CXX=clang++
LIBEVENT_HOME=D:/ProximaX/d/vcpkg/vcpkg/packages/libevent_x86-windows
CPPFLAGS+=-I${LIBEVENT_HOME}/include
LDFLAGS+=-L${LIBEVENT_HOME}/lib
else
CXX?=g++
LIBEVENT_HOME=D:/ProximaX/d/vcpkg/vcpkg/packages/libevent_x86-windows
CPPFLAGS+=-I${LIBEVENT_HOME}/include
LDFLAGS+=-L${LIBEVENT_HOME}/lib
OPENSSL_HOME=D:/ProximaX/d/vcpkg/vcpkg/packages/openssl_x86-windows
CPPFLAGS+=-I${OPENSSL_HOME}/include
LDFLAGS+=-L${OPENSSL_HOME}/lib
ATL_HOME=D:/VS17/VC/Tools/MSVC/14.16.27023/atlmfc
CPPFLAGS+=-I${ATL_HOME}/include
LDFLAGS+=-L${ATL_HOME}/lib
endif
all: swift-dynamic
swift: swift.o sha1.o compat.o sendrecv.o send_control.o hashtree.o bin.o binmap.o channel.o transfer.o httpgw.o statsgw.o cmdgw.o avgspeed.o avail.o storage.o zerostate.o zerohashtree.o livehashtree.o live.o api.o content.o swarmmanager.o address.o livesig.o exttrack.o
swift-static: swift
${CXX} ${CPPFLAGS} -o swift *.o ${LDFLAGS} -static -lrt
strip swift
touch swift-static
swift-dynamic: swift
${CXX} ${CPPFLAGS} -o swift *.o ${LDFLAGS}
touch swift-dynamic
clean:
rm -f *.o swift swift-static swift-dynamic 2>/dev/null
.PHONY: all clean swift swift-static swift-dynamic

Visual Studio does not use makefiles. You need to create a project and configure it correctly. See also this question.
That is why libraries that target both Windows and Linux provide both a makefile and a Visual Studio project file. Or they use a "meta build tool", such as CMake, that can generate both from the same source.
Alternatively you can rewrite the makefile to call the Visual Studio compiler but the compilation and linking options will be different.

Related

Linking issue in Cross Compilation for arm in linux using aarch64-linux-gnu-

I got an error when try to link (-aarch64-linux-gnu-ld) (the script containing the Makefile was downloaded from https://github.com/Icenowy/aw-el2-barebone). Error is "aarch64-linux-gnu-ld: Error: unable to disambiguate: -nostartfiles (did you mean --nostartfiles ?)
make: *** [Makefile:31: el2-bb.elf] Error 1" How to recode the line 31? of the Makefile
CROSS_COMPILE = /usr/bin/aarch64-linux-gnu-
DEBUG = 1
CC = $(CROSS_COMPILE)gcc
AS = $(CROSS_COMPILE)as
LD = $(CROSS_COMPILE)ld
OBJCOPY = $(CROSS_COMPILE)objcopy
INCLUDES = -I ./include -I ./uboot-headers -ffreestanding
DEFINES = -DSOC_HEADER="\"h6.h\""
ifneq ($(DEBUG),1)
DEFINES += -DNDEBUG
endif
ASFLAGS = $(INCLUDES) $(DEFINES) -D__ASSEMBLY__
CFLAGS = $(INCLUDES) $(DEFINES) -O2
LDSCRIPT = ldscripts/a64.ld
LDSCRIPTS = ldscripts/a64.ld ldscripts/common.ld
LDFLAGS = -nostdlib -nostartfiles -static -T $(LDSCRIPT)
OBJS = start.o init.o uart.o stack.o exceptions.o exception_funcs.o panic.o pgtables.o trapped_funcs.o
all: el2-bb.bin
el2-bb.elf: $(OBJS) $(LDSCRIPTS)
$(LD) $(LDFLAGS) $(OBJS) -o $#
el2-bb.bin: el2-bb.elf
$(OBJCOPY) -O binary $< $#
.PHONY: clean
clean:
rm -f el2-bb.* *.o
-nostartfiles is a gcc option but not an ld option.
If you use gcc to invoke the linker (say with LD=gcc in your Makefile) for making a standalone program that does not use standard startup files, you should use -nostartfiles because gcc links the startup files by default and -nostartfiles disables this.
ld doesn't links any startup files by default, so there is no option to disable linking them. You always pass startup files explicitly to ld. If you don't want startup files, just don't pass them to ld.
In order to see what startup files on your system are create an empty C program:
int main(){}
and compile it:
gcc -c empty.c
gcc -v empty.o
You are likely to see an invocation of ld (or perhaps of collect2, which calls ld) with a long, long list of options and object files.
Now run
gcc -nostartfiles -v empty.o
The .o files are now gone. That's exactly what -nostartfiles does.
When you invoke ld empty.o, these files and options are not there to begin with. In order to make a working program for say a Linux system, you need to pass most of them to ld explicitly. If you are building a program for something other system, you may not need some or all of them. So just don't pass them in.

Linux GCC Makefile a shared library with multply sources and dependencies

I have a problem trying to create a Makefile that compile multiple sorces, generate only a shared library and make an exe with another file wiht the main function.
The sorces also have dependencies.
My Makefile is
CC=gcc
CFLAGS=-Wall -g
BINS=libsensorMotor.so maintarget
all: $(BINS)
libsensorMotor.o: libsensorMotor.cpp sensorMotor.h Adafruit_ADS1015.cpp Adafruit_ADS1015.h wiringPiI2C.c wiringPiI2C.h enumADCGain.h
$(CC) $(CFLAGS) -c libsensorMotor.cpp Adafruit_ADS1015.cpp wiringPiI2C.c
libsensorMotor.so: libsensorMotor.cpp sensorMotor.h
$(CC) $(CFLAGS) -fPIC -shared -o $# libsensorMotor.cpp -lc
maintarget: maintarget.c
$(CC) $(CFLAGS) -o $# $^ -L. -lsensorMotor -pthread
clean:
rm *.o $(BINS)
The script show the errors:
libsensorMotor.so Undefined reference to 'functionXXXX'
maintarget contains the main and use libsensorMotor as a shared library. libsensorMotor depends and include all the rest of the files
The error mention all the functions that libsensorMotor uses from the include sources.
I only need to generate a correct libsensorMotor.so that can use as shared library from any other main file. Internet has many tutorials but are unclear, weird and complicated, and not show how do this simple.
Is not Makefile problem, simply the line
gcc -pthread -lm -o maintarget maintarget.c libsensorMotor.cpp Adafruit_ADS1015.cpp wiringPiI2C.c
sends same error, the compiler not recongnice the function inside the pthread_create while compile C and C++ with gcc

Converting a visual studio makefile to a linux makefile

i am new to makefiles and have just rescently created a makefile that works for a c++ project. it has two cpp files and one h file. i am trying to convert my file to work in linux but cant seem to figure out how. any ideas?
EXE = NumberGuessingGame.exe
CC = cl
LD = cl
OBJ = game.obj userInterface.obj
STD_HEADERS = header.h
CFLAGS = /c
LDFLAGS = /Fe
$(EXE): $(OBJ)
$(LD) $(OBJ) $(LDFLAGS)$(EXE)
game.obj: game.cpp $(STD_HEADERS)
$(CC) game.cpp $(CFLAGS)
userInterface.obj: userInterface.cpp $(STD_HEADERS)
$(CC) userInterface.cpp $(CFLAGS)
#prepare for complete rebuild
clean:
del /q *.obj
del /q *.exe
For in depth treatment of make on Linux, see GNU make.
There are a few differences. Binaries have no extension
EXE = NumberGuessingGame
The compiler is gcc, but need not be named, because CC is built in, same goes for LD. But since your files are named .cpp, the appropriate compiler is g++, which is CXX in make.
Object files have extension .o
OBJ = game.o userInterface.o
STD_HEADERS = header.h
Compiler flags
CXXFLAGS = -c
The equivalent for /Fe is just -o, which is not specified as LDFLAGS, but spelled out on the linker command line.
Usually, you use the compiler for linking
$(EXE): $(OBJ)
$(CXX) $(LDFLAGS) $(OBJ) -o $(EXE)
You don't need to specify the rules for object creation, they are built in. Just specify the dependencies
game.o: $(STD_HEADERS)
userInterface.o: $(STD_HEADERS)
del is called rm
clean:
rm -f $(OBJ)
rm -f $(EXE)
One important point is, indentation is one tab character, no spaces. If you have spaces instead, make will complain about
*** missing separator. Stop.
or some other strange error.
You can also use CMake to accomplish your task:
Put following into CMakeLists.txt file in the root directory of your project (<project-dir>):
cmake_minimum_required (VERSION 2.6)
project (NumberGuessingGame)
add_executable(NumberGuessingGame game.cpp serInterface.cpp)
Then on the console do
"in-source" build
$ cd <project-dir>
$ cmake .
$ make
or "out-source" build
$ mkdir <build-dir>
$ cd <build-dir>
$ cmake <project-dir>
$ make
You can adjust build setting using nice GUI tool. Just go to the build directory and run cmake-gui.
You don't need to include headers in the dependency list. The compiler will fail on its own, stopping make from continuing. However, if you're including them in the dependency list to force make to rebuild files in case the header changes, nobody will stop you.
CFLAGS never needs to contain -c, nor does LDFLAGS need -o. Below is a revamped makefile. Note that you can always override a macro explicitly defined in a makefile or implicitly defined using something like make CFLAGS=-Wall for example. I used the de facto standard CXX macro name in the event that you have C source files, which must be compiled using a C compiler (the value of the CC macro) instead of a C++ compiler.
.POSIX:
#CC is already implicitly defined.
CXX = g++
OBJ = game.o userInterface.o
STD_HEADERS = header.h
.SUFFIXES:
.SUFFIXES: .o .cpp .c
NumberGuessingGame: $(OBJ) $(STD_HEADERS)
$(CXX) $(CFLAGS) -o $# $(OBJ) $(LDFLAGS)
.cpp.o: $(STD_HEADERS)
$(CXX) $(CFLAGS) -c $<
#There is already an implicit .c.o rule, thus there is no need for it here.
#prepare for complete rebuild
clean:
-rm -f NumberGuessingGame *.o
As yegorich answered, you can use a build system like Cmake. It is much more flexible, cross-platform, and can generate Unix Makefiles as well as Nmake Makefiles and Visual Studio solutions on Windows.

Compling C++ code using command line

A am using below command to compile my c++ code and which is using OpenCV libraries and my command is just like
opencv main.cpp -o binary_name
where opencv is an alias command like
alias opencv="g++ `pkg-config --cflags opencv` `pkg-config --libs opencv`"
but if I forget the "-o binary_name" the command delete my source file. Why this happening....?
What modification should I made on the above alias command to compile my source file like
opencv main.cpp binary_name
Thanks in advance.......
The order of arguments to gcc is important, source or object files should be given before libraries, and libraries should be invoked with higher level libraries before the lower level libraries they are using.
So you should compile with
g++ -Wall -g $(pkg-config --cflags opencv) main.cpp \
$(pkg-config --libs opencv) -o binaryprog
But you really should use a Makefile, or at least have a shellscript.
Don't forget the -Wall option to get all warnings. Improve your code till no warnings are given by the compiler. Use the -g option to get debugging information, to be able to use gdb ./binaryprog to debug your program.
Once your program is debugged, replace -g by -O3 (or perhaps by -O2 -g) to ask GCC to optimize the generated code.
You can use a function instead of an alias, and use arguments:
function opencv() { g++ `pkg-config --cflags opencv` `pkg-config --libs opencv` "$1" -o "$2"; }

Cannot compile with makefile - undefined reference to `boost::re_detail

I got an assignment to improve running time of some code. The only problem is, I can't even compile it to run it on my machine in the first place. Every time I try, it stops somewhere in the midst of compiling saying this:
"undefined reference to `boost::re_detail::put_mem_block(void*)'
collect2: ld returned 1 exit status make: * [cpu] Error 1"
This is how makefile looks:
SHELL = /bin/bash
OBJECTS = main.o atom.o molecule.o charges.o pdb.o asa.o amino.o chain.o addition.o string_operation.o pdb_peptide.o protein_chain.o residue_atom.o chain_residue.o residue_contact.o atom_grid.o circles.o atom_space_calculations.o
OBJDIR = obj
VPATH = src:src/ext:$(OBJDIR)
CFLAGS = -O3 -Wall -lm -lboost_regex -L/usr/local/boost/lib
HDIRS = src,src/ext,src/qt_redistributable, usr/lib, usr/local/lib, usr/local/lib/include/boost, /usr/local/lib/lib/
IOPTS = $(addprefix -I, $(HDIRS))
cpu : $(addprefix $(OBJDIR)/, $(OBJECTS) $(CPUOBJS))
g++ $(CFLAGS) -o mcpu $^
$(OBJDIR)/%.o : %.cpp
g++ $(CFLAGS) $(IOPTS) -c $< -o $#
clean :
rm obj/*.o $(PROG)
I'm using Linux Mint x64 and I have tried everything I googled out. Installed the whole boost library in usr/local/lib (for no obvious reason because it didn't help), tried to edit LD PATH (I'm very new to Linux and I have no idea if that went right) and lots of stuff, but this thing doesn't seem to go through. Any help appreciated.
One problem with your makefile happens when you link your program. As you can see in these questions with g++ the order of your arguments at link time is really important. You need to put your libraries after your object files. One easy way to solve would be separating your linker flags (LDFLAGS) from the compiler flags (CFLAGS), and then putting LDFLAGS after $^ (your object files) in the link command.
CFLAGS = -O3 -Wall
LDFLAGS = -L/usr/local/boost/lib -lm -lboost_regex
cpu : $(addprefix $(OBJDIR)/, $(OBJECTS) $(CPUOBJS))
g++ $(CFLAGS) -o mcpu $^ $(LDFLAGS)
$(OBJDIR)/%.o : %.cpp
g++ $(CFLAGS) $(IOPTS) -c $< -o $#
As can be seen in the Catalogue of Built-In Rules:
Linking a single object file
n is made automatically from n.o by running the linker (usually called
ld) via the C compiler. The precise recipe used is:
$(CC) $(LDFLAGS) n.o $(LOADLIBES) $(LDLIBS)
and Variables Used by Implicit Rules:
LDFLAGS
Extra flags to give to compilers when they are supposed to invoke the linker,
ld, such as -L. Libraries (-lfoo) should be added to the LDLIBS variable
instead.
So in this case -lboost_regex should be set or added to LDLIBS, not LDFLAGS.

Resources