How can I convert Linux makefile to Windows makefile - windows

Following makefile, I am using to generate Fortran executable file in Linux now I need to generate same for windows. How can I write and run the same makefile in windows or if possible can I convert this makefile for windows makefile?
#Makefile for Linux
PROG = sbdart
OBJS = atms.o disort.o disutil.o drt.o params.o spectra.o \
tauaero.o taucloud.o taugas.o
FC = f95
FFLAGS = -o -c
LDFLAGS =
LIBS =
$(PROG): $(OBJS)
$(FC) $(LDFLAGS) -o $# $(OBJS) $(LIBS)
atms.o: params.o atms.f
disort.o: params.o disort.f
disutil.o: params.o disutil.f
drt.o: params.o tauaero.o taugas.o spectra.o drt.f
params.o: params.f
spectra.o: params.o spectra.f
tauaero.o: params.o tauaero.f
taucloud.o: params.o taucloud.f
taugas.o: params.o taugas.f
clean:
rm -f $(PROG) $(OBJS) *.mod

The easiest solution for porting build settings across systems I know of is to create a CMakeLists.txt and generate Makefiles for both automatically using CMake.
You can find an example of Fortran projects with CMake here.

Related

Multiple make targets in the same CMake project

In my project I have a makefile that looks like this:
CXX = clang++
CFLAGS = -std=c++11
COMMON_SOURCES = file1.cpp file2.cpp
TARGET_SOURCES = main.cpp
TEST_SOURCES = run_tests.cpp test_file1.cpp test_file2.cpp
COMMON_OBJECTS = $(COMMON_SOURCES:.c=.o)
TARGET_OBJECTS = $(TARGET_SOURCES:.c=.o)
TEST_OBJECTS = $(TEST_SOURCES:.c=.o)
EXECUTABLE = build/application
TEST_EXECUTABLE = build/tests
.PHONY: all target tests
all: target tests
target: $(EXECUTABLE)
tests: $(TEST_EXECUTABLE)
clean:
rm build/tests & rm build/application &
$(EXECUTABLE): $(COMMON_OBJECTS) $(TARGET_OBJECTS)
$(CXX) $(CFLAGS) $(LDFLAGS) $^ -o $#
$(TEST_EXECUTABLE): $(COMMON_OBJECTS) $(TEST_OBJECTS)
$(CXX) $(CFLAGS) $(LDFLAGS) $^ -o $#
.c.o:
$(CXX) $(CFLAGS) $< -o $#
This lets me run make tests or make target and it will build the appropriate executable.
How do I set up a CMakeLists file to get the same convenient build system?
Except for using clang++, I think if you put the following in a CMakeLists.txt file and then run your cmake configure step in a build directory (i.e., mkdir build; cd build; cmake ..), you should have what you are asking for.
project(myproject)
# I am not sure how you get cmake to use clang++ over g++
# CXX = clang++
add_definitions(-std=c++11)
set(COMMON_SOURCES file1.cpp file2.cpp)
set(TARGET_SOURCES main.cpp)
set(TEST_SOURCES run_tests.cpp test_file1.cpp test_file2.cpp)
add_executable(application ${COMMON_SOURCES} ${TARGET_SOURCES})
add_executable(tests ${COMMON_SOURCES} ${TEST_SOURCES})
Every add_custom_target() (and some other commands, like add_executable) actually adds target in the make sence.
add_custom_target(tests) # Note: without 'ALL'
add_executable(test_executable ...) # Note: without 'ALL'
add_dependencies(tests test_executable)
So, test_executable will be build on make tests, but not in case of simple make.

CMake with CLion

I have been using Kdevelop with a project, now im on a different laptop, and need to build the project with CLion and MinGW on Windows.
I had this makefile (works on KDevelop)
CC=gcc
DEPS = cmp_micris_defs.h
OBJ = cmp_micris_datos_msc.o cmp_micris_rutinas.o cmp_micris_UnixSocket.o cmp_micris_cfg.o cmp_micris_db.o cmp_micris_TCP.o cmp_micris_utiles.o cmp_micris_datos.o cmp_micris.o
LIBS = -lpthread -lmysqlclient
.PREFIXES = .c .o
.c.o:
$(CC) -std=gnu99 -c -I/home/borja/projects/micris2/proceso-micris2/proceso/ $< $(LIBS)
cmp_micris_borja: $(OBJ)
$(CC) -o $# $(OBJ) $(LIBS)
all: cmp_micris_borja
clean:
rm -rf $(OBJ) cmp_micris_borja
But CLion use Cmake to build, i have not used it before, what should i write in CMakeLists.txt to build like before with my makefile ?
Thanks.

My Makefile is trying to compile a non-exsistent/made up filename

This is my VERY FIRST Makefile and so I have cut and paste junk I have found all over the web. My directory structure is pretty flat and was not thought out for Makefiles. It is:
Project/
Project/Control
Project/NodeMgmt
Project/Common
Project/Interfaces
I am writing a Makefile for Control and would like it to standalone inside Control. It needs to include compile and include from Common & Interfaces. Here's my Makefile:
CC = g++
CFLAGS = -Wall -c
INCLUDES = -I/usr/local/include -I/SuperCool/Ion-1.0.0-snapshot-1/include -I/SuperCool/FastrakSDK-4.0.1-snapshot-1/include/Fastrak/Engine/Core/CoreIpc -I/Projects/Common -I/Projects/Interfaces -I/Projects/NodeMgmt -I/Projects/Controller
LFLAGS = -L/usr/local/lib -L/SuperCool/FastrakSDK-4.0.1-snapshot-1/lib
LIBS = -lCoreIpc4 -lIonOs
VPATH = ../Interfaces/
VPATH = ../Common/
VPATH = ../NodeMgmt/
SRCS = *.cc
OBJS = $(SRCS:.cc=.o)
MAIN = controller
.PHONY: clean
all: $(MAIN)
#echo Built Controller
$(MAIN): $(OBJS)
$(CC) $(CFLAGS) $(INCLUDES) -o $(MAIN) $(OBJS) $(LFLAGS) $(LIBS)
.cc.o:
$(CC) $(CFLAGS) $(INCLUDES) -c $< -o $#
clean:
$(RM) *.o $(MAIN)
It's compiling the first .cc file it finds "-c Controller.cc -o *.o" which make sense but that's all it's compiling and I get a *.o output file, not a Controller.o file. It does not compile any other files.
Here's one problem:
SRCS = *.cc
Make doesn't understand wildcards without the wildcard function:
SRCS = $(wildcard *.cc)
That should get it working; we can make minor improvements later.

How to remove Makefile Dependency on C file

I have the below Makefile and for some reason it's dependent on a file, ewapi.c. This file executes some SWIG commands and uses the ewapi.i file. I've clear out all the contents of ewapi.c and the Makefile successfully runs. If I remove the ewapi.c file the make file will not complete. The exception stack is below if that helps. Any ideas on how to change the Makefile so its not dependent on ewapi.c?
# BUILD_DIR and DIST_DIR are exported by build.xml
#
CMODE=
SWIG = swig
CC = $(PREFIX)gcc
LD = $(CC)
OBJ_DIR = $(BUILD_DIR)/obj
AUTOGEN_DIR = $(BUILD_DIR)/auto-generated
PACKAGE_DIR = $(AUTOGEN_DIR)/com/sample/jni
PACKAGE = com.sample.jni
INCLUDES = -I$(JAVA_INCLUDE) \
-I$(SAMPLE_SDK_DIR)/include \
-I$(JDK_HOME)/include
LIB_INCLUDES = -L$(SAMPLE_SDK_DIR)/lib
LIBS = /lib/libssl.so.4 \
/lib/libcrypto.so.4 \
-lSampleApi \
-lm
DIRS = $(PACKAGE_DIR) $(DIST_DIR) $(OBJ_DIR) $(AUTOGEN_DIR)
CFLAGS = $(CMODE) -Wall -fpic $(INCLUDES) -O0 -g3
SFLAGS = -java $(INCLUDES) -package $(PACKAGE) -outdir $(PACKAGE_DIR)
LDFLAGS = -shared $(LIB_INCLUDES) $(LIBS)
OBJECTS = $(OBJ_DIR)/ewapi_wrap.o $(OBJ_DIR)/ewapi.o
TARGET = $(DIST_DIR)/libSample.so
all: $(DIRS) $(TARGET)
%_wrap.c: %.i
$(SWIG) $(SFLAGS) $<
$(OBJ_DIR)/%.o: %.c
$(CC) $(CFLAGS) -c $< -o $#
$(TARGET): $(OBJECTS)
$(LD) $(OBJECTS) $(LDFLAGS) -o $#
$(DIRS):
mkdir -p $#
clean:
rm -rf $(TARGET) $(PACKAGE_DIR)/* $(TARGET) $(AUTOGEN_DIR) $(OBJ_DIR)
Exception Stack (when I remove ewapi.c):
[exec] rm ewapi_wrap.c
[exec] make-3.79.1-p7: *** No rule to make target `/test/build/obj/ewapi.o', needed by `/test/dist/libSample.so'. Stop.
The macros OBJECTS includes $(OBJ_DIR)/ewapi.o; the rule for $(TARGET) says it depends on $(OBJECTS); and the rule for all says it depends on $(TARGET). So, there needs to be a way to create ewapi.o from something - and in the absence of ewapi.c, there is no way to build ewapi.o, hence the complaint you get.
Possible fixes:
Replace ewapi.c.
Remove ewapi.o from the macro $(OBJECTS).
Remove $(OBJ_DIR)/ewapi.o from OBJECTS.

Making a better Makefile

so I learned what a Makefile was some time ago, created a template Makefile and all I do is copy and alter the same file for every program I'm doing. I changed it a few times, but it's still a very crude Makefile. How should I improve it? This is an example of my current version:
CC = g++
CFLAGS = -std=gnu++0x -m64 -O3 -Wall
IFLAGS = -I/usr/include/igraph
LFLAGS = -ligraph -lgsl -lgslcblas -lm
DFLAGS = -g -pg
# make all
all: run test
# make a fresh compilation from scratch
fresh: clean test
#makes the final executable binary
run: main.o foo1.o foo2.o
$(CC) $(CFLAGS) $(LFLAGS) $^ -o $#
#makes the test executable with debugging and profiling tags
test: test.o foo1.o foo2.o
$(CC) $(DFLAGS) $(CFLAGS) $(LFLAGS) $^ -o $#
#makes teste.o
teste.o: teste.cpp
$(CC) $(CFLAGS) $(IFLAGS) -c $^ -o $#
#makes main.o
main.o: main.cpp
$(CC) $(CFLAGS) $(IFLAGS) -c $^ -o $#
#file foo1
foo1.o: foo1.cpp
$(CC) $(CFLAGS) $(IFLAGS) -c $^ -o $#
#file foo2
foo2.o: foo2.cpp
$(CC) $(CFLAGS) $(IFLAGS) -c $^ -o $#
clean: clean-test clean-o clean-annoying
clean-test:
rm test-rfv
clean-o:
rm *.o -rfv
clean-annoying:
rm *~ -rfv
Just by visually comparing with other makefiles I saw around in the web, this seems to be not a very bright Makefile. I don't know how they work, but I can see there's significantly less boilerplate and more generic code in them.
Can this can be made better, safer, and easier to particularize for each project?
You don't want to name specific files in a makefile if you can get away with it, and 99% of the time you can. This page shows how to develop a very general makefile. The following is my own makefile, based on that page's info:
SHELL := bash
PROG := pathed.exe
OUTDIRS := bin/debug bin/rel obj/debug obj/rel
PROG_REL := bin/rel/$(PROG)
PROG_DEBUG := bin/debug/$(PROG)
SRCFILES := $(wildcard src/*.cpp)
OBJFILES_REL := $(patsubst src/%.cpp,obj/rel/%.o,$(SRCFILES))
OBJFILES_DEBUG := $(patsubst src/%.cpp,obj/debug/%.o,$(SRCFILES))
DEPFILES := $(patsubst src/%.cpp,obj/%.d,$(SRCFILES))
CFLAGS := -Iinc -Wall -Wextra -MMD -MP
DBFLAGS := -g
RELFLAGS :=
CC := g++
.PHONY: default all testmake debug release clean dirs
default: debug
all: dirs clean debug release
dirs:
#mkdir -p $(OUTDIRS)
debug: $(PROG_DEBUG)
release: $(PROG_REL)
testmake:
#echo OBJFILES_REL = $(OBJFILES_REL)
#echo OBJFILES_DEBUG = $(OBJFILES_DEBUG)
#echo SRCFILES = $(SRCFILES)
#echo DEPFILES = $(DEPFILES)
clean:
rm -f $(OBJFILES_REL) $(OBJFILES_DEBUG) $(DEPFILES) $(PROG)
$(PROG_REL): $(OBJFILES_REL)
$(CC) $(OBJFILES_REL) -o $(PROG_REL)
strip $(PROG_REL)
#echo "---- created release binary ----"
$(PROG_DEBUG): $(OBJFILES_DEBUG)
$(CC) $(OBJFILES_DEBUG) -o $(PROG_DEBUG)
#echo "---- created debug binary ----"
-include $(DEPFILES)
obj/rel/%.o: src/%.cpp
$(CC) $(RELFLAGS) $(CFLAGS) -MF $(patsubst obj/rel/%.o, obj/%.d,$#) -c $< -o $#
obj/debug/%.o: src/%.cpp
$(CC) $(DBFLAGS) $(CFLAGS) -MF $(patsubst obj/debug/%.o, obj/%.d,$#) -c $< -o $#
Do NOT use CC for the C++ compiler. The standard convention is that CC is the C compiler, CXX is the C++ compiler. CFLAGS are flags for the C compiler, CXXFLAGS are flags for the C++ compiler, and CPPFLAGS are flags for the pre-processor (eg, -I or -D flags). Use LDFLAGS for -L flags to the linker, and LDLIBS (or LOADLIBES) for -l flags.
Using the standard conventions is good not just because it makes things easier for others to understand, but also because it allows you to take advantage of implicit rules. If make needs to make a .o file from a .c file and you have not provided a rule, it will use a standard rule and honor the settings of CC, CFLAGS, and CPPFLAGS. If CC is a C++ compiler, things will probably not work.

Resources