[C exten] extconf.rg and #ifdef

Hi, depending whether my Ruby C extension is being compiled on *nix or
Windows, I need some #defines (i.e: OS_UNIX or OS_WIN).

I see no way in MKMF documentation to generate a #define (based on
RbConfig["host_os"] for example). I've seen some "hacks" in extconf.rb
like this:

···

---------------------------------------
  def add_define(name)
    $defs.push("-D#{name}")
  end

  # If I'm on *nix:
  add_define "OS_UNIX"
---------------------------------------

Is this the most ellegant way? any other solution?

Thanks a lot.

--
Iñaki Baz Castillo
<ibc@aliax.net>

Iñaki Baz Castillo писал 28.05.2012 14:57:

Hi, depending whether my Ruby C extension is being compiled on *nix or
Windows, I need some #defines (i.e: OS_UNIX or OS_WIN).

I see no way in MKMF documentation to generate a #define (based on
RbConfig["host_os"] for example). I've seen some "hacks" in extconf.rb
like this:

---------------------------------------
  def add_define(name)
    $defs.push("-D#{name}")
  end

  # If I'm on *nix:
  add_define "OS_UNIX"
---------------------------------------

Is this the most ellegant way? any other solution?

Thanks a lot.

Yeah, that's pretty much how configure scripts work. (More complex ones like
that from autoconf create config.h with the definitions, but you're unlikely
to need this.)

···

--
   WBR, Peter Zotov.

What is wrong with the generic macros the compiler sets itself? If I
remember correctly, every compiler targeting Windows sets a macro called
_WIN32, and I bet there’s something similar for other systems. There
shouldn’t be a need to manually define this in extconf.rb.

Vale,
Marvin

···

Am 28.05.2012 12:57, schrieb Iñaki Baz Castillo:

Hi, depending whether my Ruby C extension is being compiled on *nix or
Windows, I need some #defines (i.e: OS_UNIX or OS_WIN).

I see no way in MKMF documentation to generate a #define (based on
RbConfig["host_os"] for example). I've seen some "hacks" in extconf.rb
like this:

---------------------------------------
  def add_define(name)
    $defs.push("-D#{name}")
  end

  # If I'm on *nix:
  add_define "OS_UNIX"
---------------------------------------

Is this the most ellegant way? any other solution?

Thanks a lot.

--
Blog: http://pegasus-alpha.eu/blog

ASCII-Ribbon-Kampagne () | ASCII Ribbon Campaign ()
- Stoppt HTML-E-Mail /\ | - Against HTML E-Mail /\
- Stoppt proprietäre Anhänge | - Against proprietary attachments
The Ascii Ribbon Campaign official homepage - Deutsch | www.asciiribbon.org

From libuv's `include/uv.h` header:

#if defined(__unix__) || defined(__POSIX__) || defined(__APPLE__)
# include "uv-private/uv-unix.h"
#else
# include "uv-private/uv-win.h"
#endif

To help prevent multi-platform lunacy, as I find useful macros I add
them to a simple little C helper such as:

  https://gist.github.com/968522

Also, here's what MSFT publishes as Visual Studio 10's predefined C/C++
macros

  http://msdn.microsoft.com/en-us/library/b0084kay

Jon

···

---
Fail fast. Fail often. Fail publicly. Learn. Adapt. Repeat.
http://thecodeshop.github.com | http://jonforums.github.com/
twitter: @jonforums

--
Posted via http://www.ruby-forum.com/.

Do not use host_* values from rbconfig.rb.

Use target_* values from rbconfig.rb.

Using host_* is wrong.

The host_* values come from host that compiled ruby. When ruby is cross-compiled these values won't match the target and your gem will fail to compile.

You should use target_* values as these values match the target ruby was compiled for.

See: http://sources.redhat.com/autobook/autobook/autobook_261.html

···

On May 28, 2012, at 03:57, Iñaki Baz Castillo wrote:

Hi, depending whether my Ruby C extension is being compiled on *nix or
Windows, I need some #defines (i.e: OS_UNIX or OS_WIN).

I see no way in MKMF documentation to generate a #define (based on
RbConfig["host_os"] for example).

Thanks, I understand. However that worries me is the fact that the
"workaround" is modifyng $defs global variable:

  $defs.push("-D#{name}")

Is it expected that such a $defs variable will exist forever in
extconf.rb/MKMF stuff?

Thanks a lot.

···

2012/5/28 Peter Zotov <whitequark@whitequark.org>:

Yeah, that's pretty much how configure scripts work. (More complex ones like
that from autoconf create config.h with the definitions, but you're unlikely
to need this.)

--
Iñaki Baz Castillo
<ibc@aliax.net>

That would be, of course, much better than "auto-detecting" in
extconf.rb. However there could be other cases in which I need to
create a #define based on custom requirements.

I will inviestigate about the macro you mean. It seems than in *nix
systems, the compiler "should" set __unix__ define:

Thanks a lot.

···

2012/5/28 Quintus <quintus@quintilianus.eu>:

What is wrong with the generic macros the compiler sets itself? If I
remember correctly, every compiler targeting Windows sets a macro called
_WIN32, and I bet there’s something similar for other systems. There
shouldn’t be a need to manually define this in extconf.rb.

--
Iñaki Baz Castillo
<ibc@aliax.net>

From libuv's `include/uv.h` header:

#if defined(__unix__) || defined(__POSIX__) || defined(__APPLE__)
# include "uv-private/uv-unix.h"
#else
# include "uv-private/uv-win.h"
#endif

Excellent, I didn't realize of that :slight_smile:

To help prevent multi-platform lunacy, as I find useful macros I add
them to a simple little C helper such as:

CL and MinGW compiler predefs · GitHub

Really useful. Thanks a lot.

···

2012/5/28 Jon Forums <lists@ruby-forum.com>:

--
Iñaki Baz Castillo
<ibc@aliax.net>

Good to know. Thanks a lot.

···

2012/5/31 Eric Hodel <drbrain@segment7.net>:

On May 28, 2012, at 03:57, Iñaki Baz Castillo wrote:

Hi, depending whether my Ruby C extension is being compiled on *nix or
Windows, I need some #defines (i.e: OS_UNIX or OS_WIN).

I see no way in MKMF documentation to generate a #define (based on
RbConfig["host_os"] for example).

Do not use host_* values from rbconfig.rb.

Use target_* values from rbconfig.rb.

Using host_* is wrong.

The host_* values come from host that compiled ruby. When ruby is cross-compiled these values won't match the target and your gem will fail to compile.

You should use target_* values as these values match the target ruby was compiled for.

See: http://sources.redhat.com/autobook/autobook/autobook_261.html

--
Iñaki Baz Castillo
<ibc@aliax.net>

Eric Hodel wrote in post #1062725:

Hi, depending whether my Ruby C extension is being compiled on *nix or
Windows, I need some #defines (i.e: OS_UNIX or OS_WIN).

I see no way in MKMF documentation to generate a #define (based on
RbConfig["host_os"] for example).

Do not use host_* values from rbconfig.rb.

Use target_* values from rbconfig.rb.

Using host_* is wrong.

The host_* values come from host that compiled ruby. When ruby is
cross-compiled these values won't match the target and your gem will
fail to compile.

You should use target_* values as these values match the target ruby was
compiled for.

See: http://sources.redhat.com/autobook/autobook/autobook_261.html

While this definition of host/target appears wrong, it doesn't matter in
this case.

IIRC, the powerful-but-hellish autotools system gives these meanings to
build/host/target:

build - the type of the system used to configure and build a package.
Defaults to output of `config.guess`

host - the type of the system on which the built package executes.
Defaults to the same type as the build system and enables cross
compilation mode.

target - used for building compiler tools for cross compiling. The type
of the system for which any compiler tools built from the package
produce code for. Defaults to the same type as the host.

I believe it's more correct to use `RbConfig::CONFIG['host_os']` to
determine *nix v. Windows.

Here's output from two builds, the first built natively on Windows with
MinGW, and the second built on Arch Linux cross compiled with MinGW for
Windows.

RbConfig::CONFIG.each do |k,v|

> puts "#{k} = #{v}" if k =~ /build|host|target/
> end

# MinGW/GCC 4.6.2 native Windows build
target_os = mingw32
target_vendor = pc
target_cpu = i386
target = i386-pc-mingw32
host_os = mingw32
host_vendor = pc
host_cpu = i686
host = i686-pc-mingw32
build_os = mingw32
build_vendor = pc
build_cpu = i686
build = i686-pc-mingw32
target_alias =
host_alias =
build_alias =

# Arch 3.3.7 Linux -> Windows cross compiled build
# ../configure --enable-shared --disable-install-doc --host=i486-mingw32
target_os = mingw32
target_vendor = pc
target_cpu = i386
target = i386-pc-mingw32
host_os = mingw32
host_vendor = pc
host_cpu = i486
host = i486-pc-mingw32
build_os = linux-gnu
build_vendor = pc
build_cpu = i686
build = i686-pc-linux-gnu
target_alias =
host_alias = i486-mingw32
build_alias =

Jon

···

On May 28, 2012, at 03:57, Iaki Baz Castillo wrote:

---
Fail fast. Fail often. Fail publicly. Learn. Adapt. Repeat.
http://thecodeshop.github.com | http://jonforums.github.com/
twitter: @jonforums

--
Posted via http://www.ruby-forum.com/\.

Jon Forums wrote in post #1062852:

Eric Hodel wrote in post #1062725:

Hi, depending whether my Ruby C extension is being compiled on *nix or
Windows, I need some #defines (i.e: OS_UNIX or OS_WIN).

I see no way in MKMF documentation to generate a #define (based on
RbConfig["host_os"] for example).

[...SNIP...]

The host_* values come from host that compiled ruby. When ruby is
cross-compiled these values won't match the target and your gem will
fail to compile.

You should use target_* values as these values match the target ruby was
compiled for.

See: http://sources.redhat.com/autobook/autobook/autobook_261.html

[...SNIP...]

I believe it's more correct to use `RbConfig::CONFIG['host_os']` to
determine *nix v. Windows.

Forgot to include the following doco link to compare with the link Eric
provided.

···

On May 28, 2012, at 03:57, Iaki Baz Castillo wrote:

--
Posted via http://www.ruby-forum.com/\.