Use SWIG for .cpp which depends on another .cpp - cmake

I have a .cpp file which calls another .cpp file. I want to use SWIG to create a Python wrapper for this.
How do I make this using SWIG.
When I had a single .cpp file I was able to create a .so in the following manner:
//app.cpp
#include "app.hpp"
int p(int a)
{
std::cout<<"hello...SWIG runs fine!"<<std::endl;
return a;
}
//app.hpp
#include <iostream>
int p(int a);
//app.i
%module app
%{
#include "app.hpp"
%}
%include "app.hpp"
Commands run were:
swig -c++ -python app.i
g++ -Isrc -fPIC -I/../../../../usr/include/python3.6m
-I/../../../../usr/include/x86_64-linux-gnu/python3.6m -lpython3.6m -c app.cpp app_wrap.cxx
g++ -shared -fPIC -o _app.so app.o app_wrap.o
I was successful in generating a .so file with this method. However, now my app.cpp needs to use a function defined in another .cpp file (a function called int fn1(int x) in hello.cpp). How do I generate .so now? If anyone could provide a small example it'd be great!
EDIT:: Someone suggested I would have to use SWIG and CMAKE together. Is this true? If yes, how can I do so?

Solved it!
swig -c++ -python file1.i
g++ -Isrc -fPIC -I/../../../../usr/include/python3.6m
-I/../../../../usr/include/x86_64-linux-gnu/python3.6m -lpython3.6m -c file1.cpp file2.cpp file1_wrap.cxx
g++ -shared -fPIC -o _file1.pyd file1.o file2.o file1_wrap.o
Turns out we can use CMake to define dependencies and do this process automatically.
Also, SWIG can be used with CMake as mentioned on SWIG documentation Introduction_build_system

Related

Meson can't find static libs

I can compile my project by running
g++ main.cpp -l:libpj-x86_64-unknown-linux-gnu.a -lpthread -lm -luuid
or
g++ main.cpp /usr/local/lib/libpj-x86_64-unknown-linux-gnu.a -lpthread -lm -luuid
But when I try adding library with either one of:
meson.get_compiler('cpp').find_library('libpj-x86_64-unknown-linux-gnu.a')
meson.get_compiler('cpp').find_library('/usr/local/lib/libpj-x86_64-unknown-linux-gnu.a')
I'm getting error:
ERROR: C++ library 'libpj-x86_64-unknown-linux-gnu' not found
Solution was to add 'dirs' variable even tho file is in standard /usr/local/lib path and to remove .a extension.
cc.find_library('libpj-x86_64-unknown-linux-gnu', dirs: '/usr/local/lib/')
Later of course lib was available inside meson and was added to executable and tested.

How did Cygwin g++ resolve it?

I am puzzled how a mere g++ -o testpoco testpoco.cpp -lPocoFoundation was able to compile successfully in my Cygwin environment. The complete C++ code is below:
#include <Poco/File.h>
int main (int argc, char *argv[])
{
Poco::File f("/tmp/test.log");
if (f.exists()) {
return 1;
}
return 0;
}
I installed the cygwin Poco development headers and libraries and I verified they are in:
/usr/include/Poco/ (the header files)
/usr/lib/ (the libraries)
But without specifying those include and library path in g++ how did it was able to compile and produce the exe? I checked the output of g++ -v and did not see any routes to Poco.
The compiler has default search paths for include files and for libraries. (Actually the latter applies to the linker, not the compiler, but the g++ command invokes both.)
/usr/include and /usr/lib are in those default search paths.
You specified #include <Poco/File.h>, so the compiler found /usr/include/Poco/File.h.
You specified -lPocoFoundation, so the linker found /usr/lib/libPocoFoundation.dll.a, the file that contains the code implementing the PocoFoundation library under Cygwin.
I checked the output of g++ -v and did not see any routes to Poco
The command g++ -v will just print out some version information about GCC, and how it was configured. Adding the -v option to your real commands used for compiling and/or linking will show the search paths for headers and libraries.
In other words, instead of just g++ -v you should try:
g++ -o testpoco testpoco.cpp -lPocoFoundation -v
This will show the search paths that Keith Thompson refers to in his answer.

Can I use CMake to compile a program in stages?

I'm using the LLVM compiler to perform some analyses. I also have a test application I've written that I build using CMake. I'd like to compile the test application in stages:
Compile all source files of the test application to LLVM bitcode.
Link all of the bitcode files together using llvm-link.
Compile this linked bitcode file down into an actual binary (using an extra flag to run my analyses).
As an example, if I had a program test comprised of 3 files, foo.c, bar.c, and bar.h:
Normal compilation:
clang -I. -c foo.c // generates foo.o
clang -I. -c bar.c // generates bar.o
ld -lc -lgcc -o test foo.o bar.o // links foo.o and bar.o
Bitcode compilation & linking:
clang -I. -c -emit-llvm foo.c // generates foo.bc
clang -I. -c -emit-llvm bar.c // generates bar.bc
llvm-link -o test.bc foo.bc bar.bc // links foo.bc and bar.bc
clang -I. -o test test.bc // generates test
As I said, I've already written CMake files that build and compile the test application normally (i.e., in a single stage).
Is it possible, through some combination of adding custom commands and/or targets, to achieve such a thing? Or should I continue with my current approach of using bash/Python scripts to run this process?

Cross-platform static-linking SDL2

I'm building an SDL2/C++ program that needs to be portable to Windows, Mac, and Linux machines which may not have SDL installed.
I've read that static linking is the solution, but I'm not very good with compiling and don't know how to static link.
My program relies only on SDL2, GLU, and OpenGL. I'm compiling C++ with either MinGW (on Windows 8.1) or gcc (on Ubuntu 14.04) -- both of these OS's have SDL installed natively.
Here is my current makefile, derived from a sample makefile given to me by a professor of mine:
# Executable/file name
EXE=experiment
# MinGW
ifeq "$(OS)" "Windows_NT"
CFLG=-O3 -Wall -DUSEGLEW
LIBS= -lSDL2 -lglu32 -lopengl32
CLEAN=del *.exe *.o *.a
else
# OSX
ifeq "$(shell uname)" "Darwin"
CFLG=-O3 -Wall -Wno-deprecated-declarations
LIBS=-framework SDL2 -framework OpenGL
# Linux\Unix\Solaris
else
CFLG=-O3 -Wall
LIBS= `sdl2-config --cflags --libs` -lGLU -lGL -lm
endif
# OSX\Linux\Unix\Solaris
CLEAN=rm -f $(EXE) *.o *.a
endif
# Dependencies
$(EXE).o: $(EXE).cpp FORCE
.c.o:
gcc -c -o $# $(CFLG) $<
.cpp.o:
g++ -std=c++11 -c -o $# $(CFLG) $<
# Link
$(EXE):$(EXE).o
g++ -std=c++11 -O3 -o $# $^ $(LIBS)
# Clean
clean:
$(CLEAN)
# Force
FORCE:
To link with static library you either specify path to library file
gcc -o out_bin your_object_files.o path/to/lib.a -lfoo
or ask linker to use static version with -Bstatic linker flag. Usually you'll want to reset linking back to dynamic for the rest of the libraries, e.g. for static SDL2 and GLU but dynamic GL:
gcc -o out_bin your_object_files -Wl,-Bstatic -lSDL2 -lGLU -Wl,-Bdynamic -lGL
That of course implies that static versions of libraries are present in library search path list (.a libs for gcc on all specified platforms, although MSVC uses .lib for static libraries).
However you usually don't really want to do that at all. It is common practice for software to either depend on some libs (widespread on linux, with packages and dependendices lists) or bring required libraries with it. You can just distribute SDL dynamic library with your program and load it with LD_LIBRARY_PATH or relative rpath.
Please also note that newer SDL2 implements dynamic loading of functions which provides a way to override SDL with user-specified dynamic library, even if linked statically.
It wasn't related directly to static linking. When static linking, I had to include all of SDL's dependency libraries. Turns out, having -mwindows causes console communication to fail.

Unable to compile sharable .o files with g++

When i compile with the following command:
g++ -fPIC -o obj/buffer.o buffer.cpp
I get the following error:
/usr/lib/gcc/x86_64-linux-gnu/4.6.1/../../../x86_64-linux-gnu/crt1.o:
In function _start': (.text+0x20): undefined reference tomain'
I am thought with the -fPIC flag, I didn't need a main function. I get this error with all of the cpp files. I do have a main.cpp that has the shared library functions in it. You can get the source code at the following:
git clone https://github.com/nterry/39DLL-4-Linux.git
Any ideas? I know that I can use the ld binary to put all of the o files in the an so once they're done, I just need help in building them all into shareable .o files
I think that I answered my question. I added a -c to the command and it seems to have worked. Here is the command I used:
g++ -fPIC -c -o obj/list.o list.cpp
That is one of several cpp files, and all seemed to work.