From mboxrd@z Thu Jan 1 00:00:00 1970 X-Spam-Checker-Version: SpamAssassin 3.4.4 (2020-01-24) on polar.synack.me X-Spam-Level: X-Spam-Status: No, score=-1.9 required=5.0 tests=BAYES_00 autolearn=ham autolearn_force=no version=3.4.4 X-Google-Thread: 103376,3e5cb326bf672965 X-Google-Attributes: gid103376,public X-Google-Language: ENGLISH,ASCII-7-bit Path: g2news2.google.com!news2.google.com!news4.google.com!border1.nntp.dca.giganews.com!nntp.giganews.com!local01.nntp.dca.giganews.com!nntp.scarlet.biz!news.scarlet.biz.POSTED!not-for-mail NNTP-Posting-Date: Sat, 30 Sep 2006 13:06:28 -0500 From: Ludovic Brenta Newsgroups: comp.lang.ada Subject: Re: GNAT, shared libraries, building in different directories...madness! References: <1159469642.836410.101620@i42g2000cwa.googlegroups.com> Date: Sat, 30 Sep 2006 20:07:15 +0200 Message-ID: <87lko19qjw.fsf@ludovic-brenta.org> User-Agent: Gnus/5.110006 (No Gnus v0.6) Emacs/21.4 (gnu/linux) Cancel-Lock: sha1:SkTPsHiqND/qerk/eiR99OCIRMw= MIME-Version: 1.0 Content-Type: text/plain; charset=us-ascii NNTP-Posting-Host: 62.235.194.54 X-Trace: sv3-O6XvI5sujLlOWZyukMFl1vnvSsnG2lB2BWRuLj/j9L2UYWmwaimL+BE2Ra4rrjT3fEk2P/lXKQMDJeS!fbCxavCs88tXcNSCg8SjwQbNfpKsAhIwT+8nzHUSqG/Zci4XpMEpHRaQPNBMIboqBaq30EcMIw== X-Complaints-To: abuse@scarlet.be X-DMCA-Complaints-To: abuse@scarlet.biz X-Abuse-and-DMCA-Info: Please be sure to forward a copy of ALL headers X-Abuse-and-DMCA-Info: Otherwise we will be unable to process your complaint properly X-Postfilter: 1.3.32 Xref: g2news2.google.com comp.lang.ada:6812 Date: 2006-09-30T20:07:15+02:00 List-Id: Luke wrote: > I have the following directory structure: > > adael/ > adael/src/adael > adael/src/adael/common > adael/src/adael/generic > adael/src/adael/gtk2 > adael/src/adael/linux > adael/src/samples/ > adael/src/samples/test_app > adael/build/gnat/linux/ > adael/build/gnat/linux/temp/ > adael/build/gnat/linux/temp/debug/ > adael/build/gnat/linux/temp/release/ > adael/build/gnat/linux/debug/ > adael/build/gnat/linux/release/ > > So that for a linux specific build all temporary objects go to temp, > executables, ali's, so's go to the debug or release in the linux > directory. > > Can sombody please post an example makefile that can be used to build a > library and link the source to an example app without recompiling the > library source. I would prefer not to use project files if possible as > they just don't provide enough flexibility. Building a library and using it in a program involves the following steps: 1. Building the object and .ali files for the library 2. Linking the object files into a shared libray 3. Copying the .ali files to a "deployment" directory, and making them read-only 4. Building the program, so it sees the .ali files and the .so file but not the .o files for the library. Otherwise, gnatmake will link the library .o files statically into the final executable. Since you've chosen a particularly complex directory structure, your Makefile will be horrendously complex - as you yourself say, "madness". I would really recommend you reconsider your decision not to use project files; contrary to what you say, they can be quite flexible since you can pass variables to them. Here is how I would do it: I would have three project files and one makefile. The first project file would build the library, placing the .o files in the temp directory: project Build_Adael is Compiler := External ("COMPILER", "gnat"); Target := External ("TARGET", "linux"); Build := External ("BUILD", "release"); for Source_Dirs use ("src/adael", "src/common", "src/generic", "src/gtk2", "src/" & Target); for Object_Dir use "build/" & Compiler & "/" & Target & "/temp/" & Build; package Compiler is for Default_Switches ("Ada") use ("-fPIC", "-g", "-O2", "-gnatVa", "-gntafno"); end Compiler; end Build_Adael; The second project file would use the read-only .ali from the deployment directory, and the source files from the source directory. You would ship this project file with your library. project Adael is Compiler := External ("COMPILER", "gnat"); Target := External ("TARGET", "linux"); Build := External ("BUILD", "release"); for Source_Dirs use ("src/adael", "src/common", "src/generic", "src/gtk2", "src/" & Target); for Object_Dir use "build/" & Compiler & "/" & Target & "/" & Build; -- no "temp" -- No package Compiler, since we won't compile the library. But -- we can make it convenient for users to link with the shared -- library: Linker_Switches := "-ladael"; package Linker is for Default_Switches ("Ada") use (Linker_Switches); end Linker; end Adael; The third project file would build the samples. You would encourage your users to write similar project files for their own programs. with "adael"; project Adael_Samples is Compiler := External ("COMPILER", "gnat"); Target := External ("TARGET", "linux"); Build := External ("BUILD", "release"); for Source_Dirs use ("src/samples/**"); for Object_Dir use "build/" & Compiler & "/" & Target & "/samples/" & Build; for Executable_Dir use "build/" & Compiler & "/" & Target & "/" & Build; package Compiler is for Default_Switches ("Ada") use ("-g", "-O2", "-gnatVa", "-gntafno"); -- no fPIC end Compiler; package Linker renames Adael.Linker; end Adael_Samples; Now, the Makefile would glue them all together, create directories as needed, and simply call gnatmake: # O mighty Emacs, this is a -*- Makefile -*- .SUFFIXES: # You can override these from the command line: COMPILER := gnat TARGET := linux BUILD := debug # Nothing should change past this point lib_dir := build/$(COMPILER)/$(TARGET)/$(BUILD) lib_build_dir := build/$(COMPILER)/$(TARGET)/temp/$(BUILD) samples_build_dir := build/$(COMPILER)/$(TARGET)/samples/$(BUILD) all: $(lib_dir)/libadael.so $(lib_dir)/test_app clean: rm -rf build args := -XCOMPILER=$(COMPILER) -XTARGET=$(TARGET) -XBUILD=$(BUILD) $(lib_dir)/libadael.so: build_adael.gpr | $(lib_dir) $(lib_build_dir) gnatmake -c -Pbuild_adael.gpr $(args) gnatgcc -shared -o $@ $(lib_build_dir)/*.o \ -Wl,-soname,$(notdir $@) -lgnat cp -p $(lib_build_dir)/*.ali $(lib_dir) chmod a=r $(lib_dir)/*.ali ifeq (release,$(BUILD)) strip $@ endif $(lib_dir)/test_app: adael_samples.gpr adael.gpr $(lib_dir)/test_app: $(lib_dir)/libadael.so | $(samples_build_dir) gnatmake -Padael_samples.gpr $(notdir $@) $(args) ifeq (release,$(BUILD)) strip $@ endif $(lib_dir) $(lib_build_dir) $(samples_build_dir): -mkdir -p $@ .PHONY: all clean I think you *could* do away with GNAT project files, but that way lies madness. HTH -- Ludovic Brenta.