For example, my program uses 2 external modules like below image.
There are module A and module B.
Module B uses and includes module A inside it; A's headers, library and data(=model).
But their version is different; the version of A in B is 3.6, but the latest version of A is 3.8
My program includes both modules, with my Makefile like below.
However, I got compile error or, my program get segment faults at runtime.
g++ -I$(A_PATH)/include -I$(B_PATH)/include \
-L$(A_PATH)/lib -L$(B_PATH)/lib \
-Wl,-rpath,$(A_PATH)/lib -Wl,-rpath,$(B_PATH)/lib \
…
I'd like to use the latest module A in my program, then,
what is the best way to use these modules in my Makefile?
Use different directories. One for module A v3.8 that your code'll use. Another directory for module B and under that have sub-diretory for module A v3.6. You can have Makefiles in each of these directories as well as one for you source code (in a separate directory).
Related
I have been given a static library libExample.a together with a bunch of C++ headers, which I need to use in an iOS app. The binary is fat, containing objects for iphoneos-arm64/e and iphonesimulator-x64.
I have done some research on the subject and came to the conclusion, that using a XCFramework would be the best thing to do. Still, I feel completely out of my depth, since this is my first time trying anything of the sort.
What I have done so far
1. Creating the XCFramework from library files
lipo -extract architectures from fat binary
xcodebuild -create-xcframework -library LIB-arm64.a -headers HEADERS -library ...
Importing the XCFramework into my Swift project didn't yield any usable modules. Also the folder was missing a lot of the files, I've seen in examples. It seemed like the wrong way to go about it, so I tried...
2. Creating a Framework and then a XCFramework from it
Files
Create new Objective-C Framework project ExampleFramework
Pull all my headers and the fat binary into the project
Add all my headers to the ExampleFramework.h umbrella header
Create the following ExampleFramework.modulemap:
framework module ExampleFramework {
umbrella header "ExampleFramework.h”
link "Example"
export *
module * { export * }
}
Settings
General:
1.1. Add libExample.a to Frameworks & Libraries
Build Phases:
2.1. Make all headers public
2.2. Add libExample.a to Link Binary with Libraries
2.3. Add libExample.a to Copy Bundle Resources
Build Settings:
3.1. Skip Install : No
3.2. Build Libraries for distribution : Yes
3.3. Module map file: ExampleFramework/ExampleFramework.modulemap
3.4. Defines modules: Yes
3.5. Compile Sources As: Objective-C++
I then archived the framework, for iphoneos and iphonesimulator respectively:
xcodebuild archive \
-scheme "ExampleFramework" ONLY_ACTIVE_ARCH=NO \
-archivePath "path/to/ExampleFramework_${SDK}.xcarchive" \
-sdk ${SDK} \
SKIP_INSTALL=NO \
BUILD_LIBRARIES_FOR_DISTRIBUTION=YES
...and generated a XCFramework from the outputs:
xcodebuild -create-xcframework \
-framework "path/to/ExampleFramework_iphoneos.xcarchive/Products/Library/Frameworks/ExampleFramework.framework"
-framework ...
-output "path/to/ExampleFramework.xcframework"
Build Errors
The folder structure I got from this looked promising, so I tried adding the XCFramework to my iOS project. The module was being found now, but XCode stopped compiling at the first #include, saying it wasn't able to find stdexcept, from which I concluded it was missing the C++ standard library headers.
I tried setting Header Search Paths in Build Settings. Looking for the right path I found a couple, that looked relevant to me:
/Applications/Xcode_13.2.1.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/include/c++/v1
/Applications/Xcode_13.2.1.app/Contents/Developer/Platforms/iPhoneSimulator.platform/Developer/SDKs/iPhoneSimulator.sdk/usr/include
/Applications/Xcode_13.2.1.app/Contents/Developer/Platforms/iPhoneOS.platform/Developer/SDKs/iPhoneOS.sdk/usr/include
Depending on which one I choose and whether I clean before building, I'm getting a bunch of different errors (it seems random). Mainly:
Unknown type name 'namespace'
and lots and lots of others, that lead to me believe XCode doesn't recognize the headers as C++.
Or:
Cyclic dependency on module 'Darwin' : Darwin -> std -> Darwin
I really have no idea at this point, so any solutions or suggestions pointing me into the right direction, would me much appreciated. I'd also be open to some completely different approach, I just want to use the library somehow.
Thanks!
For reference from module.modulemap
framework module GoogleAppMeasurement {
umbrella header "GoogleAppMeasurement-umbrella.h"
export *
module * { export * }
link framework "Security"
link framework "SystemConfiguration"
link "c++"
link "sqlite3"
link "z"
}
I am successfully using Boost Python to build a series of Python libraries. These libraries are built conditionally, depending on the settings the user specifies at build time (via CMake).
Now what I would like to do is to merge them all together into a single library, which would contain a series of modules (one per old library) only if they were needed.
So for example, if before I had:
A.so # Always built
B.so # Compiled if B was set
C.so # Compiled if C was set
Now I'd like to have:
MyLib.so # Always built
---
import MyLib
MyLib.A # always works
MyLib.B # works only if MyLib was compiled with B set
MyLib.C # works only if MyLib was compiled with C set
I already know how to create namespaces with Boost Python (via class_), but I'm not sure how I could setup the project so that this final result was possible.
With CMake I can conditionally add files to compile, but I don't know how to define the MyLib module in C++ so that I can add parts to it in separate files.
For now I've added some ifdefs inside the exporting functions which limit the exports based on defines created in CMake.
It's not bad although I'd have preferred to keep the code clean from this, but for now it's my only solution.
In my Makefile I have
CC=g++
When I do mgrep gcc, I have several versions listed like:
gnu/gcc/4.2.1
gnu/gcc/4.7.3
etc
I can do a module load to change my gcc version.
Now suppose I want to use multiple versions simultaneously in different makefiles, how do I do it?
The module system is basically just setting up a path to the requested module. If you want a particular compiler in a particular makefile, then you can do three things:
Expect the user of the makefile to load the correct version before calling Make. Possibly combined with some condition based on gcc -v|grep ${GCC_VERSION} to check that it's the right version.
Perform module load gnu/gcc/${GCC_VERSION} inside your makefile.
Use CC=/somewhere/path-to-gcc-version/bin/g++ instead of CC=g++.
Personally, I prefer 1 or 3. You can find out what the path is by doing module load ... and then which g++.
[By the way, I would use CXX=g++ and CC=gcc - assuming you are not compiling files called *.c as C++-code]
In our workflow, we can have a module A that is composed of several header files, module A not producing any binary (side note: it will obviously be used by other modules, that include some of the headers from module A to produce binaries).
A good example would be a header-only library, for which CMake 3 introduces a good support thanks to the notion of INTERFACE library (see this SO answer, and CMake's documentation of the feature).
We can make an interface library target out of module A:
add_library(module_A INTERFACE)
That gives us all the nice features of CMakes targets (it is possible to use it as another target's dependency, to export it, to transitively forward requirements etc.)
But in this case, the headers in module A do not show up in our IDE (Xcode, yet we expect it to be the same with most/every other IDE).
This proves to be a major drawback in the workflow, since we need the files composing module A to be shown in the IDE for edition. Is it possible to achieve that ?
Several months down the line, I did not find a way to directly list the header files for an INTERFACE library.
Since the question still has some views, here is what I ended up doing (i.e. what appears like the lesser hack currently available).
Imagine module A is a header only library. In the CMakeLists.txt declaring its target:
# Define 'modA_headers' variable to list all the header files
set(modA_headers
utility.h
moreUtilities.h
...)
add_library(moduleA INTERFACE) # 'moduleA' is an INTERFACE pseudo target
#
# From here, the target 'moduleA' can be customised
#
target_include_directories(moduleA ...) # Transitively forwarded
install(TARGETS moduleA ...)
#
# HACK: have the files showing in the IDE, under the name 'moduleA_ide'
#
add_custom_target(moduleA_ide SOURCES ${modA_headers})
I do not accept this answer, since I expect further releases of CMake to offer a more semantically correct approach, which will then be accepted : )
You can use the new target_sources command in CMake 3.1.
add_library(moduleA INTERFACE)
target_include_directories(moduleA INTERFACE ...)
target_sources(moduleA INTERFACE
${CMAKE_CURRENT_SOURCE_DIR}/utility.h
${CMAKE_CURRENT_SOURCE_DIR}/moreUtilities.h
)
It is also transitive.
http://www.cmake.org/cmake/help/v3.1/command/target_sources.html#command:target_sources
The limitation of not being able to export targets which have INTERFACE_SOURCES has been lifted for CMake 3.3.
I want to provide my C++ project with a Python interface. Technically, I have decided to use Cython for wrapping the C++ code. Over time, the entire project is meant to become a Python extension module, but at first, this is highly experimental. Gradually, C++ classes need to be exposed to Python.
My question is how to best organize files and build configurations so that Cython-generated and human-written C++ code do not get mixed and the Python extension module is cleanly built seperate from the other targets.
I imagine a directory structure like this for the source files, and some build directory for Cython.
Project/
src/
*.h
*.cpp
cython/
Project.pyx
setup.py
Basically I have 3 folders :
CPROJECT, The C++ library : producing a libcproject.so shared object
CYPROJECT, The cythonized Python extension : producing the cyproject.so using Cython
DEPENDENCIES, The dependencies : where I copy external requirements for both projects
In 1. I build the C++ extension (compiled with gcc - -shared, -fPIC compile options) that will be exposed to python and that the CYPROJECT relies on to expose features to Python. As a post processing command, the resulting .so is copied into DEPENDENCIES/libcproject/ (as well as the include files). This way the library is, of course, usable independently in a pure C++ project as well.
In 2. I make use of 3 sub-folders :
adapters : which mainly contains C++ additional classes (often classes derived from the ones provided by libcproject.so). Those are usually classes that are enhanced with functionalities specific to Cython requirements (such as storing the PyObject * C version of a targeted Python version - inherited from object - of a given class and the reference counting management, via Py_XINCREF and Py_DECREF, ...).
pyext : where are stored all the Cython hand written .pyx files.
setup : containing the setup.sh script (for setting up the dependencies paths and calling the python setup.py build_ext --inplace for generating the final cyproject.so (to be added to the PYTHONPATH) and cyproject.pyx.
So what's in the setup sub-folder ?
Here is a sample code for setup.sh :
export PYTHONPATH=$PYTHONPATH:../../../DEPENDENCIES/Cython-0.18
export PATH=$PATH:../../../DEPENDENCIES/libcproject:../../../DEPENDENCIES/Cython-0.18/bin
# Note the `../../../DEPENDENCIES/libcproject`...
CC="gcc" \
CXX="g++" \
python setup.py build_ext --inplace
And here an example of setup.py (mainly to demonstrate how the additional adapters are compiled):
import sys
import os
import shutil
from distutils.core import setup
from distutils.extension import Extension
from Cython.Distutils import build_ext
# Cleaning
for root, dirs, files in os.walk(".", topdown=False):
for name in files:
if (name.startswith("cyproject") and not(name.endswith(".pyx"))):
os.remove(os.path.join(root, name))
for name in dirs:
if (name == "build"):
shutil.rmtree(name)
# Building
setup(
cmdclass = {'build_ext': build_ext},
ext_modules = [
Extension("cyproject",
sources=["cyproject.pyx", \
"adapter/ALabSimulatorBase.cpp", \
"adapter/ALabSimulatorTime.cpp", \
"adapter/ALabNetBinding.cpp", \
"adapter/AValueArg.cpp", \
"adapter/ALabSiteSetsManager.cpp", \
"adapter/ALabSite.cpp", \
],
libraries=["cproject"],
language="c++",
extra_compile_args=["-I../inc", "-I../../../DEPENDENCIES/python2.7/inc", "-I../../../DEPENDENCIES/gsl-1.8/include"],
extra_link_args=["-L../lib"]
extra_compile_args=["-fopenmp", "-O3"],
extra_link_args=[]
)
]
)
And finally, the main .pyx, that links all the hand written .pyxs of the cython part together [cyproject.pyx] :
include "pyext/Utils.pyx"
include "pyext/TCLAP.pyx"
include "pyext/LabSimulatorBase.pyx"
include "pyext/LabBinding.pyx"
include "pyext/LabSimulatorTime.pyx"
...
Note : All the files generated by Cython remains in this setup folder, well separated from the hand written stuffs (adapters and pyext), as expected.
In 3. Using a separated DEPENDENCIES folder allows to keep things well separated (in case I would move the CYPROJECT - and its dependencies - in some other environment).
All of this to give you an overview (a pertinent one, I hope) on how one can organize that sort of project.