-
Notifications
You must be signed in to change notification settings - Fork 1.8k
add freebsd version of wxStandardPaths::GetExecutablePath #25284
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: master
Are you sure you want to change the base?
Conversation
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Thanks for adding this code, but, indeed, support for it needs to be added to the build system too:
- You need to add new compile-time option
wxHAS_PROCSTAT
(you may choose a better name if you have one, of course), i.e. add it to the "Unix-specific options" section ofsetup.h.in
andbuild/cmake/setup.h.in
. - You should add
AC_CHECK_LIB(procstat, procstat_getpathname)
(this assumes that all the other functions are always available in that library if this one is) toconfigure.ac
and add-lprocstat
toWXCONFIG_LIBS
andAC_DEFINE(wxHAS_PROCSTAT)
if the check succeeds. - For CMake, I'm not sure how exactly to do it, to be honest, but I think you might use
FIND_LIBRARY()
.
src/unix/stdpaths.cpp
Outdated
if (n_proc != 1) | ||
break; | ||
|
||
procstat_getpathname(ps, procs, pathname, sizeof(pathname)); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Shouldn't we check the return value of this one, i.e. compare it with 0?
src/unix/stdpaths.cpp
Outdated
break; | ||
|
||
procstat_getpathname(ps, procs, pathname, sizeof(pathname)); | ||
} while (false); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The do/while(false)
hack is rather ugly and unnecessary in C++ code. It would be nicer to rewrite this without, e.g.
auto* const ps = procstat_open_sysctl();
if (!ps)
return wxStandardPathsBase::GetExecutablePath();
wxON_BLOCK_EXIT1(procstat_close, ps);
auto* const procs = procstat_getprocs();
if (!procs)
return wxStandardPathsBase::GetExecutablePath();
wxON_BLOCK_EXIT2(procstat_freeprocs, ps, procs);
if (procstat_getpathname(ps, procs, pathname, sizeof(pathname)) != 0)
return wxStandardPathsBase::GetExecutablePath();
return pathname;
add lib to wx-config --libs output and define wxHAS_PROCSTAT in cxxflags
use wxON_BLOCK_EXIT to cleanup allocated structs test for wxHAS_PROCSTAT being defined through configure steps
not complete yet
I have refactored the |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Thanks, this looks much better, but there is some confusion between wxUSE_PROCSTAT
and wxHAS_PROCSTAT
: I've suggested the latter to test for procstat stuff presence in the library code, and this is the only place where it's needed, so there is no need to add it to wx-config --cxxflags
output. Also, it's not a user-settable option (unless we want to allow disabling it by using --disable-procstat
with configure, but I don't think it's worth it) it, so wxUSE_PROCSTAT
is not needed at all. Finally, wxHAS_XXX
constants are, by convention, either defined (as 1) or not, they should never be defined as 0.
As for CMake, I'm not sure what is the problem exactly?
P.S. Oh, sorry, and I forgot to say, but configure
needs to be regenerated by running autoconf (ideally using autoconf-for-wx
container with the fixed autoconf version, but you can do it using your autoconf version too, I'll just rerun it before merging then), otherwise your changes are not even tested in the FreeBSD CI job.
src/unix/stdpaths.cpp
Outdated
#include "wx/textfile.h" | ||
|
||
#if defined( __LINUX__ ) || defined( __VMS ) | ||
#include <unistd.h> | ||
#endif | ||
|
||
#if defined(__FreeBSD__) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think this should be
#if defined(__FreeBSD__) | |
#ifdef wxHAS_PROCSTAT |
src/unix/stdpaths.cpp
Outdated
@@ -167,6 +177,28 @@ wxString wxStandardPaths::GetExecutablePath() const | |||
|
|||
if ( !exeStr.empty() ) | |||
return exeStr; | |||
#elif defined(__FreeBSD__) && wxHAS_PROCSTAT |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
And this
#elif defined(__FreeBSD__) && wxHAS_PROCSTAT | |
#elif defined(wxHAS_PROCSTAT) |
src/unix/stdpaths.cpp
Outdated
|
||
// procstat_freeprocs should be called before procstat_close | ||
wxON_BLOCK_EXIT2(procstat_freeprocs, ps, procs); | ||
wxON_BLOCK_EXIT1(procstat_close, ps); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This line needs to be moved above (before procs
initialization), otherwise procstat_close()
won't be called if procstat_getprocs()
fails and we return early.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
procstat_close
needs to be called after procstat_freeprocs
so that ps
is still valid in the procstat_freeprocs
call. I was thinking code execution order, but the destructors would be run while clearing the stack, so that would be lifo making the first code line the last to run, which would work.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Not sure if I'm missing something, but yes, exactly: because the dtors run in the opposite order, you have to put the guard for procstat_close()
before the one for procstat_freeprocs()
.
configure.ac
Outdated
@@ -7732,6 +7751,11 @@ case "$wxUSE_ZLIB" in | |||
;; | |||
esac | |||
|
|||
if test "$wxUSE_PROCSTAT" = "yes"; then | |||
WXCONFIG_CXXFLAGS="$WXCONFIG_CXXFLAGS -DwxHAS_PROCSTAT=1" |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This shouldn't be necessary: wxHAS_PROCSTAT
is only used internally.
WXCONFIG_CXXFLAGS="$WXCONFIG_CXXFLAGS -DwxHAS_PROCSTAT=1" |
build/cmake/setup.h.in
Outdated
/* | ||
On FreeBSD use libprocstat to get executable path name. | ||
*/ | ||
#cmakedefine01 wxHAS_PROCSTAT |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
#cmakedefine01 wxHAS_PROCSTAT | |
#cmakedefine wxHAS_PROCSTAT |
configure.ac
Outdated
@@ -200,6 +200,7 @@ case "${host}" in | |||
AC_DEFINE(__FREEBSD__) | |||
AC_DEFINE(__BSD__) | |||
DEFAULT_DEFAULT_wxUSE_GTK=1 | |||
wxUSE_PROCSTAT=yes |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I don't think this is needed at all, we already check for host
before testing for procstat below.
configure.ac
Outdated
*-*-freebsd*) | ||
AC_MSG_CHECKING([for libprocstat]) | ||
AC_CHECK_LIB(procstat, procstat_getpathname, [ | ||
PROCSTAT_LINK=" -L/usr/lib -lprocstat" |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Is -L/usr/lib
really needed? I'd expect the linked to look in this directory by default.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
When building static libs, the libs and app built and found the lib in /usr/lib
but when building the shared libs linking failed with unable to find libprocstat
so I added -L/usr/lib
build/cmake/build.cfg.in
Outdated
@@ -22,6 +22,7 @@ USE_GUI=@wxUSE_GUI_bf@ | |||
USE_HTML=@wxUSE_HTML_bf@ | |||
USE_MEDIA=@wxUSE_MEDIA_bf@ | |||
USE_OPENGL=@wxUSE_OPENGL_bf@ | |||
USE_PROCSTAT=@wxUSE_PROCSTAT_bf@ |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I don't think we need this.
I discovered the need to run autoconf, I didn't commit |
Yes, this is why using the container image mentioned above is best, but if this can't be done, it's still better to regenerate it to at least test compiling this code in the FreeBSD CI job. |
remove define in cxxflags rearrange placement of wxON_BLOCK_EXIT
Also of note, I'm not sure the lib tests need to go into configure, it would appear that freebsd is the only system using libprocstat, FreeBSD > 9.0 will always have it, searching man pages for procstat_* functions for netbsd, openbsd, dragonfly, darwin all come up empty. |
build/cmake/lib/base/CMakeLists.txt
Outdated
|
||
if (${CMAKE_SYSTEM_NAME} STREQUAL "FreeBSD") | ||
wx_lib_link_libraries(wxbase PUBLIC "-lprocstat") | ||
target_compile_definitions(wxbase PRIVATE "-DwxHAS_PROCSTAT") |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
We normally don't use compile definitions. Everything is added to setup.h[.in]
.
Most of the items there are named HAVE_[NAME]
, so in this case HAVE_PROCSTAT
.
To integrate it in CMake, I think you can add a check in setup.cmake
to check if the header is available:
check_include_file(libprocstat.h HAVE_PROCSTAT)
This will set HAVE_PROCSTAT
to 1 if it is available, and if setup.h.in
contains this variable, it will be automatically set in the generated setup.h
.
And then in base/CmakeLists.txt
if (HAVE_PROCSTAT)
wx_lib_link_libraries(wxbase PUBLIC "-lprocstat")
endif()
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Everything I can think of trying with cmake has failed, using cmake 3.31.6. I think mainly due to the inability to include libprocstat.h
by itself. I tried check_include_files
with the list of includes needed but that has failed as well.
Using find_library
in cmake does work, but still need to use target_compile_definitions
to define it when compiling.
Every FreeBSD release since 9.0 (released 2012) has had libprocstat
and headers. The searches I have done show FreeBSD as the only one using libprocstat
. So just testing for FreeBSD
will ensure the headers and lib exists, it isn't an optional component and no other system appears to have it.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
You'll need to update setup.h.in
too. With the patch below, the CMake build works for me (the library can be PRIVATE
and doesn't need -l
prefix). I also couldn't get check_include_files
to work.
I used wxHAVE_PROCSTAT
name because you also use this name in stdpaths.cpp
.
For configure, I think you can just replace CXXFLAGS="${CXXFLAGS} -DwxHAVE_PROCSTAT"
with AC_DEFINE(wxHAVE_PROCSTAT)
, but I have not tested this.
build/cmake/lib/base/CMakeLists.txt | 5 +++++
build/cmake/setup.h.in | 3 +++
setup.h.in | 3 +++
src/png | 2 +-
src/webp | 0
5 files changed, 12 insertions(+), 1 deletion(-)
diff --git a/build/cmake/lib/base/CMakeLists.txt b/build/cmake/lib/base/CMakeLists.txt
index 7f60e93f527..32507f919c6 100644
--- a/build/cmake/lib/base/CMakeLists.txt
+++ b/build/cmake/lib/base/CMakeLists.txt
@@ -52,6 +52,11 @@ if(wxUSE_THREADS AND CMAKE_THREAD_LIBS_INIT)
wx_lib_link_libraries(wxbase PRIVATE ${CMAKE_THREAD_LIBS_INIT})
endif()
+if (${CMAKE_SYSTEM_NAME} STREQUAL "FreeBSD")
+ set(wxHAVE_PROCSTAT 1)
+ wx_lib_link_libraries(wxbase PRIVATE "procstat")
+endif()
+
if(APPLE)
wx_lib_link_libraries(wxbase
PUBLIC
diff --git a/build/cmake/setup.h.in b/build/cmake/setup.h.in
index 952dcb68a49..d469368809b 100644
--- a/build/cmake/setup.h.in
+++ b/build/cmake/setup.h.in
@@ -908,6 +908,9 @@
/* Define if you have wcsnlen() function */
#cmakedefine wxHAVE_WCSNLEN 1
+/* define if you have procstat (FreeBSD) */
+#cmakedefine wxHAVE_PROCSTAT 1
+
/* The number of bytes in a wchar_t. */
@SIZEOF_WCHAR_T_CODE@
diff --git a/setup.h.in b/setup.h.in
index 5d65c131a09..870cf9819eb 100644
--- a/setup.h.in
+++ b/setup.h.in
@@ -907,6 +907,9 @@
/* Define if you have wcsnlen() function */
#undef wxHAVE_WCSNLEN
+/* define if you have procstat (FreeBSD) */
+#undef wxHAVE_PROCSTAT
+
/* The number of bytes in a wchar_t. */
#undef SIZEOF_WCHAR_T
move FreeBSD test into setup.cmake to get the define in setup.h
@MaartenBent using set have procstat works, only if it is in I see two issues, the second would need to be addressed in a different issue.
This means with static libs, building the samples, demos and utils works. (except wxrc which I need to manually add With shared libs, the libs build but the apps fail without
This would appear to be dependencies, shared libs fail to link with libs that haven't compiled yet. Although, base linking to gtk libs doesn't sound right to me.
|
I guess this makes sense. I have no idea what is happening with the libraries it tries to link to. For me building the I did have to add some extra CMake flags, similar to what is needed in CI, to make everything work, but this was related to finding system libraries, not wx libraries: Lines 67 to 71 in 5bc736d
|
Hi, currently on FreeBSD
wxStandardPaths::GetExecutablePath
returns an empty string, this update fills in the right path.Question - where would I add
-lprocstat
towx-config --libs
output when run on FreeBSD?