Make a DLL file from a Fortran source using a Makefile - dll

How would I make a DLL file from a Makefile where the files are written in Fortran?
I'm working with Windows but having it compiled under a Linux system isn't a problem.
I have two modules and one file that uses those modules.
Normally, I would just write the following to to produce what I want:
gfortran module1.f90 module2.f90 main.f90 -o main.dll

If module1.f90 and module2.f90 are just modules and you want to create a dll, you may use the following command:
gfortran -o main.dll module1.f90 module2.f90 -shared -fPIC -lgfortran
It will generate a dll that can be loaded later by the main program.
The main flags here for generate a lib are -shared and -fPIC.
If main.f90 is the main program, the output should be an exe, and the command to compile maybe:
gfortran -o main.exe module1.f90 module2.f90 main.f90
It will generate an exe with the main file using the modules.
Edit:
Here, is a sample Makefile that builds the DLL (for the question):
FC=gfortran
FFLAGS=-g -shared -fPIC
LDFLAGS=-lgfortran
main.dll: main.f90 module1.o module2.o
$(FC) $(LDFLAGS) -o $# $?
module1.o: module1.f90
$(FC) $(FFLAGS) -o $# $?
module2.o: module2.f90
$(FC) $(FFLAGS) -o $# $?
clean:
rm -f *.o *.exe *.dll
After executing it:
gfortran -g -shared -fPIC -o module1.o module1.f90
gfortran -g -shared -fPIC -o module2.o module2.f90
gfortran -o main.dll main.f90 module1.o module2.o
It generates the DLL:
20/12/2016 16:23 59.091 main.dll
Maybe, this Makefile can be improved with use of macros.
HTH
tested with gfortran version 6.2.0 (x86_64-posix-seh-rev0, Built by MinGW-W64 project)

Related

How to call a function at start and end of building a target in cmake

I'm looking for a way to execute shell code when starting and finishing the build of a target in cmake. The final goal is to send a message to a data tracking tool indicating when builds start and finish.
So for example, if "make" build targets alpha, beta and gamma, I'd like to call foo_begin() when alpha starts building and foo_end when target alpha is successfully built, and so on for all the targets.
Is this possible?
It is not possible to call arbitrary CMake functions at build time. Once the build system is generated, all the normal variable state and function definitions are discarded (i.e. they are not in cache). The COMMAND argument to add_custom_command takes a shell command, not a CMake function.
However, you can use CMake's script mode, so if what you want is to use CMake as a scripting language just to implement some build hooks, you can do this:
Let's create a file called proc_target.cmake with these contents:
cmake_minimum_required(VERSION 3.23)
if (PRE_BUILD)
message(STATUS "PRE_BUILD: ${TARGET}")
else ()
message(STATUS "POST_BUILD: ${TARGET}")
endif ()
Now in the CMakeLists.txt we can write:
cmake_minimum_required(VERSION 3.23)
project(example)
add_executable(foo main.cpp)
add_custom_command(
TARGET foo PRE_BUILD
COMMAND "${CMAKE_COMMAND}"
-DTARGET=foo
-DPRE_BUILD=1
-P "${CMAKE_CURRENT_SOURCE_DIR}/proc_target.cmake"
)
add_custom_command(
TARGET foo POST_BUILD
COMMAND "${CMAKE_COMMAND}"
-DTARGET=foo
-DPRE_BUILD=0
-P "${CMAKE_CURRENT_SOURCE_DIR}/proc_target.cmake"
)
Then when you run this build, you'll see the following commands:
$ cmake -G Ninja -S . -B build -DCMAKE_BUILD_TYPE=Release
...
$ cmake --build build -- -nv
[1/2] /usr/bin/c++ -O3 -DNDEBUG -MD -MT CMakeFiles/foo.dir/main.cpp.o -MF CMakeFiles/foo.dir/main.cpp.o.d -o CMakeFiles/foo.dir/main.cpp.o -c /path/to/main.cpp
[2/2] cd /path/to/build && /usr/bin/cmake -DTARGET=foo -DPRE_BUILD=1 -P /path/to/proc_target.cmake && cd /path/to/build && /usr/bin/c++ -O3 -DNDEBUG CMakeFiles/foo.dir/main.cpp.o -o foo && cd /path/to/build && /usr/bin/cmake -DTARGET=foo -DPRE_BUILD=0 -P /path/to/proc_target.cmake
You can see how proc_target.cmake is called twice: once just before and once just after invoking the linker for foo. If you want proc_target to run before any of the sources are compiled, then you would want to write:
add_custom_command(
OUTPUT pre-foo.stamp
COMMAND "${CMAKE_COMMAND}"
-DTARGET=foo
-DPRE_BUILD=1
-P "${CMAKE_CURRENT_SOURCE_DIR}/proc_target.cmake"
COMMAND "${CMAKE_COMMAND}" -E touch pre-foo.stamp
DEPENDS "$<TARGET_PROPERTY:foo,SOURCES>"
)
add_custom_target(pre-foo DEPENDS "${CMAKE_CURRENT_BINARY_DIR}/pre-foo.stamp")
add_dependencies(foo pre-foo)
instead of the PRE_BUILD custom command above. Then you would get:
[1/3] cd /path/to/build && /usr/bin/cmake -DTARGET=foo -DPRE_BUILD=1 -P /path/to/proc_target.cmake
[2/3] /usr/bin/c++ -O3 -DNDEBUG -MD -MT CMakeFiles/foo.dir/main.cpp.o -MF CMakeFiles/foo.dir/main.cpp.o.d -o CMakeFiles/foo.dir/main.cpp.o -c /path/to/main.cpp
[3/3] : && /usr/bin/c++ -O3 -DNDEBUG CMakeFiles/foo.dir/main.cpp.o -o foo && cd /path/to/build && /usr/bin/cmake -DTARGET=foo -DPRE_BUILD=0 -P /path/to/proc_target.cmake
And now you can see that the custom target pre-foo is processed before foo.
This is most likely not what you want, however. It's over-engineered. If you want to generate a source file for a target, you should use add_custom_command(OUTPUT) directly and attach the output to the target as a source file (i.e. when you call add_executable or via target_sources).
Per #botje's comment, it seems I need cmake's add_custom_command with build event specifies. I will however need PRE_BUILD, which the documentation informs me is only available for vs-studio, while I am building use cmake & gcc. So I guess I have a new question: how to duplicate the behavior of PRE_BUILD in a cmake/gcc build environment.

makefile with debug option

I am kinda rookie in makefile field but trying to write makefile that would go in two modes: normal mode make outputing executable file called say bingo depending on some files and a mode make debug outputing executable file called bingo.debug that shall be compiled with debug option. I'm trying to use target variable with the following result:
PROGRAM = bingo
SUFIX = .debug
CC = gcc
CFLAGS = -Wall -O2
DEBUG = -g -D DEBUG
all: $(PROGRAM)
debug: CFLAGS += $(DEBUG)
debug: PROGRAM += $(SUFIX)
debug: all
file1.o: file1.c file1.h
$(CC) -c $(CFLAGS) -o $# $<
file2.o: file2.c file2.h
$(CC) -c $(CFLAGS) -o $# $<
$(PROGRAM).o: $(PROGRAM).c
$(CC) -c $(CFLAGS) -o $# $<
$(PROGRAM): file1.o file2.o ($PROGRAM).o
$(CC) -o $# $^
.PHONY: all clean
clean:
rm -rf $(PROGRAM) *.o
It looks like make debug correctly compiles the file with debug flags but it does not change the file name (i.e. both modes outputs the same bingo file). Any help much appriciated!
You cannot use target-specific variables in targets. The documentation is very clear that they are available only in recipes.
In general it's problematic to do things this way, because make has no idea which objects were built with debug and which weren't. If you forget to do a complete clean and/or run make the wrong way then you'll get a mix of different object files: some compiled with debug and some not.
Instead, you should put your debug object files in a different directory from your non-debug object files so you don't have to worry about that.

Cocoa project without Xcode

I am writing a sample application on Mac OS X using Cocoa.
Things were fine when I was using Xcode to built and debug.
But when I started building by makefile, program is same, every file is same (as shown by diff), output is different.
My first question: Is this makefile to build a cocoa project correct?
Make file is:
CLANG = /Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/bin/clang
LINK = /Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/bin/clang
ARCH = x86_64
MIN_VERSION = 10.8
DEBUG_PATH = bin/debug
SYSROOT = /Applications/Xcode.app/Contests/Developer/Platforms/MacOSX.platform/Developer/SDKs/MacOSX10.8.sdk/
IBTOOL = /Applications/Xcode.app/Contents/Developer/usr/bin/ibtool
SDK = /Applications/Xcode.app/Contents/Developer/Platforms/MacOSX.platform/Developer/SDKs/MacOSX10.8.sdk
FRAME = /Applications/Xcode.app/Contents/Developer/Platforms/MacOSX.platform/Developer/SDKs/MacOSX10.8.sdk/System/Library/Frameworks
LIB = /Applications/Xcode.app/Contents/Developer/Platforms/MacOSX.platform/Developer/SDKs/MacOSX10.8.sdk/usr/lib
FLAGS = -g -O0
debug: $(DEBUG_PATH)/test.app
run:
open $(DEBUG_PATH)/test.app
$(DEBUG_PATH)/test.app: $(DEBUG_PATH)/test
cp $(DEBUG_PATH)/test $(DEBUG_PATH)/test.app/Contents/MacOS/test
cp en.lproj/credits.rtf $(DEBUG_PATH)/test.app/Contents/Resources/en.lproj
cp en.lproj/InfoPlist.strings $(DEBUG_PATH)/test.app/Contents/Resources/en.lproj
cp PkgInfo $(DEBUG_PATH)/test.app/Contents/
rm -f $(DEBUG_PATH)/test
cp test-core-text-Info.plist $(DEBUG_PATH)/test.app/Contents/Info.plist
touch $#
$(DEBUG_PATH)/test: $(DEBUG_PATH)/AppDelegate.o $(DEBUG_PATH)/main.o
mkdir -p $(DEBUG_PATH)/test.app/Contents/MacOS/../Resources/en.lproj
$(CLANG) -arch $(ARCH) -isysroot $(SYSROOT) -L$(DEBUG_PATH)/ -L$(LIB) -mmacosx-version-min=$(MIN_VERSION) AppDelegate.o main.o -framework Cocoa -o $# -F $(FRAME)
$(IBTOOL) --errors --warnings --notices --output-format human-readable-text --compile $(DEBUG_PATH)/test.app/Contents/Resources/en.lproj/MainMenu.nib en.lproj/MainMenu.xib --sdk $(SDK)
clean:
rm -rf $(DEBUG_PATH)/test.app
rm -f $(DEBUG_PATH)/*
$(DEBUG_PATH)/AppDelegate.o: src/AppDelegate.m
$(CLANG) -arch $(ARCH) $(FLAGS) -Wall -c $< -o $#
$(DEBUG_PATH)/main.o: src/main.m
$(CLANG) -arch $(ARCH) $(FLAGS) -Wall -c $< -o $#
Output of Xcode (run app from anywhere)
Output by makefile
It is still conundrum to me that the program is same, Info.plist is same, nib is same, why the output is different.
What is the thing I am missing?

Makefile: How do I use variables in the left hand side of the rule?

Let's say I want to rewrite this:
main.o: main.cpp
g++ -c main.cpp
factorial.o: factorial.cpp
g++ -c factorial.cpp
hello.o: hello.cpp
g++ -c hello.cpp
in a more generic way as something like this:
SOURCES = main factorial hello
$(SOURCES).o: $(SOURCES).cpp
g++ -c $(SOURCES).cpp
How do I do that?
First we tell the compiler how to nme the output files, just to avoid misunderstanding:
main.o: main.cpp
g++ -c main.cpp -o main.o
factorial.o: factorial.cpp
g++ -c factorial.cpp -o factorial.o
hello.o: hello.cpp
g++ -c hello.cpp -o hello.o
Then we put in automatic variables, to reduce redundancy:
main.o: main.cpp
g++ -c $< -o $#
factorial.o: factorial.cpp
g++ -c $< -o $#
hello.o: hello.cpp
g++ -c $< -o $#
Then we realize that these rules all look the same, so we combine them as a static pattern rule:
main.o factorial.o hello.o: %.o : %.cpp
g++ -c $< -o $#
Then we use a variable to store the names of the objects:
OBJECTS := main.o factorial.o hello.o
$(OBJECTS): %.o : %.cpp
g++ -c $< -o $#

Prepending a path on make

In my makefile I have an object variable. I need to prepend obj/ to every .o file. How would I do this?
CC=g++
CFLAGS=-C -Wall
LDFLAGS=-lsqlite3 -lpthread -ldl
SOURCES=main.cpp Database.cpp actionInit.cpp TileSet.cpp Player.cpp
OBJECTS=$(SOURCES:.cpp=.o)
EXECUTABLE=mahjong-counter
all: bin $(OBJECTS) $(EXECUTABLE)
bin:
mkdir -p bin
%.o: %.cpp
$(CC) $(LDFLAGS) $< -c -o $#
$(EXECUTABLE): $(OBJECTS)
$(CC) $(LDFLAGS) $(OBJECTS) -o $(EXECUTABLE)
clean:
rm $(OBJECTS)
You want CXX, not CC. CC is for C compiler, not the C++ compiler
In any case, I believe the following should work:
CXX=g++
CXXFLAGS=-C -Wall
LDFLAGS=-lsqlite3 -lpthread -ldl
OBJ_DIR = obj
BIN_DIR = bin
EXECUTABLE=mahjong-counter
SOURCES= main.cpp Database.cpp actionInit.cpp TileSet.cpp Player.cpp
OBJECTS= $(SOURCES:%.cpp=$(OBJ_DIR)/%.o)
all: dirs $(OBJECTS) $(EXECUTABLE)
$(EXECUTABLE): $(OBJECTS)
$(CC) $(LDFLAGS) $(OBJECTS) -o $(EXECUTABLE)
$(OBJ_DIR)/%.o: %.cpp
$(CXX) $(CXXFLAGS) $< -o $#
dirs:
mkdir -p $(BIN_DIR)
mkdir -p $(OBJ_DIR)
.PHONY: dirs all
You could use more expressive version of substitution you employed when assigning OBJECTS
OBJECTS=$(SOURCES:%.cpp=obj/%.o)
or use a standard text transformation function
OBJECTS=$(addprefix obj/,$(SOURCES:.cpp=.o))