Aha! Could the /usr/***/Cellar be dependant on architecture in the cmake file perhaps?
I also have to admit to using some performance enhancers for this experiment (chatGPT), but as it compiles fine, and it is the linker that is complaining, I think it has been coaxed into providing something that should run at least.
Using the example you provided, I got a little bit farther. I did not get an error when running your example node, but this one still spits out a linker error:
ld: warning: passed two min versions (10.10.0, 10.12) for platform macOS. Using 10.12.
Undefined symbols for architecture x86_64:
“_fits_getimg_param”, referenced from:
_display_fits_image in composite-Aq6gm3-95525c.o
ld: symbol(s) not found for architecture x86_64
clang: error: linker command failed with exit code 1 (use -v to see invocation)
C code for the node:
/**
* @file
* MM.image.fetchFits node implementation.
*
* @copyright Copyright © 2012–2022 Magneson.
* This code may be modified and distributed under the terms of the MIT License.
* For more information, see https://vuo.org/license.
*/
#include "node.h"
#include "fitsio.h"
#include "fitsio2.h"
#include <OpenGL/gl.h>
VuoModuleMetadata({
"title" : "Fetch FITS",
"description" : "Fetches a FITS file as a Vuo Image",
"keywords" : [ ],
"version" : "1.0.0",
"dependencies" : [ "cfitsio.dylib" ],
});
VuoImage display_fits_image(const char *filename) {
fitsfile *fptr;
int status = 0;
int bitpix, naxis;
long naxes[FITS_MAX_DIM];
unsigned char *pixels;
int x, y;
// Open FITS file.
fits_open_file(&fptr, filename, READONLY, &status);
// Get the image dimensions and type.
fits_get_img_param(fptr, FITS_MAX_DIM, &bitpix, &naxis, naxes, &status);
// Allocate memory for the pixel data.
pixels = (unsigned char *) malloc(naxes[0] * naxes[1] * sizeof(unsigned char));
// Read the image data.
long fpixel[FITS_MAX_DIM];
fpixel[0] = 1;
fpixel[1] = 1;
long nelements = naxes[0] * naxes[1];
for (int i = 2; i <= naxis; i++) {
nelements *= naxes[i-1];
fpixel[i] = 1;
}
fits_read_pix(fptr, TBYTE, fpixel, nelements, NULL, pixels, NULL, &status);
// Close the FITS file.
fits_close_file(fptr, &status);
// Create a GL texture from the pixel data.
unsigned int textureName;
glGenTextures(1, &textureName);
glBindTexture(GL_TEXTURE_2D, textureName);
glTexImage2D(GL_TEXTURE_2D, 0, GL_LUMINANCE, naxes[0], naxes[1], 0, GL_LUMINANCE, GL_UNSIGNED_BYTE, pixels);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
// Create VuoImage from GL texture.
VuoImage image = VuoImage_make(textureName, GL_LUMINANCE, naxes[0], naxes[1]);
// Free the pixel data.
free(pixels);
// Return VuoImage.
return image;
}
void nodeEvent
(
VuoInputData(VuoText) url,
VuoOutputData(VuoImage) fitsImage
)
{
*fitsImage = display_fits_image(url);
}
Relevant part of CMakeLists.txt:
set(compiledNodes "")
foreach (source ${sources})
set(compiledNode "")
set(bitcodeParts "")
list(LENGTH CMAKE_OSX_ARCHITECTURES archCount)
foreach (arch ${CMAKE_OSX_ARCHITECTURES})
get_filename_component(bitcode ${source} NAME_WLE)
set(compiledNode "${bitcode}.vuonode")
if (archCount EQUAL 1)
set(bitcode "${bitcode}.vuonode")
else()
set(bitcode "${bitcode}-${arch}.vuonode")
endif()
add_custom_command(
DEPENDS "${PROJECT_SOURCE_DIR}/${source}"
COMMENT "Compiling node class (${arch})"
COMMAND ${VUO_FRAMEWORK}/../vuo-compile
"${PROJECT_SOURCE_DIR}/${source}"
--target ${arch}-apple-macosx10.12.0
--output ${bitcode}
--header-search-path /usr/local/Cellar/cfitsio/4.2.0/include # for #include "fitsio.h"
OUTPUT ${bitcode}
)
if (archCount GREATER 1)
list(APPEND bitcodeParts ${bitcode})
endif()
endforeach()
if (archCount GREATER 1)
add_custom_command(
DEPENDS ${bitcodeParts}
COMMENT "Merging into multi-architecture file"
COMMAND lipo -create ${bitcodeParts} -output ${compiledNode}
OUTPUT ${compiledNode}
)
endif()
list(APPEND compiledNodes ${compiledNode})
endforeach()
#Name your nodeset
set(nodeset MM.image.vuonode)
add_custom_command(
DEPENDS ${compiledNodes}
COMMENT "Packaging node set and copying to User Modules folder"
COMMAND zip --quiet --junk-paths ${nodeset}
${compiledNodes}
COMMAND cp ${nodeset} ${userModules}
OUTPUT ${nodeset}
)
set(installedDylib ${userModules}/libcfitsio.dylib)
add_custom_command(
COMMENT "Copying libcfitsio.dylib to User Modules folder"
COMMAND cp /usr/local/Cellar/cfitsio/4.2.0/lib/libcfitsio.dylib ${installedDylib}
OUTPUT ${installedDylib}
)
add_custom_target(node ALL
DEPENDS ${installedNode} ${installedDylib}
)