Contents
Makefile para un componente de OpenOffice
A continuación explicaré el Makefile de ejemplo CppComponent que se encuentra en el SDK de OpenOffice, de Debian Squeeze, con esta explicación es más fácil hacer su propio Makefile, para sus propios componentes, que es una gran ayuda. Para efectos de entenderlo, es bueno tener presente la gráfica:
Otra explicación muy buena sobre el Makefile está en [5], pero es otro diferente al que usaremos.
Primeras definiciones
Las dos primeras líneas del Makefile contendrán las definiciones de las variables PRJ y SETTINGS. PRJ es el path del sdk de openoffice, o sea el directorio /usr/lib/openoffice/basis3.2/sdk/, y SETTINGS es el path del directorio de settings del sdk, si estamos parados en el directorio /usr/lib/openoffice/basis3.2/sdk/examples/DevelopersGuide/Components/MyComponent entonces las dos primeras líneas serán así:
PRJ = ../../../.. SETTINGS = $(PRJ)/settings
Estructura de Directorios
Como vimos el directorio de compilación es diferente al directorio de las fuentes, el directorio de fuentes es en este caso:
pwd /usr/lib/openoffice/basis3.2/sdk/examples/DevelopersGuide/Components/MyComponent
O sea el directorio de fuentes está en <OpenOffice.org1.1_SDK>/examples/DevelopersGuide/Components/MyComponent.
La estructura de directorios de la salida que se encontrará en /root/openoffice.org3.2_sdk/LINUXexample.out es:
├── bin ├── inc │ └── com │ └── sun │ └── star │ ├── <dirs> │ ├── *.hdl │ └── *.hpp ├── lib │ └── counter.uno.so ├── misc │ ├── oosdk_cpp_types.flag │ ├── counter │ │ └── XCountable.urd │ └── CppComponentSample │ ├── counter │ │ └── META-INF │ │ └── manifest.xml │ ├── counter.uno.rdb │ ├── Counter.urd │ └── Linux_x86_64 │ └── counter.uno.so └── slo
La estructura de los includes para C++ (que son los archivos .hpp) y para IDL (que son los archivos .hdl) es como sigue:
├── inc │ └── com │ └── sun │ └── star │ ├── beans │ │ ├── *.hdl │ │ └── *.hpp │ ├── bridge │ │ ├── *.hdl │ │ ├── *.hpp │ │ └── oleautomation │ │ ├── *.hdl │ │ ├── *.hpp │ ├── connection │ │ ├── *.hpp │ │ └── *.hdl │ ├── container │ │ ├── *.hdl │ │ └── *.hpp │ ├── corba │ │ ├── *.hdl │ │ ├── *.hpp │ │ ├── giop │ │ │ ├── *.hdl │ │ │ └── *.hpp │ │ ├── iiop │ │ │ ├── *.hdl │ │ │ └── *.hpp │ │ └── iop │ │ ├── *.hdl │ │ └── *.hpp │ ├── io │ │ ├── *.hdl │ │ └── *.hpp │ ├── java │ │ ├── *.hdl │ │ └── *.hpp │ ├── lang │ │ ├── *.hdl │ │ └── *.hpp │ ├── loader │ │ ├── *.hdl │ │ └── *.hpp │ ├── reflection │ │ ├── *.hdl │ │ └── *.hp │ ├── registry │ │ ├── *.hdl │ │ └── *.hpp │ ├── script │ │ ├── *.hdl │ │ └── *.hpp │ ├── security │ │ ├── *.hdl │ │ └── *.hpp │ ├── task │ │ ├── *.hdl │ │ └── *.hpp │ ├── test │ │ ├── bridge │ │ │ ├── *.hdl │ │ │ └── *.hpp │ │ ├── performance │ │ │ ├── *.hdl │ │ │ └── *.hpp │ │ ├── *.hdl │ │ └── *.hpp │ ├── uno │ │ ├── *.hdl │ │ └── *.hpp │ ├── uri │ │ ├── *.hpp │ │ └── *.hdl │ └── util │ ├── logging │ │ ├── *.hdl │ │ └── *.hpp │ ├── *.hdl │ └── *.hpp
Esta estructura de directorios con sus archivos .hdl y .hpp, es generada por el cppumaker en la regla incluida en el archivo stdtarget explicado más adelante.
Incluciones de Makefiles externos
Luego de lo anterior vendrán las inclusiones de tres includes:
include $(SETTINGS)/settings.mk include $(SETTINGS)/std.mk include $(SETTINGS)/dk.mk
Existe una cuarta que sería stdtarget, pero no la vamos a incluir aquí, pues va a quedar luego de las variables que definamos, ya la veremos más tarde.
settings.mk
En este settings se incluyen las variables como el OS=LINUX, PS=/, CC=gcc, SHAREDLIB_EXT=so, los flags del compilador, etc, es bueno mirar este archivo, porque contiene todos las variables importantes que se usan para el Makefile. Claro este archivo está de tal forma que puede soportar Windows, o Solaris, no hay que hacer nada, pues el automáticamente revisa el sistema y cuadra las variables para Linux, hay que tener presente que se debió haber ejecutado setsdkenv_unix y luego modificado el archivo /root/.bashrc para agregar la línea de inclusión, explicada en [7].
std.mk
En este archivo de settings, están las variables estándar que se usan en los Makefiles, como es OUT que siempre termina en <algo>example.out, UNOPKG_EXT=uno.pkg, los directorios de la salida el directorio del idl IDL_DIR=$(PRJ)/idl, las variables URE_TYPES y URE_SERVICES, etc.
dk.mk
En este archivo están las definiciones de SDKVERSION=3.2, y de BUILDID=320m12(Build:9483). Pilas SDKVERSION debe estar en 3.2, o este tutorial no va a cuadrar muy bien.
Exploración de las variables inciales
Para explorar las variables iniciales, haga el siguiente Makefile.test, y ejecute make -f Makefile.test
PRJ=../../../..
SETTINGS=$(PRJ)/settings
include $(SETTINGS)/settings.mk
include $(SETTINGS)/std.mk
include $(SETTINGS)/dk.mk
all :
echo $(URE_TYPES)Debe imprimir algo como:
# make -f Makefile.test echo ""/usr/lib/ure/share/misc/types.rdb"" /usr/lib/ure/share/misc/types.rdb
Pruebe en lugar de URE_TYPES, cualquier variable como por ejemplo OFFICE_SERVICES, o SDK_JAVA_UNO_BOOTSTRAP_FILES, SHAREDLIB_EXT etc... Es bueno jugar con esto para conocer qué tiene cada variable.
Archivos de Flags
Los archivos de Flags se utilizan para poder realizar reglas en determinada secuencia. Si por ejemplo deseamos realizar un archivo de extención .o, que le precede a otro archivo de extensión .o, una forma de hacerlo es usar otro archivo intermedio que nos indique cuando fue realizado el primer archivo, y así el segundo archivo dependerá de este archivo, dichos archivos intermedios son los archivos Flags.
Archivos Flags predefinidos
- SDKTYPEFLAG
En el archivo stdtarget.mk, se define el archivo SDKTYPEFLAG ../../../../LINUXexample.out/misc/oosdk_cpp_types.flag, este usa una regla que la veremos más adelante.
- REGISTERFLAG
Este flag se usa para hacer la instalación del registro, es una dependencia de la regla install que está en el archivo stdtarget.mk. Inicialmente se encuentra vacío, luego no se ejecuta nada, si se define entonces se puede definir un proceso de instalación. Por el momento no he profundizado en este tema.
Definiciones específicas para el proyecto
A continuación vienen las definiciones de las variables para el proyecto que queramos instalar:
SAMPLE_NAME=CppComponentSample
SAMPLE_INC_OUT=$(OUT_INC)/$(SAMPLE_NAME)
SAMPLE_GEN_OUT=$(OUT_MISC)/$(SAMPLE_NAME)
SAMPLE_SLO_OUT=$(OUT_SLO)/$(SAMPLE_NAME)
SAMPLE_OBJ_OUT=$(OUT_OBJ)/$(SAMPLE_NAME)
COMP_NAME=CppComponent
COMP_IMPL_NAME=$(COMP_NAME).uno.$(SHAREDLIB_EXT)
APP1_NAME= TestCppComponent
APP1_BINARY= $(OUT_BIN)/$(APP1_NAME)$(EXE_EXT)
COMP_RDB_NAME = $(COMP_NAME).uno.rdb
COMP_RDB = $(SAMPLE_GEN_OUT)/$(COMP_RDB_NAME)
COMP_PACKAGE = $(OUT_BIN)/$(COMP_NAME).$(UNOOXT_EXT)
COMP_PACKAGE_URL = $(subst \\,\,"$(COMP_PACKAGE_DIR)$(PS)$(COMP_NAME).$(UNOOXT_EXT)")
COMP_UNOPKG_MANIFEST = $(SAMPLE_GEN_OUT)/$(COMP_NAME)/META-INF/manifest.xml
COMP_MAPFILE = $(SAMPLE_GEN_OUT)/$(COMP_NAME).uno.map
COMP_REGISTERFLAG = $(SAMPLE_GEN_OUT)/devguide_$(COMP_NAME)_register_component.flag
COMP_TYPEFLAG = $(SAMPLE_GEN_OUT)/devguide_$(COMP_NAME)_types.flag
IDLFILES = some.idl
CXXFILES = service2_impl.cxx
SLOFILES = $(patsubst %.cxx,$(SAMPLE_SLO_OUT)/%.$(OBJ_EXT),$(CXXFILES))
GENURDFILES = $(patsubst %.idl,$(SAMPLE_GEN_OUT)/%.urd,$(IDLFILES))
#TYPELIST=-Tmy_module.XSomething \
# -Tmy_modules.MyService1 \
# -Tmy_module.MyService2
TYPELIST=com.sun.star.lang.XSingleServiceFactory \
com.sun.star.lang.XMultiServiceFactory \
com.sun.star.lang.XServiceInfo \
com.sun.star.registry.XRegistryKey\
foo.XCountable \
foo.CounterIncluya lo anterior en el Makefile, y comience a explorar las variables para entenderas. Hay básicamente cuatro grupos de variables, todas las que comienzan con SAMPLE; son las que se refieren al ejemplo CppComponentSample que son los directorios en dónde quedan guardados los archivos generados /root/openoffice.org3.2_sdk/LINUXexample.out/<dir>,las que comienzan con COMP son las que se refieren al componente CppComponent como tal y las que comienzan con APP; son las que se refieren a la aplicación TestCppComponent. El cuarto grupo son las otras, que vale la pena explorar en detalle:
- IDLFILES : Es simplemente el archivo IDL
- CXXFILES : Es el archivo de c++ para el registro del componente, puede ser cualquier de los dos service1_impl.cxx o service2_impl.cxx
- SLOFILES : Es el archivo compilado de CXXFILE con el path en el que se encuentra: '/root/openoffice.org3.2_sdk/LINUXexample.out/slo/CppComponentSample/counter.o', se construye reemplazando con la función patsubst el patron '%.cxx' en 'service2_impl.cxx' por la cadena que resulta de unir 'SAMPLE_SLO_OUT' con el wildcard '%' y la extención '.o'.; o sea por la cadena '/root/openoffice.org3.2_sdk/LINUXexample.out/slo/CppComponentSample/%.o'. El wildcard '%' sirve para hacer match con cualquier cosa, en este caso el match lo hace con la cadena vacía antes de 'service2_impl.cxx'. Es algo truculento, pero se usa bastante.
- GENURDFILES : Aquí se vuelve a usar el truco con patsubst para obtener el archivo compilado '.urd': '/root/openoffice.org3.2_sdk/LINUXexample.out/misc/CppComponentSample/Counter.urd'. Juegue con él para entenderlo.
- TYPELIST : Es la lista de servicios e interfaces que pueda haber, para ver cuales son mire los includes en counter.cxx.
Reglas
Aquí comenzamos con la sección de reglas, la primera regla que hay en el archivo es la regla por defecto es la que determina el objetivo último del Makefile que es la de crear el archivo SAMPLE_NAME, y se hace con el instructivo ALL, combinado con el .PHONY, para entender en detalle esto es mejor leer [1].
Primera regla
# Targets
.PHONY: ALL
ALL : \
$(SAMPLE_NAME)Claro como es la primera vez que se va a usar y no hay ninguna regla para construir el SAMPLE_NAME, va a botar un error:
make: *** No hay ninguna regla para construir el objetivo `CppComponentSample', necesario para `ALL'. Alto.
Para evitar este error y podamos continuar con la explicación, debemos hacer la regla para crear el SAMPLE_NAME que es el archivo CppComponentSample, usemos una regla tonta que lista los archivos del directorio:
$(SAMPLE_NAME) :
echo
Inclusión de stdtarget
Ante de la regla para el $(SAMPLE_NAME) y después de la regla que nombramos como la primera regla ponga el siguiente include:
include $(SETTINGS)/stdtarget.mk
Este include contiene la regla para el target del install en caso de que haya un archivo que sea un $(REGISTERFLAG), y también la regla para construir el archivo de flag /root/openoffice.org3.2_sdk/LINUXexample.out/misc/oosdk_cpp_types.flag que está en la variable $(SDKTYPEFLAG), también ayuda a construir los archivos .hdl, y .hpp a partir del types.rdb, vea la gráfica, por esto es muy importante utilizarlo, literalmente contiene los siguiente:
.SUFFIXES:
.SECONDARY:
ifeq "$(DEBUG)" "yes"
debug : ALL
endif
.PHONY: install
install: $(REGISTERFLAG)
$(SDKTYPEFLAG): #$(URE_TYPES) $(OFFICE_TYPES)
-$(MKDIR) $(subst /,$(PS),$(@D))
-$(DEL) $(subst \\,\,$(subst /,$(PS),$(SDKTYPEFLAG)))
$(CPPUMAKER) -Gc -BUCR -O$(OUT_INC) $(URE_TYPES) $(OFFICE_TYPES)
echo flagged > $@Esta regla produce las siguientes sentencias:
mkdir -p /root/openoffice.org3.2_sdk/LINUXexample.out/misc/CppComponentSample "/usr/lib/ure/bin/regmerge" /root/openoffice.org3.2_sdk/LINUXexample.out/misc/CppComponentSample/counter.uno.rdb /UCR /root/openoffice.org3.2_sdk/LINUXexample.out/misc/CppComponentSample/Counter.urd mkdir -p /root/openoffice.org3.2_sdk/LINUXexample.out/misc rm -f /root/openoffice.org3.2_sdk/LINUXexample.out/misc/oosdk_cpp_types.flag
Lo que hacen estos comandos es primero crear el directorio misc, luego eliminar el archivo de flags, paso siguiente crear la estructura dentro del directorio inc con los archivos de cabezeras .hdl y .hpp, y por último recrea el archivo de flag para actualizar su fecha y hora de creación.
Reglas para construir el .urd y el .rdb
Según la gráfica de arriba el .urd depende del .idl y se construye con el idlc, a su vez el .rdb depende del .urd y se genera con el regmerge, las reglas son como sigue:
$(SAMPLE_GEN_OUT)/%.urd : %.idl
-$(MKDIR) $(subst /,$(PS),$(@D))
$(IDLC) -I. -I$(IDL_DIR) -O$(SAMPLE_GEN_OUT) $<
$(SAMPLE_GEN_OUT)/%.rdb : $(GENURDFILES)
-$(DEL) $(subst \\,\,$(subst /,$(PS),$@))
-$(MKDIR) $(subst /,$(PS),$(@D))
$(REGMERGE) $@ /UCR $(GENURDFILES)Este código produce:
mkdir -p /root/openoffice.org3.2_sdk/LINUXexample.out/misc/CppComponentSample "/usr/lib/openoffice/basis3.2/sdk/bin/idlc" -I. -I../../../../idl -O/root/openoffice.org3.2_sdk/LINUXexample.out/misc/CppComponentSample Counter.idl Compiling: Counter.idl rm -f /root/openoffice.org3.2_sdk/LINUXexample.out/misc/CppComponentSample/counter.uno.rdb mkdir -p /root/openoffice.org3.2_sdk/LINUXexample.out/misc/CppComponentSample "/usr/lib/ure/bin/regmerge" /root/openoffice.org3.2_sdk/LINUXexample.out/misc/CppComponentSample/counter.uno.rdb /UCR /root/openoffice.org3.2_sdk/LINUXexample.out/misc/CppComponentSample/Counter.urd
Recuerde que $@ es el target, en este caso $(SAMPLE_GEN_OUT)/%.rdb, y aunque no esté aquí $^ es la lista de dependencias. Estos archivos se generarán en el directorio $(OUT_MISC) /root/openoffice.org3.2_sdk/LINUXexample.out/misc, dicho directorio proviene de la especificación en el archivo std.mk.
Generación del .hlp y el .hpp
La regla que le sigue es la regla para construir los archivos sample.hlp y sample.hpp, en el directorio SAMPLE_INC_OUT /root/openoffice.org3.2_sdk/LINUXexample.out/inc/CppComponentSample, se usa un archivo de flags COMP_TYPEFLAG /root/openoffice.org3.2_sdk/LINUXexample.out/misc/CppComponentSample/devguide_CppComponent _types.flag, mire arriba Inclusión de stdtarget. Para poder generarlo. Dependen del archivo de flags SDKTYPEFLAG /root/openoffice.org3.2_sdk/LINUXexample.out/misc/oosdk_cpp_types.flag y de COMP_RDB /root/openoffice.org3.2_sdk/LINUXexample.out/misc/CppComponentSample/CppComponent/counter.uno.rdb que fue generado en la regla anterior.
$(COMP_TYPEFLAG) : $(COMP_RDB) $(SDKTYPEFLAG)
-$(DEL) $(subst \\,\,$(subst /,$(PS),$@))
-$(MKDIR) $(subst /,$(PS),$(@D))
$(CPPUMAKER) -Gc -BUCR -O$(SAMPLE_INC_OUT) $(TYPESLIST) $(COMP_RDB) -X$(URE_TYPES) -X$(OFFICE_TYPES)
echo flagged > $@Esta regla produce las siguientes líneas de ejecución:
rm -f /root/openoffice.org3.2_sdk/LINUXexample.out/misc/CppComponentSample/devguide_counter_types.flag mkdir -p /root/openoffice.org3.2_sdk/LINUXexample.out/misc/CppComponentSample "/usr/lib/openoffice/basis3.2/sdk/bin/cppumaker" -Gc -BUCR -O/root/openoffice.org3.2_sdk/LINUXexample.out/inc/CppComponentSample /root/openoffice.org3.2_sdk/LINUXexample.out/misc/CppComponentSample/counter.uno.rdb -X"/usr/lib/ure/share/misc/types.rdb" #-X"/usr/lib/openoffice/basis3.2/program/offapi.rdb" echo flagged > /root/openoffice.org3.2_sdk/LINUXexample.out/misc/CppComponentSample/devguide_counter_types.flag
Compilación de los archivos .o
Esto se hace por medio de la regla:
$(SAMPLE_SLO_OUT)/%.$(OBJ_EXT) : %.cxx $(COMP_TYPEFLAG)
-$(MKDIR) $(subst /,$(PS),$(@D))
$(CC) $(CC_FLAGS) $(CC_INCLUDES) -I$(SAMPLE_INC_OUT) $(CC_DEFINES) $(CC_OUTPUT_SWITCH)$(subst /,$(PS),$@) $<Depenpende claramente de todo los archivos .cxx y de haber generado los archivos .hlp y .hpp de la regla anterior por medio del archivo de flags COMP_TYPEFLAG, esta regla genera las siguientes líneas de código:
mkdir -p /root/openoffice.org3.2_sdk/LINUXexample.out/slo/CppComponentSample gcc -c -O -fpic -I. -I/root/openoffice.org3.2_sdk/LINUXexample.out/inc -I/root/openoffice.org3.2_sdk/LINUXexample.out/inc/examples -I../../../../include -I/root/openoffice.org3.2_sdk/LINUXexample.out/inc/CppComponentSample -DUNX -DGCC -DLINUX -DCPPU_ENV=gcc3 -DGXX_INCLUDE_PATH=/usr/include/c++/4.4 -o/root/openoffice.org3.2_sdk/LINUXexample.out/slo/CppComponentSample/counter.o counter.cxx
Regla para el archivo .uno.map
Esta regla para Linux es copiar sólo el archivo ../../../../settings/component.uno.map en /root/openoffice.org3.2_sdk/LINUXexample.out/misc/CppComponentSample/counter.uno.map, para MacOsx, se le adiciona una línea más.
$(COMP_MAPFILE) : $(SLOFILES)
-$(MKDIR) $(subst /,$(PS),$(@D))
cat $(PRJ)/settings/component.uno.map > $(COMP_MAPFILE)
ifeq "$(OS)" "MACOSX"
nm -gx $(SLOFILES) | $(ADDSYMBOLS) >> $(COMP_MAPFILE)
endifEsta regla genera:
mkdir -p /root/openoffice.org3.2_sdk/LINUXexample.out/misc/CppComponentSample cat ../../../../settings/component.uno.map > /root/openoffice.org3.2_sdk/LINUXexample.out/misc/CppComponentSample/counter.uno.map
Generación de las librerías .so
Estas librerías se linkean para Linux y MacOsx con la siguiente regla:
$(SHAREDLIB_OUT)/%.$(SHAREDLIB_EXT) : $(SLOFILES) $(COMP_MAPFILE)
-$(MKDIR) $(subst /,$(PS),$(@D)) && $(DEL) $(subst \\,\,$(subst /,$(PS),$@))
$(LINK) $(COMP_LINK_FLAGS) $(LINK_LIBS) -o $@ $(SLOFILES) \
$(CPPUHELPERLIB) $(CPPULIB) $(SALLIB) $(STLPORTLIB) $(STC++LIB) $(CPPUHELPERDYLIB) $(CPPUDYLIB) $(SALDYLIB)
ifeq "$(OS)" "MACOSX"
$(INSTALL_NAME_URELIBS) $@
endifgenera la siguiente ejecución, salvo la línea de las librerías que no están instaladas
mkdir -p /root/openoffice.org3.2_sdk/LINUXexample.out/lib && rm -f /root/openoffice.org3.2_sdk/LINUXexample.out/lib/counter.uno.so
g++ -shared '-Wl,-rpath,$ORIGIN' -Wl,--version-script,../../../../settings/component.uno.map -L"/root/openoffice.org3.2_sdk/LINUXexample.out/lib" -L"/usr/lib/openoffice/basis3.2/sdk/lib" -L"/usr/lib/ure/lib" -o /root/openoffice.org3.2_sdk/LINUXexample.out/lib/counter.uno.so /root/openoffice.org3.2_sdk/LINUXexample.out/slo/CppComponentSample/counter.o \
-luno_cppuhelpergcc3 -luno_cppu -luno_sal Depende de el archivos .o y del archivo .uno.map generados en las dos reglas anteriores.
Reglas para la instalación del componente
Para instalar el componente es importante que no esté corriendo el openoffice. Para permitir esto ponga en YES la variable SDK_AUTO_DEPLOYMENT = YES, esto se configura al correr el setsdkenv_unix que se esplicó en [3], al poner la configuración como sigue:
Automatic deployment of UNO components (YES/NO) [YES]:
Regla para la generación del manifesto.xml
$(SAMPLE_GEN_OUT)/%/manifest.xml :
-$(MKDIR) $(subst /,$(PS),$(@D))
@echo $(OSEP)?xml version="$(QM)1.0$(QM)" encoding="$(QM)UTF-8$(QM)"?$(CSEP) > $@
@echo $(OSEP)!DOCTYPE manifest:manifest PUBLIC "$(QM)-//OpenOffice.org//DTD Manifest 1.0//EN$(QM)" "$(QM)Manifest.dtd$(QM)"$(CSEP) >> $@
@echo $(OSEP)manifest:manifest xmlns:manifest="$(QM)http://openoffice.org/2001/manifest$(QM)"$(CSEP) >> $@
@echo $(SQM) $(SQM)$(OSEP)manifest:file-entry manifest:media-type="$(QM)application/vnd.sun.star.uno-typelibrary;type=RDB$(QM)" >> $@
@echo $(SQM) $(SQM)manifest:full-path="$(QM)$(subst /META-INF,,$(subst $(SAMPLE_GEN_OUT)/,,$(@D))).uno.rdb$(QM)"/$(CSEP)
>> $@
@echo $(SQM) $(SQM)$(OSEP)manifest:file-entry manifest:media-type="$(QM)application/vnd.sun.star.uno-component;type=native;platform=$(UNOPKG_P
LATFORM)$(QM)" >> $@
@echo $(SQM) $(SQM)manifest:full-path="$(QM)$(subst /META-INF,,$(subst $(SAMPLE_GEN_OUT)/,,$(UNOPKG_PLATFORM)/$(@D))).uno
.$(SHAREDLIB_EXT)$(QM)"/$(CSEP) >> $@
@echo $(OSEP)/manifest:manifest$(CSEP) >> $@Esta regla produce:
mkdir -p /root/openoffice.org3.2_sdk/LINUXexample.out/misc/CppComponentSample/counter/META-INF
Y genera el archivo manifesto.xml, este es un archivo xml, que se genera a partir de la salida estandar, usando echo <texto> > <archivo.xml> y echo >> <archivo.xml>. Y contiene:
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE manifest:manifest PUBLIC "-//OpenOffice.org//DTD Manifest 1.0//EN" "Manifest.dtd">
<manifest:manifest xmlns:manifest="http://openoffice.org/2001/manifest">
<manifest:file-entry manifest:media-type="application/vnd.sun.star.uno-typelibrary;type=RDB"
manifest:full-path="counter.uno.rdb"/>
<manifest:file-entry manifest:media-type="application/vnd.sun.star.uno-component;type=native;platform=Linux_x86_64"
manifest:full-path="Linux_x86_64/counter.uno.so"/>
</manifest:manifest>
Regla para generar el .oxt
$(COMP_PACKAGE) : $(SHAREDLIB_OUT)/$(COMP_IMPL_NAME) $(COMP_RDB) $(COMP_UNOPKG_MANIFEST)
-$(DEL) $(subst \\,\,$(subst /,$(PS),$@))
-$(MKDIR) $(subst /,$(PS),$(@D))
-$(MKDIR) $(subst /,$(PS),$(SAMPLE_GEN_OUT)/$(UNOPKG_PLATFORM))
$(COPY) $(subst /,$(PS),$<) $(subst /,$(PS),$(SAMPLE_GEN_OUT)/$(UNOPKG_PLATFORM))
cd $(subst /,$(PS),$(SAMPLE_GEN_OUT)) && $(SDK_ZIP) ../../bin/$(@F) $(COMP_RDB_NAME) $(UNOPKG_PLATFORM)/$(<F)
cd $(subst /,$(PS),$(SAMPLE_GEN_OUT)/$(subst .$(UNOOXT_EXT),,$(@F))) && $(SDK_ZIP) -u ../../../bin/$(@F) META-INF/manifest.xmlEste archivo depende del componente CppComponent.uno.so, del CppComponent.uno.rdb, y del manifest.xml, para entender qué es $(@F), $(<F), vea las variables automáticas en [2].
Esta regla produce:
rm -f /root/openoffice.org3.2_sdk/LINUXexample.out/bin/counter.oxt mkdir -p /root/openoffice.org3.2_sdk/LINUXexample.out/bin mkdir -p /root/openoffice.org3.2_sdk/LINUXexample.out/misc/CppComponentSample/Linux_x86_64 cp /root/openoffice.org3.2_sdk/LINUXexample.out/lib/counter.uno.so /root/openoffice.org3.2_sdk/LINUXexample.out/misc/CppComponentSample/Linux_x86_64 cd /root/openoffice.org3.2_sdk/LINUXexample.out/misc/CppComponentSample && "/usr/bin/zip" ../../bin/counter.oxt counter.uno.rdb Linux_x86_64/counter.uno.so adding: counter.uno.rdb (deflated 92%) adding: Linux_x86_64/counter.uno.so (deflated 68%) cd /root/openoffice.org3.2_sdk/LINUXexample.out/misc/CppComponentSample/counter && "/usr/bin/zip" -u ../../../bin/counter.oxt META-INF/manifest.xml adding: META-INF/manifest.xml (deflated 52%)
Ejecución del Extension Manager
Por medio de un archivo de flags, se ejecuta el Extension Manager y se genera el archivo de flags para el archivo CppComponentSample y la regla SimpleComponent.odt.load.
$(COMP_REGISTERFLAG) : $(COMP_PACKAGE)
ifeq "$(SDK_AUTO_DEPLOYMENT)" "YES"
-$(DEL) $(subst \\,\,$(subst /,$(PS),$@))
-$(MKDIR) $(subst /,$(PS),$(@D))
$(DEPLOYTOOL) $(COMP_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 --------------------------------------------------------------------------------
endifSi la variable SDK_AUTO_DEPLOYMENT está en algo diferente a YES, esta regla produce, el siguiente mensaje:
-------------------------------------------------------------------------------- If you want to install your component automatically, please set the environment variable SDK_AUTO_DEPLOYMENT = YES. But note that auto deployment is only possible if no office instance is running. --------------------------------------------------------------------------------
Si la variable SDK_AUTO_DEPLOYMENT está en YES, ejecuta las siguientes instrucciones:
rm -f /root/openoffice.org3.2_sdk/LINUXexample.out/misc/CppComponentSample/devguide_counter_register_component.flag mkdir -p /root/openoffice.org3.2_sdk/LINUXexample.out/misc/CppComponentSample "/usr/lib/openoffice/program/unopkg" add -f "/root/openoffice.org3.2_sdk/LINUXexample.out/bin/counter.oxt" getImplementationEnvironnement return gcc3 component_writeInfo called New key : /com.sun.star.comp.example.cpp.Counter/UNO/SERVICES --component_writeInfo calls MyCounterImpl::getSupportedServiceNames_Static() MyCounterImpl::getSupportedServiceNames_Static( ) called with foo.Counter ----Sub-Key : foo.Counter build getImplementationEnvironnement return gcc3 getSupportedServiceNames_MyCounterImpl called getSupportedServiceNames_MyCounterImpl called getImplementationEnvironnement return gcc3 getSupportedServiceNames_MyCounterImpl called getSupportedServiceNames_MyCounterImpl called getImplementationEnvironnement return gcc3 getSupportedServiceNames_MyCounterImpl called getSupportedServiceNames_MyCounterImpl called
Las últimas líneas aparecen porque adicioné como en el counter que hicimos inicialmente las líneas de printf, pero retirándoloas aparece los siguiente:
rm -f /root/openoffice.org3.2_sdk/LINUXexample.out/misc/CppComponentSample/devguide_counter_register_component.flag mkdir -p /root/openoffice.org3.2_sdk/LINUXexample.out/misc/CppComponentSample "/usr/lib/openoffice/program/unopkg" add -f "/root/openoffice.org3.2_sdk/LINUXexample.out/bin/counter.oxt"
Este ejecuta el comando unopkg add -f CppComponent.oxt [4], claro con en el directorio correspondiente, y genera un archivo de flags devguide_CppComponent_register_component.flag para poder ejecutarlo en secuencia make.
Reglas auxiliares
Compilación del aplicativo TestCppComponent
$(SAMPLE_OBJ_OUT)/$(APP1_NAME).$(OBJ_EXT) : $(APP1_NAME).cxx $(COMP_TYPEFLAG)
-$(MKDIR) $(subst /,$(PS),$(@D))
$(CC) $(CC_FLAGS) $(CC_INCLUDES) -I$(SAMPLE_INC_OUT) $(CC_DEFINES) $(CC_OUTPUT_SWITCH)$(subst /,$(PS),$@) $<Esta regla produce:
mkdir -p /root/openoffice.org3.2_sdk/LINUXexample.out/obj/CppComponentSample gcc -c -O -fpic -I. -I/root/openoffice.org3.2_sdk/LINUXexample.out/inc -I/root/openoffice.org3.2_sdk/LINUXexample.out/inc/examples -I../../../../include -I/root/openoffice.org3.2_sdk/LINUXexample.out/inc/CppComponentSample -DUNX -DGCC -DLINUX -DCPPU_ENV=gcc3 -DGXX_INCLUDE_PATH=/usr/include/c++/4.4 -o/root/openoffice.org3.2_sdk/LINUXexample.out/obj/CppComponentSample/TestCppComponent.o TestCppComponent.cxx
Pero genera los siguientes errores:
TestCppComponent.cxx:45:51: error: com/sun/star/frame/XComponentLoader.hpp: No existe el fichero o el directorio TestCppComponent.cxx:46:36: error: my_module/MyService1.hpp: No existe el fichero o el directorio TestCppComponent.cxx:47:36: error: my_module/MyService2.hpp: No existe el fichero o el directorio TestCppComponent.cxx:53: error: ‘frame’ is not a namespace-name TestCppComponent.cxx:53: error: expected namespace-name before ‘;’ token make: *** [/root/openoffice.org3.2_sdk/LINUXexample.out/obj/CppComponentSample/TestCppComponent.o] Error 1
Estos errores ocurren porque en el Typelist no están dichas interfaces [6], para eso hay que modificar el Makelist en el Typelist así:
Nota dichas líneas las voy a comentar para poder instalar el componente recien hecho.
TYPELIST=com.sun.star.frame.XComponentLoader \
com.sun.star.bridge.XUnoUrlResolver
#-Tmy_module.XSomething \
# -Tmy_modules.MyService1 \
# -Tmy_module.MyService2Modifique el TestCppComponent.cxx las líneas del include de los servicios:
/*#include <my_module/MyService1.hpp> #include <my_module/MyService2.hpp>*/
Y agrege un int main(){} comentando el resto del las líneas del SAL_IMPLEMENT_MAIN hasta el final del archivo:
int main(){}
/*SAL_IMPLEMENT_MAIN()
{
...
}*/Las siguientes líneas compilar el archivo _TestCppComponent
$(OUT_BIN)/_$(APP1_NAME)$(EXE_EXT) : $(SAMPLE_OBJ_OUT)/$(APP1_NAME).$(OBJ_EXT)
-$(MKDIR) $(subst /,$(PS),$(@D))
-$(MKDIR) $(subst /,$(PS),$(SAMPLE_GEN_OUT))
ifeq "$(OS)" "WIN"
$(LINK) $(EXE_LINK_FLAGS) /OUT:$@ /MAP:$(SAMPLE_GEN_OUT)/$(basename $(@F)).map \
$< $(CPPUHELPERLIB) $(CPPULIB) $(SALHELPERLIB) $(SALLIB) $(STLPORTLIB)
else
$(LINK) $(EXE_LINK_FLAGS) $(LINK_LIBS) -o $@ $< \
$(CPPUHELPERLIB) $(CPPULIB) $(SALHELPERLIB) $(SALLIB) $(STLPORTLIB) $(STDC++LIB) $(CPPUHELPERDYLIB) $(CPPUDYLIB) $(SALHELPERDYLIB) $(SALDYLIB)
ifeq "$(OS)" "MACOSX"
$(INSTALL_NAME_URELIBS_BIN) $@
endif
endif
$(OUT_BIN)/$(APP1_NAME)$(EXE_EXT) : $(OUT_BIN)/_$(APP1_NAME)$(EXE_EXT)
$(COPY) $(subst /,$(PS),$(BIN_DIR)/unoapploader$(EXE_EXT)) $(subst /,$(PS),$@)
# touch the target to renew the date for correct dependencies.
# Note: no touch under windows! The unoapploader.exe is copied always.
ifneq "$(OS)" "WIN"
touch $@
endifEstas líneas producen:
mkdir -p /root/openoffice.org3.2_sdk/LINUXexample.out/bin
mkdir -p /root/openoffice.org3.2_sdk/LINUXexample.out/misc/CppComponentSample
g++ -Wl,--allow-shlib-undefined -Wl,-export-dynamic -Wl,-z,defs -Wl,--no-whole-archive -L"/root/openoffice.org3.2_sdk/LINUXexample.out/lib" -L"/usr/lib/openoffice/basis3.2/sdk/lib" -L"/usr/lib/ure/lib" -o /root/openoffice.org3.2_sdk/LINUXexample.out/bin/_TestCppComponent /root/openoffice.org3.2_sdk/LINUXexample.out/obj/CppComponentSample/TestCppComponent.o \
-luno_cppuhelpergcc3 -luno_cppu -luno_salhelpergcc3 -luno_sal
cp ../../../../bin/unoapploader /root/openoffice.org3.2_sdk/LINUXexample.out/bin/TestCppComponent
touch /root/openoffice.org3.2_sdk/LINUXexample.out/bin/TestCppComponent
Regla para generar el SAMPLE_NAME '''CppComponentSample'''
Por últimoa aperecerá un mensaje para ejecutar el make con .run correspondiente a la siguiente regla:
$(SAMPLE_NAME) : $(COMP_REGISTERFLAG) $(APP1_BINARY)
@echo --------------------------------------------------------------------------------
@echo Please use the following command to execute the example!
@echo -
@echo $(MAKE) $(APP1_NAME).run
@echo --------
@echo The simple C++ component was installed if SDK_AUTO_DEPLOYMENT = YES.
@echo You can use this component inside your office installation, see the example
@echo description. You can also load the "$(QM)SimpleComponent.odt$(QM)" document containing
@echo a StarBasic macro which uses this component.
@echo -
@echo $(MAKE) SimpleComponent.odt.load
@echo --------------------------------------------------------------------------------Que produce:
Please use the following command to execute the example! - make TestCppComponent.run
The simple C++ component was installed if SDK_AUTO_DEPLOYMENT = YES. You can use this component inside your office installation, see the example description. You can also load the "SimpleComponent.odt" document containing a StarBasic macro which uses this component. - make SimpleComponent.odt.load
En caso de que se ejecute cualquier archivo con
make <archivo>.run
El make ejecuta la siguiente regla:
%.run: $(OUT_BIN)/%$(EXE_EXT)
$(subst /,$(PS),$(OUT_BIN))$(PS)$(basename $@)
# cd $(subst /,$(PS),$(OUT_BIN)) && $(basename $@)De la misma forma si se ejecuta el comando:
make SimpleComponent.odt.load
Se ejecuta la siguiente regla:
SimpleComponent.odt.load : $(COMP_REGISTERFLAG)
"$(OFFICE_PROGRAM_PATH)$(PS)soffice" $(basename $@)
Regla para limpiar los archivos innecesarios
La regla para limpiar estos archivos es:
.PHONY: clean
clean :
-$(DELRECURSIVE) $(subst /,$(PS),$(SAMPLE_INC_OUT))
-$(DELRECURSIVE) $(subst /,$(PS),$(SAMPLE_GEN_OUT))
-$(DELRECURSIVE) $(subst /,$(PS),$(SAMPLE_SLO_OUT))
-$(DELRECURSIVE) $(subst /,$(PS),$(SAMPLE_OBJ_OUT))
-$(DEL) $(subst \\,\,$(subst /,$(PS),$(OUT_BIN)/$(COMP_NAME)*))
-$(DEL) $(subst \\,\,$(subst /,$(PS),$(OUT_BIN)/*$(APP1_NAME)*))Esta regla se ejecuta con:
make clean
y borra los contenidos de los directorios que afecta:
rm -rf ../../../../LINUXexample.out/inc/CppComponentSample rm -rf ../../../../LINUXexample.out/misc/CppComponentSample rm -rf ../../../../LINUXexample.out/slo/CppComponentSample rm -rf ../../../../LINUXexample.out/obj/CppComponentSample rm -f ../../../../LINUXexample.out/bin/counter* rm -f ../../../../LINUXexample.out/bin/*TestCppComponent*
Par limpiar completamente los archivos creados use la siguiente cadena de comandos:
make clean rm /usr/lib/openoffice/basis3.2/sdk/LINUXexample.out/misc/CppComponentSample -rdf rm /usr/lib/openoffice/basis3.2/sdk/LINUXexample.out/misc/oosdk_cpp_types.flag rm /usr/lib/openoffice/basis3.2/sdk/LINUXexample.out -rdf rm /root/openoffice.org3.2_sdk/LINUXexample.out -rdf
[1] http://www.gnu.org/software/make/manual/make.html#Phony-Targets
[2] http://www.gnu.org/software/make/manual/make.html#Automatic-Variables
[3] http://wiki.opdevel.com/OpenOffice
[4] http://wiki.services.openoffice.org/wiki/Documentation/DevGuide/Extensions/unopkg
[5] http://wiki.services.openoffice.org/wiki/MakeFil
[6] http://wiki.services.openoffice.org/wiki/UNO_automation_with_a_binary_%28executable%29