How can I prevent cmake from linking MACOSX bundle resource files ?
When I add a resource file to a MACOSX application bundle, it is taken by the linker due to its .obj postfix. The linker tries to link it without success. He writes a warning:
Linking CXX executable mwe.app/Contents/MacOS/mwe
ld: warning: ignoring file ../star.obj, file was built for unsupported file format
( 0x23 0x20 0x42 0x6C 0x65 0x6E 0x64 0x65 0x72 0x20 0x76 0x32 0x2E 0x37 0x30 0x20 )
which is not the architecture being linked (x86_64): ../star.obj
Of course he cannot link it because star.obj is a 3D model text file in the obj format:
# Blender v2.70 (sub 0) OBJ File: 'star.blend'
o Plane
v 0.510396 -0.000389 0.998397
v -0.926169 -0.000017 -0.001603
v 0.510396 0.000355 -1.001603
[..and many more vertices]
The resulting problem is; the file is not put into the MACOSX bundle folder because the linker ignored it.
VisorZ#Mac ~/MWE> ll build/mwe.app/Contents/Resources/
total 8
-rw-r--r-- 1 Stephan staff 62B 6 Aug 22:36 star.off
(See, star.obj is missing here) ------------------------------------^
I would like to exclude that obj file from the link file lists via cmake.
But neither the source file properties
MACOSX_PACKAGE_LOCATION,
EXTERNAL_OBJECT FALSE,
LANGUAGE "myMODEL"
nor the target property
RESOURCE
can do that. Here is a minimum working example CMakeLists.txt:
# Minimum Working Example to create mwe.app on MACOSX with linker
# trying to process *.obj files which are marked as resource files
CMAKE_MINIMUM_REQUIRED(VERSION 2.8)
PROJECT(mwe)
SET_SOURCE_FILES_PROPERTIES(
star.obj # 3D model as OBJ txt file
star.off # 3D model as OFF txt file
PROPERTIES
MACOSX_PACKAGE_LOCATION Resources
)
ADD_EXECUTABLE(
${PROJECT_NAME}
MACOSX_BUNDLE # needs to be second argument, enables bundling
helloworld.cpp # will be compiled
star.obj # will not be bundled because it will be taken by linker
star.off # will be bundled
)
Use HEADER_FILE_ONLY and try not to think too much about the name of it.
set_source_files_properties(
star.obj # 3D model as OBJ txt file
star.off # 3D model as OFF txt file
PROPERTIES
HEADER_FILE_ONLY ON
)
If you want to stop the linker from trying to link the files you can add them to a custom target as such:
ADD_CUSTOM_TARGET (testTarget SOURCES myFile.obj myFile.off)
This is especially handy for having files show up in your project tree but not having them compiled/linked.
Related
The sources in the source file are lance.c send.c request.c alloc.c Pcntn3.rc
Builds only: send.obj request.obj alloc.obj Pcntn3.res
error LNK1181: cannot open input file "obj\i386\lance.obj"
expecting it to build lance.obj so the compiler can do the final linking for the sys file.
Not on the hard drive anywhere.
I was compiling my rust code with llvm/clang, and some extern libraries were used, so the compiler tried to link them.
But the linker throwed an error: ld.lld: error: /path/to/libwinapi_shcore.a: unknown file type
Then I checked this file and found that it's not like common .a file:
INPUT(
libwinapi_shcore-api-ms-win-shcore-stream-winrt-l1-1-0.a
libwinapi_shcore-api-ms-win-shcore-scaling-l1-1-2.a
libwinapi_shcore-api-ms-win-core-featurestaging-l1-1-0.a
libwinapi_shcore-api-ms-win-shcore-scaling-l1-1-1.a
libwinapi_shcore-api-ms-win-shcore-scaling-l1-1-0.a
libwinapi_shcore-api-ms-win-core-featurestaging-l1-1-1.a
)
What does these mean? Shouldn't .a file be a binary file?
I'm using ghostscript to generate rather large PDF files, and profiling has lead me to believe that a lot of time is spent compressing data.
For whatever reason, the ghostscript source tree ships with a copy of the zlib 1.2.11 source code, which is then compiled into the resulting gs executable.
I would like to benchmark other zlib implementations, notably Cloudflare's and possibly Intel's.
In ghostscript's Makefile.in, there's an interesting section:
# Define the directory where the zlib sources are stored.
# See zlib.mak for more information.
SHARE_ZLIB=#SHARE_ZLIB#
ZSRCDIR=#ZLIBDIR#
#ZLIB_NAME=gz
ZLIB_NAME=z
ZLIB_CFLAGS=#ZLIBCFLAGS#
And looking in base/zlib.mak:
# makefile for zlib library code.
# Users of this makefile must define the following:
# GSSRCDIR - the GS library source directory
# ZSRCDIR - the source directory
# ZGENDIR - the generated intermediate file directory
# ZOBJDIR - the object directory
# SHARE_ZLIB - 0 to compile zlib, 1 to share
# ZLIB_NAME - if SHARE_ZLIB=1, the name of the shared library
# ZAUXDIR - the directory for auxiliary objects.
So, in theory, one should just compile zlib elsewhere, get an .so file (perhaps?), set SHARE_ZLIB to 1 and ZLIB_name to /foo/bar/zlib_cloudflare/libz.so and everything should be good. Except it doesn't work, and there's zero documentation.
I'm new to Fortran (gfortran on windows) and want to use the random number generator vsrnggaussian.
vsrnggaussian needs the Intel MKL VSL modules 'mkl_vsl_type' and 'mkl_vsl' which are provided in the mkl_vsl.f90 file. This file needs to be included to generate the module files 'mkl_vsl_type.mod' and 'mkl_vsl.mod' which are used to process the Fortran use clauses referencing to the VSL interface:
use mkl_vsl_type
use mkl_vsl
I tried multiple things to include the mkl_vsl.f90 file but none of them work:
I inserted the file into the project directory --> 793 errors occured (can't list all of them here in detail) such as:
Unexpected data declaration statement at (1)
[...] at (1) has no implicit type
expecting [...] statement at (1)
unexpected [...] statement at (1)
and finally Fatal Error: Cannot open module file 'mkl_vsl_type.mod' for reading at (1): No such file or directory. compilation terminated. "gfortran -g -o incl_mkl.exe ../incl_mkl.f90" terminated with exit code 1. Build might be incomplete.
I used the full path in the include statement: INCLUDE 'C:/Program Files (x86)/IntelSWTools/compilers_and_libraries_2016.1.146/windows/mkl/include/mkl_vsl.f90' --> Error: Can't open included file
I tried the -Idir compiler command: gfortran -I/Program Files (x86)/IntelSWTools/compilers_and_libraries_2016.1.146/windows/mkl/include/ -g -o incl_mkl.exe --> gfortran: error: Files: no such file or directory
I put this into the makefile: INCLUDES=-I. -I/Program Files (x86)/IntelSWTools/compilers_and_libraries_2016.1.146/windows/mkl/include/ --> Error: Can't open included file
How do I include the mkl_vsl.f90 file??
edit: my simple code to include the mkl_vsl.f90 file
(this code will be compiled first before i compile my main code with vsrnggaussian):
Program INCL
IMPLICIT NONE
INCLUDE 'mkl_vsl.f90'
!INCLUDE 'C:/Program Files (x86)/IntelSWTools/compilers_and_libraries_2016.1.146/windows/mkl/include/mkl_vsl.f90'
END Program
You'd need to USE both vsl_type and vsl modules. The reason is that the derived types in vsl are defined in vsl_type. MWE
Program INCL
use mkl_vsl_type
use mkl
IMPLICIT NONE
write(6, *) 'hello world'
END Program
You would need to pass the address to file mkl_vsl.f90 to ifort and the mkl flag.
ifort -mkl foo.f90 <address>/mkl_vsl.f90
For using any specific subroutine of MKL consult their website. There is also extensive examples that come with MKL. You may find it in C:/Program Files (x86)/IntelSWTools/compilers_and_libraries_2016.1.146/windows/mkl/examples or something like that.
I have a problem with setting up a visibility of my shared library. I would like to ask for help in resolving my issue as described below:
I have a bunch of source files which I would like to build as shared library:
+Base
|_Parameter
| |_Parameter.h
| |_Parameter_Exception.h
| |_Parameter_Exception.cpp
|_Data
| |_DataInput.h
| |_DataInput_Exception.h
| |_DataInput_Exception.cpp
...
Well there are some more files in there but I think it does not influence my problem description.
I am using CMake in order to build this SHARED library. Here is part of my CMakeLists.txt which deals with building the library.
project( Base )
cmake_minimum_required(VERSION 3.5
set( Base_HEADERS
Parameter/Parameter.h
Parameter/Parameter_Exception.h
Data/DataInput.h
Data/DataInput_Exception.h
)
set( Base_SOURCES
Parameter/Parameter_Exception.cpp
Data/DataInput_Exception.cpp
)
set( LIBRARY_OUTPUT_PATH ${CMAKE_RUNTIME_OUTPUT_DIRECTORY} )
add_library( Base SHARED ${Base_SOURCES} ${Base_HEADERS} )
generate_export_header( ${PROJECT_NAME} EXPORT_FILE_NAME ${PROJECT_NAME}_Export.h )
This setup builds libBase.so shared library without any problem. It is important to mention that I have set some visibility related flags to be used during linking:
set( CMAKE_SHARED_LINKER_FLAGS "-Wl,--no-undefined -fvisibility=hidden -fvisibility-inlines-hidden" )
As configured in Base library CMakeLists.txt partly listed above:
Base_Export.h header containig GCC visibility attributes macros is
generated by CMake. It is then included in my sources listed in the
tree up there.
By default all the symbols shall be hidden as set in
linker flags (-fvisibility=hidden)
For example a piece of Parameter_Exception.h:
#include "Base_Export.h"
class SomeException : public std::exception
{
public:
SomeException( void ) {}
...
};
Please notice I have not set any visibility attribute here (by a macro defined in Base_Export). So I would assume, the symbol of SomeException class shall be hidden to all the DSO "users" (due to -fvisibility=hidden)
But it doesn't seem so. Unfortunately:
Once I use the library, it the exception is usable although the symbol should be hidden. I would expect link failure cause by this code snippet "outside the library":
#include "Parameter/Parameter_Exception.h"
...
try
{
...
}
/* THIS SHOULD FAIL IN LINKING DUE TO UNDEFINED SYMBOL, RIGHT? */
catch( const SomeException & e )
{
...
}
I have also tried to look for the symbol in the libBase.so using the command:
readelf -Ws libBase.so
it lists enormously long text:
Num: Value Size Type Bind Vis Ndx Name
0: 0000000000000000 0 NOTYPE LOCAL DEFAULT UND
1: 000000000008b7e0 0 SECTION LOCAL DEFAULT 9
....
but what I have noticed here is that in "Vis" column up there there is always DEFAULT which implies a default visibility ( __attribute__((visibility("default"))) ) to me BUT I would expect to see HIDDEN in there ( __attribute__((visibility("hidden"))) )
So what am I doing wrong? Or my understanding is not correct? I know all the linked flags are propagated correctly but seem to have no effect.
My toolchain configuration as listed by CMake configuration script (GCC version that supports visibility attributes):
...
-- The CXX compiler identification is GNU 5.3.1
-- Check for working CXX compiler: /usr/bin/c++
-- Check for working CXX compiler: /usr/bin/c++ -- works
...
-- Performing Test COMPILER_HAS_HIDDEN_VISIBILITY
-- Performing Test COMPILER_HAS_HIDDEN_VISIBILITY - Success
-- Performing Test COMPILER_HAS_HIDDEN_INLINE_VISIBILITY
-- Performing Test COMPILER_HAS_HIDDEN_INLINE_VISIBILITY - Success
-- Performing Test COMPILER_HAS_DEPRECATED_ATTR
-- Performing Test COMPILER_HAS_DEPRECATED_ATTR - Success
-- Configuring done
-- Generating done
Many thanks in advance to anybody willing to help me and possibly others having the same trouble as I do.
Thanks again, Martin
CMake has direct support for symbol visibility handling, so you shouldn't need to touch CMAKE_SHARED_LINKER_FLAGS or CMAKE_CXX_FLAGS at all. You can set the visibility on a per-target basis like this:
set_target_properties(Base PROPERTIES
C_VISIBILITY_PRESET hidden
CXX_VISIBILITY_PRESET hidden
VISIBILITY_INLINES_HIDDEN YES
)
CMake will then ensure the relevant flags are added for you. Rather than having to set these properties for each target, it is usually more convenient to set the associated variables to set the defaults for all subsequently created targets (and this is what I generally recommend and use in projects I work on):
cmake_minimum_required(VERSION 3.5)
project(Base)
set(CMAKE_C_VISIBILITY_PRESET hidden)
set(CMAKE_CXX_VISIBILITY_PRESET hidden)
set(CMAKE_VISIBILITY_INLINES_HIDDEN YES)
add_library(Base SHARED ...)
When used in conjunction with the GenerateExportHeader module (which you already appear to be using), you get support not just for gcc/clang, but also Visual Studio, making it a nice cross-platform way of controlling symbol visibility. You don't need to know the relevant compiler flags or attributes, CMake will handle them for you and give you equivalent behavior across all the compilers.
-fvisibility=hidden and -fvisibility-inlines-hidden are compiler options,
not linker options. Set them in CMAKE_CXX_FLAGS