Skip to content

Commit

Permalink
Linux-related build fixes.
Browse files Browse the repository at this point in the history
Now both Darwin and Linux versions of Nu can be built
and installed using the Nu two-stage build process.

Stage 1: Use rake to build a statically-linked Nu shell.

	% rake

Stage 2: Use the resulting 'mininush' to run nuke.

	% mininush tools/nuke

Installation Notes: On Darwin, Nu is installed as a
framework in /Library/Frameworks. On Linux, it is built
as a dynamic library and installed in /usr/local/lib
(or the lib dir of whatever is your desired installation
prefix). Because nush is linked against libNu.so,
running "nuke install" will crash on Linux when the
libNu.so is overwritten. So be sure to install with
"mininush tools/nuke install".

Linux builds require NuFound, a customized version of
libFoundation. Ports to other Foundation libraries are
welcome.
  • Loading branch information
Tim Burks committed Mar 13, 2008
1 parent f1e2e5b commit b46ed84
Show file tree
Hide file tree
Showing 12 changed files with 98 additions and 29 deletions.
45 changes: 29 additions & 16 deletions Nukefile
Expand Up @@ -46,8 +46,8 @@ END)

;; includes
(if (eq (uname) "Darwin")
(then (set @includes ""))
(else (set @includes " -I/usr/local/include")))
(then (set @includes " -I./include "))
(else (set @includes " -I./include -I/usr/local/include")))

(if (NSFileManager directoryExistsNamed:"#{@prefix}/include") (@includes appendString:" -I #{@prefix}/include"))

Expand All @@ -68,6 +68,9 @@ END)
(if (eq (uname) "Darwin") (then (set @framework_initializer "NuInit")))
(set @framework_creator_code "????")

;; for Linux, we build Nu as a dynamic library
(set @dylib "libNu")

;; build configuration
(set @cc "gcc")
(set @leopard "")
Expand Down Expand Up @@ -103,7 +106,7 @@ END)
join)))
(else (set @ldflags
((list
"-lNuFoundation -L/usr/local/lib -lobjc -Wl,--rpath -Wl,/usr/local/lib"
"-lNuFound -L/usr/local/lib -lobjc -Wl,--rpath -Wl,/usr/local/lib"
(cond ;; statically link in pcre since most people won't have it..
((NSFileManager fileExistsNamed:"/usr/lib/libpcre.a") "/usr/lib/libpcre.a")
((NSFileManager fileExistsNamed:"#{@prefix}/lib/libpcre.a") ("#{@prefix}/lib/libpcre.a"))
Expand All @@ -114,15 +117,19 @@ END)
;; Setup the tasks for compilation and framework-building.
;; These are defined in the nuke application source file.
(compilation-tasks)
(framework-tasks)
(if (eq (uname) "Darwin")
(then (framework-tasks))
(else (dylib-tasks)))

(task "framework" => "#{@framework_headers_dir}/Nu.h")

(file "#{@framework_headers_dir}/Nu.h" => "objc/Nu.h" @framework_headers_dir is
(SH "cp objc/Nu.h #{@framework_headers_dir}"))
(if (eq (uname) "Darwin")
(file "#{@framework_headers_dir}/Nu.h" => "objc/Nu.h" @framework_headers_dir is
(SH "cp objc/Nu.h #{@framework_headers_dir}")))

(task "clobber" => "clean" is
(SH "rm -rf nush #{@framework_dir} doc")
(if (eq (uname) "Darwin")
(SH "rm -rf nush #{@framework_dir} doc"))
((filelist "^examples/[^/]*$") each:
(do (example-dir)
(puts example-dir)
Expand All @@ -136,10 +143,10 @@ END)
(if (eq (uname) "Darwin")
(then
(file nush_thin_binary => "framework" "build/#{architecture}/main.o" is
(SH "#{@cc} #{@cflags} -arch #{architecture} -F. -framework Nu build/#{architecture}/main.o #{@ldflags} -o #{(target name)}")))
(SH "#{@cc} #{@cflags} #{@mflags} main/main.m -arch #{architecture} -F. -framework Nu #{@ldflags} -o #{(target name)}")))
(else
(file nush_thin_binary => (@c_objects objectForKey:architecture) (@m_objects objectForKey:architecture) is
(SH "#{@cc} #{@cflags} -F. build/#{architecture}/nu.o /usr/lib/libNu.so #{@ldflags} -o #{(target name)}"))))))
(file nush_thin_binary => "dylib" (@c_objects objectForKey:architecture) (@m_objects objectForKey:architecture) is
(SH "#{@cc} #{@cflags} #{@mflags} main/main.m #{@library_executable_name} #{@ldflags} -o #{(target name)}"))))))

(file "nush" => "framework" nush_thin_binaries is
(if (eq (uname) "Darwin")
Expand Down Expand Up @@ -170,14 +177,20 @@ END)
(task "install" => "nush" is
('("nuke" "nubile" "nutemplate" "nutest" "nudoc" "nubake") each:
(do (program)
(SH "sudo ditto tools/#{program} #{@installprefix}/bin")))
(SH "sudo ditto nush #{@installprefix}/bin")
(SH "sudo rm -rf #{@destdir}/Library/Frameworks/#{@framework}.framework")
(SH "ditto #{@framework}.framework #{@destdir}/Library/Frameworks/#{@framework}.framework")
(SH "sudo cp tools/#{program} #{@installprefix}/bin")))
(SH "sudo cp nush #{@installprefix}/bin")
(if (eq (uname) "Darwin")
;; install the framework
(SH "sudo rm -rf #{@destdir}/Library/Frameworks/#{@framework}.framework")
(SH "ditto #{@framework}.framework #{@destdir}/Library/Frameworks/#{@framework}.framework"))
(if (eq (uname) "Linux")
;; install the dynamic library
(SH "sudo cp #{@library_executable_name} #{@installprefix}/lib"))
(SH "sudo mkdir -p #{@installprefix}/share")
(SH "sudo rm -rf #{@installprefix}/share/nu")
(SH "sudo ditto share/nu #{@installprefix}/share/nu")
(SH "sudo ditto examples #{@installprefix}/share/nu/examples"))
(SH "sudo cp -rp share/nu #{@installprefix}/share/nu")
(if (eq (uname) "Darwin")
(SH "sudo ditto examples #{@installprefix}/share/nu/examples")))

;; Build a disk image for distributing the framework.
(task "framework_image" => "framework" is
Expand Down
4 changes: 2 additions & 2 deletions Rakefile
Expand Up @@ -49,7 +49,7 @@ CLEAN.include("*/*.o")
CLOBBER.include("mininush")

@c_files = FileList['objc/*.c']
@objc_files = FileList['objc/*.m']
@objc_files = FileList['objc/*.m'] + FileList['main/*.m']
@gcc_files = @objc_files + @c_files
@gcc_objects = @gcc_files.sub(/\.c$/, '.o').sub(/\.m$/, '.o')

Expand All @@ -67,7 +67,7 @@ end
@ldflags += @lib_dirs.map {|libdir| " -L#{libdir}"}.join
@ldflags += " #{FFI_LIB}"
if SYSTEM == "Linux"
@ldflags += " -lobjc -lNuFoundation"
@ldflags += " -lobjc -lNuFound"
@ldflags += " -Wl,--rpath -Wl,/usr/local/lib"
end

Expand Down
22 changes: 22 additions & 0 deletions examples/Benwanu/objc/main.m
@@ -0,0 +1,22 @@
/*!
@file main.m
@copyright Copyright (c) 2007 Neon Design Technology, Inc.
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/
int NuMain(int argc, const char *argv[]);

int main(int argc, const char *argv[])
{
return NuMain(argc, argv);
}
2 changes: 1 addition & 1 deletion examples/Growler/Nukefile
@@ -1,5 +1,5 @@

(set @nu_files (filelist "^[^/]*nu$")) ;; don't forget that filelist expects regular expressions.
(set @nu_files (filelist "^nu/.*\.nu$")) ;; don't forget that filelist expects regular expressions.

(set @application "Growler")
(set @application_identifier "nu.programming.growler")
Expand Down
File renamed without changes.
File renamed without changes.
File renamed without changes.
1 change: 1 addition & 0 deletions include/Nu/Nu.h
File renamed without changes.
2 changes: 0 additions & 2 deletions nu/cocoa.nu
Expand Up @@ -86,5 +86,3 @@
(global NSOrderedAscending -1)
(global NSOrderedSame 0)
(global NSOrderedDescending 1)
(global NO 0)
(global YES 1)
18 changes: 10 additions & 8 deletions objc/operator.m
Expand Up @@ -524,11 +524,11 @@ - (id) callWithArguments:(id)cdr context:(NSMutableDictionary *)context
expressions = [expressions cdr];
}
}
#ifdef DARWIN
#ifdef DARWIN
@finally
#else
NS_ENDHANDLER
#endif
#else
NS_ENDHANDLER
#endif
{
// evaluate all the expressions that are in finally blocks
id expressions = cdr;
Expand Down Expand Up @@ -1272,7 +1272,7 @@ - (id) callWithArguments:(id)cdr context:(NSMutableDictionary *)context
if ([split count] == 2) {
id frameworkName = [split objectAtIndex:0];
id nuFileName = [split objectAtIndex:1];
#ifdef LINUX
#ifdef LINUX
if ([frameworkName isEqual:@"Nu"]) {
if (loadNuLibraryFile(nuFileName, parser, context, symbolTable) == nil) {
[NSException raise:@"NuLoadFailed" format:@"unable to load %@", nuFileName];
Expand All @@ -1281,7 +1281,7 @@ - (id) callWithArguments:(id)cdr context:(NSMutableDictionary *)context
return [symbolTable symbolWithCString:"t"];
}
}
#endif
#endif
NSBundle *framework = [NSBundle frameworkWithName:frameworkName];
if ([framework loadNuFile:nuFileName withContext:context])
return [symbolTable symbolWithCString:"t"];
Expand Down Expand Up @@ -1324,10 +1324,10 @@ - (id) callWithArguments:(id)cdr context:(NSMutableDictionary *)context
if ([Nu loadNuFile:resourceName fromBundleWithIdentifier:@"nu.programming.framework" withContext:context])
return [symbolTable symbolWithCString:"t"];

#ifdef LINUX
#ifdef LINUX
if (loadNuLibraryFile(resourceName, parser, context, symbolTable))
return [symbolTable symbolWithCString:"t"];
#endif
#endif

// if no file was found, try to load a framework with the given name
if ([NSBundle frameworkWithName:resourceName])
Expand Down Expand Up @@ -1746,6 +1746,8 @@ void load_builtins(NuSymbolTable *symbolTable)
{
[(NuSymbol *) [[symbolTable symbolWithCString:"t"] retain] setValue:[symbolTable symbolWithCString:"t"]];
[(NuSymbol *) [[symbolTable symbolWithCString:"nil"] retain] setValue:Nu__null];
[(NuSymbol *) [[symbolTable symbolWithCString:"YES"] retain] setValue:[NSNumber numberWithInt:1]];
[(NuSymbol *) [[symbolTable symbolWithCString:"NO"] retain] setValue:[NSNumber numberWithInt:0]];

install("car", Nu_car_operator);
install("cdr", Nu_cdr_operator);
Expand Down
33 changes: 33 additions & 0 deletions tools/nuke
Expand Up @@ -624,6 +624,39 @@

(task "library" => @library_executable_name))

;; use this to create all the linking and assembly tasks to build a dynamically-linkable library
(macro dylib-tasks
(unless (and @arch (@arch length))
(set @arch (list (NSString stringWithShellCommand:"arch"))))
(set libext (if (eq (uname) "Darwin") (then "dylib") (else "so")))

;; library architecture-specific executable
(set @library_executables (NSMutableArray array))
(@arch each:
(do (architecture)
(set library_executable "build/#{architecture}/#{@dylib}.#{libext}")
(@library_executables addObject:library_executable)
(if (eq (uname) "Darwin")
(then (set dylibflag "-dynamiclib"))
(else (set dylibflag "-shared")))
(if (eq (uname) "Darwin")
(then (set archflags "-arch #{architecture}"))
(else (set archflags "")))
(file library_executable => (@c_objects objectForKey:architecture) (@m_objects objectForKey:architecture) is
(set command "#{@cc} #{((@c_objects objectForKey:architecture) join)} #{((@m_objects objectForKey:architecture) join)} #{archflags} #{@cflags} #{@ldflags} #{dylibflag} -o '#{(target name)}'")
(SH command))))

;; fat dynamic library
(set @library_executable_name "#{@dylib}.#{libext}")
(file @library_executable_name => @library_executables is
(if (eq (uname) "Darwin")
(then (set command "lipo -create #{(@library_executables join)} -output '#{@library_executable_name}'"))
(else (set command "cp '#{(@library_executables objectAtIndex:0)}' '#{@library_executable_name}'")))
(SH command))

(task "dylib" => @library_executable_name))


;; @abstract A project consisting of an interrelated set of NukeTasks.
;; @discussion NukeProjects gather together a related set of NukeTask task descriptions
;; and allow them to be more easily referred to by name. There is typically
Expand Down

0 comments on commit b46ed84

Please sign in to comment.