Difference between revisions of "MakeFile"
SergeMoutou (talk | contribs) m (New page: =Makefile structure= We will artificially divide the makefile in four parts : *the setting part *the compilation part *the execute part *the clean part All makefiles provided with SDK have...) |
|||
(46 intermediate revisions by one other user not shown) | |||
Line 1: | Line 1: | ||
+ | {{Warn|This chapter is under construction.}} | ||
+ | It is mportant for you to have skill on necessary tools for [[Documentation/DevGuide/WritingUNO/Required_Files|UNO development]]. | ||
=Makefile structure= | =Makefile structure= | ||
We will artificially divide the makefile in four parts : | We will artificially divide the makefile in four parts : | ||
Line 28: | Line 30: | ||
The third line is directory-dependent : where your makefile lie and how do you reach the setting directory will change this line and the following, pointing toward the « settings » directory. Of course an other way is to use an absolute URL but portability is worse. The goal of other lines is to prepare compilation. We have let in red macros that seem not to be defined at first glance. But if you have a look to std.mk you will find the lacking definitions even if this files introduce other undefined macros which are in fact defined in settings.mk | The third line is directory-dependent : where your makefile lie and how do you reach the setting directory will change this line and the following, pointing toward the « settings » directory. Of course an other way is to use an absolute URL but portability is worse. The goal of other lines is to prepare compilation. We have let in red macros that seem not to be defined at first glance. But if you have a look to std.mk you will find the lacking definitions even if this files introduce other undefined macros which are in fact defined in settings.mk | ||
− | =Lifetime example | + | ==Starting with Lifetime example== |
The lifetime example is introduced in (page ). The file used to create this example is find in « <OOSDK>/examples/DevelopersGuide/ProfUNO/Lifetime ». The Lifetime directory contains a complicated makefile able of creating either a Java or a C++ example. We focus only on C++ code. | The lifetime example is introduced in (page ). The file used to create this example is find in « <OOSDK>/examples/DevelopersGuide/ProfUNO/Lifetime ». The Lifetime directory contains a complicated makefile able of creating either a Java or a C++ example. We focus only on C++ code. | ||
− | A shorter Makefile | + | ===A shorter Makefile=== |
We want to start from a shorter Makefile example than those given with SDK. For example the LifeTime example can be correctly compiled under Linux with this makefile : | We want to start from a shorter Makefile example than those given with SDK. For example the LifeTime example can be correctly compiled under Linux with this makefile : | ||
<pre> | <pre> | ||
Line 95: | Line 97: | ||
</pre> | </pre> | ||
This makefile is OS dependant. It only works under Linux. The makefiles provided with SDK are OS independent and then use more macros. We want now gives some details for each part of a makefile. | This makefile is OS dependant. It only works under Linux. The makefiles provided with SDK are OS independent and then use more macros. We want now gives some details for each part of a makefile. | ||
+ | |||
=Header file generation= | =Header file generation= | ||
+ | As [[UNO_automation_with_a_binary_%28executable%29#The_Compilation_Chain|already mentioned]], hpp files are constructed, not provided. | ||
==The Lifetime example== | ==The Lifetime example== | ||
We begin with this example because it's the simplest example. | We begin with this example because it's the simplest example. | ||
− | First Figure | + | |
+ | First Figure below demonstrates how to generate the required hdl and hpp files starting from a rdb file and idl files. You will probably easier understand the makefile if you know how works the cppumaker command. As an example we give : | ||
<pre> | <pre> | ||
$ cppumaker -Gc -BUCR some.idl <OOo>/program/types.rdb -OSomeWhere | $ cppumaker -Gc -BUCR some.idl <OOo>/program/types.rdb -OSomeWhere | ||
</pre> | </pre> | ||
− | + | ||
+ | [[Image:HeaderFileGene.png]] | ||
+ | |||
+ | The [http://udk.openoffice.org/common/man/tools.html#cppumaker cppumaker documentation] states | ||
* -O<path> path describes the root directory for the generated output. The output directory tree is generated under this directory. | * -O<path> path describes the root directory for the generated output. The output directory tree is generated under this directory. | ||
* -T<name> name specifies a type or a list of types. The output for this [t1;...] type is generated. If no '-T' option is specified, then output for all types is generated. | * -T<name> name specifies a type or a list of types. The output for this [t1;...] type is generated. If no '-T' option is specified, then output for all types is generated. | ||
* -B<name> name specifies the base node. | * -B<name> name specifies the base node. | ||
* -Gc generate only target files whose content will be changed. | * -Gc generate only target files whose content will be changed. | ||
+ | |||
+ | A question comes at first : how we know what hpp files are needed ? For the time being I can't answer this question in a general manner, but I hope to have partially answered in previous chapters. | ||
+ | The corresponding makefile part which generates all of the hpp files is shown below : | ||
+ | <pre> | ||
+ | COMPONENT_NAME=ProfUnoLifetime | ||
+ | DKREGISTRYNAME=/usr/lib/openoffice/program/types.rdb | ||
+ | PRJ=../../../.. | ||
+ | SETTINGS=$(PRJ)/settings | ||
+ | OUT_INC=$(PRJ)/LINUXexample.out/inc | ||
+ | OUT_COMP_INC=$(OUT_INC)/$(COMPONENT_NAME) | ||
+ | TYPES := \ | ||
+ | com.sun.star.uno.XNamingService \ | ||
+ | com.sun.star.uno.XComponentContext \ | ||
+ | com.sun.star.uno.XWeak \ | ||
+ | com.sun.star.uno.XAggregation \ | ||
+ | com.sun.star.lang.XMain \ | ||
+ | com.sun.star.lang.XMultiServiceFactory \ | ||
+ | com.sun.star.lang.XSingleComponentFactory \ | ||
+ | com.sun.star.lang.XTypeProvider \ | ||
+ | com.sun.star.lang.XComponent \ | ||
+ | com.sun.star.registry.XSimpleRegistry \ | ||
+ | com.sun.star.registry.XImplementationRegistration \ | ||
+ | com.sun.star.bridge.XBridgeFactory \ | ||
+ | com.sun.star.bridge.XUnoUrlResolver \ | ||
+ | com.sun.star.container.XHierarchicalNameAccess | ||
+ | |||
+ | TYPESLIST = $(foreach t,$(TYPES),-T$(t)) | ||
+ | GENHPPFILES = $(foreach t,$(TYPES),$(OUT_COMP_INC)/$(subst .,/,$(t)).hpp) | ||
+ | |||
+ | # Targets | ||
+ | .PHONY: ALL | ||
+ | ALL : ProUNOLifetimeExample | ||
+ | |||
+ | include $(SETTINGS)/stdtarget.mk | ||
+ | |||
+ | $(GENHPPFILES) : | ||
+ | -$(MKDIR) $(subst /,$(PS),$(@D)) | ||
+ | cppumaker -Gc -BUCR -O$(OUT_COMP_INC) $(TYPESLIST) $(DKREGISTRYNAME) | ||
+ | </pre> | ||
+ | Again MKDIR and PS indicates macros that seem to be undefined but they are defined in settings.mk file. | ||
+ | |||
+ | An other way to construct header files is to use a makefile and an other tool : xml2cmp. You can find an example in <OpenOffice.org1.1_SDK>/examples/cpp/remoteclient directory. | ||
+ | |||
+ | ==A more sophisticated example== | ||
+ | The hpp construction is not always so easy. This can occur every time you [[Constructing_Components|have a component]]. The problem in this case is the cppumaker tool is unable to generate a hpp file if its corresponding interface not registered. | ||
+ | |||
+ | [[Image:AddingTypes.png]] | ||
+ | |||
+ | As you can see in Figure above you have to use idlc to create an urd file. This file and the types.rdb files are used to create a rdb file with regmerge. After and only after cppumaker is able to generate the hpp file corresponding to the starting IDL file. A complete example is given in the makefile in . We give here what is done in a shell under Linux to see this construction in action : | ||
+ | <pre> | ||
+ | mkdir -p ../../../LINUXexample.out/misc/counter | ||
+ | idlc -I. -I../../../idl -O../../../LINUXexample.out/misc/counter XCountable.idl | ||
+ | idlc: compile 'XCountable.idl' ... | ||
+ | idlc: returned successful | ||
+ | Sun Microsystems (R) idlc Version 1.0 | ||
+ | |||
+ | mkdir -p ../../../LINUXexample.out/bin | ||
+ | rm -f ../../../LINUXexample.out/bin/counter.uno.rdb | ||
+ | regmerge ../../../LINUXexample.out/bin/counter.uno.rdb /UCR ../../../LINUXexample.out/misc/counter/XCountable.urd | ||
+ | regmerge ../../../LINUXexample.out/bin/counter.uno.rdb / "/usr/lib/openoffice/program/types.rdb" | ||
+ | mkdir -p ../../../LINUXexample.out/misc | ||
+ | rm -f ../../../LINUXexample.out/misc/cpp_counter_types.flag | ||
+ | cppumaker -Gc -BUCR -O../../../LINUXexample.out/inc/counter ../../../LINUXexample.out/bin/counter.uno.rdb | ||
+ | echo flagged > ../../../LINUXexample.out/misc/cpp_counter_types.flag | ||
+ | Here is the makefile corresponding part : | ||
+ | .... | ||
+ | $(OUT_COMP_GEN)/%.urd : %.idl | ||
+ | -$(MKDIR) $(subst /,$(PS),$(@D)) | ||
+ | idlc -I. -I$(IDL_DIR) -O$(OUT_COMP_GEN) $< | ||
+ | |||
+ | # This example type library will be extended by the office types | ||
+ | $(OUT_BIN)/%.rdb : $(GENURDFILES) | ||
+ | -$(MKDIR) $(subst /,$(PS),$(@D)) | ||
+ | -$(DEL) $(subst /,$(PS),$@) | ||
+ | regmerge $@ /UCR $(GENURDFILES) | ||
+ | regmerge $@ / $(DKREGISTRYNAME) | ||
+ | |||
+ | $(COMPONENT_TYPEFLAG) : $(COMPONENT_RDB) $(COMPONENT_XML) | ||
+ | -$(MKDIR) $(subst /,$(PS),$(@D)) | ||
+ | -$(DEL) $(subst /,$(PS),$(COMPONENT_TYPEFLAG)) | ||
+ | cppumaker -Gc -BUCR -O$(OUT_COMP_INC) $(TYPESLIST) $(COMPONENT_RDB) | ||
+ | echo flagged > $@ | ||
+ | ..... | ||
+ | </pre> | ||
+ | You are now ready to use gcc to compile your code. | ||
+ | |||
+ | =Compiling with gcc= | ||
+ | The compilation is achieved in two steps or more steps depending how many files we have to compile. The way is making object files first and then linking. | ||
+ | ==A two step compilation example== | ||
+ | We give first a two step compilation example. You can find such example in | ||
+ | <pre> <OpenOffice.org1.1_SDK>/examples/DevelopersGuide/ProfUNO/CppBinding</pre> | ||
+ | or | ||
+ | <pre><OpenOffice.org1.1_SDK>/examples/DevelopersGuide/ProfUNO/Lifetime</pre> | ||
+ | and probably elsewhere. | ||
+ | |||
+ | See the Figure below of the compilation chain corresponding to this two step process. | ||
+ | |||
+ | [[Image:TwoStep.png]] | ||
+ | |||
+ | To simplify our compilation chain figures we allways present this two step process like below when possible. | ||
+ | |||
+ | [[Image:TwoStep2.png]] | ||
+ | |||
+ | <pre> | ||
+ | $(OUT_COMP_OBJ)/%.$(OBJ_EXT) : %.cxx $(GENHPPFILES) | ||
+ | -$(MKDIR) $(subst /,$(PS),$(@D)) | ||
+ | $(CC) $(CC_FLAGS) $(CC_INCLUDES) -I$(OUT_COMP_INC) $(CC_DEFINES) $(CC_OUTPUT_SWITCH)$(subst /,$(PS),$@) $< | ||
+ | |||
+ | $(OUT_BIN)/%$(EXE_EXT) : $(OBJFILES) | ||
+ | -$(MKDIR) $(subst /,$(PS),$(@D)) | ||
+ | -$(MKDIR) $(subst /,$(PS),$(OUT_COMP_GEN)) | ||
+ | ifeq "$(OS)" "WIN" | ||
+ | $(LINK) $(EXE_LINK_FLAGS) /OUT:$@ /MAP:$(OUT_COMP_GEN)/$(subst $(EXE_EXT),.map,$(@F)) \ | ||
+ | $(OBJFILES) $(CPPUHELPERLIB) $(CPPULIB) $(SALHELPERLIB) $(SALLIB) $(STLPORTLIB) | ||
+ | else | ||
+ | $(LINK) $(EXE_LINK_FLAGS) $(LINK_LIBS) -o $@ $(OBJFILES) \ | ||
+ | $(CPPUHELPERLIB) $(CPPULIB) $(SALHELPERLIB) $(SALLIB) $(STLPORTLIB) $(STDC++LIB) | ||
+ | endif | ||
+ | </pre> | ||
+ | We don't use red color because again all is defined : CPPUHELPERLIB .... in settings.mk | ||
+ | |||
+ | As you can see linking is done with a lot of library : cppuhelperlib, cppulib, salhelperlib ... I want to mention here that in the Lifetime example I have removed all libraries but keeped cppuhelperlib and this example works properly. | ||
+ | |||
+ | ==A three step compilation example== | ||
+ | If you want to use helper as mentioned in [[Constructing_Helpers#Reflection_Helper|Reflection helper]], you have to manage such construction. I mean construct an object file for the Helper and then construct the complete program. Here is a short description of the compilation chain | ||
+ | |||
+ | [[Image:ThreeStep.png]] | ||
+ | |||
+ | where you see exactly the three steps compilation. | ||
+ | |||
+ | We give a part of an other short makefile used to compile a binary with an helper : | ||
+ | <pre> | ||
+ | $(OUT_COMP_OBJ)/$(OBJFILE) : $(CXXFILE) $(GENHPPFILES) $(HELPER).hpp | ||
+ | -mkdir -p $(subst /,$(PS),$(@D)) | ||
+ | gcc $(CC_FLAGS) $(CC_INCLUDES) -I. -I/usr/include -I$(OUT_COMP_INC)/examples \ | ||
+ | -I../../../../include -I$(OUT_COMP_INC) $(CC_DEFINES) -o$(OUT_COMP_OBJ)/$(OBJFILE) $(CXXFILE) | ||
+ | |||
+ | $(OUT_COMP_OBJ)/$(HELPER).o : $(HELPER).cxx $(HELPER).hpp | ||
+ | -mkdir -p $(OUT_COMP_OBJ)/ | ||
+ | gcc $(CC_FLAGS) $(CC_INCLUDES) -I. -I/usr/include -I$(OUT_COMP_INC)/examples \ | ||
+ | -I../../../../include -I$(OUT_COMP_INC) $(CC_DEFINES) -o$(OUT_COMP_OBJ)/$(HELPER).o $(HELPER).cxx | ||
+ | |||
+ | |||
+ | $(OUT_COMP_BIN)/$(OUTBIN) : $(OUT_COMP_OBJ)/$(OBJFILE) $(OUT_COMP_OBJ)/$(HELPER).o | ||
+ | -mkdir -p $(OUT_COMP_BIN) | ||
+ | gcc -Wl -export-dynamic -L../../../../LINUXexample.out/lib -L../../../../linux/lib \ | ||
+ | -L/usr/lib/openoffice/program $(OUT_COMP_OBJ)/$(HELPER).o \ | ||
+ | -o$(OUT_COMP_BIN)/$(OUTBIN) $(OUT_COMP_OBJ)/$(OBJFILE) -lcppuhelpergcc3 -lcppu \ | ||
+ | -lsalhelpergcc3 -lsal -lstlport_gcc | ||
+ | </pre> | ||
+ | where we see a first compilation of all cxx files into object files and a link (with gcc). Note that this makefile is OS dependant and works only on Linux systems. Here is what you see in a shell when using this kind of MakeFile : | ||
+ | |||
+ | <pre> | ||
+ | gcc -c -O -fpic -fno-rtti -I. -I/usr/include -I../../../../LINUXexample.out/inc/examples \ | ||
+ | -I../../../../include -I../../../../LINUXexample.out/inc -DUNX -DGCC -DLINUX -DCPPU_ENV=gcc3 -o../../../../LINUXexample.out/obj/office_connect.o office_connect.cxx | ||
+ | mkdir -p ../../../../LINUXexample.out/obj/ | ||
+ | gcc -c -O -fpic -fno-rtti -I. -I/usr/include -I../../../../LINUXexample.out/inc/examples \ | ||
+ | -I../../../../include -I../../../../LINUXexample.out/inc -DUNX -DGCC -DLINUX -DCPPU_ENV=gcc3 -o../../../../LINUXexample.out/obj/ReflectionHelper.o ReflectionHelper.cxx | ||
+ | mkdir -p ../../../../LINUXexample.out/bin | ||
+ | gcc -Wl -export-dynamic -L../../../../LINUXexample.out/lib -L../../../../linux/lib -L/usr/lib/openoffice/program \ | ||
+ | ../../../../LINUXexample.out/obj/ReflectionHelper.o \ | ||
+ | -o../../../../LINUXexample.out/bin/office_connect ../../../../LINUXexample.out/obj/office_connect.o -lcppuhelpergcc3 -lcppu -lsalhelpergcc3 -lsal -lstlport_gcc | ||
+ | </pre> | ||
+ | |||
+ | The complete MakeFile is [[MakeFile#Office_connect_with_a_helper|given here]]. | ||
+ | |||
+ | ==A four step compilation example== | ||
+ | We encounter a four step example in <OpenOffice.org1.1_SDK>/examples/cpp/counter where two cxx files are compiled. The first counter.cxx is compiled first as conter.o and after as counter.uno.so and the second file countermain.cxx is compiled as countermain.o and then as countermain, a binary executable file. | ||
+ | The Figure below shows us what is new in this makefile : constructing a dynamic library (top of the figure). | ||
+ | |||
+ | [[Image:FourStep.png]] | ||
+ | |||
+ | Here we give the makefile example : | ||
+ | <pre> | ||
+ | .... | ||
+ | COMPONENT_NAME=counter | ||
+ | COMPONENT_IMPL_NAME=$(COMPONENT_NAME).uno.$(SHAREDLIB_EXT) | ||
+ | COMPONENT_IMPL=$(SHAREDLIB_OUT)/$(COMPONENT_IMPL_NAME) | ||
+ | COMPONENT_RDB_NAME = $(COMPONENT_NAME).uno.rdb | ||
+ | COMPONENT_RDB = $(OUT_BIN)/$(COMPONENT_RDB_NAME) | ||
+ | ..... | ||
+ | ifeq "$(OS)" "WIN" | ||
+ | $(SHAREDLIB_OUT)/%.$(SHAREDLIB_EXT) : $(SLOFILES) $(OUT_COMP_GEN)/%.def | ||
+ | -$(MKDIR) $(subst /,$(PS),$(@D)) | ||
+ | -$(MKDIR) $(subst /,$(PS),$(OUT_COMP_GEN)) | ||
+ | $(LINK) $(LIBRARY_LINK_FLAGS) /OUT:$@ /MAP:$(OUT_COMP_GEN)/$(subst $(SHAREDLIB_EXT),map,$(@F)) \ | ||
+ | /DEF:$(OUT_COMP_GEN)/$(subst $(SHAREDLIB_EXT),def,$(@F)) $(SLOFILES) \ | ||
+ | $(CPPUHELPERLIB) $(CPPULIB) $(SALLIB) $(STLPORTLIB) msvcrt.lib kernel32.lib | ||
+ | else | ||
+ | $(SHAREDLIB_OUT)/%.$(SHAREDLIB_EXT) : $(SLOFILES) | ||
+ | -$(MKDIR) $(subst /,$(PS),$(@D)) | ||
+ | $(LINK) $(LIBRARY_LINK_FLAGS) $(LINK_LIBS) -o $@ $^\ | ||
+ | $(CPPUHELPERLIB) $(CPPULIB) $(SALLIB) $(STLPORTLIB) $(STC++LIB) | ||
+ | endif | ||
+ | </pre> | ||
+ | Perhaps is it more easy to understand with showing what happens with this makefile part in a Linux shell : | ||
+ | <pre> | ||
+ | gcc -c -O -fpic -fno-rtti -I. -I/usr/include -I../../../LINUXexample.out/inc/examples -I../../../include -I../../../LINUXexample.out/inc/counter -DUNX -DGCC -DLINUX -DCPPU_ENV=gcc3 -o../../../LINUXexample.out/slo/counter/counter.o counter.cxx | ||
+ | mkdir -p ../../../LINUXexample.out/lib | ||
+ | gcc -shared '-Wl,-rpath,$ORIGIN' -L../../../LINUXexample.out/lib -L../../../linux/lib -L/usr/lib/openoffice/program -o ../../../LINUXexample.out/lib/counter.uno.so ../../../LINUXexample.out/slo/counter/counter.o\ | ||
+ | -lcppuhelpergcc3 -lcppu -lsal -lstlport_gcc | ||
+ | </pre> | ||
+ | We want to show now other parts of the makefile. | ||
+ | |||
+ | =Use of pkgchk (deprecated see unopkg)= | ||
+ | The binary tool pkgchk is useful when designing a component. The two steps involved with the pkgchk are : | ||
+ | *constructing a zip file | ||
+ | *installing the zip file | ||
+ | |||
+ | Here is a makefile example managing this situation : | ||
+ | <pre> | ||
+ | $(OUT_BIN)/%.zip : $(SHAREDLIB_OUT)/%.$(SHAREDLIB_EXT) $(OUT_COMP_GEN)/%.rdb | ||
+ | -$(MKDIR) $(subst /,$(PS),$(@D)) | ||
+ | -$(MKDIR) $(subst /,$(PS),$(OUT_COMP_GEN)/$(PACKAGE_LIB_DIR)) | ||
+ | $(COPY) $(subst /,$(PS),$<) $(subst /,$(PS),$(OUT_COMP_GEN)/$(PACKAGE_LIB_DIR)) | ||
+ | cd $(subst /,$(PS),$(OUT_COMP_GEN)) && jar cvfM ../../bin/$(@F) $(basename $(@F)).rdb $(PACKAGE_LIB_DIR)/$(<F) | ||
+ | |||
+ | $(REGISTERFLAG) : $(COMPONENT_PACKAGE) | ||
+ | ifneq "$(SDK_AUTO_DEPLOYMENT)" "" | ||
+ | -$(MKDIR) $(subst /,$(PS),$(@D)) | ||
+ | -$(DEL) $(subst /,$(PS),$@) | ||
+ | $(DEPLOYTOOL) $(COMPONENT_PACKAGE_URL) | ||
+ | @echo flagged > $(subst /,$(PS),$@) | ||
+ | else | ||
+ | @echo -------------------------------------------------------------------------------- | ||
+ | @echo If you want to install your component automatically, please set the environment | ||
+ | @echo variable SDK_AUTO_DEPLOYMENT = YES. But note that auto deployment is only | ||
+ | @echo possible if no office instance is running. | ||
+ | @echo -------------------------------------------------------------------------------- | ||
+ | endif | ||
+ | </pre> | ||
+ | =The two last parts : execution and cleaning= | ||
+ | We have now to execute. Something like | ||
+ | <pre> | ||
+ | ProUNOLifetimeExamples : $(OUT_BIN)/$(COMPONENT_NAME)$(EXE_EXT) | ||
+ | @echo -------------------------------------------------------------------------------- | ||
+ | @echo Please use one of the following commands to execute the examples! | ||
+ | @echo - | ||
+ | @echo make ProfUnoLifetime.runexe | ||
+ | @echo -------------------------------------------------------------------------------- | ||
+ | |||
+ | %.runexe: $(OUT_BIN)/%$(EXE_EXT) | ||
+ | cd $(subst /,$(PS),$(OUT_BIN)) && $(basename $@) | ||
+ | </pre> | ||
+ | which works well. The cleaning part is not complicated too : | ||
+ | <pre> | ||
+ | .PHONY: clean | ||
+ | clean : | ||
+ | -$(DELRECURSIVE) $(subst /,$(PS),$(OUT_COMP_INC)) | ||
+ | -$(DELRECURSIVE) $(subst /,$(PS),$(OUT_COMP_GEN)) | ||
+ | -$(DELRECURSIVE) $(subst /,$(PS),$(OUT_COMP_OBJ)) | ||
+ | -$(DEL) $(subst /,$(PS),$(OUT_BIN)/$(COMPONENT_NAME).*) | ||
+ | </pre> | ||
+ | |||
+ | = Complete MakeFile examples = | ||
+ | We give first a makefile I have used when using helper(s). | ||
+ | |||
+ | ==Office_connect with a helper== | ||
+ | Th use of a Reflection Helper has been explained [[Constructing_Helpers#Reflection_Helper|in the corresponding section]]. | ||
+ | |||
+ | Here is the complete makefile : | ||
+ | <pre> | ||
+ | # very simple makefile | ||
+ | HELPER = ReflectionHelper | ||
+ | CXXFILE = office_connect.cxx | ||
+ | OBJFILE = office_connect.o | ||
+ | OUTBIN = office_connect | ||
+ | OUT_COMP_INC = ../../../../LINUXexample.out/inc | ||
+ | OUT_COMP_OBJ = ../../../../LINUXexample.out/obj | ||
+ | OUT_COMP_BIN = ../../../../LINUXexample.out/bin | ||
+ | COMPONENT_RDB = $(OUT_COMP_BIN)/office_connect.rdb | ||
+ | CC_FLAGS = -c -O -fpic -fno-rtti | ||
+ | CC_DEFINES = -DUNX -DGCC -DLINUX -DCPPU_ENV=gcc3 | ||
+ | PS = / | ||
+ | TYPES := \ | ||
+ | com.sun.star.uno.XNamingService \ | ||
+ | ....\ | ||
+ | com.sun.star.xml.sax.SAXException | ||
+ | |||
+ | TYPESLIST = $(foreach t,$(TYPES),-T$(t)) | ||
+ | GENHPPFILES = $(foreach t,$(TYPES),$(OUT_COMP_INC)/$(subst .,/,$(t)).hpp) | ||
+ | |||
+ | ALL : \ | ||
+ | ProUNOCppBindingExample | ||
+ | |||
+ | |||
+ | #office_connectrc is provided with SDK | ||
+ | $(OUT_COMP_BIN)/office_connectrc : office_connectrc | ||
+ | -mkdir -p $(OUT_COMP_BIN) | ||
+ | cp office_connectrc $(OUT_COMP_BIN)/office_connectrc | ||
+ | |||
+ | $(COMPONENT_RDB) : | ||
+ | -mkdir -p $(OUT_COMP_BIN) | ||
+ | regmerge $(COMPONENT_RDB) / "/usr/lib/openoffice/program/types.rdb" | ||
+ | @echo -------------------------------------------------------------------------------- | ||
+ | @echo Register necessary runtime components in $(COMPONENT_RDB) | ||
+ | @echo -------------------------------------------------------------------------------- | ||
+ | regcomp -register -r $(COMPONENT_RDB) -c connector.uno.so | ||
+ | regcomp -register -r $(COMPONENT_RDB) -c remotebridge.uno.so | ||
+ | regcomp -register -r $(COMPONENT_RDB) -c bridgefac.uno.so | ||
+ | regcomp -register -r $(COMPONENT_RDB) -c uuresolver.uno.so | ||
+ | # @echo bla > $@ | ||
+ | |||
+ | $(GENHPPFILES) : $(subst /,$(PS),$(@D)) | ||
+ | mkdir -p $(subst /,$(PS),$(@D)) | ||
+ | cppumaker -Gc -BUCR -O$(OUT_COMP_INC) $(TYPESLIST) "/usr/lib/openoffice/program/types.rdb" | ||
+ | |||
+ | $(OUT_COMP_OBJ)/$(OBJFILE) : $(CXXFILE) $(GENHPPFILES) $(HELPER).hpp | ||
+ | -mkdir -p $(subst /,$(PS),$(@D)) | ||
+ | gcc $(CC_FLAGS) $(CC_INCLUDES) -I. -I/usr/include -I$(OUT_COMP_INC)/examples \ | ||
+ | -I../../../../include -I$(OUT_COMP_INC) $(CC_DEFINES) -o$(OUT_COMP_OBJ)/$(OBJFILE) $(CXXFILE) | ||
+ | |||
+ | $(OUT_COMP_OBJ)/$(HELPER).o : $(HELPER).cxx $(HELPER).hpp | ||
+ | -mkdir -p $(OUT_COMP_OBJ)/ | ||
+ | gcc $(CC_FLAGS) $(CC_INCLUDES) -I. -I/usr/include -I$(OUT_COMP_INC)/examples \ | ||
+ | -I../../../../include -I$(OUT_COMP_INC) $(CC_DEFINES) -o$(OUT_COMP_OBJ)/$(HELPER).o $(HELPER).cxx | ||
+ | |||
+ | |||
+ | $(OUT_COMP_BIN)/$(OUTBIN) : $(OUT_COMP_OBJ)/$(OBJFILE) $(OUT_COMP_OBJ)/$(HELPER).o | ||
+ | -mkdir -p $(OUT_COMP_BIN) | ||
+ | gcc -Wl -export-dynamic -L../../../../LINUXexample.out/lib -L../../../../linux/lib -L/usr/lib/openoffice/program \ | ||
+ | $(OUT_COMP_OBJ)/$(HELPER).o \ | ||
+ | -o$(OUT_COMP_BIN)/$(OUTBIN) $(OUT_COMP_OBJ)/$(OBJFILE) -lcppuhelpergcc3 -lcppu -lsalhelpergcc3 -lsal -lstlport_gcc | ||
+ | |||
+ | |||
+ | ProUNOCppBindingExample : $(OUT_COMP_BIN)/$(OUTBIN) $(OUT_COMP_BIN)/office_connectrc | ||
+ | @echo -------------------------------------------------------------------------------- | ||
+ | @echo Please use one of the following commands to execute the examples! | ||
+ | @echo | ||
+ | @echo make office_connect.run | ||
+ | @echo -------------------------------------------------------------------------------- | ||
+ | |||
+ | office_connect.run : $(OUT_COMP_BIN)/$(OUTBIN) $(OUT_COMP_BIN)/office_connectrc | ||
+ | cd $(OUT_COMP_BIN) && $(OUTBIN) | ||
+ | |||
+ | </pre> | ||
+ | |||
+ | =Windows Makefile= | ||
+ | Redrgreen has provided a windows makefile in the OOoForum. | ||
+ | To do : study [http://www.oooforum.org/forum/viewtopic.phtml?p=43698&highlight=#43698 redrgreen makefile]. | ||
+ | |||
+ | ==The include part== | ||
+ | <pre> | ||
+ | ################################################################################# | ||
+ | # | ||
+ | # makefile_wxoo.mk | ||
+ | # ND 06-05-2004 | ||
+ | # | ||
+ | ################################################################################# | ||
+ | |||
+ | MKDIR = mkdir | ||
+ | DEL = del | ||
+ | CXX = cl | ||
+ | LINK = link | ||
+ | CAT=type | ||
+ | RM = rm | ||
+ | RMDIR = rmdir | ||
+ | WINDRES = Rc | ||
+ | |||
+ | WXWIN = c:\wx242msw | ||
+ | PRJ = c:/oo_sdk | ||
+ | IDL_DIR=$(PRJ)/idl | ||
+ | |||
+ | CXXINCLUDES = -I. -I$(PRJ)/include -I$(WXWIN)/lib/mswd -I$(WXWIN)/include -I$(WXWIN)/contrib/include -I$(WXWIN)/src/regex -I$(WXWIN)/src/png -I$(WXWIN)/src/zlib -I$(WXWIN)/src/jpeg -I$(WXWIN)/src/tiff | ||
+ | CXXFLAGS = -c -W2 -nologo /Zm500 | ||
+ | CXXDEFINES = -DWIN32 -D__WIN32__ -D_WINDOWS -DWINVER=0x0400 /D__WIN95__ -DSTRICT /Zi /D__WXDEBUG__ /D__WXMSW__ /Od /Gy /MDd /D__WINDOWS__ /GX- | ||
+ | CXXOUTPUT_SWITCH = -Fo | ||
+ | |||
+ | EXE_LINK_FLAGS= /DEBUG:notmapped,full /DEBUGTYPE:cv /NOLOGO /SUBSYSTEM:windows,4.0 /MACHINE:X86 | ||
+ | |||
+ | SALLIB=isal.lib | ||
+ | CPPULIB=icppu.lib | ||
+ | CPPUHELPERLIB=icppuhelper.lib | ||
+ | SALHELPERLIB=isalhelper.lib | ||
+ | STLPORTLIB=stlport_vc7.lib | ||
+ | |||
+ | RUNTIMELIBS = $(WXWIN)\lib\wxmswd.lib kernel32.lib user32.lib gdi32.lib comdlg32.lib winspool.lib winmm.lib shell32.lib oldnames.lib comctl32.lib odbc32.lib ole32.lib oleaut32.lib uuid.lib rpcrt4.lib advapi32.lib wsock32.lib $(WXWIN)\lib\regexd.lib $(WXWIN)\lib\pngd.lib $(WXWIN)\lib\zlibd.lib $(WXWIN)\lib\jpegd.lib $(WXWIN)\lib\tiffd.lib | ||
+ | |||
+ | |||
+ | #substitute the extension .urd for .idl in the variable GENURDFILES | ||
+ | GENURDFILES = $(patsubst %.idl,%.urd,$(IDLFILES)) | ||
+ | |||
+ | #substitute double \\ for single \ in the path variable DKREG... | ||
+ | DKREGISTRYNAME=$(subst \\,\,"$(OFFICE_PROGRAM_PATH)\types.rdb") | ||
+ | |||
+ | COMPONENT_TYPEFLAG = cpp_$(COMPONENT_NAME)_types.flag | ||
+ | COMPONENT_XML=$(COMPONENT_NAME).uno.xml | ||
+ | COMPONENT_ENV_FLAG = cpp_$(COMPONENT_NAME)_prepare_env.flag | ||
+ | |||
+ | #__________________________________________________________________________________ | ||
+ | |||
+ | ################################################################################# | ||
+ | # | ||
+ | # using the list of types we just made we now have to prpend a -T to each one | ||
+ | # we do this using the foreach command of make as follows | ||
+ | # the variable t represents each type in the list $(TYPES) | ||
+ | # and foreach one we prepend -T storing the result in TYPELIST | ||
+ | # | ||
+ | ################################################################################# | ||
+ | |||
+ | |||
+ | TYPESLIST = $(foreach t,$(TYPES),-T$(t)) | ||
+ | GENHPPFILES = $(foreach t,$(TYPES),$(subst .,/,$(t)).hpp) | ||
+ | |||
+ | |||
+ | #__________________________________________________________________________________ | ||
+ | |||
+ | ################################################################# | ||
+ | # | ||
+ | # delete any existing version of this file before merging it | ||
+ | # remerge the reg db file under the key /UCR | ||
+ | # comment out if only using the main registry | ||
+ | # remerge the reg db file we just made with the one for OO | ||
+ | # # | ||
+ | ################################################################# | ||
+ | %.rdb : #$(GENURDFILES) | ||
+ | -$(DEL) $@ | ||
+ | #comment out following for non components | ||
+ | # -regmerge $@ /UCR $(GENURDFILES) | ||
+ | -regmerge $@ / $(DKREGISTRYNAME) | ||
+ | |||
+ | #________________________________________________________________________________ | ||
+ | |||
+ | ################################################################# | ||
+ | # | ||
+ | # use this for non components example | ||
+ | # | ||
+ | ################################################################# | ||
+ | $(GENHPPFILES) : | ||
+ | # -$(MKDIR) $(subst /,$(PS),$(@D)) | ||
+ | cppumaker -Gc -BUCR -O. $(TYPESLIST) $(DKREGISTRYNAME) | ||
+ | |||
+ | #_________________________________________________________________________________ | ||
+ | |||
+ | |||
+ | ################################################################# | ||
+ | # | ||
+ | # Register the components we are going to use | ||
+ | # Comment out if building a component | ||
+ | # | ||
+ | ################################################################# | ||
+ | $(COMPONENT_ENV_FLAG) : $(COMPONENT_RDB_NAME) | ||
+ | -$(DEL) $@ | ||
+ | @echo -------------------------------------------------------------------------------- | ||
+ | @echo Register necessary runtime components in $(COMPONENT_RDB_NAME) | ||
+ | @echo -------------------------------------------------------------------------------- | ||
+ | regcomp -register -r $(COMPONENT_RDB_NAME) -c connector.uno.dll | ||
+ | regcomp -register -r $(COMPONENT_RDB_NAME) -c remotebridge.uno.dll | ||
+ | regcomp -register -r $(COMPONENT_RDB_NAME) -c bridgefac.uno.dll | ||
+ | regcomp -register -r $(COMPONENT_RDB_NAME) -c uuresolver.uno.dll | ||
+ | @echo bla > $@ | ||
+ | |||
+ | #___________________________________________________________________________ | ||
+ | |||
+ | .PHONY: clean | ||
+ | clean : | ||
+ | -$(RM) *.o | ||
+ | -$(RM) *.obj | ||
+ | -$(RM) *.exe | ||
+ | -$(RM) *.res | ||
+ | -$(RM) *.map | ||
+ | -$(RM) *.ilk | ||
+ | -$(RM) *.pdb | ||
+ | -$(RM) *.dll | ||
+ | -$(RM) *.lib | ||
+ | -$(RM) *.rdb | ||
+ | -$(RM) *.flag | ||
+ | -$(RMDIR) /S /Q com | ||
+ | -$(RMDIR) /S /Q foo | ||
+ | </pre> | ||
+ | |||
+ | and the makefile now. | ||
+ | ==MakeFile part== | ||
+ | <pre> | ||
+ | ############################################################################# | ||
+ | # | ||
+ | # projectmakefile.mk | ||
+ | # ND 07-05-2004 | ||
+ | # | ||
+ | ############################################################################# | ||
+ | |||
+ | |||
+ | OUT = #the out directory | ||
+ | TARGET = #the target file name goes here without extension | ||
+ | OBJFILES = $(patsubst %.cpp,%.obj,$(TARGETS)) | ||
+ | OBJECTS = $(TARGET).obj #include all object files here | ||
+ | COMPONENT_NAME = ProfUnoCppBinding | ||
+ | COMPONENT_RDB_NAME = $(TARGET).rdb | ||
+ | PROJECT_NAME = #the project name goes here | ||
+ | |||
+ | |||
+ | TYPES := \ | ||
+ | com.sun.star.uno.XNamingService \ | ||
+ | #the rest of your types go here | ||
+ | |||
+ | # if we are using nmake uncomment the following line | ||
+ | #!INCLUDE ../makefile_wxoo.mk | ||
+ | |||
+ | All: $(PROJECT_NAME) | ||
+ | |||
+ | # if we are using gnu make uncomment the following line | ||
+ | include ../makefile_wxoo.mk | ||
+ | |||
+ | |||
+ | #________________________________________________________________________________ | ||
+ | |||
+ | # compile the object files | ||
+ | %.obj: %.cpp $(GENHPPFILES) #$(COMPONENT_TYPEFLAG) | ||
+ | $(CXX) $(CXXFLAGS) $(CXXINCLUDES) $(CXXDEFINES) $(CXXOUTPUT_SWITCH)$@ $< | ||
+ | |||
+ | #________________________________________________________________________________ | ||
+ | |||
+ | #comment out dll name if not building a component | ||
+ | #$(COMPONENT_NAME).uno.dll | ||
+ | %.exe : %.obj $(OBJECTS) $(TARGET).res | ||
+ | $(LINK) $(EXE_LINK_FLAGS) /OUT:$@ /MAP:$(basename $(@F)).map \ | ||
+ | $(OBJECTS) $(TARGET).res $(CPPUHELPERLIB) $(CPPULIB) $(SALHELPERLIB) $(SALLIB) $(STLPORTLIB) $(RUNTIMELIBS) | ||
+ | |||
+ | #________________________________________________________________________________ | ||
+ | |||
+ | |||
+ | $(TARGET).res: $(TARGET).rc | ||
+ | $(WINDRES) -r /i$(WXWIN)\include /i$(WXWIN)\contrib\include \ | ||
+ | -fo$(TARGET).res $(TARGET).rc | ||
+ | |||
+ | #_________________________________________________________________________________ | ||
+ | |||
+ | |||
+ | $(PROJECT_NAME) : $(TARGET).exe $(COMPONENT_ENV_FLAG) $(TARGET).res | ||
+ | @echo -------------------------------------------------------------------------------- | ||
+ | @echo Please use the following commands to execute the example! | ||
+ | @echo - | ||
+ | @echo $(TARGET) | ||
+ | @echo -------------------------------------------------------------------------------- | ||
+ | </pre> | ||
+ | |||
+ | =Conclusion : your own MakeFile= | ||
+ | |||
+ | =Home Page= | ||
+ | |||
+ | {{Template:Home_Page}} | ||
+ | |||
+ | =See also= |
Latest revision as of 21:55, 13 July 2018
It is mportant for you to have skill on necessary tools for UNO development.
Makefile structure
We will artificially divide the makefile in four parts :
- the setting part
- the compilation part
- the execute part
- the clean part
All makefiles provided with SDK have this structure. We can find very different compilation parts with each example provided. In this chapter we only discuss the setting part. If you have a look on the <OOSDK> directory you will see a « settings » directory. You have to use this directory if you want OS independent makefile. In general this is done with something like :
COMPONENT_NAME=ProfUnoLifetime DKREGISTRYNAME=/usr/lib/openoffice/program/types.rdb PRJ=../../../.. SETTINGS=$(PRJ)/settings include $(SETTINGS)/settings.mk include $(SETTINGS)/std.mk include $(SETTINGS)/dk.mk # Define non-platform/compiler specific settings COMPONENT_NAME=ProfUnoLifetime OUT_COMP_INC=$(OUT_INC)/$(COMPONENT_NAME) OUT_COMP_GEN=$(OUT_MISC)/$(COMPONENT_NAME) OUT_COMP_OBJ=$(OUT_OBJ)/$(COMPONENT_NAME) CXXFILES = ProfUnoLifetime.cxx OBJFILES = $(patsubst %.cxx,$(OUT_COMP_OBJ)/%.$(OBJ_EXT),$(CXXFILES))
The third line is directory-dependent : where your makefile lie and how do you reach the setting directory will change this line and the following, pointing toward the « settings » directory. Of course an other way is to use an absolute URL but portability is worse. The goal of other lines is to prepare compilation. We have let in red macros that seem not to be defined at first glance. But if you have a look to std.mk you will find the lacking definitions even if this files introduce other undefined macros which are in fact defined in settings.mk
Starting with Lifetime example
The lifetime example is introduced in (page ). The file used to create this example is find in « <OOSDK>/examples/DevelopersGuide/ProfUNO/Lifetime ». The Lifetime directory contains a complicated makefile able of creating either a Java or a C++ example. We focus only on C++ code.
A shorter Makefile
We want to start from a shorter Makefile example than those given with SDK. For example the LifeTime example can be correctly compiled under Linux with this makefile :
# very simple makefile CXXFILE = Test_Process.cxx OBJFILE = Test_Process.o OUTBIN = Test_Process OUT_COMP_INC = ../../../../LINUXexample.out/inc/ProfUnoLifetime OUT_COMP_OBJ = ../../../../LINUXexample.out/obj/ProfUnoLifetime OUT_COMP_BIN = ../../../../LINUXexample.out/bin CC_FLAGS = -c -O -fpic -fno-rtti CC_DEFINES = -DUNX -DGCC -DLINUX -DCPPU_ENV=gcc3 PS = / TYPES := \ com.sun.star.uno.XNamingService \ com.sun.star.uno.XComponentContext \ com.sun.star.uno.XWeak \ com.sun.star.uno.XAggregation \ com.sun.star.lang.XMain \ com.sun.star.lang.XMultiServiceFactory \ com.sun.star.lang.XSingleComponentFactory \ com.sun.star.lang.XTypeProvider \ com.sun.star.lang.XComponent \ com.sun.star.registry.XSimpleRegistry \ com.sun.star.registry.XImplementationRegistration \ com.sun.star.bridge.XBridgeFactory \ com.sun.star.bridge.XUnoUrlResolver \ com.sun.star.drawing.XDrawPage \ com.sun.star.container.XHierarchicalNameAccess TYPESLIST = $(foreach t,$(TYPES),-T$(t)) GENHPPFILES = $(foreach t,$(TYPES),$(OUT_COMP_INC)/$(subst .,/,$(t)).hpp) ALL : \ ProUNOLifetimeExamples $(GENHPPFILES) : $(subst /,$(PS),$(@D)) mkdir -p $(OUT_COMP_INC)/$(subst /,$(PS),$(@D)) cppumaker -Gc -BUCR -O$(OUT_COMP_INC) $(TYPESLIST) "/usr/lib/openoffice/program/types.rdb" $(OUT_COMP_OBJ)/$(OBJFILE) : $(CXXFILE) $(GENHPPFILES) mkdir -p $(OUT_COMP_OBJ)/$(subst /,$(PS),$(@D)) gcc $(CC_FLAGS) $(CC_INCLUDES) -I. \ -I/usr/include -I../../../../LINUXexample.out/inc/examples \ -I../../../../include -I../../../../LINUXexample.out/inc/ProfUnoLifetime $(CC_DEFINES) \ -o$(OUT_COMP_OBJ)/$(OBJFILE) $(CXXFILE) $(OUT_COMP_BIN)/$(OUTBIN) : $(OUT_COMP_OBJ)/$(OBJFILE) mkdir -p $(OUT_COMP_BIN) gcc -Wl -export-dynamic -L../../../../LINUXexample.out/lib -L../../../../linux/lib \ -L/usr/lib/openoffice/program -o$(OUT_COMP_BIN)/$(OUTBIN) \ $(OUT_COMP_OBJ)/$(OBJFILE) -lcppuhelpergcc3 -lcppu -lsalhelpergcc3 -lsal -lstlport_gcc ProUNOLifetimeExamples : $(OUT_COMP_BIN)/$(OUTBIN) @echo -------------------------------------------------------------------------------- @echo Please use one of the following commands to execute the examples! @echo @echo make ProfUnoLifetime.run @echo -------------------------------------------------------------------------------- ProfUnoLifetime.run : $(OUT_COMP_BIN)/$(OUTBIN) cd $(OUT_COMP_BIN) && $(OUTBIN)
This makefile is OS dependant. It only works under Linux. The makefiles provided with SDK are OS independent and then use more macros. We want now gives some details for each part of a makefile.
Header file generation
As already mentioned, hpp files are constructed, not provided.
The Lifetime example
We begin with this example because it's the simplest example.
First Figure below demonstrates how to generate the required hdl and hpp files starting from a rdb file and idl files. You will probably easier understand the makefile if you know how works the cppumaker command. As an example we give :
$ cppumaker -Gc -BUCR some.idl <OOo>/program/types.rdb -OSomeWhere
The cppumaker documentation states
- -O<path> path describes the root directory for the generated output. The output directory tree is generated under this directory.
- -T<name> name specifies a type or a list of types. The output for this [t1;...] type is generated. If no '-T' option is specified, then output for all types is generated.
- -B<name> name specifies the base node.
- -Gc generate only target files whose content will be changed.
A question comes at first : how we know what hpp files are needed ? For the time being I can't answer this question in a general manner, but I hope to have partially answered in previous chapters. The corresponding makefile part which generates all of the hpp files is shown below :
COMPONENT_NAME=ProfUnoLifetime DKREGISTRYNAME=/usr/lib/openoffice/program/types.rdb PRJ=../../../.. SETTINGS=$(PRJ)/settings OUT_INC=$(PRJ)/LINUXexample.out/inc OUT_COMP_INC=$(OUT_INC)/$(COMPONENT_NAME) TYPES := \ com.sun.star.uno.XNamingService \ com.sun.star.uno.XComponentContext \ com.sun.star.uno.XWeak \ com.sun.star.uno.XAggregation \ com.sun.star.lang.XMain \ com.sun.star.lang.XMultiServiceFactory \ com.sun.star.lang.XSingleComponentFactory \ com.sun.star.lang.XTypeProvider \ com.sun.star.lang.XComponent \ com.sun.star.registry.XSimpleRegistry \ com.sun.star.registry.XImplementationRegistration \ com.sun.star.bridge.XBridgeFactory \ com.sun.star.bridge.XUnoUrlResolver \ com.sun.star.container.XHierarchicalNameAccess TYPESLIST = $(foreach t,$(TYPES),-T$(t)) GENHPPFILES = $(foreach t,$(TYPES),$(OUT_COMP_INC)/$(subst .,/,$(t)).hpp) # Targets .PHONY: ALL ALL : ProUNOLifetimeExample include $(SETTINGS)/stdtarget.mk $(GENHPPFILES) : -$(MKDIR) $(subst /,$(PS),$(@D)) cppumaker -Gc -BUCR -O$(OUT_COMP_INC) $(TYPESLIST) $(DKREGISTRYNAME)
Again MKDIR and PS indicates macros that seem to be undefined but they are defined in settings.mk file.
An other way to construct header files is to use a makefile and an other tool : xml2cmp. You can find an example in <OpenOffice.org1.1_SDK>/examples/cpp/remoteclient directory.
A more sophisticated example
The hpp construction is not always so easy. This can occur every time you have a component. The problem in this case is the cppumaker tool is unable to generate a hpp file if its corresponding interface not registered.
As you can see in Figure above you have to use idlc to create an urd file. This file and the types.rdb files are used to create a rdb file with regmerge. After and only after cppumaker is able to generate the hpp file corresponding to the starting IDL file. A complete example is given in the makefile in . We give here what is done in a shell under Linux to see this construction in action :
mkdir -p ../../../LINUXexample.out/misc/counter idlc -I. -I../../../idl -O../../../LINUXexample.out/misc/counter XCountable.idl idlc: compile 'XCountable.idl' ... idlc: returned successful Sun Microsystems (R) idlc Version 1.0 mkdir -p ../../../LINUXexample.out/bin rm -f ../../../LINUXexample.out/bin/counter.uno.rdb regmerge ../../../LINUXexample.out/bin/counter.uno.rdb /UCR ../../../LINUXexample.out/misc/counter/XCountable.urd regmerge ../../../LINUXexample.out/bin/counter.uno.rdb / "/usr/lib/openoffice/program/types.rdb" mkdir -p ../../../LINUXexample.out/misc rm -f ../../../LINUXexample.out/misc/cpp_counter_types.flag cppumaker -Gc -BUCR -O../../../LINUXexample.out/inc/counter ../../../LINUXexample.out/bin/counter.uno.rdb echo flagged > ../../../LINUXexample.out/misc/cpp_counter_types.flag Here is the makefile corresponding part : .... $(OUT_COMP_GEN)/%.urd : %.idl -$(MKDIR) $(subst /,$(PS),$(@D)) idlc -I. -I$(IDL_DIR) -O$(OUT_COMP_GEN) $< # This example type library will be extended by the office types $(OUT_BIN)/%.rdb : $(GENURDFILES) -$(MKDIR) $(subst /,$(PS),$(@D)) -$(DEL) $(subst /,$(PS),$@) regmerge $@ /UCR $(GENURDFILES) regmerge $@ / $(DKREGISTRYNAME) $(COMPONENT_TYPEFLAG) : $(COMPONENT_RDB) $(COMPONENT_XML) -$(MKDIR) $(subst /,$(PS),$(@D)) -$(DEL) $(subst /,$(PS),$(COMPONENT_TYPEFLAG)) cppumaker -Gc -BUCR -O$(OUT_COMP_INC) $(TYPESLIST) $(COMPONENT_RDB) echo flagged > $@ .....
You are now ready to use gcc to compile your code.
Compiling with gcc
The compilation is achieved in two steps or more steps depending how many files we have to compile. The way is making object files first and then linking.
A two step compilation example
We give first a two step compilation example. You can find such example in
<OpenOffice.org1.1_SDK>/examples/DevelopersGuide/ProfUNO/CppBinding
or
<OpenOffice.org1.1_SDK>/examples/DevelopersGuide/ProfUNO/Lifetime
and probably elsewhere.
See the Figure below of the compilation chain corresponding to this two step process.
To simplify our compilation chain figures we allways present this two step process like below when possible.
$(OUT_COMP_OBJ)/%.$(OBJ_EXT) : %.cxx $(GENHPPFILES) -$(MKDIR) $(subst /,$(PS),$(@D)) $(CC) $(CC_FLAGS) $(CC_INCLUDES) -I$(OUT_COMP_INC) $(CC_DEFINES) $(CC_OUTPUT_SWITCH)$(subst /,$(PS),$@) $< $(OUT_BIN)/%$(EXE_EXT) : $(OBJFILES) -$(MKDIR) $(subst /,$(PS),$(@D)) -$(MKDIR) $(subst /,$(PS),$(OUT_COMP_GEN)) ifeq "$(OS)" "WIN" $(LINK) $(EXE_LINK_FLAGS) /OUT:$@ /MAP:$(OUT_COMP_GEN)/$(subst $(EXE_EXT),.map,$(@F)) \ $(OBJFILES) $(CPPUHELPERLIB) $(CPPULIB) $(SALHELPERLIB) $(SALLIB) $(STLPORTLIB) else $(LINK) $(EXE_LINK_FLAGS) $(LINK_LIBS) -o $@ $(OBJFILES) \ $(CPPUHELPERLIB) $(CPPULIB) $(SALHELPERLIB) $(SALLIB) $(STLPORTLIB) $(STDC++LIB) endif
We don't use red color because again all is defined : CPPUHELPERLIB .... in settings.mk
As you can see linking is done with a lot of library : cppuhelperlib, cppulib, salhelperlib ... I want to mention here that in the Lifetime example I have removed all libraries but keeped cppuhelperlib and this example works properly.
A three step compilation example
If you want to use helper as mentioned in Reflection helper, you have to manage such construction. I mean construct an object file for the Helper and then construct the complete program. Here is a short description of the compilation chain
where you see exactly the three steps compilation.
We give a part of an other short makefile used to compile a binary with an helper :
$(OUT_COMP_OBJ)/$(OBJFILE) : $(CXXFILE) $(GENHPPFILES) $(HELPER).hpp -mkdir -p $(subst /,$(PS),$(@D)) gcc $(CC_FLAGS) $(CC_INCLUDES) -I. -I/usr/include -I$(OUT_COMP_INC)/examples \ -I../../../../include -I$(OUT_COMP_INC) $(CC_DEFINES) -o$(OUT_COMP_OBJ)/$(OBJFILE) $(CXXFILE) $(OUT_COMP_OBJ)/$(HELPER).o : $(HELPER).cxx $(HELPER).hpp -mkdir -p $(OUT_COMP_OBJ)/ gcc $(CC_FLAGS) $(CC_INCLUDES) -I. -I/usr/include -I$(OUT_COMP_INC)/examples \ -I../../../../include -I$(OUT_COMP_INC) $(CC_DEFINES) -o$(OUT_COMP_OBJ)/$(HELPER).o $(HELPER).cxx $(OUT_COMP_BIN)/$(OUTBIN) : $(OUT_COMP_OBJ)/$(OBJFILE) $(OUT_COMP_OBJ)/$(HELPER).o -mkdir -p $(OUT_COMP_BIN) gcc -Wl -export-dynamic -L../../../../LINUXexample.out/lib -L../../../../linux/lib \ -L/usr/lib/openoffice/program $(OUT_COMP_OBJ)/$(HELPER).o \ -o$(OUT_COMP_BIN)/$(OUTBIN) $(OUT_COMP_OBJ)/$(OBJFILE) -lcppuhelpergcc3 -lcppu \ -lsalhelpergcc3 -lsal -lstlport_gcc
where we see a first compilation of all cxx files into object files and a link (with gcc). Note that this makefile is OS dependant and works only on Linux systems. Here is what you see in a shell when using this kind of MakeFile :
gcc -c -O -fpic -fno-rtti -I. -I/usr/include -I../../../../LINUXexample.out/inc/examples \ -I../../../../include -I../../../../LINUXexample.out/inc -DUNX -DGCC -DLINUX -DCPPU_ENV=gcc3 -o../../../../LINUXexample.out/obj/office_connect.o office_connect.cxx mkdir -p ../../../../LINUXexample.out/obj/ gcc -c -O -fpic -fno-rtti -I. -I/usr/include -I../../../../LINUXexample.out/inc/examples \ -I../../../../include -I../../../../LINUXexample.out/inc -DUNX -DGCC -DLINUX -DCPPU_ENV=gcc3 -o../../../../LINUXexample.out/obj/ReflectionHelper.o ReflectionHelper.cxx mkdir -p ../../../../LINUXexample.out/bin gcc -Wl -export-dynamic -L../../../../LINUXexample.out/lib -L../../../../linux/lib -L/usr/lib/openoffice/program \ ../../../../LINUXexample.out/obj/ReflectionHelper.o \ -o../../../../LINUXexample.out/bin/office_connect ../../../../LINUXexample.out/obj/office_connect.o -lcppuhelpergcc3 -lcppu -lsalhelpergcc3 -lsal -lstlport_gcc
The complete MakeFile is given here.
A four step compilation example
We encounter a four step example in <OpenOffice.org1.1_SDK>/examples/cpp/counter where two cxx files are compiled. The first counter.cxx is compiled first as conter.o and after as counter.uno.so and the second file countermain.cxx is compiled as countermain.o and then as countermain, a binary executable file. The Figure below shows us what is new in this makefile : constructing a dynamic library (top of the figure).
Here we give the makefile example :
.... COMPONENT_NAME=counter COMPONENT_IMPL_NAME=$(COMPONENT_NAME).uno.$(SHAREDLIB_EXT) COMPONENT_IMPL=$(SHAREDLIB_OUT)/$(COMPONENT_IMPL_NAME) COMPONENT_RDB_NAME = $(COMPONENT_NAME).uno.rdb COMPONENT_RDB = $(OUT_BIN)/$(COMPONENT_RDB_NAME) ..... ifeq "$(OS)" "WIN" $(SHAREDLIB_OUT)/%.$(SHAREDLIB_EXT) : $(SLOFILES) $(OUT_COMP_GEN)/%.def -$(MKDIR) $(subst /,$(PS),$(@D)) -$(MKDIR) $(subst /,$(PS),$(OUT_COMP_GEN)) $(LINK) $(LIBRARY_LINK_FLAGS) /OUT:$@ /MAP:$(OUT_COMP_GEN)/$(subst $(SHAREDLIB_EXT),map,$(@F)) \ /DEF:$(OUT_COMP_GEN)/$(subst $(SHAREDLIB_EXT),def,$(@F)) $(SLOFILES) \ $(CPPUHELPERLIB) $(CPPULIB) $(SALLIB) $(STLPORTLIB) msvcrt.lib kernel32.lib else $(SHAREDLIB_OUT)/%.$(SHAREDLIB_EXT) : $(SLOFILES) -$(MKDIR) $(subst /,$(PS),$(@D)) $(LINK) $(LIBRARY_LINK_FLAGS) $(LINK_LIBS) -o $@ $^\ $(CPPUHELPERLIB) $(CPPULIB) $(SALLIB) $(STLPORTLIB) $(STC++LIB) endif
Perhaps is it more easy to understand with showing what happens with this makefile part in a Linux shell :
gcc -c -O -fpic -fno-rtti -I. -I/usr/include -I../../../LINUXexample.out/inc/examples -I../../../include -I../../../LINUXexample.out/inc/counter -DUNX -DGCC -DLINUX -DCPPU_ENV=gcc3 -o../../../LINUXexample.out/slo/counter/counter.o counter.cxx mkdir -p ../../../LINUXexample.out/lib gcc -shared '-Wl,-rpath,$ORIGIN' -L../../../LINUXexample.out/lib -L../../../linux/lib -L/usr/lib/openoffice/program -o ../../../LINUXexample.out/lib/counter.uno.so ../../../LINUXexample.out/slo/counter/counter.o\ -lcppuhelpergcc3 -lcppu -lsal -lstlport_gcc
We want to show now other parts of the makefile.
Use of pkgchk (deprecated see unopkg)
The binary tool pkgchk is useful when designing a component. The two steps involved with the pkgchk are :
- constructing a zip file
- installing the zip file
Here is a makefile example managing this situation :
$(OUT_BIN)/%.zip : $(SHAREDLIB_OUT)/%.$(SHAREDLIB_EXT) $(OUT_COMP_GEN)/%.rdb -$(MKDIR) $(subst /,$(PS),$(@D)) -$(MKDIR) $(subst /,$(PS),$(OUT_COMP_GEN)/$(PACKAGE_LIB_DIR)) $(COPY) $(subst /,$(PS),$<) $(subst /,$(PS),$(OUT_COMP_GEN)/$(PACKAGE_LIB_DIR)) cd $(subst /,$(PS),$(OUT_COMP_GEN)) && jar cvfM ../../bin/$(@F) $(basename $(@F)).rdb $(PACKAGE_LIB_DIR)/$(<F) $(REGISTERFLAG) : $(COMPONENT_PACKAGE) ifneq "$(SDK_AUTO_DEPLOYMENT)" "" -$(MKDIR) $(subst /,$(PS),$(@D)) -$(DEL) $(subst /,$(PS),$@) $(DEPLOYTOOL) $(COMPONENT_PACKAGE_URL) @echo flagged > $(subst /,$(PS),$@) else @echo -------------------------------------------------------------------------------- @echo If you want to install your component automatically, please set the environment @echo variable SDK_AUTO_DEPLOYMENT = YES. But note that auto deployment is only @echo possible if no office instance is running. @echo -------------------------------------------------------------------------------- endif
The two last parts : execution and cleaning
We have now to execute. Something like
ProUNOLifetimeExamples : $(OUT_BIN)/$(COMPONENT_NAME)$(EXE_EXT) @echo -------------------------------------------------------------------------------- @echo Please use one of the following commands to execute the examples! @echo - @echo make ProfUnoLifetime.runexe @echo -------------------------------------------------------------------------------- %.runexe: $(OUT_BIN)/%$(EXE_EXT) cd $(subst /,$(PS),$(OUT_BIN)) && $(basename $@)
which works well. The cleaning part is not complicated too :
.PHONY: clean clean : -$(DELRECURSIVE) $(subst /,$(PS),$(OUT_COMP_INC)) -$(DELRECURSIVE) $(subst /,$(PS),$(OUT_COMP_GEN)) -$(DELRECURSIVE) $(subst /,$(PS),$(OUT_COMP_OBJ)) -$(DEL) $(subst /,$(PS),$(OUT_BIN)/$(COMPONENT_NAME).*)
Complete MakeFile examples
We give first a makefile I have used when using helper(s).
Office_connect with a helper
Th use of a Reflection Helper has been explained in the corresponding section.
Here is the complete makefile :
# very simple makefile HELPER = ReflectionHelper CXXFILE = office_connect.cxx OBJFILE = office_connect.o OUTBIN = office_connect OUT_COMP_INC = ../../../../LINUXexample.out/inc OUT_COMP_OBJ = ../../../../LINUXexample.out/obj OUT_COMP_BIN = ../../../../LINUXexample.out/bin COMPONENT_RDB = $(OUT_COMP_BIN)/office_connect.rdb CC_FLAGS = -c -O -fpic -fno-rtti CC_DEFINES = -DUNX -DGCC -DLINUX -DCPPU_ENV=gcc3 PS = / TYPES := \ com.sun.star.uno.XNamingService \ ....\ com.sun.star.xml.sax.SAXException TYPESLIST = $(foreach t,$(TYPES),-T$(t)) GENHPPFILES = $(foreach t,$(TYPES),$(OUT_COMP_INC)/$(subst .,/,$(t)).hpp) ALL : \ ProUNOCppBindingExample #office_connectrc is provided with SDK $(OUT_COMP_BIN)/office_connectrc : office_connectrc -mkdir -p $(OUT_COMP_BIN) cp office_connectrc $(OUT_COMP_BIN)/office_connectrc $(COMPONENT_RDB) : -mkdir -p $(OUT_COMP_BIN) regmerge $(COMPONENT_RDB) / "/usr/lib/openoffice/program/types.rdb" @echo -------------------------------------------------------------------------------- @echo Register necessary runtime components in $(COMPONENT_RDB) @echo -------------------------------------------------------------------------------- regcomp -register -r $(COMPONENT_RDB) -c connector.uno.so regcomp -register -r $(COMPONENT_RDB) -c remotebridge.uno.so regcomp -register -r $(COMPONENT_RDB) -c bridgefac.uno.so regcomp -register -r $(COMPONENT_RDB) -c uuresolver.uno.so # @echo bla > $@ $(GENHPPFILES) : $(subst /,$(PS),$(@D)) mkdir -p $(subst /,$(PS),$(@D)) cppumaker -Gc -BUCR -O$(OUT_COMP_INC) $(TYPESLIST) "/usr/lib/openoffice/program/types.rdb" $(OUT_COMP_OBJ)/$(OBJFILE) : $(CXXFILE) $(GENHPPFILES) $(HELPER).hpp -mkdir -p $(subst /,$(PS),$(@D)) gcc $(CC_FLAGS) $(CC_INCLUDES) -I. -I/usr/include -I$(OUT_COMP_INC)/examples \ -I../../../../include -I$(OUT_COMP_INC) $(CC_DEFINES) -o$(OUT_COMP_OBJ)/$(OBJFILE) $(CXXFILE) $(OUT_COMP_OBJ)/$(HELPER).o : $(HELPER).cxx $(HELPER).hpp -mkdir -p $(OUT_COMP_OBJ)/ gcc $(CC_FLAGS) $(CC_INCLUDES) -I. -I/usr/include -I$(OUT_COMP_INC)/examples \ -I../../../../include -I$(OUT_COMP_INC) $(CC_DEFINES) -o$(OUT_COMP_OBJ)/$(HELPER).o $(HELPER).cxx $(OUT_COMP_BIN)/$(OUTBIN) : $(OUT_COMP_OBJ)/$(OBJFILE) $(OUT_COMP_OBJ)/$(HELPER).o -mkdir -p $(OUT_COMP_BIN) gcc -Wl -export-dynamic -L../../../../LINUXexample.out/lib -L../../../../linux/lib -L/usr/lib/openoffice/program \ $(OUT_COMP_OBJ)/$(HELPER).o \ -o$(OUT_COMP_BIN)/$(OUTBIN) $(OUT_COMP_OBJ)/$(OBJFILE) -lcppuhelpergcc3 -lcppu -lsalhelpergcc3 -lsal -lstlport_gcc ProUNOCppBindingExample : $(OUT_COMP_BIN)/$(OUTBIN) $(OUT_COMP_BIN)/office_connectrc @echo -------------------------------------------------------------------------------- @echo Please use one of the following commands to execute the examples! @echo @echo make office_connect.run @echo -------------------------------------------------------------------------------- office_connect.run : $(OUT_COMP_BIN)/$(OUTBIN) $(OUT_COMP_BIN)/office_connectrc cd $(OUT_COMP_BIN) && $(OUTBIN)
Windows Makefile
Redrgreen has provided a windows makefile in the OOoForum. To do : study redrgreen makefile.
The include part
################################################################################# # # makefile_wxoo.mk # ND 06-05-2004 # ################################################################################# MKDIR = mkdir DEL = del CXX = cl LINK = link CAT=type RM = rm RMDIR = rmdir WINDRES = Rc WXWIN = c:\wx242msw PRJ = c:/oo_sdk IDL_DIR=$(PRJ)/idl CXXINCLUDES = -I. -I$(PRJ)/include -I$(WXWIN)/lib/mswd -I$(WXWIN)/include -I$(WXWIN)/contrib/include -I$(WXWIN)/src/regex -I$(WXWIN)/src/png -I$(WXWIN)/src/zlib -I$(WXWIN)/src/jpeg -I$(WXWIN)/src/tiff CXXFLAGS = -c -W2 -nologo /Zm500 CXXDEFINES = -DWIN32 -D__WIN32__ -D_WINDOWS -DWINVER=0x0400 /D__WIN95__ -DSTRICT /Zi /D__WXDEBUG__ /D__WXMSW__ /Od /Gy /MDd /D__WINDOWS__ /GX- CXXOUTPUT_SWITCH = -Fo EXE_LINK_FLAGS= /DEBUG:notmapped,full /DEBUGTYPE:cv /NOLOGO /SUBSYSTEM:windows,4.0 /MACHINE:X86 SALLIB=isal.lib CPPULIB=icppu.lib CPPUHELPERLIB=icppuhelper.lib SALHELPERLIB=isalhelper.lib STLPORTLIB=stlport_vc7.lib RUNTIMELIBS = $(WXWIN)\lib\wxmswd.lib kernel32.lib user32.lib gdi32.lib comdlg32.lib winspool.lib winmm.lib shell32.lib oldnames.lib comctl32.lib odbc32.lib ole32.lib oleaut32.lib uuid.lib rpcrt4.lib advapi32.lib wsock32.lib $(WXWIN)\lib\regexd.lib $(WXWIN)\lib\pngd.lib $(WXWIN)\lib\zlibd.lib $(WXWIN)\lib\jpegd.lib $(WXWIN)\lib\tiffd.lib #substitute the extension .urd for .idl in the variable GENURDFILES GENURDFILES = $(patsubst %.idl,%.urd,$(IDLFILES)) #substitute double \\ for single \ in the path variable DKREG... DKREGISTRYNAME=$(subst \\,\,"$(OFFICE_PROGRAM_PATH)\types.rdb") COMPONENT_TYPEFLAG = cpp_$(COMPONENT_NAME)_types.flag COMPONENT_XML=$(COMPONENT_NAME).uno.xml COMPONENT_ENV_FLAG = cpp_$(COMPONENT_NAME)_prepare_env.flag #__________________________________________________________________________________ ################################################################################# # # using the list of types we just made we now have to prpend a -T to each one # we do this using the foreach command of make as follows # the variable t represents each type in the list $(TYPES) # and foreach one we prepend -T storing the result in TYPELIST # ################################################################################# TYPESLIST = $(foreach t,$(TYPES),-T$(t)) GENHPPFILES = $(foreach t,$(TYPES),$(subst .,/,$(t)).hpp) #__________________________________________________________________________________ ################################################################# # # delete any existing version of this file before merging it # remerge the reg db file under the key /UCR # comment out if only using the main registry # remerge the reg db file we just made with the one for OO # # ################################################################# %.rdb : #$(GENURDFILES) -$(DEL) $@ #comment out following for non components # -regmerge $@ /UCR $(GENURDFILES) -regmerge $@ / $(DKREGISTRYNAME) #________________________________________________________________________________ ################################################################# # # use this for non components example # ################################################################# $(GENHPPFILES) : # -$(MKDIR) $(subst /,$(PS),$(@D)) cppumaker -Gc -BUCR -O. $(TYPESLIST) $(DKREGISTRYNAME) #_________________________________________________________________________________ ################################################################# # # Register the components we are going to use # Comment out if building a component # ################################################################# $(COMPONENT_ENV_FLAG) : $(COMPONENT_RDB_NAME) -$(DEL) $@ @echo -------------------------------------------------------------------------------- @echo Register necessary runtime components in $(COMPONENT_RDB_NAME) @echo -------------------------------------------------------------------------------- regcomp -register -r $(COMPONENT_RDB_NAME) -c connector.uno.dll regcomp -register -r $(COMPONENT_RDB_NAME) -c remotebridge.uno.dll regcomp -register -r $(COMPONENT_RDB_NAME) -c bridgefac.uno.dll regcomp -register -r $(COMPONENT_RDB_NAME) -c uuresolver.uno.dll @echo bla > $@ #___________________________________________________________________________ .PHONY: clean clean : -$(RM) *.o -$(RM) *.obj -$(RM) *.exe -$(RM) *.res -$(RM) *.map -$(RM) *.ilk -$(RM) *.pdb -$(RM) *.dll -$(RM) *.lib -$(RM) *.rdb -$(RM) *.flag -$(RMDIR) /S /Q com -$(RMDIR) /S /Q foo
and the makefile now.
MakeFile part
############################################################################# # # projectmakefile.mk # ND 07-05-2004 # ############################################################################# OUT = #the out directory TARGET = #the target file name goes here without extension OBJFILES = $(patsubst %.cpp,%.obj,$(TARGETS)) OBJECTS = $(TARGET).obj #include all object files here COMPONENT_NAME = ProfUnoCppBinding COMPONENT_RDB_NAME = $(TARGET).rdb PROJECT_NAME = #the project name goes here TYPES := \ com.sun.star.uno.XNamingService \ #the rest of your types go here # if we are using nmake uncomment the following line #!INCLUDE ../makefile_wxoo.mk All: $(PROJECT_NAME) # if we are using gnu make uncomment the following line include ../makefile_wxoo.mk #________________________________________________________________________________ # compile the object files %.obj: %.cpp $(GENHPPFILES) #$(COMPONENT_TYPEFLAG) $(CXX) $(CXXFLAGS) $(CXXINCLUDES) $(CXXDEFINES) $(CXXOUTPUT_SWITCH)$@ $< #________________________________________________________________________________ #comment out dll name if not building a component #$(COMPONENT_NAME).uno.dll %.exe : %.obj $(OBJECTS) $(TARGET).res $(LINK) $(EXE_LINK_FLAGS) /OUT:$@ /MAP:$(basename $(@F)).map \ $(OBJECTS) $(TARGET).res $(CPPUHELPERLIB) $(CPPULIB) $(SALHELPERLIB) $(SALLIB) $(STLPORTLIB) $(RUNTIMELIBS) #________________________________________________________________________________ $(TARGET).res: $(TARGET).rc $(WINDRES) -r /i$(WXWIN)\include /i$(WXWIN)\contrib\include \ -fo$(TARGET).res $(TARGET).rc #_________________________________________________________________________________ $(PROJECT_NAME) : $(TARGET).exe $(COMPONENT_ENV_FLAG) $(TARGET).res @echo -------------------------------------------------------------------------------- @echo Please use the following commands to execute the example! @echo - @echo $(TARGET) @echo --------------------------------------------------------------------------------